Path: blob/main/src/solvers/dgsem_p4est/subcell_limiters_2d.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{2}, 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 indexing24i_primary_start, i_primary_step = index_to_start_step_2d(primary_indices[1],25index_range)26j_primary_start, j_primary_step = index_to_start_step_2d(primary_indices[2],27index_range)28i_secondary_start, i_secondary_step = index_to_start_step_2d(secondary_indices[1],29index_range)30j_secondary_start, j_secondary_step = index_to_start_step_2d(secondary_indices[2],31index_range)3233i_primary = i_primary_start34j_primary = j_primary_start35i_secondary = i_secondary_start36j_secondary = j_secondary_start3738for node in eachnode(dg)39var_primary = u[variable, i_primary, j_primary, primary_element]40var_secondary = u[variable, i_secondary, j_secondary, secondary_element]4142var_min[i_primary, j_primary, primary_element] = min(var_min[i_primary,43j_primary,44primary_element],45var_secondary)46var_max[i_primary, j_primary, primary_element] = max(var_max[i_primary,47j_primary,48primary_element],49var_secondary)5051var_min[i_secondary, j_secondary, secondary_element] = min(var_min[i_secondary,52j_secondary,53secondary_element],54var_primary)55var_max[i_secondary, j_secondary, secondary_element] = max(var_max[i_secondary,56j_secondary,57secondary_element],58var_primary)5960# Increment primary element indices61i_primary += i_primary_step62j_primary += j_primary_step63i_secondary += i_secondary_step64j_secondary += j_secondary_step65end66end6768return nothing69end7071@inline function calc_bounds_twosided_boundary!(var_min, var_max, variable, u, t,72boundary_conditions::BoundaryConditionPeriodic,73mesh::P4estMesh{2},74equations, dg, cache)75return nothing76end7778@inline function calc_bounds_twosided_boundary!(var_min, var_max, variable, u, t,79boundary_conditions,80mesh::P4estMesh{2},81equations, dg, cache)82(; boundary_condition_types, boundary_indices) = boundary_conditions83(; contravariant_vectors) = cache.elements8485(; boundaries) = cache86index_range = eachnode(dg)8788foreach_enumerate(boundary_condition_types) do (i, boundary_condition)89for boundary in boundary_indices[i]90element = boundaries.neighbor_ids[boundary]91node_indices = boundaries.node_indices[boundary]92direction = indices2direction(node_indices)9394i_node_start, i_node_step = index_to_start_step_2d(node_indices[1],95index_range)96j_node_start, j_node_step = index_to_start_step_2d(node_indices[2],97index_range)9899i_node = i_node_start100j_node = j_node_start101for i in eachnode(dg)102normal_direction = get_normal_direction(direction,103contravariant_vectors,104i_node, j_node, element)105106u_inner = get_node_vars(u, equations, dg, i_node, j_node, element)107108u_outer = get_boundary_outer_state(u_inner, t, boundary_condition,109normal_direction,110mesh, equations, dg, cache,111i_node, j_node, element)112var_outer = u_outer[variable]113114var_min[i_node, j_node, element] = min(var_min[i_node, j_node, element],115var_outer)116var_max[i_node, j_node, element] = max(var_max[i_node, j_node, element],117var_outer)118119i_node += i_node_step120j_node += j_node_step121end122end123end124125return nothing126end127128function calc_bounds_onesided_interface!(var_minmax, minmax, variable, u,129semi, mesh::P4estMesh{2})130_, equations, dg, cache = mesh_equations_solver_cache(semi)131132(; neighbor_ids, node_indices) = cache.interfaces133index_range = eachnode(dg)134135for interface in eachinterface(dg, cache)136# Get element and side index information on the primary element137primary_element = neighbor_ids[1, interface]138primary_indices = node_indices[1, interface]139140# Get element and side index information on the secondary element141secondary_element = neighbor_ids[2, interface]142secondary_indices = node_indices[2, interface]143144# Create the local i,j indexing145i_primary_start, i_primary_step = index_to_start_step_2d(primary_indices[1],146index_range)147j_primary_start, j_primary_step = index_to_start_step_2d(primary_indices[2],148index_range)149i_secondary_start, i_secondary_step = index_to_start_step_2d(secondary_indices[1],150index_range)151j_secondary_start, j_secondary_step = index_to_start_step_2d(secondary_indices[2],152index_range)153154i_primary = i_primary_start155j_primary = j_primary_start156i_secondary = i_secondary_start157j_secondary = j_secondary_start158159for node in eachnode(dg)160var_primary = variable(get_node_vars(u, equations, dg, i_primary, j_primary,161primary_element), equations)162var_secondary = variable(get_node_vars(u, equations, dg, i_secondary,163j_secondary, secondary_element),164equations)165166var_minmax[i_primary, j_primary, primary_element] = minmax(var_minmax[i_primary,167j_primary,168primary_element],169var_secondary)170var_minmax[i_secondary, j_secondary, secondary_element] = minmax(var_minmax[i_secondary,171j_secondary,172secondary_element],173var_primary)174175# Increment primary element indices176i_primary += i_primary_step177j_primary += j_primary_step178i_secondary += i_secondary_step179j_secondary += j_secondary_step180end181end182183return nothing184end185186@inline function calc_bounds_onesided_boundary!(var_minmax, minmax, variable, u, t,187boundary_conditions::BoundaryConditionPeriodic,188mesh::P4estMesh{2},189equations, dg, cache)190return nothing191end192193@inline function calc_bounds_onesided_boundary!(var_minmax, minmax, variable, u, t,194boundary_conditions,195mesh::P4estMesh{2},196equations, dg, cache)197(; boundary_condition_types, boundary_indices) = boundary_conditions198(; contravariant_vectors) = cache.elements199200(; boundaries) = cache201index_range = eachnode(dg)202203foreach_enumerate(boundary_condition_types) do (i, boundary_condition)204for boundary in boundary_indices[i]205element = boundaries.neighbor_ids[boundary]206node_indices = boundaries.node_indices[boundary]207direction = indices2direction(node_indices)208209i_node_start, i_node_step = index_to_start_step_2d(node_indices[1],210index_range)211j_node_start, j_node_step = index_to_start_step_2d(node_indices[2],212index_range)213214i_node = i_node_start215j_node = j_node_start216for node in eachnode(dg)217normal_direction = get_normal_direction(direction,218contravariant_vectors,219i_node, j_node, element)220221u_inner = get_node_vars(u, equations, dg, i_node, j_node, element)222223u_outer = get_boundary_outer_state(u_inner, t, boundary_condition,224normal_direction,225mesh, equations, dg, cache,226i_node, j_node, element)227var_outer = variable(u_outer, equations)228229var_minmax[i_node, j_node, element] = minmax(var_minmax[i_node, j_node,230element],231var_outer)232233i_node += i_node_step234j_node += j_node_step235end236end237end238239return nothing240end241end # @muladd242243244