Path: blob/main/src/solvers/dgsem_p4est/containers_parallel_3d.jl
5616 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# Initialize node_indices of MPI interface container8@inline function init_mpi_interface_node_indices!(mpi_interfaces::P4estMPIInterfaceContainer{3},9faces, local_side, orientation,10mpi_interface_id)11# Align interface at the primary element (primary element has surface indices (:i_forward, :j_forward)).12# The secondary element needs to be indexed differently.13if local_side == 114surface_index1 = :i_forward15surface_index2 = :j_forward16else # local_side == 217surface_index1, surface_index2 = orientation_to_indices_p4est(faces[2],18faces[1],19orientation)20end2122if faces[local_side] == 023# Index face in negative x-direction24mpi_interfaces.node_indices[mpi_interface_id] = (:begin, surface_index1,25surface_index2)26elseif faces[local_side] == 127# Index face in positive x-direction28mpi_interfaces.node_indices[mpi_interface_id] = (:end, surface_index1,29surface_index2)30elseif faces[local_side] == 231# Index face in negative y-direction32mpi_interfaces.node_indices[mpi_interface_id] = (surface_index1, :begin,33surface_index2)34elseif faces[local_side] == 335# Index face in positive y-direction36mpi_interfaces.node_indices[mpi_interface_id] = (surface_index1, :end,37surface_index2)38elseif faces[local_side] == 439# Index face in negative z-direction40mpi_interfaces.node_indices[mpi_interface_id] = (surface_index1, surface_index2,41:begin)42else # faces[local_side] == 543# Index face in positive z-direction44mpi_interfaces.node_indices[mpi_interface_id] = (surface_index1, surface_index2,45:end)46end4748return mpi_interfaces49end5051# Initialize node_indices of MPI mortar container. Works the same as for its serial counterpart.52# faces[1] is expected to be the face of the small side.53@inline function init_mortar_node_indices!(mortars::P4estMPIMortarContainer{3},54faces, orientation, mortar_id)55for side in 1:256# Align mortar at small side.57# The large side needs to be indexed differently.58if side == 159surface_index1 = :i_forward60surface_index2 = :j_forward61else62surface_index1, surface_index2 = orientation_to_indices_p4est(faces[2],63faces[1],64orientation)65end6667if faces[side] == 068# Index face in negative x-direction69mortars.node_indices[side, mortar_id] = (:begin, surface_index1,70surface_index2)71elseif faces[side] == 172# Index face in positive x-direction73mortars.node_indices[side, mortar_id] = (:end, surface_index1,74surface_index2)75elseif faces[side] == 276# Index face in negative y-direction77mortars.node_indices[side, mortar_id] = (surface_index1, :begin,78surface_index2)79elseif faces[side] == 380# Index face in positive y-direction81mortars.node_indices[side, mortar_id] = (surface_index1, :end,82surface_index2)83elseif faces[side] == 484# Index face in negative z-direction85mortars.node_indices[side, mortar_id] = (surface_index1, surface_index2,86:begin)87else # faces[side] == 588# Index face in positive z-direction89mortars.node_indices[side, mortar_id] = (surface_index1, surface_index2,90:end)91end92end9394return mortars95end9697# Normal directions of small element surfaces are needed to calculate the mortar fluxes. Initialize98# them for locally available small elements.99function init_normal_directions!(mpi_mortars::P4estMPIMortarContainer{3},100basis, elements)101@unpack local_neighbor_ids, local_neighbor_positions, node_indices = mpi_mortars102@unpack contravariant_vectors = elements103index_range = eachnode(basis)104105@threaded for mortar in 1:nmpimortars(mpi_mortars)106small_indices = node_indices[1, mortar]107small_direction = indices2direction(small_indices)108109i_small_start, i_small_step_i, i_small_step_j = index_to_start_step_3d(small_indices[1],110index_range)111j_small_start, j_small_step_i, j_small_step_j = index_to_start_step_3d(small_indices[2],112index_range)113k_small_start, k_small_step_i, k_small_step_j = index_to_start_step_3d(small_indices[3],114index_range)115116for (element, position) in zip(local_neighbor_ids[mortar],117local_neighbor_positions[mortar])118# ignore large elements119if position == 5120continue121end122123i_small = i_small_start124j_small = j_small_start125k_small = k_small_start126for j in eachnode(basis)127for i in eachnode(basis)128# Get the normal direction on the small element.129# Note, contravariant vectors at interfaces in negative coordinate direction130# are pointing inwards. This is handled by `get_normal_direction`.131normal_direction = get_normal_direction(small_direction,132contravariant_vectors,133i_small, j_small, k_small,134element)135@views mpi_mortars.normal_directions[:, i, j, position, mortar] .= normal_direction136137i_small += i_small_step_i138j_small += j_small_step_i139k_small += k_small_step_i140end141i_small += i_small_step_j142j_small += j_small_step_j143k_small += k_small_step_j144end145end146end147148return nothing149end150end # muladd151152153