Path: blob/main/src/solvers/dgsem_structured/dg.jl
5591 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# This method is called when a SemidiscretizationHyperbolic is constructed.8# It constructs the basic `cache` used throughout the simulation to compute9# the RHS etc.10function create_cache(mesh::Union{StructuredMesh, StructuredMeshView},11equations::AbstractEquations, dg::DG, ::Any,12::Type{uEltype}) where {uEltype <: Real}13elements = init_elements(mesh, equations, dg.basis, uEltype)1415# Container cache16cache = (; elements)1718# Add Volume-Integral cache19cache = (; cache...,20create_cache(mesh, equations, dg.volume_integral, dg, cache, uEltype)...)2122return cache23end2425# Extract contravariant vector Ja^i (i = index) as SVector26@inline function get_contravariant_vector(index, contravariant_vectors, indices...)27return SVector(ntuple(@inline(dim->contravariant_vectors[dim, index, indices...]),28Val(ndims(contravariant_vectors) - 3)))29end3031# Dimension agnostic, i.e., valid for all 1D, 2D, and 3D `StructuredMesh`es.32function calc_boundary_flux!(cache, t, boundary_condition::BoundaryConditionPeriodic,33mesh::StructuredMesh, equations, surface_integral,34dg::DG)35@assert isperiodic(mesh)3637return nothing38end3940function rhs!(du, u, t,41mesh::Union{StructuredMesh, StructuredMeshView{2}}, equations,42boundary_conditions, source_terms::Source,43dg::DG, cache) where {Source}44backend = trixi_backend(u)4546# Reset du47@trixi_timeit timer() "reset ∂u/∂t" set_zero!(du, dg, cache)4849# Calculate volume integral50@trixi_timeit timer() "volume integral" begin51calc_volume_integral!(backend, du, u, mesh,52have_nonconservative_terms(equations), equations,53dg.volume_integral, dg, cache)54end5556# Prolong solution to interfaces57@trixi_timeit timer() "prolong2interfaces" begin58prolong2interfaces!(cache, u, mesh, equations, dg)59end6061# Calculate interface fluxes62@trixi_timeit timer() "interface flux" begin63calc_interface_flux!(cache.elements.surface_flux_values, mesh,64have_nonconservative_terms(equations), equations,65dg.surface_integral, dg, cache)66end6768# `prolong2boundaries!` is not required for `StructuredMesh` since boundary values69# are stored in the interface datastructure (`interfaces_u`),70# so we can directly calculate the boundary fluxes without prolongation.7172# Calculate boundary fluxes73@trixi_timeit timer() "boundary flux" begin74calc_boundary_flux!(cache, t, boundary_conditions, mesh, equations,75dg.surface_integral, dg)76end7778# Calculate surface integrals79@trixi_timeit timer() "surface integral" begin80calc_surface_integral!(backend, du, u, mesh, equations,81dg.surface_integral, dg, cache)82end8384# Apply Jacobian from mapping to reference element85@trixi_timeit timer() "Jacobian" apply_jacobian!(backend, du, mesh, equations, dg,86cache)8788# Calculate source terms89@trixi_timeit timer() "source terms" begin90calc_sources!(du, u, t, source_terms, equations, dg, cache)91end9293return nothing94end9596@inline function calc_boundary_flux_by_direction!(surface_flux_values, t,97orientation,98boundary_condition::BoundaryConditionPeriodic,99mesh::Union{StructuredMesh,100StructuredMeshView},101have_nonconservative_terms::False,102equations,103surface_integral, dg::DG, cache,104direction, node_indices,105surface_node_indices, element)106@assert isperiodic(mesh, orientation)107return nothing108end109110@inline function calc_boundary_flux_by_direction!(surface_flux_values, t,111orientation,112boundary_condition::BoundaryConditionPeriodic,113mesh::Union{StructuredMesh,114StructuredMeshView},115have_nonconservative_terms::True,116equations,117surface_integral, dg::DG, cache,118direction, node_indices,119surface_node_indices, element)120@assert isperiodic(mesh, orientation)121return nothing122end123124@inline function calc_boundary_flux_by_direction!(surface_flux_values, t,125orientation,126boundary_condition,127mesh::Union{StructuredMesh,128StructuredMeshView},129have_nonconservative_terms::False,130equations,131surface_integral, dg::DG, cache,132direction, node_indices,133surface_node_indices, element)134@unpack node_coordinates, contravariant_vectors, inverse_jacobian, interfaces_u = cache.elements135# Boundary values are for `StructuredMesh` stored in the interface datastructure136boundaries_u = interfaces_u137@unpack surface_flux = surface_integral138139u_inner = get_node_vars(boundaries_u, equations, dg, surface_node_indices...,140direction, element)141x = get_node_coords(node_coordinates, equations, dg, node_indices..., element)142143# If the mapping is orientation-reversing, the contravariant vectors' orientation144# is reversed as well. The normal vector must be oriented in the direction145# from `left_element` to `right_element`, or the numerical flux will be computed146# incorrectly (downwind direction).147sign_jacobian = sign(inverse_jacobian[node_indices..., element])148149# Contravariant vector Ja^i is the normal vector150normal = sign_jacobian *151get_contravariant_vector(orientation, contravariant_vectors,152node_indices..., element)153154# If the mapping is orientation-reversing, the normal vector will be reversed (see above).155# However, the flux now has the wrong sign, since we need the physical flux in normal direction.156flux = sign_jacobian *157boundary_condition(u_inner, normal, direction, x, t, surface_flux, equations)158159# Only flux contribution for boundary element, boundary face is the boundary flux160for v in eachvariable(equations)161surface_flux_values[v, surface_node_indices..., direction, element] = flux[v]162end163164return nothing165end166167@inline function calc_boundary_flux_by_direction!(surface_flux_values, t,168orientation,169boundary_condition,170mesh::Union{StructuredMesh,171StructuredMeshView},172have_nonconservative_terms::True,173equations,174surface_integral, dg::DG, cache,175direction, node_indices,176surface_node_indices, element)177@unpack node_coordinates, contravariant_vectors, inverse_jacobian, interfaces_u = cache.elements178# Boundary values are for `StructuredMesh` stored in the interface datastructure179boundaries_u = interfaces_u180@unpack surface_flux = surface_integral181182u_inner = get_node_vars(boundaries_u, equations, dg, surface_node_indices...,183direction, element)184x = get_node_coords(node_coordinates, equations, dg, node_indices..., element)185186# If the mapping is orientation-reversing, the contravariant vectors' orientation187# is reversed as well. The normal vector must be oriented in the direction188# from `left_element` to `right_element`, or the numerical flux will be computed189# incorrectly (downwind direction).190sign_jacobian = sign(inverse_jacobian[node_indices..., element])191192# Contravariant vector Ja^i is the normal vector193normal = sign_jacobian *194get_contravariant_vector(orientation, contravariant_vectors,195node_indices..., element)196197# If the mapping is orientation-reversing, the normal vector will be reversed (see above).198# However, the flux now has the wrong sign, since we need the physical flux in normal direction.199flux, noncons_flux = boundary_condition(u_inner, normal, direction, x, t,200surface_flux, equations)201202# Only flux contribution for boundary element, boundary face is the boundary flux203for v in eachvariable(equations)204surface_flux_values[v, surface_node_indices..., direction, element] = sign_jacobian *205(flux[v] +2060.5f0 *207noncons_flux[v])208end209210return nothing211end212213@inline function get_inverse_jacobian(inverse_jacobian,214mesh::Union{StructuredMesh, StructuredMeshView,215UnstructuredMesh2D, P4estMesh,216T8codeMesh},217indices...)218return inverse_jacobian[indices...]219end220221include("containers.jl")222include("dg_1d.jl")223include("dg_2d.jl")224include("dg_3d.jl")225226include("indicators_1d.jl")227include("indicators_2d.jl")228include("indicators_3d.jl")229230include("subcell_limiters_2d.jl")231include("dg_2d_subcell_limiters.jl")232233# Specialized implementations used to improve performance234include("dg_2d_compressible_euler.jl")235include("dg_3d_compressible_euler.jl")236end # @muladd237238239