Path: blob/main/src/solvers/dgsem_t8code/containers_3d.jl
5590 views
# By default, Julia/LLVM does not use fused multiply-add operations (FMAs).1# Since these FMAs can increase the performance of many numerical algorithms,2# we need to opt-in explicitly.3# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details.4@muladd begin5#! format: noindent67# Interpolate tree_node_coordinates to each quadrant at the specified nodes8function calc_node_coordinates!(node_coordinates,9mesh::T8codeMesh{3, RealT},10nodes::AbstractVector) where {RealT <: Real}11# We use `StrideArray`s here since these buffers are used in performance-critical12# places and the additional information passed to the compiler makes them faster13# than native `Array`s.14tmp1 = StrideArray(undef, real(mesh),15StaticInt(3), static_length(nodes), static_length(mesh.nodes),16static_length(mesh.nodes))17matrix1 = StrideArray(undef, real(mesh),18static_length(nodes), static_length(mesh.nodes))19matrix2 = similar(matrix1)20matrix3 = similar(matrix1)21baryweights_in = barycentric_weights(mesh.nodes)2223num_local_trees = t8_forest_get_num_local_trees(mesh.forest)2425current_index = 026for itree in 0:(num_local_trees - 1)27tree_class = t8_forest_get_tree_class(mesh.forest, itree)28eclass_scheme = t8_forest_get_eclass_scheme(mesh.forest, tree_class)29num_elements_in_tree = t8_forest_get_tree_num_elements(mesh.forest, itree)30global_itree = t8_forest_global_tree_id(mesh.forest, itree)3132for ielement in 0:(num_elements_in_tree - 1)33element = t8_forest_get_element_in_tree(mesh.forest, itree, ielement)34element_level = t8_element_level(eclass_scheme, element)3536# Note, `t8_hex_len` is encoded as an integer (Morton encoding) in37# relation to `t8_hex_root_len`. This line transforms the38# "integer" length to a float in relation to the unit interval [0,1].39element_length = t8_hex_len(element_level) / t8_hex_root_len4041element_coords = Vector{RealT}(undef, 3)42t8_element_vertex_reference_coords(eclass_scheme, element, 0,43pointer(element_coords))4445nodes_out_x = (2 *46(element_length * 0.5f0 * (nodes .+ 1) .+ element_coords[1]) .-471)48nodes_out_y = (2 *49(element_length * 0.5f0 * (nodes .+ 1) .+ element_coords[2]) .-501)51nodes_out_z = (2 *52(element_length * 0.5f0 * (nodes .+ 1) .+ element_coords[3]) .-531)5455polynomial_interpolation_matrix!(matrix1, mesh.nodes, nodes_out_x,56baryweights_in)57polynomial_interpolation_matrix!(matrix2, mesh.nodes, nodes_out_y,58baryweights_in)59polynomial_interpolation_matrix!(matrix3, mesh.nodes, nodes_out_z,60baryweights_in)6162multiply_dimensionwise!(view(node_coordinates, :, :, :, :,63current_index += 1),64matrix1, matrix2, matrix3,65view(mesh.tree_node_coordinates, :, :, :, :,66global_itree + 1), tmp1)67end68end6970return node_coordinates71end7273# This routine was copied and adapted from `src/dgsem_p4est/containers_3d.jl`: `orientation_to_indices_p4est`.74function init_mortar_neighbor_ids!(mortars::P4estMortarContainer{3}, my_face,75other_face, orientation, neighbor_ielements,76mortar_id)77# my_face and other_face are the face directions (zero-based)78# of "my side" and "other side" respectively.79# Face corner 0 of the face with the lower face direction connects to a corner of the other face.80# The number of this corner is the orientation code in `p4est`.81lower = my_face <= other_face8283# x_pos, y_neg, and z_pos are the directions in which the face has right-handed coordinates84# when looked at from the outside.85my_right_handed = my_face in (1, 2, 5)86other_right_handed = other_face in (1, 2, 5)8788# If both or none are right-handed when looked at from the outside, they will have different89# orientations when looked at from the same side of the interface.90flipped = my_right_handed == other_right_handed9192# In the following illustrations, the face corner numbering of `p4est` is shown.93# ξ and η are the local coordinates of the respective face.94# We're looking at both faces from the same side of the interface, so that "other side"95# (in the illustrations on the left) has right-handed coordinates.96if !flipped97if orientation == 098# Corner 0 of other side matches corner 0 of my side99# 2┌──────┐3 2┌──────┐3100# │ │ │ │101# │ │ │ │102# 0└──────┘1 0└──────┘1103# η η104# ↑ ↑105# │ │106# └───> ξ └───> ξ107108mortars.neighbor_ids[1, mortar_id] = neighbor_ielements[1] + 1109mortars.neighbor_ids[2, mortar_id] = neighbor_ielements[2] + 1110mortars.neighbor_ids[3, mortar_id] = neighbor_ielements[3] + 1111mortars.neighbor_ids[4, mortar_id] = neighbor_ielements[4] + 1112113elseif ((lower && orientation == 2) # Corner 0 of my side matches corner 2 of other side114||115(!lower && orientation == 1)) # Corner 0 of other side matches corner 1 of my side116# 2┌──────┐3 0┌──────┐2117# │ │ │ │118# │ │ │ │119# 0└──────┘1 1└──────┘3120# η ┌───> η121# ↑ │122# │ ↓123# └───> ξ ξ124125mortars.neighbor_ids[1, mortar_id] = neighbor_ielements[2] + 1126mortars.neighbor_ids[2, mortar_id] = neighbor_ielements[4] + 1127mortars.neighbor_ids[3, mortar_id] = neighbor_ielements[1] + 1128mortars.neighbor_ids[4, mortar_id] = neighbor_ielements[3] + 1129130elseif ((lower && orientation == 1) # Corner 0 of my side matches corner 1 of other side131||132(!lower && orientation == 2)) # Corner 0 of other side matches corner 2 of my side133# 2┌──────┐3 3┌──────┐1134# │ │ │ │135# │ │ │ │136# 0└──────┘1 2└──────┘0137# η ξ138# ↑ ↑139# │ │140# └───> ξ η <───┘141142mortars.neighbor_ids[1, mortar_id] = neighbor_ielements[3] + 1143mortars.neighbor_ids[2, mortar_id] = neighbor_ielements[1] + 1144mortars.neighbor_ids[3, mortar_id] = neighbor_ielements[4] + 1145mortars.neighbor_ids[4, mortar_id] = neighbor_ielements[2] + 1146147else # orientation == 3148# Corner 0 of my side matches corner 3 of other side and149# corner 0 of other side matches corner 3 of my side.150# 2┌──────┐3 1┌──────┐0151# │ │ │ │152# │ │ │ │153# 0└──────┘1 3└──────┘2154# η ξ <───┐155# ↑ │156# │ ↓157# └───> ξ η158159mortars.neighbor_ids[1, mortar_id] = neighbor_ielements[4] + 1160mortars.neighbor_ids[2, mortar_id] = neighbor_ielements[3] + 1161mortars.neighbor_ids[3, mortar_id] = neighbor_ielements[2] + 1162mortars.neighbor_ids[4, mortar_id] = neighbor_ielements[1] + 1163end164else # flipped165if orientation == 0166# Corner 0 of other side matches corner 0 of my side167# 2┌──────┐3 1┌──────┐3168# │ │ │ │169# │ │ │ │170# 0└──────┘1 0└──────┘2171# η ξ172# ↑ ↑173# │ │174# └───> ξ └───> η175176mortars.neighbor_ids[1, mortar_id] = neighbor_ielements[1] + 1177mortars.neighbor_ids[2, mortar_id] = neighbor_ielements[3] + 1178mortars.neighbor_ids[3, mortar_id] = neighbor_ielements[2] + 1179mortars.neighbor_ids[4, mortar_id] = neighbor_ielements[4] + 1180181elseif orientation == 2182# Corner 0 of my side matches corner 2 of other side and183# corner 0 of other side matches corner 2 of my side.184# 2┌──────┐3 0┌──────┐1185# │ │ │ │186# │ │ │ │187# 0└──────┘1 2└──────┘3188# η ┌───> ξ189# ↑ │190# │ ↓191# └───> ξ η192193mortars.neighbor_ids[1, mortar_id] = neighbor_ielements[3] + 1194mortars.neighbor_ids[2, mortar_id] = neighbor_ielements[4] + 1195mortars.neighbor_ids[3, mortar_id] = neighbor_ielements[1] + 1196mortars.neighbor_ids[4, mortar_id] = neighbor_ielements[2] + 1197198elseif orientation == 1199# Corner 0 of my side matches corner 1 of other side and200# corner 0 of other side matches corner 1 of my side.201# 2┌──────┐3 3┌──────┐2202# │ │ │ │203# │ │ │ │204# 0└──────┘1 1└──────┘0205# η η206# ↑ ↑207# │ │208# └───> ξ ξ <───┘209210mortars.neighbor_ids[1, mortar_id] = neighbor_ielements[2] + 1211mortars.neighbor_ids[2, mortar_id] = neighbor_ielements[1] + 1212mortars.neighbor_ids[3, mortar_id] = neighbor_ielements[4] + 1213mortars.neighbor_ids[4, mortar_id] = neighbor_ielements[3] + 1214215else # orientation == 3216# Corner 0 of my side matches corner 3 of other side and217# corner 0 of other side matches corner 3 of my side.218# 2┌──────┐3 2┌──────┐0219# │ │ │ │220# │ │ │ │221# 0└──────┘1 3└──────┘1222# η η <───┐223# ↑ │224# │ ↓225# └───> ξ ξ226227mortars.neighbor_ids[1, mortar_id] = neighbor_ielements[4] + 1228mortars.neighbor_ids[2, mortar_id] = neighbor_ielements[2] + 1229mortars.neighbor_ids[3, mortar_id] = neighbor_ielements[3] + 1230mortars.neighbor_ids[4, mortar_id] = neighbor_ielements[1] + 1231end232end233end234end # @muladd235236237