Path: blob/main/src/solvers/dgsem_p4est/subcell_limiters_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: noindent67function calc_bounds_twosided_interface!(var_min, var_max, variable, u,8semi, mesh::P4estMesh{3}, equations)9_, _, dg, cache = mesh_equations_solver_cache(semi)1011(; neighbor_ids, node_indices) = cache.interfaces12index_range = eachnode(dg)1314for interface in eachinterface(dg, cache)15# Get element and side index information on the primary element16primary_element = neighbor_ids[1, interface]17primary_indices = node_indices[1, interface]1819# Get element and side index information on the secondary element20secondary_element = neighbor_ids[2, interface]21secondary_indices = node_indices[2, interface]2223# Create the local i,j,k indexing24i_primary_start, i_primary_step_i, i_primary_step_j = index_to_start_step_3d(primary_indices[1],25index_range)26j_primary_start, j_primary_step_i, j_primary_step_j = index_to_start_step_3d(primary_indices[2],27index_range)28k_primary_start, k_primary_step_i, k_primary_step_j = index_to_start_step_3d(primary_indices[3],29index_range)3031i_primary = i_primary_start32j_primary = j_primary_start33k_primary = k_primary_start3435i_secondary_start, i_secondary_step_i, i_secondary_step_j = index_to_start_step_3d(secondary_indices[1],36index_range)37j_secondary_start, j_secondary_step_i, j_secondary_step_j = index_to_start_step_3d(secondary_indices[2],38index_range)39k_secondary_start, k_secondary_step_i, k_secondary_step_j = index_to_start_step_3d(secondary_indices[3],40index_range)4142i_secondary = i_secondary_start43j_secondary = j_secondary_start44k_secondary = k_secondary_start4546for j in eachnode(dg)47for i in eachnode(dg)48var_primary = u[variable, i_primary, j_primary, k_primary,49primary_element]50var_secondary = u[variable, i_secondary, j_secondary, k_secondary,51secondary_element]5253var_min[i_primary, j_primary, k_primary, primary_element] = min(var_min[i_primary,54j_primary,55k_primary,56primary_element],57var_secondary)58var_max[i_primary, j_primary, k_primary, primary_element] = max(var_max[i_primary,59j_primary,60k_primary,61primary_element],62var_secondary)6364var_min[i_secondary, j_secondary, k_secondary, secondary_element] = min(var_min[i_secondary,65j_secondary,66k_secondary,67secondary_element],68var_primary)69var_max[i_secondary, j_secondary, k_secondary, secondary_element] = max(var_max[i_secondary,70j_secondary,71k_secondary,72secondary_element],73var_primary)7475# Increment the primary element indices76i_primary += i_primary_step_i77j_primary += j_primary_step_i78k_primary += k_primary_step_i79# Increment the secondary element surface indices80i_secondary += i_secondary_step_i81j_secondary += j_secondary_step_i82k_secondary += k_secondary_step_i83end84# Increment the primary element indices85i_primary += i_primary_step_j86j_primary += j_primary_step_j87k_primary += k_primary_step_j88# Increment the secondary element surface indices89i_secondary += i_secondary_step_j90j_secondary += j_secondary_step_j91k_secondary += k_secondary_step_j92end93end9495return nothing96end9798@inline function calc_bounds_twosided_boundary!(var_min, var_max, variable, u, t,99boundary_conditions::BoundaryConditionPeriodic,100mesh::P4estMesh{3},101equations, dg, cache)102return nothing103end104105@inline function calc_bounds_twosided_boundary!(var_min, var_max, variable, u, t,106boundary_conditions,107mesh::P4estMesh{3},108equations, dg, cache)109(; boundary_condition_types, boundary_indices) = boundary_conditions110(; contravariant_vectors) = cache.elements111112(; boundaries) = cache113index_range = eachnode(dg)114115foreach_enumerate(boundary_condition_types) do (i, boundary_condition)116for boundary in boundary_indices[i]117element = boundaries.neighbor_ids[boundary]118node_indices = boundaries.node_indices[boundary]119direction = indices2direction(node_indices)120121i_node_start, i_node_step_i, i_node_step_j = index_to_start_step_3d(node_indices[1],122index_range)123j_node_start, j_node_step_i, j_node_step_j = index_to_start_step_3d(node_indices[2],124index_range)125k_node_start, k_node_step_i, k_node_step_j = index_to_start_step_3d(node_indices[3],126index_range)127128i_node = i_node_start129j_node = j_node_start130k_node = k_node_start131for j in eachnode(dg)132for i in eachnode(dg)133normal_direction = get_normal_direction(direction,134contravariant_vectors,135i_node, j_node, k_node,136element)137138u_inner = get_node_vars(u, equations, dg, i_node, j_node, k_node,139element)140141u_outer = get_boundary_outer_state(u_inner, t, boundary_condition,142normal_direction,143mesh, equations, dg, cache,144i_node, j_node, k_node, element)145var_outer = u_outer[variable]146147var_min[i_node, j_node, k_node, element] = min(var_min[i_node,148j_node,149k_node,150element],151var_outer)152var_max[i_node, j_node, k_node, element] = max(var_max[i_node,153j_node,154k_node,155element],156var_outer)157158i_node += i_node_step_i159j_node += j_node_step_i160k_node += k_node_step_i161end162i_node += i_node_step_j163j_node += j_node_step_j164k_node += k_node_step_j165end166end167end168169return nothing170end171172function calc_bounds_onesided_interface!(var_minmax, minmax, variable, u,173semi, mesh::P4estMesh{3})174_, equations, dg, cache = mesh_equations_solver_cache(semi)175176(; neighbor_ids, node_indices) = cache.interfaces177index_range = eachnode(dg)178179for interface in eachinterface(dg, cache)180# Get element and side index information on the primary element181primary_element = neighbor_ids[1, interface]182primary_indices = node_indices[1, interface]183184# Get element and side index information on the secondary element185secondary_element = neighbor_ids[2, interface]186secondary_indices = node_indices[2, interface]187188# Create the local i,j,k indexing189i_primary_start, i_primary_step_i, i_primary_step_j = index_to_start_step_3d(primary_indices[1],190index_range)191j_primary_start, j_primary_step_i, j_primary_step_j = index_to_start_step_3d(primary_indices[2],192index_range)193k_primary_start, k_primary_step_i, k_primary_step_j = index_to_start_step_3d(primary_indices[3],194index_range)195196i_primary = i_primary_start197j_primary = j_primary_start198k_primary = k_primary_start199200i_secondary_start, i_secondary_step_i, i_secondary_step_j = index_to_start_step_3d(secondary_indices[1],201index_range)202j_secondary_start, j_secondary_step_i, j_secondary_step_j = index_to_start_step_3d(secondary_indices[2],203index_range)204k_secondary_start, k_secondary_step_i, k_secondary_step_j = index_to_start_step_3d(secondary_indices[3],205index_range)206207i_secondary = i_secondary_start208j_secondary = j_secondary_start209k_secondary = k_secondary_start210211for j in eachnode(dg)212for i in eachnode(dg)213var_primary = variable(get_node_vars(u, equations, dg, i_primary,214j_primary, k_primary,215primary_element), equations)216var_secondary = variable(get_node_vars(u, equations, dg, i_secondary,217j_secondary, k_secondary,218secondary_element),219equations)220221var_minmax[i_primary, j_primary, k_primary, primary_element] = minmax(var_minmax[i_primary,222j_primary,223k_primary,224primary_element],225var_secondary)226var_minmax[i_secondary, j_secondary, k_secondary, secondary_element] = minmax(var_minmax[i_secondary,227j_secondary,228k_secondary,229secondary_element],230var_primary)231232# Increment the primary element indices233i_primary += i_primary_step_i234j_primary += j_primary_step_i235k_primary += k_primary_step_i236# Increment the secondary element surface indices237i_secondary += i_secondary_step_i238j_secondary += j_secondary_step_i239k_secondary += k_secondary_step_i240end241# Increment the primary element indices242i_primary += i_primary_step_j243j_primary += j_primary_step_j244k_primary += k_primary_step_j245# Increment the secondary element surface indices246i_secondary += i_secondary_step_j247j_secondary += j_secondary_step_j248k_secondary += k_secondary_step_j249end250end251252return nothing253end254255@inline function calc_bounds_onesided_boundary!(var_minmax, minmax, variable, u, t,256boundary_conditions::BoundaryConditionPeriodic,257mesh::P4estMesh{3},258equations, dg, cache)259return nothing260end261262@inline function calc_bounds_onesided_boundary!(var_minmax, minmax, variable, u, t,263boundary_conditions,264mesh::P4estMesh{3},265equations, dg, cache)266(; boundary_condition_types, boundary_indices) = boundary_conditions267(; contravariant_vectors) = cache.elements268269(; boundaries) = cache270index_range = eachnode(dg)271272foreach_enumerate(boundary_condition_types) do (i, boundary_condition)273for boundary in boundary_indices[i]274element = boundaries.neighbor_ids[boundary]275node_indices = boundaries.node_indices[boundary]276direction = indices2direction(node_indices)277278i_node_start, i_node_step_i, i_node_step_j = index_to_start_step_3d(node_indices[1],279index_range)280j_node_start, j_node_step_i, j_node_step_j = index_to_start_step_3d(node_indices[2],281index_range)282k_node_start, k_node_step_i, k_node_step_j = index_to_start_step_3d(node_indices[3],283index_range)284285i_node = i_node_start286j_node = j_node_start287k_node = k_node_start288for j in eachnode(dg)289for i in eachnode(dg)290normal_direction = get_normal_direction(direction,291contravariant_vectors,292i_node, j_node, k_node,293element)294295u_inner = get_node_vars(u, equations, dg, i_node, j_node, k_node,296element)297298u_outer = get_boundary_outer_state(u_inner, t, boundary_condition,299normal_direction,300mesh, equations, dg, cache,301i_node, j_node, k_node, element)302var_outer = variable(u_outer, equations)303304var_minmax[i_node, j_node, k_node, element] = minmax(var_minmax[i_node,305j_node,306k_node,307element],308var_outer)309310i_node += i_node_step_i311j_node += j_node_step_i312k_node += k_node_step_i313end314i_node += i_node_step_j315j_node += j_node_step_j316k_node += k_node_step_j317end318end319end320321return nothing322end323end # @muladd324325326