From 2bd998a1e46bbb56d641ceb1f4e6e4b8b39b99dc Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Thu, 3 Apr 2025 17:45:46 +0200 Subject: [PATCH 01/83] add auxliary variables - add container for node and surface auxiliary variables - add initializer to SemidiscretizationHyperbolic - dispatch on have_auxiliary_node_vars for 2D TreeMesh rhs! --- src/Trixi.jl | 2 +- src/callbacks_step/save_solution_dg.jl | 38 ++- src/callbacks_step/stepsize.jl | 6 +- src/callbacks_step/stepsize_dg2d.jl | 32 ++- src/equations/equations.jl | 26 ++ src/equations/numerical_fluxes.jl | 12 + .../semidiscretization_hyperbolic.jl | 28 +- src/solvers/dg.jl | 24 ++ src/solvers/dgsem_tree/containers.jl | 53 ++++ src/solvers/dgsem_tree/containers_2d.jl | 53 ++++ src/solvers/dgsem_tree/dg_2d.jl | 263 +++++++++++++++--- 11 files changed, 489 insertions(+), 48 deletions(-) diff --git a/src/Trixi.jl b/src/Trixi.jl index 93bf88516b1..5d7875f4496 100644 --- a/src/Trixi.jl +++ b/src/Trixi.jl @@ -150,7 +150,7 @@ include("visualization/visualization.jl") # export types/functions that define the public API of Trixi.jl -export AcousticPerturbationEquations2D, +export AcousticPerturbationEquations2D, AcousticPerturbationEquations2DAuxVars, CompressibleEulerEquations1D, CompressibleEulerEquations2D, CompressibleEulerEquations3D, CompressibleEulerMulticomponentEquations1D, diff --git a/src/callbacks_step/save_solution_dg.jl b/src/callbacks_step/save_solution_dg.jl index ee18ee1acbd..aba7976d7bf 100644 --- a/src/callbacks_step/save_solution_dg.jl +++ b/src/callbacks_step/save_solution_dg.jl @@ -5,6 +5,34 @@ @muladd begin #! format: noindent +@inline function convert_to_solution_variables(u, solution_variables, cache, + have_auxiliary_node_vars::False, + equations) + # Reinterpret the solution array as an array of conservative variables, + # compute the solution variables via broadcasting, and reinterpret the + # result as a plain array of floating point numbers + return Array(reinterpret(eltype(u), + solution_variables.(reinterpret(SVector{nvariables(equations), + eltype(u)}, u), + Ref(equations)))) +end + +@inline function convert_to_solution_variables(u, solution_variables, cache, + have_auxiliary_node_vars::True, + equations) + @unpack auxiliary_node_vars = cache.auxiliary_variables + # Reinterpret the solution array as an array of conservative variables, + # compute the solution variables via broadcasting, and reinterpret the + # result as a plain array of floating point numbers + return Array(reinterpret(eltype(u), + solution_variables.(reinterpret(SVector{nvariables(equations), + eltype(u)}, u), + reinterpret(SVector{n_auxiliary_node_vars(equations), + eltype(auxiliary_node_vars)}, + auxiliary_node_vars), + Ref(equations)))) +end + function save_solution_file(u, time, dt, timestep, mesh::Union{SerialTreeMesh, StructuredMesh, StructuredMeshView, @@ -30,14 +58,8 @@ function save_solution_file(u, time, dt, timestep, data = u n_vars = nvariables(equations) else - # Reinterpret the solution array as an array of conservative variables, - # compute the solution variables via broadcasting, and reinterpret the - # result as a plain array of floating point numbers - data = Array(reinterpret(eltype(u), - solution_variables.(reinterpret(SVector{nvariables(equations), - eltype(u)}, u), - Ref(equations)))) - + data = convert_to_solution_variables(u, solution_variables, cache, + have_auxiliary_node_vars(equations), equations) # Find out variable count by looking at output from `solution_variables` function n_vars = size(data, 1) end diff --git a/src/callbacks_step/stepsize.jl b/src/callbacks_step/stepsize.jl index f6d7a8fc2a3..8eae162e6ad 100644 --- a/src/callbacks_step/stepsize.jl +++ b/src/callbacks_step/stepsize.jl @@ -107,7 +107,8 @@ function calculate_dt(u_ode, t, cfl_number::Real, semi::AbstractSemidiscretizati u = wrap_array(u_ode, mesh, equations, solver, cache) dt = cfl_number * max_dt(u, t, mesh, - have_constant_speed(equations), equations, + have_constant_speed(equations), + have_auxiliary_node_vars(equations), equations, solver, cache) end # Case for `cfl_number` as a function of time `t`. @@ -116,7 +117,8 @@ function calculate_dt(u_ode, t, cfl_number, semi::AbstractSemidiscretization) u = wrap_array(u_ode, mesh, equations, solver, cache) dt = cfl_number(t) * max_dt(u, t, mesh, - have_constant_speed(equations), equations, + have_constant_speed(equations), + have_auxiliary_node_vars(equations), equations, solver, cache) end diff --git a/src/callbacks_step/stepsize_dg2d.jl b/src/callbacks_step/stepsize_dg2d.jl index b895dcd5b5d..eb54026f203 100644 --- a/src/callbacks_step/stepsize_dg2d.jl +++ b/src/callbacks_step/stepsize_dg2d.jl @@ -6,7 +6,8 @@ #! format: noindent function max_dt(u, t, mesh::TreeMesh{2}, - constant_speed::False, equations, dg::DG, cache) + constant_speed::False, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection max_scaled_speed = nextfloat(zero(t)) @@ -28,7 +29,34 @@ function max_dt(u, t, mesh::TreeMesh{2}, end function max_dt(u, t, mesh::TreeMesh{2}, - constant_speed::True, equations, dg::DG, cache) + constant_speed::False, have_auxiliary_node_vars::True, + equations, dg::DG, cache) + @unpack auxiliary_node_vars = cache.auxiliary_variables + # to avoid a division by zero if the speed vanishes everywhere, + # e.g. for steady-state linear advection + max_scaled_speed = nextfloat(zero(t)) + + @batch reduction=(max, max_scaled_speed) for element in eachelement(dg, cache) + max_lambda1 = max_lambda2 = zero(max_scaled_speed) + for j in eachnode(dg), i in eachnode(dg) + u_node = get_node_vars(u, equations, dg, i, j, element) + aux_node = get_auxiliary_node_vars(auxiliary_node_vars, + equations, dg, i, j, element) + lambda1, lambda2 = max_abs_speeds(u_node, aux_node, equations) + max_lambda1 = max(max_lambda1, lambda1) + max_lambda2 = max(max_lambda2, lambda2) + end + inv_jacobian = cache.elements.inverse_jacobian[element] + max_scaled_speed = max(max_scaled_speed, + inv_jacobian * (max_lambda1 + max_lambda2)) + end + + return 2 / (nnodes(dg) * max_scaled_speed) +end + +function max_dt(u, t, mesh::TreeMesh{2}, + constant_speed::True, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection max_scaled_speed = nextfloat(zero(t)) diff --git a/src/equations/equations.jl b/src/equations/equations.jl index 096c644506a..c465d835dab 100644 --- a/src/equations/equations.jl +++ b/src/equations/equations.jl @@ -81,6 +81,14 @@ function Base.show(io::IO, ::MIME"text/plain", equations::AbstractEquations) "variable " * string(variable), varnames(cons2cons, equations)[variable]) end + if have_auxiliary_node_vars(equations) == Trixi.True() + summary_line(io, "#auxiliary variables", n_auxiliary_node_vars(equations)) + for variable in eachauxiliaryvariable(equations) + summary_line(increment_indent(io), + "variable " * string(variable), + varnames(cons2aux, equations)[variable]) + end + end summary_footer(io) end end @@ -307,6 +315,23 @@ combined with certain solvers (e.g., subcell limiting). function n_nonconservative_terms end have_constant_speed(::AbstractEquations) = False() +""" + have_auxiliary_node_vars(equations) +Trait function determining whether `equations` need to access additional auxiliary +variables. +The return value will be `True()` or `False()` to allow dispatching on the return type. +""" +have_auxiliary_node_vars(::AbstractEquations) = False() +""" + n_auxiliary_node_vars(equations) + +Number of auxiliary variables used by `equations`. This function needs to be specialized +only if equations has auxiliary variables. +""" +function n_auxiliary_node_vars end +@inline eachauxiliaryvariable(equations::AbstractEquations) = + Base.OneTo(n_auxiliary_node_vars(equations)) + """ default_analysis_errors(equations) @@ -639,6 +664,7 @@ include("lattice_boltzmann_3d.jl") abstract type AbstractAcousticPerturbationEquations{NDIMS, NVARS} <: AbstractEquations{NDIMS, NVARS} end include("acoustic_perturbation_2d.jl") +include("acoustic_perturbation_2d_auxiliary_variables.jl") # Linearized Euler equations abstract type AbstractLinearizedEulerEquations{NDIMS, NVARS} <: diff --git a/src/equations/numerical_fluxes.jl b/src/equations/numerical_fluxes.jl index ec834310c30..9793444caf5 100644 --- a/src/equations/numerical_fluxes.jl +++ b/src/equations/numerical_fluxes.jl @@ -44,6 +44,18 @@ end dissipation(u_ll, u_rr, orientation_or_normal_direction, equations)) end +@inline function (numflux::FluxPlusDissipation)(u_ll, u_rr, aux_ll, aux_rr, + orientation_or_normal_direction, + equations) + @unpack numerical_flux, dissipation = numflux + + return (numerical_flux(u_ll, u_rr, aux_ll, aux_rr, + orientation_or_normal_direction, equations) + + + dissipation(u_ll, u_rr, aux_ll, aux_rr, + orientation_or_normal_direction, equations)) +end + function Base.show(io::IO, f::FluxPlusDissipation) print(io, "FluxPlusDissipation(", f.numerical_flux, ", ", f.dissipation, ")") end diff --git a/src/semidiscretization/semidiscretization_hyperbolic.jl b/src/semidiscretization/semidiscretization_hyperbolic.jl index 02cff56a1d0..1173e0e3dd3 100644 --- a/src/semidiscretization/semidiscretization_hyperbolic.jl +++ b/src/semidiscretization/semidiscretization_hyperbolic.jl @@ -64,11 +64,19 @@ function SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver # `RealT` is used as real type for node locations etc. # while `uEltype` is used as element type of solutions etc. RealT = real(solver), uEltype = RealT, - initial_cache = NamedTuple()) + initial_cache = NamedTuple(), + auxiliary_field = nothing) @assert ndims(mesh) == ndims(equations) cache = (; create_cache(mesh, equations, solver, RealT, uEltype)..., initial_cache...) + + # Add specialized parts of the cache for auxiliary node variables + cache = (; cache..., + create_cache_auxiliary(mesh, equations, solver, cache, + have_auxiliary_node_vars(equations), + auxiliary_field)...) + _boundary_conditions = digest_boundary_conditions(boundary_conditions, mesh, solver, cache) @@ -103,6 +111,20 @@ function remake(semi::SemidiscretizationHyperbolic; uEltype = real(semi.solver), source_terms, boundary_conditions, uEltype) end +# If there are auxiliary variables, initialize them +function create_cache_auxiliary(mesh, equations, solver, cache, + have_auxiliary_node_vars::True, auxiliary_field) + auxiliary_variables = init_auxiliary_node_variables(mesh, equations, solver, cache, + auxiliary_field) + return (; auxiliary_variables) +end + +# Do nothing if there are no auxiliary variables +function create_cache_auxiliary(mesh, equations, solver, cache, + have_auxiliary_node_vars::False, auxiliary_field) + return NamedTuple() +end + # general fallback function digest_boundary_conditions(boundary_conditions, mesh, solver, cache) boundary_conditions @@ -315,6 +337,10 @@ function Base.show(io::IO, ::MIME"text/plain", semi::SemidiscretizationHyperboli print_boundary_conditions(io, semi) summary_line(io, "source terms", semi.source_terms) + if have_auxiliary_node_vars(semi.equations) == Trixi.True() + summary_line(io, "auxiliary variables", + semi.cache.auxiliary_variables.auxiliary_field) + end summary_line(io, "solver", semi.solver |> typeof |> nameof) summary_line(io, "total #DOFs per field", ndofsglobal(semi)) summary_footer(io) diff --git a/src/solvers/dg.jl b/src/solvers/dg.jl index a0fb0d95079..0036166846e 100644 --- a/src/solvers/dg.jl +++ b/src/solvers/dg.jl @@ -559,6 +559,12 @@ end SVector(ntuple(@inline(v->u[v, indices...]), Val(nvariables(equations)))) end +# Return the auxiliary variables at a given volume node index +@inline function get_auxiliary_node_vars(auxiliary_node_vars, equations, ::DG, indices...) + return SVector(ntuple(@inline(v->auxiliary_node_vars[v, indices...]), + Val(n_auxiliary_node_vars(equations)))) +end + @inline function get_surface_node_vars(u, equations, solver::DG, indices...) # There is a cut-off at `n == 10` inside of the method # `ntuple(f::F, n::Integer) where F` in Base at ntuple.jl:17 @@ -570,6 +576,16 @@ end return u_ll, u_rr end +# Return the auxiliary variables at a given surface node index +@inline function get_auxiliary_surface_node_vars(aux_surface_node_vars, equations, ::DG, + indices...) + aux_vars_ll = SVector(ntuple(@inline(v->aux_surface_node_vars[1, v, indices...]), + Val(n_auxiliary_node_vars(equations)))) + aux_vars_rr = SVector(ntuple(@inline(v->aux_surface_node_vars[2, v, indices...]), + Val(n_auxiliary_node_vars(equations)))) + return aux_vars_ll, aux_vars_rr +end + @inline function set_node_vars!(u, u_node, equations, solver::DG, indices...) for v in eachvariable(equations) u[v, indices...] = u_node[v] @@ -577,6 +593,14 @@ end return nothing end +@inline function set_auxiliary_node_vars!(auxiliary_node_vars, aux_node, equations, + solver::DG, indices...) + for v in 1:n_auxiliary_node_vars(equations) + auxiliary_node_vars[v, indices...] = aux_node[v] + end + return nothing +end + @inline function add_to_node_vars!(u, u_node, equations, solver::DG, indices...) for v in eachvariable(equations) u[v, indices...] += u_node[v] diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index 3f05daf81d8..2cf66fbcc44 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -52,6 +52,59 @@ function reinitialize_containers!(mesh::TreeMesh, equations, dg::DGSEM, cache) end end +# Container for storing values of auxiliary variables at volume/surface quadrature nodes +struct AuxiliaryNodeVariablesContainer{NDIMS, uEltype <: Real, NDIMSP2, AuxiliaryVariables} + auxiliary_node_vars::Array{uEltype, NDIMSP2} # [var, i, j, element] + auxiliary_surface_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] + + # internal `resize!`able storage + _auxiliary_node_vars::Vector{uEltype} + _auxiliary_surface_node_vars::Vector{uEltype} + + # save initialization function + auxiliary_field::AuxiliaryVariables +end + +# Create auxiliary node variable container +function init_auxiliary_node_variables(mesh, equations, solver, cache, + auxiliary_field) + @unpack elements, interfaces = cache + + n_elements = nelements(elements) + n_interfaces = ninterfaces(interfaces) + NDIMS = ndims(mesh) + uEltype = eltype(elements) + nan_uEltype = convert(uEltype, NaN) + + _auxiliary_node_vars = fill(nan_uEltype, + n_auxiliary_node_vars(equations) * + nnodes(solver)^NDIMS * n_elements) + auxiliary_node_vars = unsafe_wrap(Array, pointer(_auxiliary_node_vars), + (n_auxiliary_node_vars(equations), + ntuple(_ -> nnodes(solver), NDIMS)..., + n_elements)) + _auxiliary_surface_node_vars = fill(nan_uEltype, + 2 * n_auxiliary_node_vars(equations) * + nnodes(solver)^(NDIMS - 1) * + n_interfaces) + auxiliary_surface_node_vars = unsafe_wrap(Array, pointer(_auxiliary_surface_node_vars), + (2, n_auxiliary_node_vars(equations), + ntuple(_ -> nnodes(solver), NDIMS - 1)..., + n_interfaces)) + + auxiliary_variables = + AuxiliaryNodeVariablesContainer{NDIMS, uEltype, NDIMS + 2, typeof(auxiliary_field)}( + auxiliary_node_vars, auxiliary_surface_node_vars, + _auxiliary_node_vars, _auxiliary_surface_node_vars, + auxiliary_field) + + init_auxiliary_node_variables!(auxiliary_variables, mesh, equations, solver, cache, + auxiliary_field) + init_auxiliary_surface_node_variables!(auxiliary_variables, mesh, equations, solver, + cache) + return auxiliary_variables +end + # Dimension-specific implementations include("containers_1d.jl") include("containers_2d.jl") diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index f0d66fd2353..7d19f366e47 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1422,4 +1422,57 @@ function Base.resize!(container::ContainerSubcellLimiterIDP2D, capacity) return nothing end + +# Initialize auxiliary node variables (2D implementation) +function init_auxiliary_node_variables!(auxiliary_variables, mesh, equations, solver, + cache, auxiliary_field) + @unpack auxiliary_node_vars = auxiliary_variables + @unpack node_coordinates = cache.elements + + @threaded for element in eachelement(solver, cache) + for j in eachnode(solver), i in eachnode(solver) + x_local = get_node_coords(node_coordinates, equations, solver, + i, j, element) + set_auxiliary_node_vars!(auxiliary_node_vars, + auxiliary_field(x_local, equations), + equations, solver, i, j, element) + end + end + return nothing +end + +# Initialize auxiliary surface node variables (2D implementation) +function init_auxiliary_surface_node_variables!(auxiliary_variables, mesh, equations, + solver, cache) + @unpack auxiliary_node_vars, auxiliary_surface_node_vars = auxiliary_variables + @unpack orientations, neighbor_ids = cache.interfaces + + @threaded for interface in eachinterface(solver, cache) + left_element = neighbor_ids[1, interface] + right_element = neighbor_ids[2, interface] + + if orientations[interface] == 1 + # interface in x-direction + for j in eachnode(solver) + for v in axes(auxiliary_surface_node_vars, 2) + auxiliary_surface_node_vars[1, v, j, interface] = + auxiliary_node_vars[v, nnodes(solver), j, left_element] + auxiliary_surface_node_vars[2, v, j, interface] = + auxiliary_node_vars[v, 1, j, right_element] + end + end + else # if orientations[interface] == 2 + # interface in y-direction + for i in eachnode(solver) + for v in axes(auxiliary_surface_node_vars, 2) + auxiliary_surface_node_vars[1, v, i, interface] = + auxiliary_node_vars[v, i, nnodes(solver), left_element] + auxiliary_surface_node_vars[2, v, i, interface] = + auxiliary_node_vars[v, i, 1, right_element] + end + end + end + end + return nothing +end end # @muladd diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 84c789099ce..f8dc88cbf15 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -119,8 +119,7 @@ function rhs!(du, u, t, # Calculate volume integral @trixi_timeit timer() "volume integral" begin - calc_volume_integral!(du, u, mesh, - have_nonconservative_terms(equations), equations, + calc_volume_integral!(du, u, mesh, equations, dg.volume_integral, dg, cache) end @@ -133,7 +132,8 @@ function rhs!(du, u, t, # Calculate interface fluxes @trixi_timeit timer() "interface flux" begin calc_interface_flux!(cache.elements.surface_flux_values, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_auxiliary_node_vars(equations), equations, dg.surface_integral, dg, cache) end @@ -173,7 +173,8 @@ function rhs!(du, u, t, # Calculate source terms @trixi_timeit timer() "source terms" begin - calc_sources!(du, u, t, source_terms, equations, dg, cache) + calc_sources!(du, u, t, source_terms, have_auxiliary_node_vars(equations), + equations, dg, cache) end return nothing @@ -183,12 +184,13 @@ function calc_volume_integral!(du, u, mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - nonconservative_terms, equations, + equations, volume_integral::VolumeIntegralWeakForm, dg::DGSEM, cache) @threaded for element in eachelement(dg, cache) weak_form_kernel!(du, u, element, mesh, - nonconservative_terms, equations, + have_nonconservative_terms(equations), + have_auxiliary_node_vars(equations), equations, dg, cache) end @@ -204,7 +206,8 @@ See also https://github.com/trixi-framework/Trixi.jl/issues/1671#issuecomment-17 =# @inline function weak_form_kernel!(du, u, element, mesh::TreeMesh{2}, - nonconservative_terms::False, equations, + nonconservative_terms::False, + auxiliary_node_var::False, equations, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -230,6 +233,38 @@ See also https://github.com/trixi-framework/Trixi.jl/issues/1671#issuecomment-17 return nothing end +@inline function weak_form_kernel!(du, u, + element, mesh::TreeMesh{2}, + nonconservative_terms::False, + auxiliary_node_var::True, equations, + dg::DGSEM, cache, alpha = true) + # true * [some floating point value] == [exactly the same floating point value] + # This can (hopefully) be optimized away due to constant propagation. + @unpack derivative_dhat = dg.basis + @unpack auxiliary_node_vars = cache.auxiliary_variables + + # Calculate volume terms in one element + for j in eachnode(dg), i in eachnode(dg) + u_node = get_node_vars(u, equations, dg, i, j, element) + aux_node = get_auxiliary_node_vars(auxiliary_node_vars, + equations, dg, i, j, element) + + flux1 = flux(u_node, aux_node, 1, equations) + for ii in eachnode(dg) + multiply_add_to_node_vars!(du, alpha * derivative_dhat[ii, i], flux1, + equations, dg, ii, j, element) + end + + flux2 = flux(u_node, aux_node, 2, equations) + for jj in eachnode(dg) + multiply_add_to_node_vars!(du, alpha * derivative_dhat[jj, j], flux2, + equations, dg, i, jj, element) + end + end + + return nothing +end + # flux differencing volume integral. For curved meshes averaging of the # mapping terms, stored in `cache.elements.contravariant_vectors`, is peeled apart # from the evaluation of the physical fluxes in each Cartesian direction @@ -238,19 +273,21 @@ function calc_volume_integral!(du, u, StructuredMeshView{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - nonconservative_terms, equations, + equations, volume_integral::VolumeIntegralFluxDifferencing, dg::DGSEM, cache) @threaded for element in eachelement(dg, cache) flux_differencing_kernel!(du, u, element, mesh, - nonconservative_terms, equations, + have_nonconservative_terms(equations), + have_auxiliary_node_vars(equations), equations, volume_integral.volume_flux, dg, cache) end end @inline function flux_differencing_kernel!(du, u, element, mesh::TreeMesh{2}, - nonconservative_terms::False, equations, + nonconservative_terms::False, + have_auxiliary_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -287,9 +324,58 @@ end end end + @inline function flux_differencing_kernel!(du, u, element, mesh::TreeMesh{2}, - nonconservative_terms::True, equations, + nonconservative_terms::False, + have_auxiliary_node_vars::True, equations, + volume_flux, dg::DGSEM, cache, alpha = true) + # true * [some floating point value] == [exactly the same floating point value] + # This can (hopefully) be optimized away due to constant propagation. + @unpack derivative_split = dg.basis + @unpack auxiliary_node_vars = cache.auxiliary_variables + + # Calculate volume integral in one element + for j in eachnode(dg), i in eachnode(dg) + u_node = get_node_vars(u, equations, dg, i, j, element) + aux_node = get_auxiliary_node_vars(auxiliary_node_vars, equations, dg, + i, j, element) + + # All diagonal entries of `derivative_split` are zero. Thus, we can skip + # the computation of the diagonal terms. In addition, we use the symmetry + # of the `volume_flux` to save half of the possible two-point flux + # computations. + + # x direction + for ii in (i + 1):nnodes(dg) + u_node_ii = get_node_vars(u, equations, dg, ii, j, element) + aux_node_ii = get_auxiliary_node_vars(auxiliary_node_vars, equations, dg, + ii, j, element) + flux1 = volume_flux(u_node, u_node_ii, aux_node, aux_node_ii, 1, equations) + multiply_add_to_node_vars!(du, alpha * derivative_split[i, ii], flux1, + equations, dg, i, j, element) + multiply_add_to_node_vars!(du, alpha * derivative_split[ii, i], flux1, + equations, dg, ii, j, element) + end + + # y direction + for jj in (j + 1):nnodes(dg) + u_node_jj = get_node_vars(u, equations, dg, i, jj, element) + aux_node_jj = get_auxiliary_node_vars(auxiliary_node_vars, equations, dg, + i, jj, element) + flux2 = volume_flux(u_node, u_node_jj, aux_node, aux_node_jj, 2, equations) + multiply_add_to_node_vars!(du, alpha * derivative_split[j, jj], flux2, + equations, dg, i, j, element) + multiply_add_to_node_vars!(du, alpha * derivative_split[jj, j], flux2, + equations, dg, i, jj, element) + end + end +end + +@inline function flux_differencing_kernel!(du, u, + element, mesh::TreeMesh{2}, + nonconservative_terms::True, + have_auxiliary_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -335,7 +421,7 @@ function calc_volume_integral!(du, u, mesh::Union{TreeMesh{2}, StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - nonconservative_terms, equations, + equations, volume_integral::VolumeIntegralShockCapturingHG, dg::DGSEM, cache) @unpack volume_flux_dg, volume_flux_fv, indicator = volume_integral @@ -355,16 +441,16 @@ function calc_volume_integral!(du, u, if dg_only flux_differencing_kernel!(du, u, element, mesh, - nonconservative_terms, equations, + have_nonconservative_terms(equations), equations, volume_flux_dg, dg, cache) else # Calculate DG volume integral contribution flux_differencing_kernel!(du, u, element, mesh, - nonconservative_terms, equations, + have_nonconservative_terms(equations), equations, volume_flux_dg, dg, cache, 1 - alpha_element) # Calculate FV volume integral contribution - fv_kernel!(du, u, mesh, nonconservative_terms, equations, volume_flux_fv, + fv_kernel!(du, u, mesh, have_nonconservative_terms(equations), equations, volume_flux_fv, dg, cache, element, alpha_element) end end @@ -377,14 +463,14 @@ function calc_volume_integral!(du, u, mesh::Union{TreeMesh{2}, StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - nonconservative_terms, equations, + equations, volume_integral::VolumeIntegralPureLGLFiniteVolume, dg::DGSEM, cache) @unpack volume_flux_fv = volume_integral # Calculate LGL FV volume integral @threaded for element in eachelement(dg, cache) - fv_kernel!(du, u, mesh, nonconservative_terms, equations, volume_flux_fv, + fv_kernel!(du, u, mesh, have_nonconservative_terms(equations), equations, volume_flux_fv, dg, cache, element, true) end @@ -569,7 +655,8 @@ end function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{2}, - nonconservative_terms::False, equations, + nonconservative_terms::False, + have_auxiliary_node_vars::False, equations, surface_integral, dg::DG, cache) @unpack surface_flux = surface_integral @unpack u, neighbor_ids, orientations = cache.interfaces @@ -603,7 +690,46 @@ end function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{2}, - nonconservative_terms::True, equations, + nonconservative_terms::False, + have_auxiliary_node_vars::True, equations, + surface_integral, dg::DG, cache) + @unpack surface_flux = surface_integral + @unpack u, neighbor_ids, orientations = cache.interfaces + @unpack auxiliary_surface_node_vars = cache.auxiliary_variables + + @threaded for interface in eachinterface(dg, cache) + # Get neighboring elements + left_id = neighbor_ids[1, interface] + right_id = neighbor_ids[2, interface] + + # Determine interface direction with respect to elements: + # orientation = 1: left -> 2, right -> 1 + # orientation = 2: left -> 4, right -> 3 + left_direction = 2 * orientations[interface] + right_direction = 2 * orientations[interface] - 1 + + for i in eachnode(dg) + # Call pointwise Riemann solver + u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) + aux_ll, aux_rr = get_auxiliary_surface_node_vars( + auxiliary_surface_node_vars, equations, dg, i, interface) + flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, + orientations[interface], equations) + # Copy flux to left and right element storage + for v in eachvariable(equations) + surface_flux_values[v, i, left_direction, left_id] = flux[v] + surface_flux_values[v, i, right_direction, right_id] = flux[v] + end + end + end + + return nothing +end + +function calc_interface_flux!(surface_flux_values, + mesh::TreeMesh{2}, + nonconservative_terms::True, + have_auxiliary_node_vars::False, equations, surface_integral, dg::DG, cache) surface_flux, nonconservative_flux = surface_integral.surface_flux @unpack u, neighbor_ids, orientations = cache.interfaces @@ -694,7 +820,6 @@ end function calc_boundary_flux!(cache, t, boundary_conditions::NamedTuple, mesh::TreeMesh{2}, equations, surface_integral, dg::DG) - @unpack surface_flux_values = cache.elements @unpack n_boundaries_per_direction = cache.boundaries # Calculate indices @@ -702,30 +827,34 @@ function calc_boundary_flux!(cache, t, boundary_conditions::NamedTuple, firsts = lasts - n_boundaries_per_direction .+ 1 # Calc boundary fluxes in each direction - calc_boundary_flux_by_direction!(surface_flux_values, t, boundary_conditions[1], + calc_boundary_flux_by_direction!(t, boundary_conditions[1], have_nonconservative_terms(equations), + have_auxiliary_node_vars(equations), equations, surface_integral, dg, cache, 1, firsts[1], lasts[1]) - calc_boundary_flux_by_direction!(surface_flux_values, t, boundary_conditions[2], + calc_boundary_flux_by_direction!(t, boundary_conditions[2], have_nonconservative_terms(equations), + have_auxiliary_node_vars(equations), equations, surface_integral, dg, cache, 2, firsts[2], lasts[2]) - calc_boundary_flux_by_direction!(surface_flux_values, t, boundary_conditions[3], + calc_boundary_flux_by_direction!(t, boundary_conditions[3], have_nonconservative_terms(equations), + have_auxiliary_node_vars(equations), equations, surface_integral, dg, cache, 3, firsts[3], lasts[3]) - calc_boundary_flux_by_direction!(surface_flux_values, t, boundary_conditions[4], + calc_boundary_flux_by_direction!(t, boundary_conditions[4], have_nonconservative_terms(equations), + have_auxiliary_node_vars(equations), equations, surface_integral, dg, cache, 4, firsts[4], lasts[4]) end -function calc_boundary_flux_by_direction!(surface_flux_values::AbstractArray{<:Any, 4}, - t, - boundary_condition, - nonconservative_terms::False, equations, +function calc_boundary_flux_by_direction!(t, boundary_condition, + nonconservative_terms::False, + have_auxiliary_node_vars::False, equations, surface_integral, dg::DG, cache, direction, first_boundary, last_boundary) + @unpack surface_flux_values = cache.elements @unpack surface_flux = surface_integral @unpack u, neighbor_ids, neighbor_sides, node_coordinates, orientations = cache.boundaries @@ -756,12 +885,53 @@ function calc_boundary_flux_by_direction!(surface_flux_values::AbstractArray{<:A return nothing end -function calc_boundary_flux_by_direction!(surface_flux_values::AbstractArray{<:Any, 4}, - t, - boundary_condition, - nonconservative_terms::True, equations, +function calc_boundary_flux_by_direction!(t, boundary_condition, + nonconservative_terms::False, + have_auxiliary_node_vars::True, equations, surface_integral, dg::DG, cache, direction, first_boundary, last_boundary) + @unpack surface_flux_values = cache.elements + @unpack surface_flux = surface_integral + @unpack u, neighbor_ids, neighbor_sides, node_coordinates, orientations = cache.boundaries + @unpack auxiliary_surface_node_vars = cache.auxiliary_variables + + @threaded for boundary in first_boundary:last_boundary + # Get neighboring element + neighbor = neighbor_ids[boundary] + + for i in eachnode(dg) + # Get boundary flux + u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, boundary) + aux_ll, aux_rr = get_auxiliary_surface_node_vars(auxiliary_surface_node_vars, + equations, dg, i, boundary) + if neighbor_sides[boundary] == 1 # Element is on the left, boundary on the right + u_inner = u_ll + aux_inner = aux_ll + else # Element is on the right, boundary on the left + u_inner = u_rr + aux_inner = aux_rr + end + + x = get_node_coords(node_coordinates, equations, dg, i, boundary) + flux = boundary_condition(u_inner, aux_inner, orientations[boundary], + direction, x, t, surface_flux, equations) + + # Copy flux to left and right element storage + for v in eachvariable(equations) + surface_flux_values[v, i, direction, neighbor] = flux[v] + end + end + end + + return nothing +end + +function calc_boundary_flux_by_direction!(t, boundary_condition, + nonconservative_terms::True, + have_auxiliary_node_vars::False, equations, + surface_integral, dg::DG, cache, + direction, first_boundary, last_boundary) + @unpack surface_flux_values = cache.elements @unpack u, neighbor_ids, neighbor_sides, node_coordinates, orientations = cache.boundaries @threaded for boundary in first_boundary:last_boundary @@ -1188,12 +1358,17 @@ function apply_jacobian!(du, mesh::TreeMesh{2}, end # TODO: Taal dimension agnostic -function calc_sources!(du, u, t, source_terms::Nothing, +function calc_sources!(du, u, t, source_terms::Nothing, have_auxiliary_node_vars::False, + equations::AbstractEquations{2}, dg::DG, cache) + return nothing +end + +function calc_sources!(du, u, t, source_terms::Nothing, have_auxiliary_node_vars::True, equations::AbstractEquations{2}, dg::DG, cache) return nothing end -function calc_sources!(du, u, t, source_terms, +function calc_sources!(du, u, t, source_terms, have_auxiliary_node_vars::False, equations::AbstractEquations{2}, dg::DG, cache) @unpack node_coordinates = cache.elements @@ -1209,4 +1384,24 @@ function calc_sources!(du, u, t, source_terms, return nothing end + +function calc_sources!(du, u, t, source_terms, have_auxiliary_node_vars::True, + equations::AbstractEquations{2}, dg::DG, cache) + @unpack node_coordinates = cache.elements + @unpack auxiliary_node_vars = cache.auxiliary_variables + + @threaded for element in eachelement(dg, cache) + for j in eachnode(dg), i in eachnode(dg) + u_local = get_node_vars(u, equations, dg, i, j, element) + aux_local = get_auxiliary_node_vars(auxiliary_node_vars, equations, dg, + i, j, element) + x_local = get_node_coords(node_coordinates, equations, dg, + i, j, element) + du_local = source_terms(u_local, aux_local, x_local, t, equations) + add_to_node_vars!(du, du_local, equations, dg, i, j, element) + end + end + + return nothing +end end # @muladd From 8b9b55643b6c7a3f68a1ebab184629f6f9aa8dd4 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Thu, 3 Apr 2025 17:47:36 +0200 Subject: [PATCH 02/83] add AcousticPerturbationEquations2DAuxVars to demonstrate how auxiliary variables can be used instead of augmenting the solution state vector --- .../elixir_acoustics_convergence_auxvars.jl | 65 +++ .../elixir_acoustics_gauss_wall_auxvars.jl | 81 ++++ ...tic_perturbation_2d_auxiliary_variables.jl | 388 ++++++++++++++++++ 3 files changed, 534 insertions(+) create mode 100644 examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl create mode 100644 examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_auxvars.jl create mode 100644 src/equations/acoustic_perturbation_2d_auxiliary_variables.jl diff --git a/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl b/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl new file mode 100644 index 00000000000..6dc5fbb48a4 --- /dev/null +++ b/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl @@ -0,0 +1,65 @@ +using OrdinaryDiffEqLowStorageRK +using Trixi + +############################################################################### +# semidiscretization of the acoustic perturbation equations + +function auxiliary_variables_mean_values(x, equations) + # constant auxiliary variables (mean state) + return global_mean_vars(equations) +end + +equations = AcousticPerturbationEquations2DAuxVars(v_mean_global = (0.5, 0.3), + c_mean_global = 2.0, + rho_mean_global = 0.9) + +initial_condition = initial_condition_convergence_test + +# Create DG solver with polynomial degree = 3 and (local) Lax-Friedrichs/Rusanov flux as surface flux +solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs) + +coordinates_min = (0.0, 0.0) # minimum coordinates (min(x), min(y)) +coordinates_max = (2.0, 2.0) # maximum coordinates (max(x), max(y)) + +# Create a uniformly refined mesh with periodic boundaries +mesh = TreeMesh(coordinates_min, coordinates_max, + initial_refinement_level = 3, + n_cells_max = 30_000) # set maximum capacity of tree data structure + +# A semidiscretization collects data structures and functions for the spatial discretization +semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, + source_terms = source_terms_convergence_test, + auxiliary_field = auxiliary_variables_mean_values) + +############################################################################### +# ODE solvers, callbacks etc. + +# Create ODE problem with time span from 0.0 to 1.0 +tspan = (0.0, 1.0) +ode = semidiscretize(semi, tspan) + +# At the beginning of the main loop, the SummaryCallback prints a summary of the simulation setup +# and resets the timers +summary_callback = SummaryCallback() + +# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results +analysis_callback = AnalysisCallback(semi, interval = 100) + +# The SaveSolutionCallback allows to save the solution to a file in regular intervals +save_solution = SaveSolutionCallback(interval = 100, + solution_variables = cons2prim) + +# The StepsizeCallback handles the re-calculation of the maximum Δt after each time step +stepsize_callback = StepsizeCallback(cfl = 0.5) + +# Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver +callbacks = CallbackSet(summary_callback, analysis_callback, save_solution, + stepsize_callback) + +############################################################################### +# run the simulation + +# OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks +sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false); + dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback + ode_default_options()..., callback = callbacks); diff --git a/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_auxvars.jl b/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_auxvars.jl new file mode 100644 index 00000000000..a4673035947 --- /dev/null +++ b/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_auxvars.jl @@ -0,0 +1,81 @@ +using OrdinaryDiffEqLowStorageRK +using Trixi + +############################################################################### +# semidiscretization of the acoustic perturbation equations + +equations = AcousticPerturbationEquations2DAuxVars(v_mean_global = (0.5, 0.0), + c_mean_global = 1.0, + rho_mean_global = 1.0) + +# Create DG solver with polynomial degree = 5 and (local) Lax-Friedrichs/Rusanov flux as surface flux +solver = DGSEM(polydeg = 5, surface_flux = flux_lax_friedrichs) + +coordinates_min = (-100.0, 0.0) # minimum coordinates (min(x), min(y)) +coordinates_max = (100.0, 200.0) # maximum coordinates (max(x), max(y)) + +# Create a uniformly refined mesh with periodic boundaries +mesh = TreeMesh(coordinates_min, coordinates_max, + initial_refinement_level = 4, + n_cells_max = 100_000, + periodicity = false) + +""" + initial_condition_gauss_wall(x, t, equations::AcousticPerturbationEquations2DAuxVars) + +A Gaussian pulse, used in the `gauss_wall` example elixir in combination with +[`boundary_condition_wall`](@ref). Uses the global mean values from `equations`. +""" +function initial_condition_gauss_wall(x, t, + equations::AcousticPerturbationEquations2DAuxVars) + RealT = eltype(x) + v1_prime = 0 + v2_prime = 0 + p_prime = exp(-log(convert(RealT, 2)) * (x[1]^2 + (x[2] - 25)^2) / 25) + p_prime_scaled = p_prime / equations.c_mean_global^2 + + return SVector(v1_prime, v2_prime, p_prime_scaled) +end +initial_condition = initial_condition_gauss_wall + +function auxiliary_variables_mean_values(x, equations) + # constant auxiliary variables (mean state) + return global_mean_vars(equations) +end + +# A semidiscretization collects data structures and functions for the spatial discretization +semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, + boundary_conditions = boundary_condition_wall, + auxiliary_field = auxiliary_variables_mean_values) + +############################################################################### +# ODE solvers, callbacks etc. + +# Create ODE problem with time span from 0.0 to 30.0 +tspan = (0.0, 30.0) +ode = semidiscretize(semi, tspan) + +# At the beginning of the main loop, the SummaryCallback prints a summary of the simulation setup +# and resets the timers +summary_callback = SummaryCallback() + +# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results +analysis_callback = AnalysisCallback(semi, interval = 100) + +# The SaveSolutionCallback allows to save the solution to a file in regular intervals +save_solution = SaveSolutionCallback(interval = 100, solution_variables = cons2state) + +# The StepsizeCallback handles the re-calculation of the maximum Δt after each time step +stepsize_callback = StepsizeCallback(cfl = 0.7) + +# Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver +callbacks = CallbackSet(summary_callback, analysis_callback, save_solution, + stepsize_callback) + +############################################################################### +# run the simulation + +# OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks +sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false); + dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback + ode_default_options()..., callback = callbacks) diff --git a/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl b/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl new file mode 100644 index 00000000000..3b68956f37d --- /dev/null +++ b/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl @@ -0,0 +1,388 @@ +# By default, Julia/LLVM does not use fused multiply-add operations (FMAs). +# Since these FMAs can increase the performance of many numerical algorithms, +# we need to opt-in explicitly. +# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details. +@muladd begin +#! format: noindent + +@doc raw""" + AcousticPerturbationEquations2DAuxVars(v_mean_global, c_mean_global, rho_mean_global) + +Alternative implementation of [`AcousticPerturbationEquations2D`](@ref) using auxiliary +variables. +""" +struct AcousticPerturbationEquations2DAuxVars{RealT <: Real} <: + AbstractAcousticPerturbationEquations{2, 3} + v_mean_global::SVector{2, RealT} + c_mean_global::RealT + rho_mean_global::RealT +end + +function AcousticPerturbationEquations2DAuxVars(v_mean_global::NTuple{2, <:Real}, + c_mean_global::Real, + rho_mean_global::Real) + return AcousticPerturbationEquations2DAuxVars(SVector(v_mean_global), c_mean_global, + rho_mean_global) +end + +function AcousticPerturbationEquations2DAuxVars(; v_mean_global::NTuple{2, <:Real}, + c_mean_global::Real, + rho_mean_global::Real) + return AcousticPerturbationEquations2DAuxVars(SVector(v_mean_global), c_mean_global, + rho_mean_global) +end + +have_auxiliary_node_vars(::AcousticPerturbationEquations2DAuxVars) = True() +n_auxiliary_node_vars(::AcousticPerturbationEquations2DAuxVars) = 4 + +""" + global_mean_vars(equations::AcousticPerturbationEquations2DAuxVars) + +Returns the global mean variables stored in `equations`. This makes it easier +to define flexible initial conditions for problems with constant mean flow. +""" +function global_mean_vars(equations::AcousticPerturbationEquations2DAuxVars) + return equations.v_mean_global[1], equations.v_mean_global[2], + equations.c_mean_global, + equations.rho_mean_global +end + +""" + initial_condition_constant(x, t, equations::AcousticPerturbationEquations2DAuxVars) + +A constant initial condition where the state variables are zero and the mean flow is constant. +Uses the global mean values from `equations`. +""" +function initial_condition_constant(x, t, equations::AcousticPerturbationEquations2DAuxVars) + v1_prime = 0 + v2_prime = 0 + p_prime_scaled = 0 + + return SVector(v1_prime, v2_prime, p_prime_scaled) +end + +""" + initial_condition_convergence_test(x, t, equations::AcousticPerturbationEquations2DAuxVars) + +A smooth initial condition used for convergence tests in combination with +[`source_terms_convergence_test`](@ref). Uses the global mean values from `equations`. +""" +function initial_condition_convergence_test(x, t, + equations::AcousticPerturbationEquations2DAuxVars) + RealT = eltype(x) + a = 1 + c = 2 + L = 2 + f = 2.0f0 / L + A = convert(RealT, 0.2) + omega = 2 * convert(RealT, pi) * f + init = c + A * sin(omega * (x[1] + x[2] - a * t)) + + v1_prime = init + v2_prime = init + p_prime = init^2 + p_prime_scaled = p_prime / equations.c_mean_global^2 + + return SVector(v1_prime, v2_prime, p_prime_scaled) +end + +""" + source_terms_convergence_test(u, x, t, equations::AcousticPerturbationEquations2DAuxVars) + +Source terms used for convergence tests in combination with +[`initial_condition_convergence_test`](@ref). +""" +function source_terms_convergence_test(u, aux, x, t, + equations::AcousticPerturbationEquations2DAuxVars) + v1_mean, v2_mean, c_mean, rho_mean = aux + + RealT = eltype(u) + a = 1 + c = 2 + L = 2 + f = 2.0f0 / L + A = convert(RealT, 0.2) + omega = 2 * convert(RealT, pi) * f + + si, co = sincos(omega * (x[1] + x[2] - a * t)) + tmp = v1_mean + v2_mean - a + + du1 = du2 = A * omega * co * (2 * c / rho_mean + tmp + 2 / rho_mean * A * si) + du3 = A * omega * co * (2 * c_mean^2 * rho_mean + 2 * c * tmp + 2 * A * tmp * si) / + c_mean^2 + + return SVector(du1, du2, du3) +end + +""" + initial_condition_gauss(x, t, equations::AcousticPerturbationEquations2DAuxVars) + +A Gaussian pulse in a constant mean flow. Uses the global mean values from `equations`. +""" +function initial_condition_gauss(x, t, equations::AcousticPerturbationEquations2DAuxVars) + v1_prime = 0 + v2_prime = 0 + p_prime = exp(-4 * (x[1]^2 + x[2]^2)) + p_prime_scaled = p_prime / equations.c_mean_global^2 + + return SVector(v1_prime, v2_prime, p_prime_scaled) +end + +""" + boundary_condition_wall(u_inner, aux_inner, orientation, direction, x, t, + surface_flux_function, + equations::AcousticPerturbationEquations2DAuxVars) + +Boundary conditions for a solid wall. +""" +function boundary_condition_wall(u_inner, aux_inner, orientation, direction, x, t, + surface_flux_function, + equations::AcousticPerturbationEquations2DAuxVars) + # Boundary state is equal to the inner state except for the perturbed velocity. For boundaries + # in the -x/+x direction, we multiply the perturbed velocity in the x direction by -1. + # Similarly, for boundaries in the -y/+y direction, we multiply the perturbed velocity in the + # y direction by -1 + if direction in (1, 2) # x direction + u_boundary = SVector(-u_inner[1], u_inner[2], u_inner[3]) + else # y direction + u_boundary = SVector(u_inner[1], -u_inner[2], u_inner[3]) + end + + # Calculate boundary flux + if iseven(direction) # u_inner is "left" of boundary, u_boundary is "right" of boundary + flux = surface_flux_function(u_inner, u_boundary, aux_inner, aux_inner, + orientation, equations) + else # u_boundary is "left" of boundary, u_inner is "right" of boundary + flux = surface_flux_function(u_boundary, u_inner, aux_inner, aux_inner, + orientation, equations) + end + + return flux +end + +""" + boundary_condition_slip_wall(u_inner, aux_inner, normal_direction, x, t, + surface_flux_function, + equations::AcousticPerturbationEquations2DAuxVars) + +Use an orthogonal projection of the perturbed velocities to zero out the normal velocity +while retaining the possibility of a tangential velocity in the boundary state. +Further details are available in the paper: +- Marcus Bauer, Jürgen Dierke and Roland Ewert (2011) + Application of a discontinuous Galerkin method to discretize acoustic perturbation equations + [DOI: 10.2514/1.J050333](https://doi.org/10.2514/1.J050333) +""" +function boundary_condition_slip_wall(u_inner, normal_direction::AbstractVector, x, t, + surface_flux_function, + equations::AcousticPerturbationEquations2DAuxVars) + # normalize the outward pointing direction + normal = normal_direction / norm(normal_direction) + + # compute the normal perturbed velocity + u_normal = normal[1] * u_inner[1] + normal[2] * u_inner[2] + + # create the "external" boundary solution state + u_boundary = SVector(u_inner[1] - 2 * u_normal * normal[1], + u_inner[2] - 2 * u_normal * normal[2], + u_inner[3]) + + # calculate the boundary flux + flux = surface_flux_function(u_inner, u_boundary, normal_direction, equations) + + return flux +end + +# Calculate 1D flux for a single point +@inline function flux(u, aux, orientation::Integer, + equations::AcousticPerturbationEquations2DAuxVars) + v1_prime, v2_prime, p_prime_scaled = u + v1_mean, v2_mean, c_mean, rho_mean = aux + + # Calculate flux for conservative state variables + RealT = eltype(u) + if orientation == 1 + f1 = v1_mean * v1_prime + v2_mean * v2_prime + + c_mean^2 * p_prime_scaled / rho_mean + f2 = zero(RealT) + f3 = rho_mean * v1_prime + v1_mean * p_prime_scaled + else + f1 = zero(RealT) + f2 = v1_mean * v1_prime + v2_mean * v2_prime + + c_mean^2 * p_prime_scaled / rho_mean + f3 = rho_mean * v2_prime + v2_mean * p_prime_scaled + end + + return SVector(f1, f2, f3) +end + +# Calculate maximum wave speed for local Lax-Friedrichs-type dissipation +@inline function max_abs_speed_naive(u_ll, u_rr, aux_ll, aux_rr, orientation::Integer, + equations::AcousticPerturbationEquations2DAuxVars) + # Calculate v = v_prime + v_mean + v_prime_ll = u_ll[orientation] + v_prime_rr = u_rr[orientation] + v_mean_ll = aux_ll[orientation] + v_mean_rr = aux_rr[orientation] + + v_ll = v_prime_ll + v_mean_ll + v_rr = v_prime_rr + v_mean_rr + + c_mean_ll = aux_ll[3] + c_mean_rr = aux_rr[3] + + return max(abs(v_ll), abs(v_rr)) + max(c_mean_ll, c_mean_rr) +end + +# Less "cautious", i.e., less overestimating `λ_max` compared to `max_abs_speed_naive` +@inline function max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, orientation::Integer, + equations::AcousticPerturbationEquations2DAuxVars) + # Calculate v = v_prime + v_mean + v_prime_ll = u_ll[orientation] + v_prime_rr = u_rr[orientation] + v_mean_ll = aux_ll[orientation] + v_mean_rr = aux_rr[orientation] + + v_ll = v_prime_ll + v_mean_ll + v_rr = v_prime_rr + v_mean_rr + + c_mean_ll = aux_ll[3] + c_mean_rr = aux_rr[3] + + return max(abs(v_ll) + c_mean_ll, abs(v_rr) + c_mean_rr) +end + +# Calculate 1D flux for a single point in the normal direction +# Note, this directional vector is not normalized +@inline function flux(u, aux, normal_direction::AbstractVector, + equations::AcousticPerturbationEquations2DAuxVars) + v1_prime, v2_prime, p_prime_scaled = u + v1_mean, v2_mean, c_mean, rho_mean = aux + + f1 = normal_direction[1] * (v1_mean * v1_prime + v2_mean * v2_prime + + c_mean^2 * p_prime_scaled / rho_mean) + f2 = normal_direction[2] * (v1_mean * v1_prime + v2_mean * v2_prime + + c_mean^2 * p_prime_scaled / rho_mean) + f3 = (normal_direction[1] * (rho_mean * v1_prime + v1_mean * p_prime_scaled) + + + normal_direction[2] * (rho_mean * v2_prime + v2_mean * p_prime_scaled)) + + return SVector(f1, f2, f3) +end + +# Calculate maximum wave speed for local Lax-Friedrichs-type dissipation +@inline function max_abs_speed_naive(u_ll, u_rr, aux_ll, aux_rr, + normal_direction::AbstractVector, + equations::AcousticPerturbationEquations2DAuxVars) + # Calculate v = v_prime + v_mean + v_prime_ll = normal_direction[1] * u_ll[1] + normal_direction[2] * u_ll[2] + v_prime_rr = normal_direction[1] * u_rr[1] + normal_direction[2] * u_rr[2] + v_mean_ll = normal_direction[1] * aux_ll[1] + normal_direction[2] * aux_ll[2] + v_mean_rr = normal_direction[1] * aux_rr[1] + normal_direction[2] * aux_rr[2] + + v_ll = v_prime_ll + v_mean_ll + v_rr = v_prime_rr + v_mean_rr + + c_mean_ll = aux_ll[3] + c_mean_rr = aux_rr[3] + + # The v_normals are already scaled by the norm + return (max(abs(v_ll), abs(v_rr)) + + max(c_mean_ll, c_mean_rr) * norm(normal_direction)) +end + +# Less "cautious", i.e., less overestimating `λ_max` compared to `max_abs_speed_naive` +@inline function max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, + normal_direction::AbstractVector, + equations::AcousticPerturbationEquations2DAuxVars) + # Calculate v = v_prime + v_mean + v_prime_ll = normal_direction[1] * u_ll[1] + normal_direction[2] * u_ll[2] + v_prime_rr = normal_direction[1] * u_rr[1] + normal_direction[2] * u_rr[2] + v_mean_ll = normal_direction[1] * aux_ll[1] + normal_direction[2] * aux_ll[2] + v_mean_rr = normal_direction[1] * aux_rr[1] + normal_direction[2] * aux_rr[2] + + v_ll = v_prime_ll + v_mean_ll + v_rr = v_prime_rr + v_mean_rr + + c_mean_ll = aux_ll[3] + c_mean_rr = aux_rr[3] + + norm_ = norm(normal_direction) + # The v_normals are already scaled by the norm + return max(abs(v_ll) + c_mean_ll * norm_, abs(v_rr) + c_mean_rr * norm_) +end + +@inline function flux_central(u_ll, u_rr, aux_ll, aux_rr, orientation_or_normal_direction, + equations::AcousticPerturbationEquations2DAuxVars) + # Calculate regular 1D fluxes + f_ll = flux(u_ll, aux_ll, orientation_or_normal_direction, equations) + f_rr = flux(u_rr, aux_rr, orientation_or_normal_direction, equations) + + # Average regular fluxes + return 0.5f0 * (f_ll + f_rr) +end + +# Specialized `DissipationLocalLaxFriedrichs` taking into account auxiliary variables +@inline function (dissipation::DissipationLocalLaxFriedrichs)(u_ll, u_rr, aux_ll, aux_rr, + orientation_or_normal_direction, + equations::AcousticPerturbationEquations2DAuxVars) + λ = dissipation.max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, + orientation_or_normal_direction, equations) + diss = -0.5f0 * λ * (u_rr - u_ll) + return SVector(diss[1], diss[2], diss[3]) +end + +@inline have_constant_speed(::AcousticPerturbationEquations2DAuxVars) = False() + +@inline function max_abs_speeds(u, aux, equations::AcousticPerturbationEquations2DAuxVars) + v1_mean, v2_mean, c_mean, _ = aux + + return abs(v1_mean) + c_mean, abs(v2_mean) + c_mean +end + +function varnames(::typeof(cons2cons), ::AcousticPerturbationEquations2DAuxVars) + ("v1_prime", "v2_prime", "p_prime_scaled") +end + +# Convenience functions for retrieving state variables and mean variables +function cons2state(u, aux, ::AcousticPerturbationEquations2DAuxVars) + return SVector(u[1], u[2], u[3]) +end + +function varnames(::typeof(cons2state), ::AcousticPerturbationEquations2DAuxVars) + ("v1_prime", "v2_prime", "p_prime_scaled") +end + +function cons2aux(u, aux, equations::AcousticPerturbationEquations2D) + return SVector(aux[1], aux[2], aux[3], aux[4]) +end + +function varnames(::typeof(cons2aux), ::AcousticPerturbationEquations2DAuxVars) + ("v1_mean", "v2_mean", "c_mean", "rho_mean") +end + +# Convert conservative variables to primitive +@inline function cons2prim(u, aux, equations::AcousticPerturbationEquations2DAuxVars) + p_prime_scaled = u[3] + c_mean = aux[3] + p_prime = p_prime_scaled * c_mean^2 + + return SVector(u[1], u[2], p_prime) +end + +function varnames(::typeof(cons2prim), ::AbstractAcousticPerturbationEquations{2}) + ("v1_prime", "v2_prime", "p_prime", + "v1_mean", "v2_mean", "c_mean", "rho_mean") +end + +# Convert primitive variables to conservative +@inline function prim2cons(u, aux, equations::AcousticPerturbationEquations2DAuxVars) + p_prime = u[3] + c_mean = aux[3] + p_prime_scaled = p_prime / c_mean^2 + + return SVector(u[1], u[2], p_prime_scaled) +end + +# Convert conservative variables to entropy variables +@inline cons2entropy(u, equations::AcousticPerturbationEquations2DAuxVars) = u +end # @muladd From d9d7054530b49cf10f4db594e5a7e0c0cf293c33 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Thu, 3 Apr 2025 17:49:34 +0200 Subject: [PATCH 03/83] add tests for AcousticPerturbationEquations2DAuxVars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ŕesults have to be identical to the corresponing AcousticPerturbationEquations2D results --- test/test_tree_2d_acoustics.jl | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/test_tree_2d_acoustics.jl b/test/test_tree_2d_acoustics.jl index 070eca87728..099d4a1d970 100644 --- a/test/test_tree_2d_acoustics.jl +++ b/test/test_tree_2d_acoustics.jl @@ -40,6 +40,28 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem") end end +@trixi_testset "elixir_acoustics_convergence_auxvars.jl" begin + @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_acoustics_convergence_auxvars.jl"), + l2=[ + 0.0019921138796370834, + 0.002090394698052287, + 0.0006091925854593805 + ], + linf=[ + 0.00769282588065634, + 0.008276649669227254, + 0.004196479023954813 + ]) + # Ensure that we do not have excessive memory allocations + # (e.g., from type instabilities) + let + t = sol.t[end] + u_ode = sol.u[end] + du_ode = similar(u_ode) + @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 + end +end + @trixi_testset "elixir_acoustics_gauss.jl" begin @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_acoustics_gauss.jl"), l2=[ @@ -120,6 +142,22 @@ end end end +@trixi_testset "elixir_acoustics_gauss_wall_auxvars.jl" begin + @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_acoustics_gauss_wall_auxvars.jl"), + l2=[0.019419398248465843, 0.019510701017551826, + 0.04818246051887614], + linf=[0.18193631937316496, 0.1877464607867628, + 1.0355388011792845]) + # Ensure that we do not have excessive memory allocations + # (e.g., from type instabilities) + let + t = sol.t[end] + u_ode = sol.u[end] + du_ode = similar(u_ode) + @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 + end +end + @trixi_testset "elixir_acoustics_monopole.jl" begin @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_acoustics_monopole.jl"), l2=[0.006816790293009947, 0.0065068948357351625, From 060054a0a15a02cfb2091f9dbd8c45dee7de3a0b Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Thu, 3 Apr 2025 18:09:31 +0200 Subject: [PATCH 04/83] format --- src/callbacks_step/save_solution_dg.jl | 15 ++++----- ...tic_perturbation_2d_auxiliary_variables.jl | 31 +++++++++++-------- src/equations/equations.jl | 3 +- .../semidiscretization_hyperbolic.jl | 6 ++-- src/solvers/dg.jl | 3 +- src/solvers/dgsem_tree/containers.jl | 22 +++++++------ src/solvers/dgsem_tree/containers_2d.jl | 24 +++++++++----- src/solvers/dgsem_tree/dg_2d.jl | 16 +++++----- test/test_tree_2d_acoustics.jl | 6 ++-- 9 files changed, 74 insertions(+), 52 deletions(-) diff --git a/src/callbacks_step/save_solution_dg.jl b/src/callbacks_step/save_solution_dg.jl index aba7976d7bf..5de7ff3b51e 100644 --- a/src/callbacks_step/save_solution_dg.jl +++ b/src/callbacks_step/save_solution_dg.jl @@ -25,12 +25,12 @@ end # compute the solution variables via broadcasting, and reinterpret the # result as a plain array of floating point numbers return Array(reinterpret(eltype(u), - solution_variables.(reinterpret(SVector{nvariables(equations), - eltype(u)}, u), - reinterpret(SVector{n_auxiliary_node_vars(equations), - eltype(auxiliary_node_vars)}, - auxiliary_node_vars), - Ref(equations)))) + solution_variables.(reinterpret(SVector{nvariables(equations), + eltype(u)}, u), + reinterpret(SVector{n_auxiliary_node_vars(equations), + eltype(auxiliary_node_vars)}, + auxiliary_node_vars), + Ref(equations)))) end function save_solution_file(u, time, dt, timestep, @@ -59,7 +59,8 @@ function save_solution_file(u, time, dt, timestep, n_vars = nvariables(equations) else data = convert_to_solution_variables(u, solution_variables, cache, - have_auxiliary_node_vars(equations), equations) + have_auxiliary_node_vars(equations), + equations) # Find out variable count by looking at output from `solution_variables` function n_vars = size(data, 1) end diff --git a/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl b/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl index 3b68956f37d..9a741e11d63 100644 --- a/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl +++ b/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl @@ -19,17 +19,17 @@ struct AcousticPerturbationEquations2DAuxVars{RealT <: Real} <: end function AcousticPerturbationEquations2DAuxVars(v_mean_global::NTuple{2, <:Real}, - c_mean_global::Real, - rho_mean_global::Real) + c_mean_global::Real, + rho_mean_global::Real) return AcousticPerturbationEquations2DAuxVars(SVector(v_mean_global), c_mean_global, - rho_mean_global) + rho_mean_global) end function AcousticPerturbationEquations2DAuxVars(; v_mean_global::NTuple{2, <:Real}, - c_mean_global::Real, - rho_mean_global::Real) + c_mean_global::Real, + rho_mean_global::Real) return AcousticPerturbationEquations2DAuxVars(SVector(v_mean_global), c_mean_global, - rho_mean_global) + rho_mean_global) end have_auxiliary_node_vars(::AcousticPerturbationEquations2DAuxVars) = True() @@ -53,7 +53,8 @@ end A constant initial condition where the state variables are zero and the mean flow is constant. Uses the global mean values from `equations`. """ -function initial_condition_constant(x, t, equations::AcousticPerturbationEquations2DAuxVars) +function initial_condition_constant(x, t, + equations::AcousticPerturbationEquations2DAuxVars) v1_prime = 0 v2_prime = 0 p_prime_scaled = 0 @@ -68,7 +69,7 @@ A smooth initial condition used for convergence tests in combination with [`source_terms_convergence_test`](@ref). Uses the global mean values from `equations`. """ function initial_condition_convergence_test(x, t, - equations::AcousticPerturbationEquations2DAuxVars) + equations::AcousticPerturbationEquations2DAuxVars) RealT = eltype(x) a = 1 c = 2 @@ -119,7 +120,8 @@ end A Gaussian pulse in a constant mean flow. Uses the global mean values from `equations`. """ -function initial_condition_gauss(x, t, equations::AcousticPerturbationEquations2DAuxVars) +function initial_condition_gauss(x, t, + equations::AcousticPerturbationEquations2DAuxVars) v1_prime = 0 v2_prime = 0 p_prime = exp(-4 * (x[1]^2 + x[2]^2)) @@ -311,7 +313,8 @@ end return max(abs(v_ll) + c_mean_ll * norm_, abs(v_rr) + c_mean_rr * norm_) end -@inline function flux_central(u_ll, u_rr, aux_ll, aux_rr, orientation_or_normal_direction, +@inline function flux_central(u_ll, u_rr, aux_ll, aux_rr, + orientation_or_normal_direction, equations::AcousticPerturbationEquations2DAuxVars) # Calculate regular 1D fluxes f_ll = flux(u_ll, aux_ll, orientation_or_normal_direction, equations) @@ -322,10 +325,11 @@ end end # Specialized `DissipationLocalLaxFriedrichs` taking into account auxiliary variables -@inline function (dissipation::DissipationLocalLaxFriedrichs)(u_ll, u_rr, aux_ll, aux_rr, +@inline function (dissipation::DissipationLocalLaxFriedrichs)(u_ll, u_rr, aux_ll, + aux_rr, orientation_or_normal_direction, equations::AcousticPerturbationEquations2DAuxVars) - λ = dissipation.max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, + λ = dissipation.max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, orientation_or_normal_direction, equations) diss = -0.5f0 * λ * (u_rr - u_ll) return SVector(diss[1], diss[2], diss[3]) @@ -333,7 +337,8 @@ end @inline have_constant_speed(::AcousticPerturbationEquations2DAuxVars) = False() -@inline function max_abs_speeds(u, aux, equations::AcousticPerturbationEquations2DAuxVars) +@inline function max_abs_speeds(u, aux, + equations::AcousticPerturbationEquations2DAuxVars) v1_mean, v2_mean, c_mean, _ = aux return abs(v1_mean) + c_mean, abs(v2_mean) + c_mean diff --git a/src/equations/equations.jl b/src/equations/equations.jl index c465d835dab..73db47031ab 100644 --- a/src/equations/equations.jl +++ b/src/equations/equations.jl @@ -329,8 +329,7 @@ Number of auxiliary variables used by `equations`. This function needs to be spe only if equations has auxiliary variables. """ function n_auxiliary_node_vars end -@inline eachauxiliaryvariable(equations::AbstractEquations) = - Base.OneTo(n_auxiliary_node_vars(equations)) +@inline eachauxiliaryvariable(equations::AbstractEquations) = Base.OneTo(n_auxiliary_node_vars(equations)) """ default_analysis_errors(equations) diff --git a/src/semidiscretization/semidiscretization_hyperbolic.jl b/src/semidiscretization/semidiscretization_hyperbolic.jl index 1173e0e3dd3..d040f718390 100644 --- a/src/semidiscretization/semidiscretization_hyperbolic.jl +++ b/src/semidiscretization/semidiscretization_hyperbolic.jl @@ -73,9 +73,9 @@ function SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver # Add specialized parts of the cache for auxiliary node variables cache = (; cache..., - create_cache_auxiliary(mesh, equations, solver, cache, - have_auxiliary_node_vars(equations), - auxiliary_field)...) + create_cache_auxiliary(mesh, equations, solver, cache, + have_auxiliary_node_vars(equations), + auxiliary_field)...) _boundary_conditions = digest_boundary_conditions(boundary_conditions, mesh, solver, cache) diff --git a/src/solvers/dg.jl b/src/solvers/dg.jl index 0036166846e..39e735a2ffe 100644 --- a/src/solvers/dg.jl +++ b/src/solvers/dg.jl @@ -560,7 +560,8 @@ end end # Return the auxiliary variables at a given volume node index -@inline function get_auxiliary_node_vars(auxiliary_node_vars, equations, ::DG, indices...) +@inline function get_auxiliary_node_vars(auxiliary_node_vars, equations, ::DG, + indices...) return SVector(ntuple(@inline(v->auxiliary_node_vars[v, indices...]), Val(n_auxiliary_node_vars(equations)))) end diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index 2cf66fbcc44..e632ff90fde 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -53,7 +53,8 @@ function reinitialize_containers!(mesh::TreeMesh, equations, dg::DGSEM, cache) end # Container for storing values of auxiliary variables at volume/surface quadrature nodes -struct AuxiliaryNodeVariablesContainer{NDIMS, uEltype <: Real, NDIMSP2, AuxiliaryVariables} +struct AuxiliaryNodeVariablesContainer{NDIMS, uEltype <: Real, NDIMSP2, + AuxiliaryVariables} auxiliary_node_vars::Array{uEltype, NDIMSP2} # [var, i, j, element] auxiliary_surface_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] @@ -68,7 +69,7 @@ end # Create auxiliary node variable container function init_auxiliary_node_variables(mesh, equations, solver, cache, auxiliary_field) - @unpack elements, interfaces = cache + @unpack elements, interfaces = cache n_elements = nelements(elements) n_interfaces = ninterfaces(interfaces) @@ -87,16 +88,19 @@ function init_auxiliary_node_variables(mesh, equations, solver, cache, 2 * n_auxiliary_node_vars(equations) * nnodes(solver)^(NDIMS - 1) * n_interfaces) - auxiliary_surface_node_vars = unsafe_wrap(Array, pointer(_auxiliary_surface_node_vars), + auxiliary_surface_node_vars = unsafe_wrap(Array, + pointer(_auxiliary_surface_node_vars), (2, n_auxiliary_node_vars(equations), - ntuple(_ -> nnodes(solver), NDIMS - 1)..., + ntuple(_ -> nnodes(solver), + NDIMS - 1)..., n_interfaces)) - auxiliary_variables = - AuxiliaryNodeVariablesContainer{NDIMS, uEltype, NDIMS + 2, typeof(auxiliary_field)}( - auxiliary_node_vars, auxiliary_surface_node_vars, - _auxiliary_node_vars, _auxiliary_surface_node_vars, - auxiliary_field) + auxiliary_variables = AuxiliaryNodeVariablesContainer{NDIMS, uEltype, NDIMS + 2, + typeof(auxiliary_field)}(auxiliary_node_vars, + auxiliary_surface_node_vars, + _auxiliary_node_vars, + _auxiliary_surface_node_vars, + auxiliary_field) init_auxiliary_node_variables!(auxiliary_variables, mesh, equations, solver, cache, auxiliary_field) diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index 7d19f366e47..b168bc87e78 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1455,20 +1455,28 @@ function init_auxiliary_surface_node_variables!(auxiliary_variables, mesh, equat # interface in x-direction for j in eachnode(solver) for v in axes(auxiliary_surface_node_vars, 2) - auxiliary_surface_node_vars[1, v, j, interface] = - auxiliary_node_vars[v, nnodes(solver), j, left_element] - auxiliary_surface_node_vars[2, v, j, interface] = - auxiliary_node_vars[v, 1, j, right_element] + auxiliary_surface_node_vars[1, v, j, interface] = auxiliary_node_vars[v, + nnodes(solver), + j, + left_element] + auxiliary_surface_node_vars[2, v, j, interface] = auxiliary_node_vars[v, + 1, + j, + right_element] end end else # if orientations[interface] == 2 # interface in y-direction for i in eachnode(solver) for v in axes(auxiliary_surface_node_vars, 2) - auxiliary_surface_node_vars[1, v, i, interface] = - auxiliary_node_vars[v, i, nnodes(solver), left_element] - auxiliary_surface_node_vars[2, v, i, interface] = - auxiliary_node_vars[v, i, 1, right_element] + auxiliary_surface_node_vars[1, v, i, interface] = auxiliary_node_vars[v, + i, + nnodes(solver), + left_element] + auxiliary_surface_node_vars[2, v, i, interface] = auxiliary_node_vars[v, + i, + 1, + right_element] end end end diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index f8dc88cbf15..b812d0d0f1e 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -324,7 +324,6 @@ end end end - @inline function flux_differencing_kernel!(du, u, element, mesh::TreeMesh{2}, nonconservative_terms::False, @@ -441,16 +440,17 @@ function calc_volume_integral!(du, u, if dg_only flux_differencing_kernel!(du, u, element, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), equations, volume_flux_dg, dg, cache) else # Calculate DG volume integral contribution flux_differencing_kernel!(du, u, element, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), equations, volume_flux_dg, dg, cache, 1 - alpha_element) # Calculate FV volume integral contribution - fv_kernel!(du, u, mesh, have_nonconservative_terms(equations), equations, volume_flux_fv, + fv_kernel!(du, u, mesh, have_nonconservative_terms(equations), equations, + volume_flux_fv, dg, cache, element, alpha_element) end end @@ -470,7 +470,8 @@ function calc_volume_integral!(du, u, # Calculate LGL FV volume integral @threaded for element in eachelement(dg, cache) - fv_kernel!(du, u, mesh, have_nonconservative_terms(equations), equations, volume_flux_fv, + fv_kernel!(du, u, mesh, have_nonconservative_terms(equations), equations, + volume_flux_fv, dg, cache, element, true) end @@ -711,8 +712,9 @@ function calc_interface_flux!(surface_flux_values, for i in eachnode(dg) # Call pointwise Riemann solver u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) - aux_ll, aux_rr = get_auxiliary_surface_node_vars( - auxiliary_surface_node_vars, equations, dg, i, interface) + aux_ll, aux_rr = get_auxiliary_surface_node_vars(auxiliary_surface_node_vars, + equations, dg, i, + interface) flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, orientations[interface], equations) # Copy flux to left and right element storage diff --git a/test/test_tree_2d_acoustics.jl b/test/test_tree_2d_acoustics.jl index 099d4a1d970..3e0830ece78 100644 --- a/test/test_tree_2d_acoustics.jl +++ b/test/test_tree_2d_acoustics.jl @@ -41,7 +41,8 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem") end @trixi_testset "elixir_acoustics_convergence_auxvars.jl" begin - @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_acoustics_convergence_auxvars.jl"), + @test_trixi_include(joinpath(EXAMPLES_DIR, + "elixir_acoustics_convergence_auxvars.jl"), l2=[ 0.0019921138796370834, 0.002090394698052287, @@ -143,7 +144,8 @@ end end @trixi_testset "elixir_acoustics_gauss_wall_auxvars.jl" begin - @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_acoustics_gauss_wall_auxvars.jl"), + @test_trixi_include(joinpath(EXAMPLES_DIR, + "elixir_acoustics_gauss_wall_auxvars.jl"), l2=[0.019419398248465843, 0.019510701017551826, 0.04818246051887614], linf=[0.18193631937316496, 0.1877464607867628, From 88e7f12395a42bba43cfcad93869c1d327826924 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 4 Apr 2025 09:36:42 +0200 Subject: [PATCH 05/83] extend 2D TreeMesh AMR for aux vars --- src/equations/acoustic_perturbation_2d.jl | 31 ------------ src/solvers/dgsem_tree/containers.jl | 53 ++++++++++++++++++-- src/solvers/dgsem_tree/containers_2d.jl | 4 +- src/solvers/dgsem_tree/dg_2d.jl | 60 ++++++++++++++++------- 4 files changed, 93 insertions(+), 55 deletions(-) diff --git a/src/equations/acoustic_perturbation_2d.jl b/src/equations/acoustic_perturbation_2d.jl index 08fc15ca67d..180a41f23fb 100644 --- a/src/equations/acoustic_perturbation_2d.jl +++ b/src/equations/acoustic_perturbation_2d.jl @@ -221,37 +221,6 @@ function boundary_condition_wall(u_inner, orientation, direction, x, t, return flux end -""" - boundary_condition_slip_wall(u_inner, normal_direction, x, t, surface_flux_function, - equations::AcousticPerturbationEquations2D) - -Use an orthogonal projection of the perturbed velocities to zero out the normal velocity -while retaining the possibility of a tangential velocity in the boundary state. -Further details are available in the paper: -- Marcus Bauer, Jürgen Dierke and Roland Ewert (2011) - Application of a discontinuous Galerkin method to discretize acoustic perturbation equations - [DOI: 10.2514/1.J050333](https://doi.org/10.2514/1.J050333) -""" -function boundary_condition_slip_wall(u_inner, normal_direction::AbstractVector, x, t, - surface_flux_function, - equations::AcousticPerturbationEquations2D) - # normalize the outward pointing direction - normal = normal_direction / norm(normal_direction) - - # compute the normal perturbed velocity - u_normal = normal[1] * u_inner[1] + normal[2] * u_inner[2] - - # create the "external" boundary solution state - u_boundary = SVector(u_inner[1] - 2 * u_normal * normal[1], - u_inner[2] - 2 * u_normal * normal[2], - u_inner[3], cons2mean(u_inner, equations)...) - - # calculate the boundary flux - flux = surface_flux_function(u_inner, u_boundary, normal_direction, equations) - - return flux -end - # Calculate 1D flux for a single point @inline function flux(u, orientation::Integer, equations::AcousticPerturbationEquations2D) diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index e632ff90fde..6ae5e4f86ce 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -34,6 +34,16 @@ function reinitialize_containers!(mesh::TreeMesh, equations, dg::DGSEM, cache) init_mortars!(mortars, elements, mesh) end + # re-initialize auxiliary variables container + if hasproperty(cache, :auxiliary_variables) + @unpack auxiliary_variables = cache + resize!(auxiliary_variables, length(leaf_cell_ids), + count_required_interfaces(mesh, leaf_cell_ids)) + init_auxiliary_node_variables!(auxiliary_variables, mesh, equations, dg, cache) + init_auxiliary_surface_node_variables!(auxiliary_variables, mesh, equations, dg, + cache) + end + if mpi_isparallel() # re-initialize mpi_interfaces container @unpack mpi_interfaces = cache @@ -53,8 +63,8 @@ function reinitialize_containers!(mesh::TreeMesh, equations, dg::DGSEM, cache) end # Container for storing values of auxiliary variables at volume/surface quadrature nodes -struct AuxiliaryNodeVariablesContainer{NDIMS, uEltype <: Real, NDIMSP2, - AuxiliaryVariables} +mutable struct AuxiliaryNodeVariablesContainer{NDIMS, uEltype <: Real, NDIMSP2, + AuxiliaryVariables} auxiliary_node_vars::Array{uEltype, NDIMSP2} # [var, i, j, element] auxiliary_surface_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] @@ -66,6 +76,11 @@ struct AuxiliaryNodeVariablesContainer{NDIMS, uEltype <: Real, NDIMSP2, auxiliary_field::AuxiliaryVariables end +nvariables(auxiliary_variables::AuxiliaryNodeVariablesContainer) = size(auxiliary_variables.auxiliary_node_vars, + 1) +nnodes(auxiliary_variables::AuxiliaryNodeVariablesContainer) = size(auxiliary_variables.auxiliary_node_vars, + 2) + # Create auxiliary node variable container function init_auxiliary_node_variables(mesh, equations, solver, cache, auxiliary_field) @@ -102,13 +117,43 @@ function init_auxiliary_node_variables(mesh, equations, solver, cache, _auxiliary_surface_node_vars, auxiliary_field) - init_auxiliary_node_variables!(auxiliary_variables, mesh, equations, solver, cache, - auxiliary_field) + init_auxiliary_node_variables!(auxiliary_variables, mesh, equations, solver, cache) init_auxiliary_surface_node_variables!(auxiliary_variables, mesh, equations, solver, cache) return auxiliary_variables end +# Only one-dimensional `Array`s are `resize!`able in Julia. +# Hence, we use `Vector`s as internal storage and `resize!` +# them whenever needed. Then, we reuse the same memory by +# `unsafe_wrap`ping multi-dimensional `Array`s around the +# internal storage. +function Base.resize!(auxiliary_variables::AuxiliaryNodeVariablesContainer{NDIMS}, + capacity_node_vars, capacity_node_surface_vars) where {NDIMS} + @unpack _auxiliary_node_vars, _auxiliary_surface_node_vars = auxiliary_variables + n_nodes = nnodes(auxiliary_variables) + n_variables = nvariables(auxiliary_variables) + + resize!(_auxiliary_node_vars, n_variables * n_nodes^NDIMS * capacity_node_vars) + auxiliary_variables.auxiliary_node_vars = unsafe_wrap(Array, + pointer(_auxiliary_node_vars), + (n_variables, + ntuple(_ -> n_nodes, + NDIMS)..., + capacity_node_vars)) + + resize!(_auxiliary_surface_node_vars, + 2 * n_variables * n_nodes^(NDIMS - 1) * + capacity_node_surface_vars) + auxiliary_variables.auxiliary_surface_node_vars = unsafe_wrap(Array, + pointer(_auxiliary_surface_node_vars), + (2, n_variables, + ntuple(_ -> n_nodes, + NDIMS - 1)..., + capacity_node_surface_vars)) + return nothing +end + # Dimension-specific implementations include("containers_1d.jl") include("containers_2d.jl") diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index b168bc87e78..97f6245f728 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1425,8 +1425,8 @@ end # Initialize auxiliary node variables (2D implementation) function init_auxiliary_node_variables!(auxiliary_variables, mesh, equations, solver, - cache, auxiliary_field) - @unpack auxiliary_node_vars = auxiliary_variables + cache) + @unpack auxiliary_node_vars, auxiliary_field = auxiliary_variables @unpack node_coordinates = cache.elements @threaded for element in eachelement(solver, cache) diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index b812d0d0f1e..303c2ae17d9 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -1084,14 +1084,16 @@ function calc_mortar_flux!(surface_flux_values, # Calculate fluxes orientation = orientations[mortar] - calc_fstar!(fstar_primary_upper, equations, surface_flux, dg, u_upper, mortar, - orientation) - calc_fstar!(fstar_primary_lower, equations, surface_flux, dg, u_lower, mortar, - orientation) - calc_fstar!(fstar_secondary_upper, equations, surface_flux, dg, u_upper, mortar, - orientation) - calc_fstar!(fstar_secondary_lower, equations, surface_flux, dg, u_lower, mortar, - orientation) + calc_fstar!(fstar_primary_upper, have_auxiliary_node_vars(equations), equations, + surface_flux, dg, u_upper, mortar, orientation, cache) + calc_fstar!(fstar_primary_lower, have_auxiliary_node_vars(equations), equations, + surface_flux, dg, u_lower, mortar, orientation, cache) + calc_fstar!(fstar_secondary_upper, have_auxiliary_node_vars(equations), + equations, + surface_flux, dg, u_upper, mortar, orientation, cache) + calc_fstar!(fstar_secondary_lower, have_auxiliary_node_vars(equations), + equations, + surface_flux, dg, u_lower, mortar, orientation, cache) mortar_fluxes_to_elements!(surface_flux_values, mesh, equations, mortar_l2, dg, cache, @@ -1121,14 +1123,16 @@ function calc_mortar_flux!(surface_flux_values, # Calculate fluxes orientation = orientations[mortar] - calc_fstar!(fstar_primary_upper, equations, surface_flux, dg, u_upper, mortar, - orientation) - calc_fstar!(fstar_primary_lower, equations, surface_flux, dg, u_lower, mortar, - orientation) - calc_fstar!(fstar_secondary_upper, equations, surface_flux, dg, u_upper, mortar, - orientation) - calc_fstar!(fstar_secondary_lower, equations, surface_flux, dg, u_lower, mortar, - orientation) + calc_fstar!(fstar_primary_upper, have_auxiliary_node_vars(equations), equations, + surface_flux, dg, u_upper, mortar, orientation, cache) + calc_fstar!(fstar_primary_lower, have_auxiliary_node_vars(equations), equations, + surface_flux, dg, u_lower, mortar, orientation, cache) + calc_fstar!(fstar_secondary_upper, have_auxiliary_node_vars(equations), + equations, + surface_flux, dg, u_upper, mortar, orientation, cache) + calc_fstar!(fstar_secondary_lower, have_auxiliary_node_vars(equations), + equations, + surface_flux, dg, u_lower, mortar, orientation, cache) # Add nonconservative fluxes. # These need to be adapted on the geometry (left/right) since the order of @@ -1208,9 +1212,10 @@ function calc_mortar_flux!(surface_flux_values, return nothing end -@inline function calc_fstar!(destination::AbstractArray{<:Any, 2}, equations, +@inline function calc_fstar!(destination::AbstractArray{<:Any, 2}, + have_auxiliary_node_vars::False, equations, surface_flux, dg::DGSEM, - u_interfaces, interface, orientation) + u_interfaces, interface, orientation, cache) for i in eachnode(dg) # Call pointwise two-point numerical flux function u_ll, u_rr = get_surface_node_vars(u_interfaces, equations, dg, i, interface) @@ -1223,6 +1228,25 @@ end return nothing end +@inline function calc_fstar!(destination::AbstractArray{<:Any, 2}, + have_auxiliary_node_vars::True, equations, + surface_flux, dg::DGSEM, + u_interfaces, interface, orientation, cache) + @unpack auxiliary_surface_node_vars = cache.auxiliary_variables + for i in eachnode(dg) + # Call pointwise two-point numerical flux function + u_ll, u_rr = get_surface_node_vars(u_interfaces, equations, dg, i, interface) + aux_ll, aux_rr = get_auxiliary_surface_node_vars(auxiliary_surface_node_vars, + equations, dg, i, interface) + flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, orientation, equations) + + # Copy flux to left and right element storage + set_node_vars!(destination, flux, equations, dg, i) + end + + return nothing +end + @inline function mortar_fluxes_to_elements!(surface_flux_values, mesh::TreeMesh{2}, equations, mortar_l2::LobattoLegendreMortarL2, From 15cea5cdcb80d433337dc798bd7b1e511faf9268 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 4 Apr 2025 09:40:04 +0200 Subject: [PATCH 06/83] add elixir and test for AMR with aux vars --- ...elixir_acoustics_gauss_wall_amr_auxvars.jl | 98 +++++++++++++++++++ test/test_tree_2d_acoustics.jl | 15 +++ 2 files changed, 113 insertions(+) create mode 100644 examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_amr_auxvars.jl diff --git a/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_amr_auxvars.jl b/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_amr_auxvars.jl new file mode 100644 index 00000000000..dcbaa5bc5ed --- /dev/null +++ b/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_amr_auxvars.jl @@ -0,0 +1,98 @@ +using OrdinaryDiffEqLowStorageRK +using Trixi +using Plots + +############################################################################### +# semidiscretization of the acoustic perturbation equations + +equations = AcousticPerturbationEquations2DAuxVars(v_mean_global = (0.5, 0.0), + c_mean_global = 1.0, + rho_mean_global = 1.0) + +# Create DG solver with polynomial degree = 5 and (local) Lax-Friedrichs/Rusanov flux as surface flux +solver = DGSEM(polydeg = 5, surface_flux = flux_lax_friedrichs) + +coordinates_min = (-100.0, 0.0) # minimum coordinates (min(x), min(y)) +coordinates_max = (100.0, 200.0) # maximum coordinates (max(x), max(y)) + +# Create a uniformly refined mesh with periodic boundaries +mesh = TreeMesh(coordinates_min, coordinates_max, + initial_refinement_level = 2, + n_cells_max = 100_000, + periodicity = false) + +""" + initial_condition_gauss_wall(x, t, equations::AcousticPerturbationEquations2DAuxVars) + +A Gaussian pulse, used in the `gauss_wall` example elixir in combination with +[`boundary_condition_wall`](@ref). Uses the global mean values from `equations`. +""" +function initial_condition_gauss_wall(x, t, + equations::AcousticPerturbationEquations2DAuxVars) + RealT = eltype(x) + v1_prime = 0 + v2_prime = 0 + p_prime = exp(-log(convert(RealT, 2)) * (x[1]^2 + (x[2] - 25)^2) / 25) + p_prime_scaled = p_prime / equations.c_mean_global^2 + + return SVector(v1_prime, v2_prime, p_prime_scaled) +end +initial_condition = initial_condition_gauss_wall + +function auxiliary_variables_mean_values(x, equations) + # constant auxiliary variables (mean state) + return global_mean_vars(equations) +end + +@inline function p_prime(u, equations::AcousticPerturbationEquations2DAuxVars) + return u[3] +end + +# A semidiscretization collects data structures and functions for the spatial discretization +semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, + boundary_conditions = boundary_condition_wall, + auxiliary_field = auxiliary_variables_mean_values) + +############################################################################### +# ODE solvers, callbacks etc. + +# Create ODE problem with time span from 0.0 to 30.0 +tspan = (0.0, 30.0) +ode = semidiscretize(semi, tspan) + +# At the beginning of the main loop, the SummaryCallback prints a summary of the simulation setup +# and resets the timers +summary_callback = SummaryCallback() + +# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results +analysis_callback = AnalysisCallback(semi, interval = 100) + +# The SaveSolutionCallback allows to save the solution to a file in regular intervals +save_solution = SaveSolutionCallback(interval = 100, solution_variables = cons2state) + +# The StepsizeCallback handles the re-calculation of the maximum Δt after each time step +stepsize_callback = StepsizeCallback(cfl = 0.7) + +amr_controller = ControllerThreeLevel(semi, IndicatorMax(semi, variable = p_prime), + base_level = 2, + med_level = 4, med_threshold = 0.1, + max_level = 5, max_threshold = 0.2) +amr_callback = AMRCallback(semi, amr_controller, + interval = 5, + adapt_initial_condition = true, + adapt_initial_condition_only_refine = true) + +visualization = VisualizationCallback(interval = 5, show_mesh = true, + variable_names = ["v1_prime", "v2_prime", "p_prime"]) + +# Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver +callbacks = CallbackSet(summary_callback, analysis_callback, save_solution, #visualization, + amr_callback, stepsize_callback) + +############################################################################### +# run the simulation + +# OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks +sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false); + dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback + ode_default_options()..., callback = callbacks) diff --git a/test/test_tree_2d_acoustics.jl b/test/test_tree_2d_acoustics.jl index 3e0830ece78..7a83f2c8d29 100644 --- a/test/test_tree_2d_acoustics.jl +++ b/test/test_tree_2d_acoustics.jl @@ -160,6 +160,21 @@ end end end +@trixi_testset "elixir_acoustics_gauss_wall_amr_auxvars.jl" begin + @test_trixi_include(joinpath(EXAMPLES_DIR, + "elixir_acoustics_gauss_wall_amr_auxvars.jl"), + l2=[0.0194350488, 0.0195225440, 0.00481982254], + linf=[0.183057645, 0.190845961, 1.03618809]) + # Ensure that we do not have excessive memory allocations + # (e.g., from type instabilities) + let + t = sol.t[end] + u_ode = sol.u[end] + du_ode = similar(u_ode) + @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 + end +end + @trixi_testset "elixir_acoustics_monopole.jl" begin @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_acoustics_monopole.jl"), l2=[0.006816790293009947, 0.0065068948357351625, From fa334217cc1ec4330f229f52d0c9bedd9988ad51 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 4 Apr 2025 12:05:33 +0200 Subject: [PATCH 07/83] adapt mehtod used in VisualizationCallback --- src/visualization/utilities.jl | 52 +++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/visualization/utilities.jl b/src/visualization/utilities.jl index 8b6d7c379b0..f68f73625c4 100644 --- a/src/visualization/utilities.jl +++ b/src/visualization/utilities.jl @@ -456,6 +456,43 @@ function get_data_1d(original_nodes, unstructured_data, nvisnodes, reinterpolate vcat(original_nodes[1, 1, :], original_nodes[1, end, end]) end +@inline function apply_solution_variables(u, solution_variables, + have_auxiliary_node_vars::False, equations, + solver, cache) + n_vars_in = nvariables(equations) + n_vars = length(solution_variables(get_node_vars(u, equations, solver), + equations)) + raw_data = Array{eltype(u)}(undef, n_vars, Base.tail(size(u))...) + reshaped_u = reshape(u, n_vars_in, :) + reshaped_r = reshape(raw_data, n_vars, :) + for idx in axes(reshaped_u, 2) + u_node = get_node_vars(reshaped_u, equations, solver, idx) + reshaped_r[:, idx] = solution_variables(u_node, equations) + end + return raw_data +end + +@inline function apply_solution_variables(u, solution_variables, + have_auxiliary_node_vars::True, equations, + solver, cache) + @unpack auxiliary_node_vars = cache.auxiliary_variables + n_vars_in = nvariables(equations) + n_vars_aux = n_auxiliary_node_vars(equations) + n_vars = length(solution_variables(get_node_vars(u, equations, solver), + get_auxiliary_node_vars(auxiliary_node_vars, equations, solver), + equations)) + raw_data = Array{eltype(u)}(undef, n_vars, Base.tail(size(u))...) + reshaped_u = reshape(u, n_vars_in, :) + reshaped_r = reshape(raw_data, n_vars, :) + reshaped_aux = reshape(auxiliary_node_vars, n_vars_aux, :) + for idx in axes(reshaped_u, 2) + u_node = get_node_vars(reshaped_u, equations, solver, idx) + aux_node = get_auxiliary_node_vars(reshaped_aux, equations, solver, idx) + reshaped_r[:, idx] = solution_variables(u_node, aux_node, equations) + end + return raw_data +end + # Change order of dimensions (variables are now last) and convert data to `solution_variables` # # Note: This is a low-level function that is not considered as part of Trixi.jl's interface and may @@ -473,17 +510,10 @@ function get_unstructured_data(u, solution_variables, mesh, equations, solver, c # solution_variables.(reinterpret(SVector{nvariables(equations),eltype(u)}, u), # Ref(equations)))) # n_vars = size(raw_data, 1) - n_vars_in = nvariables(equations) - n_vars = length(solution_variables(get_node_vars(u, equations, solver), - equations)) - raw_data = Array{eltype(u)}(undef, n_vars, Base.tail(size(u))...) - reshaped_u = reshape(u, n_vars_in, :) - reshaped_r = reshape(raw_data, n_vars, :) - for idx in axes(reshaped_u, 2) - reshaped_r[:, idx] = solution_variables(get_node_vars(reshaped_u, equations, - solver, idx), - equations) - end + raw_data = apply_solution_variables(u, solution_variables, + have_auxiliary_node_vars(equations), + equations, solver, cache) + n_vars = size(raw_data, 1) end unstructured_data = Array{eltype(raw_data)}(undef, From 5f8891f5b4308a57bd26d5449e4766d4f9a32434 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 4 Apr 2025 12:06:12 +0200 Subject: [PATCH 08/83] do not use VisualizationCallback --- .../tree_2d_dgsem/elixir_acoustics_gauss_wall_amr_auxvars.jl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_amr_auxvars.jl b/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_amr_auxvars.jl index dcbaa5bc5ed..d62a3e4a30a 100644 --- a/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_amr_auxvars.jl +++ b/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_amr_auxvars.jl @@ -82,11 +82,8 @@ amr_callback = AMRCallback(semi, amr_controller, adapt_initial_condition = true, adapt_initial_condition_only_refine = true) -visualization = VisualizationCallback(interval = 5, show_mesh = true, - variable_names = ["v1_prime", "v2_prime", "p_prime"]) - # Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver -callbacks = CallbackSet(summary_callback, analysis_callback, save_solution, #visualization, +callbacks = CallbackSet(summary_callback, analysis_callback, save_solution, amr_callback, stepsize_callback) ############################################################################### From 14ec2f541f6ad565bd211ee0b0faa77bc83b4125 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Mon, 7 Apr 2025 18:45:53 +0200 Subject: [PATCH 09/83] lets fix something --- src/callbacks_step/stepsize_dg1d.jl | 12 ++-- src/callbacks_step/stepsize_dg2d.jl | 60 +++++++++++-------- src/callbacks_step/stepsize_dg3d.jl | 48 ++++++++------- .../semidiscretization_euler_gravity.jl | 4 +- src/solvers/dgmulti/dg.jl | 6 +- src/solvers/dgsem_structured/dg_2d.jl | 3 +- src/solvers/dgsem_tree/dg_2d.jl | 6 +- .../dgsem_tree/dg_2d_subcell_limiters.jl | 19 +++--- src/solvers/dgsem_unstructured/dg_2d.jl | 3 +- .../paired_explicit_runge_kutta.jl | 4 +- 10 files changed, 93 insertions(+), 72 deletions(-) diff --git a/src/callbacks_step/stepsize_dg1d.jl b/src/callbacks_step/stepsize_dg1d.jl index cdb7ed21de4..90b24dc3bcc 100644 --- a/src/callbacks_step/stepsize_dg1d.jl +++ b/src/callbacks_step/stepsize_dg1d.jl @@ -6,7 +6,8 @@ #! format: noindent function max_dt(u, t, mesh::TreeMesh{1}, - constant_speed::False, equations, dg::DG, cache) + constant_speed::False, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection max_scaled_speed = nextfloat(zero(t)) @@ -26,7 +27,8 @@ function max_dt(u, t, mesh::TreeMesh{1}, end function max_dt(u, t, mesh::TreeMesh{1}, - constant_speed::True, equations, dg::DG, cache) + constant_speed::True, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection max_scaled_speed = nextfloat(zero(t)) @@ -41,7 +43,8 @@ function max_dt(u, t, mesh::TreeMesh{1}, end function max_dt(u, t, mesh::StructuredMesh{1}, - constant_speed::False, equations, dg::DG, cache) + constant_speed::False, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection max_scaled_speed = nextfloat(zero(t)) @@ -65,7 +68,8 @@ function max_dt(u, t, mesh::StructuredMesh{1}, end function max_dt(u, t, mesh::StructuredMesh{1}, - constant_speed::True, equations, dg::DG, cache) + constant_speed::True, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection max_scaled_speed = nextfloat(zero(t)) diff --git a/src/callbacks_step/stepsize_dg2d.jl b/src/callbacks_step/stepsize_dg2d.jl index eb54026f203..4cc5b9e0412 100644 --- a/src/callbacks_step/stepsize_dg2d.jl +++ b/src/callbacks_step/stepsize_dg2d.jl @@ -72,16 +72,17 @@ function max_dt(u, t, mesh::TreeMesh{2}, end function max_dt(u, t, mesh::ParallelTreeMesh{2}, - constant_speed::False, equations, dg::DG, cache) + constant_speed::False, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # call the method accepting a general `mesh::TreeMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` # and create some MPI array type, overloading broadcasting and mapreduce etc. # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), TreeMesh{2}, - typeof(constant_speed), typeof(equations), typeof(dg), - typeof(cache)}, - u, t, mesh, constant_speed, equations, dg, cache) + typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(equations), typeof(dg), typeof(cache)}, + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -89,16 +90,17 @@ function max_dt(u, t, mesh::ParallelTreeMesh{2}, end function max_dt(u, t, mesh::ParallelTreeMesh{2}, - constant_speed::True, equations, dg::DG, cache) + constant_speed::True, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # call the method accepting a general `mesh::TreeMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` # and create some MPI array type, overloading broadcasting and mapreduce etc. # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), TreeMesh{2}, - typeof(constant_speed), typeof(equations), typeof(dg), - typeof(cache)}, - u, t, mesh, constant_speed, equations, dg, cache) + typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(equations), typeof(dg), typeof(cache)}, + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -108,7 +110,8 @@ end function max_dt(u, t, mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}, StructuredMeshView{2}}, - constant_speed::False, equations, dg::DG, cache) + constant_speed::False, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection max_scaled_speed = nextfloat(zero(t)) @@ -144,7 +147,8 @@ end function max_dt(u, t, mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}, StructuredMeshView{2}}, - constant_speed::True, equations, dg::DG, cache) + constant_speed::True, have_auxiliary_node_vars::False, + equations, dg::DG, cache) @unpack contravariant_vectors, inverse_jacobian = cache.elements # to avoid a division by zero if the speed vanishes everywhere, @@ -174,16 +178,17 @@ function max_dt(u, t, end function max_dt(u, t, mesh::ParallelP4estMesh{2}, - constant_speed::False, equations, dg::DG, cache) + constant_speed::False, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # call the method accepting a general `mesh::P4estMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` # and create some MPI array type, overloading broadcasting and mapreduce etc. # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), P4estMesh{2}, - typeof(constant_speed), typeof(equations), typeof(dg), - typeof(cache)}, - u, t, mesh, constant_speed, equations, dg, cache) + typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(equations), typeof(dg), typeof(cache)}, + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -191,16 +196,17 @@ function max_dt(u, t, mesh::ParallelP4estMesh{2}, end function max_dt(u, t, mesh::ParallelP4estMesh{2}, - constant_speed::True, equations, dg::DG, cache) + constant_speed::True, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # call the method accepting a general `mesh::P4estMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` # and create some MPI array type, overloading broadcasting and mapreduce etc. # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), P4estMesh{2}, - typeof(constant_speed), typeof(equations), typeof(dg), - typeof(cache)}, - u, t, mesh, constant_speed, equations, dg, cache) + typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(equations), typeof(dg), typeof(cache)}, + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -208,16 +214,17 @@ function max_dt(u, t, mesh::ParallelP4estMesh{2}, end function max_dt(u, t, mesh::ParallelT8codeMesh{2}, - constant_speed::False, equations, dg::DG, cache) + constant_speed::False, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # call the method accepting a general `mesh::T8codeMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` # and create some MPI array type, overloading broadcasting and mapreduce etc. # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), T8codeMesh{2}, - typeof(constant_speed), typeof(equations), typeof(dg), - typeof(cache)}, - u, t, mesh, constant_speed, equations, dg, cache) + typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(equations), typeof(dg), typeof(cache)}, + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -225,16 +232,17 @@ function max_dt(u, t, mesh::ParallelT8codeMesh{2}, end function max_dt(u, t, mesh::ParallelT8codeMesh{2}, - constant_speed::True, equations, dg::DG, cache) + constant_speed::True, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # call the method accepting a general `mesh::T8codeMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` # and create some MPI array type, overloading broadcasting and mapreduce etc. # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), T8codeMesh{2}, - typeof(constant_speed), typeof(equations), typeof(dg), - typeof(cache)}, - u, t, mesh, constant_speed, equations, dg, cache) + typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(equations), typeof(dg), typeof(cache)}, + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] diff --git a/src/callbacks_step/stepsize_dg3d.jl b/src/callbacks_step/stepsize_dg3d.jl index 3324e819cee..51c0d17d118 100644 --- a/src/callbacks_step/stepsize_dg3d.jl +++ b/src/callbacks_step/stepsize_dg3d.jl @@ -6,7 +6,8 @@ #! format: noindent function max_dt(u, t, mesh::TreeMesh{3}, - constant_speed::False, equations, dg::DG, cache) + constant_speed::False, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection max_scaled_speed = nextfloat(zero(t)) @@ -29,7 +30,8 @@ function max_dt(u, t, mesh::TreeMesh{3}, end function max_dt(u, t, mesh::TreeMesh{3}, - constant_speed::True, equations, dg::DG, cache) + constant_speed::True, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection max_scaled_speed = nextfloat(zero(t)) @@ -45,7 +47,8 @@ function max_dt(u, t, mesh::TreeMesh{3}, end function max_dt(u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - constant_speed::False, equations, dg::DG, cache) + constant_speed::False, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection max_scaled_speed = nextfloat(zero(t)) @@ -83,7 +86,8 @@ function max_dt(u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3} end function max_dt(u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - constant_speed::True, equations, dg::DG, cache) + constant_speed::True, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection max_scaled_speed = nextfloat(zero(t)) @@ -120,16 +124,17 @@ function max_dt(u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3} end function max_dt(u, t, mesh::ParallelP4estMesh{3}, - constant_speed::False, equations, dg::DG, cache) + constant_speed::False, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # call the method accepting a general `mesh::P4estMesh{3}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` # and create some MPI array type, overloading broadcasting and mapreduce etc. # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), P4estMesh{3}, - typeof(constant_speed), typeof(equations), typeof(dg), - typeof(cache)}, - u, t, mesh, constant_speed, equations, dg, cache) + typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(equations), typeof(dg), typeof(cache)}, + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -137,16 +142,17 @@ function max_dt(u, t, mesh::ParallelP4estMesh{3}, end function max_dt(u, t, mesh::ParallelP4estMesh{3}, - constant_speed::True, equations, dg::DG, cache) + constant_speed::True, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # call the method accepting a general `mesh::P4estMesh{3}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` # and create some MPI array type, overloading broadcasting and mapreduce etc. # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), P4estMesh{3}, - typeof(constant_speed), typeof(equations), typeof(dg), - typeof(cache)}, - u, t, mesh, constant_speed, equations, dg, cache) + typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(equations), typeof(dg), typeof(cache)}, + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -154,16 +160,17 @@ function max_dt(u, t, mesh::ParallelP4estMesh{3}, end function max_dt(u, t, mesh::ParallelT8codeMesh{3}, - constant_speed::False, equations, dg::DG, cache) + constant_speed::False, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # call the method accepting a general `mesh::T8codeMesh{3}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` # and create some MPI array type, overloading broadcasting and mapreduce etc. # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), T8codeMesh{3}, - typeof(constant_speed), typeof(equations), typeof(dg), - typeof(cache)}, - u, t, mesh, constant_speed, equations, dg, cache) + typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(equations), typeof(dg), typeof(cache)}, + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -171,16 +178,17 @@ function max_dt(u, t, mesh::ParallelT8codeMesh{3}, end function max_dt(u, t, mesh::ParallelT8codeMesh{3}, - constant_speed::True, equations, dg::DG, cache) + constant_speed::True, have_auxiliary_node_vars::False, + equations, dg::DG, cache) # call the method accepting a general `mesh::T8codeMesh{3}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` # and create some MPI array type, overloading broadcasting and mapreduce etc. # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), T8codeMesh{3}, - typeof(constant_speed), typeof(equations), typeof(dg), - typeof(cache)}, - u, t, mesh, constant_speed, equations, dg, cache) + typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(equations), typeof(dg), typeof(cache)}, + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] diff --git a/src/semidiscretization/semidiscretization_euler_gravity.jl b/src/semidiscretization/semidiscretization_euler_gravity.jl index 6e4f05d78a4..7405f5d73a8 100644 --- a/src/semidiscretization/semidiscretization_euler_gravity.jl +++ b/src/semidiscretization/semidiscretization_euler_gravity.jl @@ -299,8 +299,8 @@ function update_gravity!(semi::SemidiscretizationEulerGravity, u_ode) while !finalstep dtau = @trixi_timeit timer() "calculate dtau" begin cfl * max_dt(u_gravity, tau, semi_gravity.mesh, - have_constant_speed(equations), equations, - semi_gravity.solver, semi_gravity.cache) + have_constant_speed(equations), have_auxiliary_node_vars::False, + equations, semi_gravity.solver, semi_gravity.cache) end # evolve solution by one pseudo-time step diff --git a/src/solvers/dgmulti/dg.jl b/src/solvers/dgmulti/dg.jl index 961268ce5af..6858121891c 100644 --- a/src/solvers/dgmulti/dg.jl +++ b/src/solvers/dgmulti/dg.jl @@ -237,7 +237,8 @@ end # for the stepsize callback function max_dt(u, t, mesh::DGMultiMesh, - constant_speed::False, equations, dg::DGMulti{NDIMS}, + constant_speed::False, have_auxiliary_node_vars::False, + equations, dg::DGMulti{NDIMS}, cache) where {NDIMS} @unpack md = mesh rd = dg.basis @@ -260,7 +261,8 @@ function max_dt(u, t, mesh::DGMultiMesh, end function max_dt(u, t, mesh::DGMultiMesh, - constant_speed::True, equations, dg::DGMulti{NDIMS}, + constant_speed::True, have_auxiliary_node_vars::False, + equations, dg::DGMulti{NDIMS}, cache) where {NDIMS} @unpack md = mesh rd = dg.basis diff --git a/src/solvers/dgsem_structured/dg_2d.jl b/src/solvers/dgsem_structured/dg_2d.jl index cb4e75149ea..f1f0ab3512e 100644 --- a/src/solvers/dgsem_structured/dg_2d.jl +++ b/src/solvers/dgsem_structured/dg_2d.jl @@ -14,8 +14,7 @@ function rhs!(du, u, t, # Calculate volume integral @trixi_timeit timer() "volume integral" begin - calc_volume_integral!(du, u, mesh, - have_nonconservative_terms(equations), equations, + calc_volume_integral!(du, u, mesh, equations, dg.volume_integral, dg, cache) end diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 303c2ae17d9..7f2a9d9331f 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -440,12 +440,14 @@ function calc_volume_integral!(du, u, if dg_only flux_differencing_kernel!(du, u, element, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_auxiliary_node_vars(equations), equations, volume_flux_dg, dg, cache) else # Calculate DG volume integral contribution flux_differencing_kernel!(du, u, element, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_auxiliary_node_vars(equations), equations, volume_flux_dg, dg, cache, 1 - alpha_element) # Calculate FV volume integral contribution diff --git a/src/solvers/dgsem_tree/dg_2d_subcell_limiters.jl b/src/solvers/dgsem_tree/dg_2d_subcell_limiters.jl index c27327be8ad..b9029bb1814 100644 --- a/src/solvers/dgsem_tree/dg_2d_subcell_limiters.jl +++ b/src/solvers/dgsem_tree/dg_2d_subcell_limiters.jl @@ -59,14 +59,13 @@ end function calc_volume_integral!(du, u, mesh::Union{TreeMesh{2}, StructuredMesh{2}, P4estMesh{2}}, - nonconservative_terms, equations, + equations, volume_integral::VolumeIntegralSubcellLimiting, dg::DGSEM, cache) @unpack limiter = volume_integral @threaded for element in eachelement(dg, cache) - subcell_limiting_kernel!(du, u, element, mesh, - nonconservative_terms, equations, + subcell_limiting_kernel!(du, u, element, mesh, equations, volume_integral, limiter, dg, cache) end @@ -75,7 +74,7 @@ end @inline function subcell_limiting_kernel!(du, u, element, mesh::Union{TreeMesh{2}, StructuredMesh{2}, P4estMesh{2}}, - nonconservative_terms, equations, + equations, volume_integral, limiter::SubcellLimiterIDP, dg::DGSEM, cache) @unpack inverse_weights = dg.basis @@ -89,8 +88,8 @@ end fhat2_L = fhat2_L_threaded[Threads.threadid()] fhat2_R = fhat2_R_threaded[Threads.threadid()] calcflux_fhat!(fhat1_L, fhat1_R, fhat2_L, fhat2_R, u, mesh, - nonconservative_terms, equations, volume_flux_dg, dg, element, - cache) + have_nonconservative_terms(equations), equations, + volume_flux_dg, dg, element, cache) # low-order FV fluxes @unpack fstar1_L_threaded, fstar1_R_threaded, fstar2_L_threaded, fstar2_R_threaded = cache @@ -100,14 +99,14 @@ end fstar1_R = fstar1_R_threaded[Threads.threadid()] fstar2_R = fstar2_R_threaded[Threads.threadid()] calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, u, mesh, - nonconservative_terms, equations, volume_flux_fv, dg, element, - cache) + have_nonconservative_terms(equations), equations, + volume_flux_fv, dg, element, cache) # antidiffusive flux calcflux_antidiffusive!(fhat1_L, fhat1_R, fhat2_L, fhat2_R, fstar1_L, fstar1_R, fstar2_L, fstar2_R, - u, mesh, nonconservative_terms, equations, limiter, dg, - element, cache) + u, mesh, have_nonconservative_terms(equations), equations, + limiter, dg, element, cache) # Calculate volume integral contribution of low-order FV flux for j in eachnode(dg), i in eachnode(dg) diff --git a/src/solvers/dgsem_unstructured/dg_2d.jl b/src/solvers/dgsem_unstructured/dg_2d.jl index 619cdb737de..d5e82ecf733 100644 --- a/src/solvers/dgsem_unstructured/dg_2d.jl +++ b/src/solvers/dgsem_unstructured/dg_2d.jl @@ -43,8 +43,7 @@ function rhs!(du, u, t, # Calculate volume integral @trixi_timeit timer() "volume integral" begin - calc_volume_integral!(du, u, mesh, - have_nonconservative_terms(equations), equations, + calc_volume_integral!(du, u, mesh, equations, dg.volume_integral, dg, cache) end diff --git a/src/time_integration/paired_explicit_runge_kutta/paired_explicit_runge_kutta.jl b/src/time_integration/paired_explicit_runge_kutta/paired_explicit_runge_kutta.jl index dfa5ed60d51..b359aa9ae74 100644 --- a/src/time_integration/paired_explicit_runge_kutta/paired_explicit_runge_kutta.jl +++ b/src/time_integration/paired_explicit_runge_kutta/paired_explicit_runge_kutta.jl @@ -59,8 +59,8 @@ function calculate_cfl(ode_algorithm::AbstractPairedExplicitRK, ode) u = wrap_array(u_ode, mesh, equations, solver, cache) cfl_number = dt_opt / max_dt(u, t0, mesh, - have_constant_speed(equations), equations, - solver, cache) + have_constant_speed(equations), have_auxiliary_node_vars(equations), + equations, solver, cache) return cfl_number end From 1e03b7ed16ad1c95439f4c2c9705aaa20a5261ae Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Tue, 8 Apr 2025 00:37:04 +0200 Subject: [PATCH 10/83] and some more --- src/callbacks_step/stepsize_dg2d.jl | 18 ++++++++++++------ src/callbacks_step/stepsize_dg3d.jl | 12 ++++++++---- .../semidiscretization_euler_gravity.jl | 2 +- src/solvers/dgsem_p4est/dg_2d.jl | 2 +- src/solvers/dgsem_p4est/dg_2d_parabolic.jl | 1 + src/solvers/dgsem_structured/dg_2d.jl | 16 ++++++++++------ src/solvers/dgsem_tree/dg_2d.jl | 4 ++-- src/solvers/dgsem_unstructured/dg_2d.jl | 3 ++- src/solvers/fdsbp_tree/fdsbp_2d.jl | 9 ++++----- src/solvers/fdsbp_unstructured/fdsbp_2d.jl | 6 ++---- .../paired_explicit_runge_kutta.jl | 3 ++- src/visualization/utilities.jl | 5 +++-- test/test_tree_2d_acoustics.jl | 2 +- 13 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/callbacks_step/stepsize_dg2d.jl b/src/callbacks_step/stepsize_dg2d.jl index 4cc5b9e0412..499ab6bedac 100644 --- a/src/callbacks_step/stepsize_dg2d.jl +++ b/src/callbacks_step/stepsize_dg2d.jl @@ -82,7 +82,8 @@ function max_dt(u, t, mesh::ParallelTreeMesh{2}, Tuple{typeof(u), typeof(t), TreeMesh{2}, typeof(constant_speed), typeof(have_auxiliary_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -100,7 +101,8 @@ function max_dt(u, t, mesh::ParallelTreeMesh{2}, Tuple{typeof(u), typeof(t), TreeMesh{2}, typeof(constant_speed), typeof(have_auxiliary_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -188,7 +190,8 @@ function max_dt(u, t, mesh::ParallelP4estMesh{2}, Tuple{typeof(u), typeof(t), P4estMesh{2}, typeof(constant_speed), typeof(have_auxiliary_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -206,7 +209,8 @@ function max_dt(u, t, mesh::ParallelP4estMesh{2}, Tuple{typeof(u), typeof(t), P4estMesh{2}, typeof(constant_speed), typeof(have_auxiliary_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -224,7 +228,8 @@ function max_dt(u, t, mesh::ParallelT8codeMesh{2}, Tuple{typeof(u), typeof(t), T8codeMesh{2}, typeof(constant_speed), typeof(have_auxiliary_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -242,7 +247,8 @@ function max_dt(u, t, mesh::ParallelT8codeMesh{2}, Tuple{typeof(u), typeof(t), T8codeMesh{2}, typeof(constant_speed), typeof(have_auxiliary_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] diff --git a/src/callbacks_step/stepsize_dg3d.jl b/src/callbacks_step/stepsize_dg3d.jl index 51c0d17d118..e3e7f40a065 100644 --- a/src/callbacks_step/stepsize_dg3d.jl +++ b/src/callbacks_step/stepsize_dg3d.jl @@ -134,7 +134,8 @@ function max_dt(u, t, mesh::ParallelP4estMesh{3}, Tuple{typeof(u), typeof(t), P4estMesh{3}, typeof(constant_speed), typeof(have_auxiliary_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -152,7 +153,8 @@ function max_dt(u, t, mesh::ParallelP4estMesh{3}, Tuple{typeof(u), typeof(t), P4estMesh{3}, typeof(constant_speed), typeof(have_auxiliary_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -170,7 +172,8 @@ function max_dt(u, t, mesh::ParallelT8codeMesh{3}, Tuple{typeof(u), typeof(t), T8codeMesh{3}, typeof(constant_speed), typeof(have_auxiliary_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -188,7 +191,8 @@ function max_dt(u, t, mesh::ParallelT8codeMesh{3}, Tuple{typeof(u), typeof(t), T8codeMesh{3}, typeof(constant_speed), typeof(have_auxiliary_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, cache) + u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] diff --git a/src/semidiscretization/semidiscretization_euler_gravity.jl b/src/semidiscretization/semidiscretization_euler_gravity.jl index 7405f5d73a8..8e2dc2b61a6 100644 --- a/src/semidiscretization/semidiscretization_euler_gravity.jl +++ b/src/semidiscretization/semidiscretization_euler_gravity.jl @@ -299,7 +299,7 @@ function update_gravity!(semi::SemidiscretizationEulerGravity, u_ode) while !finalstep dtau = @trixi_timeit timer() "calculate dtau" begin cfl * max_dt(u_gravity, tau, semi_gravity.mesh, - have_constant_speed(equations), have_auxiliary_node_vars::False, + have_constant_speed(equations), have_auxiliary_node_vars(equations), equations, semi_gravity.solver, semi_gravity.cache) end diff --git a/src/solvers/dgsem_p4est/dg_2d.jl b/src/solvers/dgsem_p4est/dg_2d.jl index 465721bb163..345a681878b 100644 --- a/src/solvers/dgsem_p4est/dg_2d.jl +++ b/src/solvers/dgsem_p4est/dg_2d.jl @@ -119,7 +119,7 @@ end function calc_interface_flux!(surface_flux_values, mesh::Union{P4estMesh{2}, T8codeMesh{2}}, - nonconservative_terms, + nonconservative_terms, have_auxiliary_node_vars, equations, surface_integral, dg::DG, cache) @unpack neighbor_ids, node_indices = cache.interfaces @unpack contravariant_vectors = cache.elements diff --git a/src/solvers/dgsem_p4est/dg_2d_parabolic.jl b/src/solvers/dgsem_p4est/dg_2d_parabolic.jl index 9f8306031c1..1b2cb94294f 100644 --- a/src/solvers/dgsem_p4est/dg_2d_parabolic.jl +++ b/src/solvers/dgsem_p4est/dg_2d_parabolic.jl @@ -233,6 +233,7 @@ function calc_gradient!(gradients, u_transformed, t, @trixi_timeit timer() "interface flux" begin calc_interface_flux!(cache_parabolic.elements.surface_flux_values, mesh, False(), # False() = no nonconservative terms + False(), # False() = no auxiliary variables equations_parabolic, dg.surface_integral, dg, cache_parabolic) end diff --git a/src/solvers/dgsem_structured/dg_2d.jl b/src/solvers/dgsem_structured/dg_2d.jl index f1f0ab3512e..ce5a89dbe2d 100644 --- a/src/solvers/dgsem_structured/dg_2d.jl +++ b/src/solvers/dgsem_structured/dg_2d.jl @@ -42,7 +42,8 @@ function rhs!(du, u, t, # Calculate source terms @trixi_timeit timer() "source terms" begin - calc_sources!(du, u, t, source_terms, equations, dg, cache) + calc_sources!(du, u, t, source_terms, have_auxiliary_node_vars(equations), + equations, dg, cache) end return nothing @@ -60,7 +61,8 @@ See also https://github.com/trixi-framework/Trixi.jl/issues/1671#issuecomment-17 mesh::Union{StructuredMesh{2}, StructuredMeshView{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - nonconservative_terms::False, equations, + nonconservative_terms::False, + have_auxiliary_node_vars::False, equations, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -103,7 +105,8 @@ end StructuredMeshView{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - nonconservative_terms::False, equations, + nonconservative_terms::False, + have_auxiliary_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) @unpack derivative_split = dg.basis @unpack contravariant_vectors = cache.elements @@ -161,15 +164,16 @@ end StructuredMeshView{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - nonconservative_terms::True, equations, + nonconservative_terms::True, + have_auxiliary_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) @unpack derivative_split = dg.basis @unpack contravariant_vectors = cache.elements symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, mesh, False(), equations, symmetric_flux, - dg, cache, alpha) + flux_differencing_kernel!(du, u, element, mesh, False(), False(), equations, + symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux for j in eachnode(dg), i in eachnode(dg) diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 7f2a9d9331f..8d1e05f9e9a 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -382,8 +382,8 @@ end symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, mesh, False(), equations, symmetric_flux, - dg, cache, alpha) + flux_differencing_kernel!(du, u, element, mesh, False(), False(), equations, + symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux for j in eachnode(dg), i in eachnode(dg) diff --git a/src/solvers/dgsem_unstructured/dg_2d.jl b/src/solvers/dgsem_unstructured/dg_2d.jl index d5e82ecf733..0ddc8da4fc9 100644 --- a/src/solvers/dgsem_unstructured/dg_2d.jl +++ b/src/solvers/dgsem_unstructured/dg_2d.jl @@ -84,7 +84,8 @@ function rhs!(du, u, t, # Calculate source terms @trixi_timeit timer() "source terms" begin - calc_sources!(du, u, t, source_terms, equations, dg, cache) + calc_sources!(du, u, t, source_terms, have_auxiliary_node_vars(equations), + equations, dg, cache) end return nothing diff --git a/src/solvers/fdsbp_tree/fdsbp_2d.jl b/src/solvers/fdsbp_tree/fdsbp_2d.jl index 0d904a7ef39..ee043d53e7b 100644 --- a/src/solvers/fdsbp_tree/fdsbp_2d.jl +++ b/src/solvers/fdsbp_tree/fdsbp_2d.jl @@ -41,8 +41,7 @@ end # 2D volume integral contributions for `VolumeIntegralStrongForm` function calc_volume_integral!(du, u, - mesh::TreeMesh{2}, - nonconservative_terms::False, equations, + mesh::TreeMesh{2}, equations, volume_integral::VolumeIntegralStrongForm, dg::FDSBP, cache) D = dg.basis # SBP derivative operator @@ -97,8 +96,7 @@ end # part of the flux splitting f^+ and the D^+ operator acts on the negative part # of the flux splitting f^-. function calc_volume_integral!(du, u, - mesh::TreeMesh{2}, - nonconservative_terms::False, equations, + mesh::TreeMesh{2}, equations, volume_integral::VolumeIntegralUpwind, dg::FDSBP, cache) # Assume that @@ -216,7 +214,8 @@ end # flux information at each side of an interface. function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{2}, - nonconservative_terms::False, equations, + nonconservative_terms::False, + have_auxiliary_node_vars::False, equations, surface_integral::SurfaceIntegralUpwind, dg::FDSBP, cache) @unpack splitting = surface_integral diff --git a/src/solvers/fdsbp_unstructured/fdsbp_2d.jl b/src/solvers/fdsbp_unstructured/fdsbp_2d.jl index 7e66e0d472b..fa7e731f58e 100644 --- a/src/solvers/fdsbp_unstructured/fdsbp_2d.jl +++ b/src/solvers/fdsbp_unstructured/fdsbp_2d.jl @@ -29,8 +29,7 @@ end # OBS! This is the standard (not de-aliased) form of the volume integral. # So it is not provably stable for variable coefficients due to the the metric terms. function calc_volume_integral!(du, u, - mesh::UnstructuredMesh2D, - nonconservative_terms::False, equations, + mesh::UnstructuredMesh2D, equations, volume_integral::VolumeIntegralStrongForm, dg::FDSBP, cache) D = dg.basis # SBP derivative operator @@ -92,8 +91,7 @@ end # part of the flux splitting f^+ and the D^+ operator acts on the negative part # of the flux splitting f^-. function calc_volume_integral!(du, u, - mesh::UnstructuredMesh2D, - nonconservative_terms::False, equations, + mesh::UnstructuredMesh2D, equations, volume_integral::VolumeIntegralUpwind, dg::FDSBP, cache) # Assume that diff --git a/src/time_integration/paired_explicit_runge_kutta/paired_explicit_runge_kutta.jl b/src/time_integration/paired_explicit_runge_kutta/paired_explicit_runge_kutta.jl index b359aa9ae74..a5eff892da5 100644 --- a/src/time_integration/paired_explicit_runge_kutta/paired_explicit_runge_kutta.jl +++ b/src/time_integration/paired_explicit_runge_kutta/paired_explicit_runge_kutta.jl @@ -59,7 +59,8 @@ function calculate_cfl(ode_algorithm::AbstractPairedExplicitRK, ode) u = wrap_array(u_ode, mesh, equations, solver, cache) cfl_number = dt_opt / max_dt(u, t0, mesh, - have_constant_speed(equations), have_auxiliary_node_vars(equations), + have_constant_speed(equations), + have_auxiliary_node_vars(equations), equations, solver, cache) return cfl_number end diff --git a/src/visualization/utilities.jl b/src/visualization/utilities.jl index f68f73625c4..8deb9c0d354 100644 --- a/src/visualization/utilities.jl +++ b/src/visualization/utilities.jl @@ -479,8 +479,9 @@ end n_vars_in = nvariables(equations) n_vars_aux = n_auxiliary_node_vars(equations) n_vars = length(solution_variables(get_node_vars(u, equations, solver), - get_auxiliary_node_vars(auxiliary_node_vars, equations, solver), - equations)) + get_auxiliary_node_vars(auxiliary_node_vars, + equations, solver), + equations)) raw_data = Array{eltype(u)}(undef, n_vars, Base.tail(size(u))...) reshaped_u = reshape(u, n_vars_in, :) reshaped_r = reshape(raw_data, n_vars, :) diff --git a/test/test_tree_2d_acoustics.jl b/test/test_tree_2d_acoustics.jl index 7a83f2c8d29..7fb602db349 100644 --- a/test/test_tree_2d_acoustics.jl +++ b/test/test_tree_2d_acoustics.jl @@ -163,7 +163,7 @@ end @trixi_testset "elixir_acoustics_gauss_wall_amr_auxvars.jl" begin @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_acoustics_gauss_wall_amr_auxvars.jl"), - l2=[0.0194350488, 0.0195225440, 0.00481982254], + l2=[0.0194350488, 0.0195225440, 0.04819822538525215], linf=[0.183057645, 0.190845961, 1.03618809]) # Ensure that we do not have excessive memory allocations # (e.g., from type instabilities) From f429f9b8769aadc2b88df8424fe76968be871b84 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 9 Apr 2025 13:48:01 +0200 Subject: [PATCH 11/83] fix performance specilization testing --- .../dg_2d_compressible_euler.jl | 2 ++ .../dgsem_tree/dg_2d_compressible_euler.jl | 2 ++ test/test_performance_specializations_2d.jl | 36 ++++++++++++------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/solvers/dgsem_structured/dg_2d_compressible_euler.jl b/src/solvers/dgsem_structured/dg_2d_compressible_euler.jl index 43f70da4750..8cd6d8d19b2 100644 --- a/src/solvers/dgsem_structured/dg_2d_compressible_euler.jl +++ b/src/solvers/dgsem_structured/dg_2d_compressible_euler.jl @@ -22,6 +22,7 @@ mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}}, nonconservative_terms::False, + have_auxiliary_node_vars::False, equations::CompressibleEulerEquations2D, volume_flux::typeof(flux_shima_etal_turbo), dg::DGSEM, cache, alpha) @@ -229,6 +230,7 @@ end mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}}, nonconservative_terms::False, + have_auxiliary_node_vars::False, equations::CompressibleEulerEquations2D, volume_flux::typeof(flux_ranocha_turbo), dg::DGSEM, cache, alpha) diff --git a/src/solvers/dgsem_tree/dg_2d_compressible_euler.jl b/src/solvers/dgsem_tree/dg_2d_compressible_euler.jl index 50b1e8cb5b4..0c014abdf69 100644 --- a/src/solvers/dgsem_tree/dg_2d_compressible_euler.jl +++ b/src/solvers/dgsem_tree/dg_2d_compressible_euler.jl @@ -67,6 +67,7 @@ end # muladd @inline function flux_differencing_kernel!(_du::PtrArray, u_cons::PtrArray, element, mesh::TreeMesh{2}, nonconservative_terms::False, + have_auxiliary_node_vars::False, equations::CompressibleEulerEquations2D, volume_flux::typeof(flux_shima_etal_turbo), dg::DGSEM, cache, alpha) @@ -229,6 +230,7 @@ end @inline function flux_differencing_kernel!(_du::PtrArray, u_cons::PtrArray, element, mesh::TreeMesh{2}, nonconservative_terms::False, + have_auxiliary_node_vars::False, equations::CompressibleEulerEquations2D, volume_flux::typeof(flux_ranocha_turbo), dg::DGSEM, cache, alpha) diff --git a/test/test_performance_specializations_2d.jl b/test/test_performance_specializations_2d.jl index 4fd39c78f64..deebeda84c4 100644 --- a/test/test_performance_specializations_2d.jl +++ b/test/test_performance_specializations_2d.jl @@ -27,11 +27,13 @@ isdir(outdir) && rm(outdir, recursive = true) u = Trixi.wrap_array(u_ode, semi) du = Trixi.wrap_array(du_ode, semi) nonconservative_terms = Trixi.have_nonconservative_terms(semi.equations) + have_auxiliary_node_vars = Trixi.have_auxiliary_node_vars(semi.equations) # Call the optimized default version du .= 0 Trixi.flux_differencing_kernel!(du, u, 1, semi.mesh, - nonconservative_terms, semi.equations, + nonconservative_terms, have_auxiliary_node_vars, + semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_specialized = du[:, :, :, 1] @@ -41,10 +43,11 @@ isdir(outdir) && rm(outdir, recursive = true) du .= 0 invoke(Trixi.flux_differencing_kernel!, Tuple{typeof(du), typeof(u), Integer, typeof(semi.mesh), - typeof(nonconservative_terms), typeof(semi.equations), + typeof(nonconservative_terms), typeof(have_auxiliary_node_vars), + typeof(semi.equations), Function, typeof(semi.solver), typeof(semi.cache), Bool}, du, u, 1, semi.mesh, - nonconservative_terms, semi.equations, + nonconservative_terms, have_auxiliary_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, 1] @@ -66,11 +69,13 @@ end u = Trixi.wrap_array(u_ode, semi) du = Trixi.wrap_array(du_ode, semi) nonconservative_terms = Trixi.have_nonconservative_terms(semi.equations) + have_auxiliary_node_vars = Trixi.have_auxiliary_node_vars(semi.equations) # Call the optimized default version du .= 0 Trixi.flux_differencing_kernel!(du, u, 1, semi.mesh, - nonconservative_terms, semi.equations, + nonconservative_terms, have_auxiliary_node_vars, + semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_specialized = du[:, :, :, 1] @@ -80,10 +85,11 @@ end du .= 0 invoke(Trixi.flux_differencing_kernel!, Tuple{typeof(du), typeof(u), Integer, typeof(semi.mesh), - typeof(nonconservative_terms), typeof(semi.equations), + typeof(nonconservative_terms), typeof(have_auxiliary_node_vars), + typeof(semi.equations), Function, typeof(semi.solver), typeof(semi.cache), Bool}, du, u, 1, semi.mesh, - nonconservative_terms, semi.equations, + nonconservative_terms, have_auxiliary_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, 1] @@ -106,11 +112,13 @@ end u = Trixi.wrap_array(u_ode, semi) du = Trixi.wrap_array(du_ode, semi) nonconservative_terms = Trixi.have_nonconservative_terms(semi.equations) + have_auxiliary_node_vars = Trixi.have_auxiliary_node_vars(semi.equations) # Call the optimized default version du .= 0 Trixi.flux_differencing_kernel!(du, u, 1, semi.mesh, - nonconservative_terms, semi.equations, + nonconservative_terms, have_auxiliary_node_vars, + semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_specialized = du[:, :, :, 1] @@ -120,10 +128,11 @@ end du .= 0 invoke(Trixi.flux_differencing_kernel!, Tuple{typeof(du), typeof(u), Integer, typeof(semi.mesh), - typeof(nonconservative_terms), typeof(semi.equations), + typeof(nonconservative_terms), typeof(have_auxiliary_node_vars), + typeof(semi.equations), Function, typeof(semi.solver), typeof(semi.cache), Bool}, du, u, 1, semi.mesh, - nonconservative_terms, semi.equations, + nonconservative_terms, have_auxiliary_node_vars,semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, 1] @@ -145,11 +154,13 @@ end u = Trixi.wrap_array(u_ode, semi) du = Trixi.wrap_array(du_ode, semi) nonconservative_terms = Trixi.have_nonconservative_terms(semi.equations) + have_auxiliary_node_vars = Trixi.have_auxiliary_node_vars(semi.equations) # Call the optimized default version du .= 0 Trixi.flux_differencing_kernel!(du, u, 1, semi.mesh, - nonconservative_terms, semi.equations, + nonconservative_terms, have_auxiliary_node_vars, + semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_specialized = du[:, :, :, 1] @@ -159,10 +170,11 @@ end du .= 0 invoke(Trixi.flux_differencing_kernel!, Tuple{typeof(du), typeof(u), Integer, typeof(semi.mesh), - typeof(nonconservative_terms), typeof(semi.equations), + typeof(nonconservative_terms), typeof(have_auxiliary_node_vars), + typeof(semi.equations), Function, typeof(semi.solver), typeof(semi.cache), Bool}, du, u, 1, semi.mesh, - nonconservative_terms, semi.equations, + nonconservative_terms, have_auxiliary_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, 1] From a59ce7ed72bc35cc9fd561d78abe166c90b6455c Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 9 Apr 2025 13:49:05 +0200 Subject: [PATCH 12/83] re-add slip wall BC --- src/equations/acoustic_perturbation_2d.jl | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/equations/acoustic_perturbation_2d.jl b/src/equations/acoustic_perturbation_2d.jl index 180a41f23fb..08fc15ca67d 100644 --- a/src/equations/acoustic_perturbation_2d.jl +++ b/src/equations/acoustic_perturbation_2d.jl @@ -221,6 +221,37 @@ function boundary_condition_wall(u_inner, orientation, direction, x, t, return flux end +""" + boundary_condition_slip_wall(u_inner, normal_direction, x, t, surface_flux_function, + equations::AcousticPerturbationEquations2D) + +Use an orthogonal projection of the perturbed velocities to zero out the normal velocity +while retaining the possibility of a tangential velocity in the boundary state. +Further details are available in the paper: +- Marcus Bauer, Jürgen Dierke and Roland Ewert (2011) + Application of a discontinuous Galerkin method to discretize acoustic perturbation equations + [DOI: 10.2514/1.J050333](https://doi.org/10.2514/1.J050333) +""" +function boundary_condition_slip_wall(u_inner, normal_direction::AbstractVector, x, t, + surface_flux_function, + equations::AcousticPerturbationEquations2D) + # normalize the outward pointing direction + normal = normal_direction / norm(normal_direction) + + # compute the normal perturbed velocity + u_normal = normal[1] * u_inner[1] + normal[2] * u_inner[2] + + # create the "external" boundary solution state + u_boundary = SVector(u_inner[1] - 2 * u_normal * normal[1], + u_inner[2] - 2 * u_normal * normal[2], + u_inner[3], cons2mean(u_inner, equations)...) + + # calculate the boundary flux + flux = surface_flux_function(u_inner, u_boundary, normal_direction, equations) + + return flux +end + # Calculate 1D flux for a single point @inline function flux(u, orientation::Integer, equations::AcousticPerturbationEquations2D) From 18305b7ca8e1fc925b8af28857a706872b53c084 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 9 Apr 2025 13:49:22 +0200 Subject: [PATCH 13/83] make ParallelTreeMesh compatible --- src/solvers/dgsem_tree/dg_2d.jl | 6 +- src/solvers/dgsem_tree/dg_2d_parallel.jl | 78 +++++++++++++++++++----- 2 files changed, 66 insertions(+), 18 deletions(-) diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 8d1e05f9e9a..7a9f6a6f77b 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -1091,11 +1091,9 @@ function calc_mortar_flux!(surface_flux_values, calc_fstar!(fstar_primary_lower, have_auxiliary_node_vars(equations), equations, surface_flux, dg, u_lower, mortar, orientation, cache) calc_fstar!(fstar_secondary_upper, have_auxiliary_node_vars(equations), - equations, - surface_flux, dg, u_upper, mortar, orientation, cache) + equations, surface_flux, dg, u_upper, mortar, orientation, cache) calc_fstar!(fstar_secondary_lower, have_auxiliary_node_vars(equations), - equations, - surface_flux, dg, u_lower, mortar, orientation, cache) + equations, surface_flux, dg, u_lower, mortar, orientation, cache) mortar_fluxes_to_elements!(surface_flux_values, mesh, equations, mortar_l2, dg, cache, diff --git a/src/solvers/dgsem_tree/dg_2d_parallel.jl b/src/solvers/dgsem_tree/dg_2d_parallel.jl index b77308c32fe..083c8d06857 100644 --- a/src/solvers/dgsem_tree/dg_2d_parallel.jl +++ b/src/solvers/dgsem_tree/dg_2d_parallel.jl @@ -476,8 +476,7 @@ function rhs!(du, u, t, # Calculate volume integral @trixi_timeit timer() "volume integral" begin - calc_volume_integral!(du, u, mesh, - have_nonconservative_terms(equations), equations, + calc_volume_integral!(du, u, mesh, equations, dg.volume_integral, dg, cache) end @@ -491,7 +490,8 @@ function rhs!(du, u, t, # Calculate interface fluxes @trixi_timeit timer() "interface flux" begin calc_interface_flux!(cache.elements.surface_flux_values, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_auxiliary_node_vars(equations), equations, dg.surface_integral, dg, cache) end @@ -528,7 +528,8 @@ function rhs!(du, u, t, # Calculate MPI interface fluxes @trixi_timeit timer() "MPI interface flux" begin calc_mpi_interface_flux!(cache.elements.surface_flux_values, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_auxiliary_node_vars(equations), equations, dg.surface_integral, dg, cache) end @@ -550,7 +551,8 @@ function rhs!(du, u, t, # Calculate source terms @trixi_timeit timer() "source terms" begin - calc_sources!(du, u, t, source_terms, equations, dg, cache) + calc_sources!(du, u, t, source_terms, have_auxiliary_node_vars(equations), + equations, dg, cache) end # Finish to send MPI data @@ -723,7 +725,8 @@ end function calc_mpi_interface_flux!(surface_flux_values, mesh::ParallelTreeMesh{2}, - nonconservative_terms::False, equations, + nonconservative_terms::False, + have_auxiliary_node_vars::False, equations, surface_integral, dg::DG, cache) @unpack surface_flux = surface_integral @unpack u, local_neighbor_ids, orientations, remote_sides = cache.mpi_interfaces @@ -762,6 +765,53 @@ function calc_mpi_interface_flux!(surface_flux_values, return nothing end +function calc_mpi_interface_flux!(surface_flux_values, + mesh::ParallelTreeMesh{2}, + nonconservative_terms::False, + have_auxiliary_node_vars::True, equations, + surface_integral, dg::DG, cache) + @unpack surface_flux = surface_integral + @unpack u, local_neighbor_ids, orientations, remote_sides = cache.mpi_interfaces + @unpack auxiliary_surface_node_vars = cache.auxiliary_variables + + @threaded for interface in eachmpiinterface(dg, cache) + # Get local neighboring element + element = local_neighbor_ids[interface] + + # Determine interface direction with respect to element: + if orientations[interface] == 1 # interface in x-direction + if remote_sides[interface] == 1 # local element in positive direction + direction = 1 + else # local element in negative direction + direction = 2 + end + else # interface in y-direction + if remote_sides[interface] == 1 # local element in positive direction + direction = 3 + else # local element in negative direction + direction = 4 + end + end + + for i in eachnode(dg) + # Call pointwise Riemann solver + u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) + aux_ll, aux_rr = get_auxiliary_surface_node_vars(auxiliary_surface_node_vars, + equations, dg, i, + interface) + flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, + orientations[interface], equations) + + # Copy flux to local element storage + for v in eachvariable(equations) + surface_flux_values[v, i, direction, element] = flux[v] + end + end + end + + return nothing +end + function calc_mpi_mortar_flux!(surface_flux_values, mesh::ParallelTreeMesh{2}, nonconservative_terms::False, equations, @@ -781,14 +831,14 @@ function calc_mpi_mortar_flux!(surface_flux_values, # Because `nonconservative_terms` is `False` the primary and secondary fluxes # are identical. So, we could possibly save on computation and just pass two copies later. orientation = orientations[mortar] - calc_fstar!(fstar_primary_upper, equations, surface_flux, dg, u_upper, mortar, - orientation) - calc_fstar!(fstar_primary_lower, equations, surface_flux, dg, u_lower, mortar, - orientation) - calc_fstar!(fstar_secondary_upper, equations, surface_flux, dg, u_upper, mortar, - orientation) - calc_fstar!(fstar_secondary_lower, equations, surface_flux, dg, u_lower, mortar, - orientation) + calc_fstar!(fstar_primary_upper, have_auxiliary_node_vars(equations), equations, + surface_flux, dg, u_upper, mortar, orientation, cache) + calc_fstar!(fstar_primary_lower, have_auxiliary_node_vars(equations), equations, + surface_flux, dg, u_lower, mortar, orientation, cache) + calc_fstar!(fstar_secondary_upper, have_auxiliary_node_vars(equations), equations, + surface_flux, dg, u_upper, mortar, orientation, cache) + calc_fstar!(fstar_secondary_lower, have_auxiliary_node_vars(equations), equations, + surface_flux, dg, u_lower, mortar, orientation, cache) mpi_mortar_fluxes_to_elements!(surface_flux_values, mesh, equations, mortar_l2, dg, cache, From 63468291ef2d1c27752688ffffa7ff8b6d5c46ac Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 9 Apr 2025 13:53:56 +0200 Subject: [PATCH 14/83] format --- src/solvers/dgsem_tree/dg_2d_parallel.jl | 6 ++++-- test/test_performance_specializations_2d.jl | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/solvers/dgsem_tree/dg_2d_parallel.jl b/src/solvers/dgsem_tree/dg_2d_parallel.jl index 083c8d06857..92cec22aa6c 100644 --- a/src/solvers/dgsem_tree/dg_2d_parallel.jl +++ b/src/solvers/dgsem_tree/dg_2d_parallel.jl @@ -835,9 +835,11 @@ function calc_mpi_mortar_flux!(surface_flux_values, surface_flux, dg, u_upper, mortar, orientation, cache) calc_fstar!(fstar_primary_lower, have_auxiliary_node_vars(equations), equations, surface_flux, dg, u_lower, mortar, orientation, cache) - calc_fstar!(fstar_secondary_upper, have_auxiliary_node_vars(equations), equations, + calc_fstar!(fstar_secondary_upper, have_auxiliary_node_vars(equations), + equations, surface_flux, dg, u_upper, mortar, orientation, cache) - calc_fstar!(fstar_secondary_lower, have_auxiliary_node_vars(equations), equations, + calc_fstar!(fstar_secondary_lower, have_auxiliary_node_vars(equations), + equations, surface_flux, dg, u_lower, mortar, orientation, cache) mpi_mortar_fluxes_to_elements!(surface_flux_values, diff --git a/test/test_performance_specializations_2d.jl b/test/test_performance_specializations_2d.jl index deebeda84c4..91ae68e89d7 100644 --- a/test/test_performance_specializations_2d.jl +++ b/test/test_performance_specializations_2d.jl @@ -132,7 +132,7 @@ end typeof(semi.equations), Function, typeof(semi.solver), typeof(semi.cache), Bool}, du, u, 1, semi.mesh, - nonconservative_terms, have_auxiliary_node_vars,semi.equations, + nonconservative_terms, have_auxiliary_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, 1] From 4be015153553bd570d83f49cf4bdc077966f3408 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 9 Apr 2025 21:59:23 +0200 Subject: [PATCH 15/83] p4est mpi interface flux --- src/solvers/dgsem_p4est/dg_2d_parallel.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/solvers/dgsem_p4est/dg_2d_parallel.jl b/src/solvers/dgsem_p4est/dg_2d_parallel.jl index 5d5225c6f9e..0f4c79f790f 100644 --- a/src/solvers/dgsem_p4est/dg_2d_parallel.jl +++ b/src/solvers/dgsem_p4est/dg_2d_parallel.jl @@ -47,6 +47,7 @@ function calc_mpi_interface_flux!(surface_flux_values, mesh::Union{ParallelP4estMesh{2}, ParallelT8codeMesh{2}}, nonconservative_terms, + have_auxiliary_node_vars, equations, surface_integral, dg::DG, cache) @unpack local_neighbor_ids, node_indices, local_sides = cache.mpi_interfaces @unpack contravariant_vectors = cache.elements @@ -88,7 +89,7 @@ function calc_mpi_interface_flux!(surface_flux_values, i_element, j_element, local_element) calc_mpi_interface_flux!(surface_flux_values, mesh, nonconservative_terms, - equations, + have_auxiliary_node_vars, equations, surface_integral, dg, cache, interface, normal_direction, node, local_side, @@ -110,7 +111,8 @@ end @inline function calc_mpi_interface_flux!(surface_flux_values, mesh::Union{ParallelP4estMesh{2}, ParallelT8codeMesh{2}}, - nonconservative_terms::False, equations, + nonconservative_terms::False, + have_auxiliary_node_vars::False, equations, surface_integral, dg::DG, cache, interface_index, normal_direction, interface_node_index, local_side, From 087f5071e8976c60820a0a13e4ee6a8441548d2b Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 9 Apr 2025 21:59:39 +0200 Subject: [PATCH 16/83] generic flux_central and DissipationLocalLaxFriedrichs --- ...tic_perturbation_2d_auxiliary_variables.jl | 22 ------------------- src/equations/numerical_fluxes.jl | 20 +++++++++++++++++ 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl b/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl index 9a741e11d63..e4b571d4c6a 100644 --- a/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl +++ b/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl @@ -313,28 +313,6 @@ end return max(abs(v_ll) + c_mean_ll * norm_, abs(v_rr) + c_mean_rr * norm_) end -@inline function flux_central(u_ll, u_rr, aux_ll, aux_rr, - orientation_or_normal_direction, - equations::AcousticPerturbationEquations2DAuxVars) - # Calculate regular 1D fluxes - f_ll = flux(u_ll, aux_ll, orientation_or_normal_direction, equations) - f_rr = flux(u_rr, aux_rr, orientation_or_normal_direction, equations) - - # Average regular fluxes - return 0.5f0 * (f_ll + f_rr) -end - -# Specialized `DissipationLocalLaxFriedrichs` taking into account auxiliary variables -@inline function (dissipation::DissipationLocalLaxFriedrichs)(u_ll, u_rr, aux_ll, - aux_rr, - orientation_or_normal_direction, - equations::AcousticPerturbationEquations2DAuxVars) - λ = dissipation.max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, - orientation_or_normal_direction, equations) - diss = -0.5f0 * λ * (u_rr - u_ll) - return SVector(diss[1], diss[2], diss[3]) -end - @inline have_constant_speed(::AcousticPerturbationEquations2DAuxVars) = False() @inline function max_abs_speeds(u, aux, diff --git a/src/equations/numerical_fluxes.jl b/src/equations/numerical_fluxes.jl index 9793444caf5..369338f04f5 100644 --- a/src/equations/numerical_fluxes.jl +++ b/src/equations/numerical_fluxes.jl @@ -24,6 +24,17 @@ DG method (except floating point errors). return 0.5f0 * (f_ll + f_rr) end +# central flux for equations with auxiliary variables +@inline function flux_central(u_ll, u_rr, aux_ll, aux_rr, orientation_or_normal_direction, + equations::AbstractEquations) + # Calculate regular 1D fluxes + f_ll = flux(u_ll, aux_ll, orientation_or_normal_direction, equations) + f_rr = flux(u_rr, aux_rr, orientation_or_normal_direction, equations) + + # Average regular fluxes + return 0.5f0 * (f_ll + f_rr) +end + """ FluxPlusDissipation(numerical_flux, dissipation) @@ -187,6 +198,15 @@ DissipationLocalLaxFriedrichs() = DissipationLocalLaxFriedrichs(max_abs_speed_na return -0.5f0 * λ * (u_rr - u_ll) end +# same as above for equations with auxiliary variables +@inline function (dissipation::DissipationLocalLaxFriedrichs)(u_ll, u_rr, aux_ll, aux_rr, + orientation_or_normal_direction, + equations) + λ = dissipation.max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, + orientation_or_normal_direction, equations) + return -0.5f0 * λ * (u_rr - u_ll) +end + function Base.show(io::IO, d::DissipationLocalLaxFriedrichs) print(io, "DissipationLocalLaxFriedrichs(", d.max_abs_speed, ")") end From 7170717a37447a2912a36db9af364aa6f12fa8cf Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Thu, 10 Apr 2025 08:02:10 +0200 Subject: [PATCH 17/83] format --- src/equations/numerical_fluxes.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/equations/numerical_fluxes.jl b/src/equations/numerical_fluxes.jl index 369338f04f5..0adff22b684 100644 --- a/src/equations/numerical_fluxes.jl +++ b/src/equations/numerical_fluxes.jl @@ -25,7 +25,8 @@ DG method (except floating point errors). end # central flux for equations with auxiliary variables -@inline function flux_central(u_ll, u_rr, aux_ll, aux_rr, orientation_or_normal_direction, +@inline function flux_central(u_ll, u_rr, aux_ll, aux_rr, + orientation_or_normal_direction, equations::AbstractEquations) # Calculate regular 1D fluxes f_ll = flux(u_ll, aux_ll, orientation_or_normal_direction, equations) @@ -199,7 +200,8 @@ DissipationLocalLaxFriedrichs() = DissipationLocalLaxFriedrichs(max_abs_speed_na end # same as above for equations with auxiliary variables -@inline function (dissipation::DissipationLocalLaxFriedrichs)(u_ll, u_rr, aux_ll, aux_rr, +@inline function (dissipation::DissipationLocalLaxFriedrichs)(u_ll, u_rr, aux_ll, + aux_rr, orientation_or_normal_direction, equations) λ = dissipation.max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, From d70749585e3391fda3969ab0a15abf7df5107a3a Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 7 May 2025 17:24:49 +0200 Subject: [PATCH 18/83] add comments to apply_solution_variables --- src/visualization/utilities.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/visualization/utilities.jl b/src/visualization/utilities.jl index 37782529683..49f688757bd 100644 --- a/src/visualization/utilities.jl +++ b/src/visualization/utilities.jl @@ -456,6 +456,7 @@ function get_data_1d(original_nodes, unstructured_data, nvisnodes, reinterpolate vcat(original_nodes[1, 1, :], original_nodes[1, end, end]) end +# Apply the `solution_variables` function to all node values stored in `u`. @inline function apply_solution_variables(u, solution_variables, have_auxiliary_node_vars::False, equations, solver, cache) @@ -472,6 +473,8 @@ end return raw_data end +# Apply the `solution_variables` function to all node values stored in `u`. +# Dispatch on `have_auxiliary_node_vars` to take into account auxiliary variables. @inline function apply_solution_variables(u, solution_variables, have_auxiliary_node_vars::True, equations, solver, cache) From ebe1b020ab34b80b4282c2edca0a2ab244f4e623 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 7 May 2025 17:40:22 +0200 Subject: [PATCH 19/83] rename *auxiliary*variables* -> *aux*vars* --- src/callbacks_step/save_solution_dg.jl | 14 +-- src/callbacks_step/stepsize.jl | 4 +- src/callbacks_step/stepsize_dg1d.jl | 8 +- src/callbacks_step/stepsize_dg2d.jl | 50 +++++----- src/callbacks_step/stepsize_dg3d.jl | 32 +++--- ...tic_perturbation_2d_auxiliary_variables.jl | 4 +- src/equations/equations.jl | 18 ++-- .../semidiscretization_euler_gravity.jl | 2 +- .../semidiscretization_hyperbolic.jl | 14 +-- src/solvers/dg.jl | 18 ++-- src/solvers/dgmulti/dg.jl | 4 +- src/solvers/dgsem_p4est/dg_2d.jl | 2 +- src/solvers/dgsem_p4est/dg_2d_parallel.jl | 6 +- src/solvers/dgsem_structured/dg_2d.jl | 8 +- .../dg_2d_compressible_euler.jl | 4 +- src/solvers/dgsem_tree/containers.jl | 78 +++++++-------- src/solvers/dgsem_tree/containers_2d.jl | 22 ++--- src/solvers/dgsem_tree/dg_2d.jl | 98 +++++++++---------- .../dgsem_tree/dg_2d_compressible_euler.jl | 4 +- src/solvers/dgsem_tree/dg_2d_parallel.jl | 22 ++--- src/solvers/dgsem_unstructured/dg_2d.jl | 2 +- src/solvers/fdsbp_tree/fdsbp_2d.jl | 2 +- .../paired_explicit_runge_kutta.jl | 2 +- src/visualization/utilities.jl | 18 ++-- test/test_performance_specializations_2d.jl | 32 +++--- 25 files changed, 234 insertions(+), 234 deletions(-) diff --git a/src/callbacks_step/save_solution_dg.jl b/src/callbacks_step/save_solution_dg.jl index affac5d83df..c99949be2cc 100644 --- a/src/callbacks_step/save_solution_dg.jl +++ b/src/callbacks_step/save_solution_dg.jl @@ -6,7 +6,7 @@ #! format: noindent @inline function convert_to_solution_variables(u, solution_variables, cache, - have_auxiliary_node_vars::False, + have_aux_node_vars::False, equations) # Reinterpret the solution array as an array of conservative variables, # compute the solution variables via broadcasting, and reinterpret the @@ -18,18 +18,18 @@ end @inline function convert_to_solution_variables(u, solution_variables, cache, - have_auxiliary_node_vars::True, + have_aux_node_vars::True, equations) - @unpack auxiliary_node_vars = cache.auxiliary_variables + @unpack aux_node_vars = cache.aux_vars # Reinterpret the solution array as an array of conservative variables, # compute the solution variables via broadcasting, and reinterpret the # result as a plain array of floating point numbers return Array(reinterpret(eltype(u), solution_variables.(reinterpret(SVector{nvariables(equations), eltype(u)}, u), - reinterpret(SVector{n_auxiliary_node_vars(equations), - eltype(auxiliary_node_vars)}, - auxiliary_node_vars), + reinterpret(SVector{n_aux_node_vars(equations), + eltype(aux_node_vars)}, + aux_node_vars), Ref(equations)))) end @@ -60,7 +60,7 @@ function save_solution_file(u, time, dt, timestep, n_vars = nvariables(equations) else data = convert_to_solution_variables(u, solution_variables, cache, - have_auxiliary_node_vars(equations), + have_aux_node_vars(equations), equations) # Find out variable count by looking at output from `solution_variables` function n_vars = size(data, 1) diff --git a/src/callbacks_step/stepsize.jl b/src/callbacks_step/stepsize.jl index 8dce7b209af..48d515446f2 100644 --- a/src/callbacks_step/stepsize.jl +++ b/src/callbacks_step/stepsize.jl @@ -121,7 +121,7 @@ function calculate_dt(u_ode, t, cfl_number::Real, semi::AbstractSemidiscretizati dt = cfl_number * max_dt(u, t, mesh, have_constant_speed(equations), - have_auxiliary_node_vars(equations), equations, + have_aux_node_vars(equations), equations, solver, cache) end # Case for `cfl_number` as a function of time `t`. @@ -131,7 +131,7 @@ function calculate_dt(u_ode, t, cfl_number, semi::AbstractSemidiscretization) dt = cfl_number(t) * max_dt(u, t, mesh, have_constant_speed(equations), - have_auxiliary_node_vars(equations), equations, + have_aux_node_vars(equations), equations, solver, cache) end diff --git a/src/callbacks_step/stepsize_dg1d.jl b/src/callbacks_step/stepsize_dg1d.jl index 90b24dc3bcc..b9294db9112 100644 --- a/src/callbacks_step/stepsize_dg1d.jl +++ b/src/callbacks_step/stepsize_dg1d.jl @@ -6,7 +6,7 @@ #! format: noindent function max_dt(u, t, mesh::TreeMesh{1}, - constant_speed::False, have_auxiliary_node_vars::False, + constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection @@ -27,7 +27,7 @@ function max_dt(u, t, mesh::TreeMesh{1}, end function max_dt(u, t, mesh::TreeMesh{1}, - constant_speed::True, have_auxiliary_node_vars::False, + constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection @@ -43,7 +43,7 @@ function max_dt(u, t, mesh::TreeMesh{1}, end function max_dt(u, t, mesh::StructuredMesh{1}, - constant_speed::False, have_auxiliary_node_vars::False, + constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection @@ -68,7 +68,7 @@ function max_dt(u, t, mesh::StructuredMesh{1}, end function max_dt(u, t, mesh::StructuredMesh{1}, - constant_speed::True, have_auxiliary_node_vars::False, + constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection diff --git a/src/callbacks_step/stepsize_dg2d.jl b/src/callbacks_step/stepsize_dg2d.jl index 32ce46d304f..716e5ed4832 100644 --- a/src/callbacks_step/stepsize_dg2d.jl +++ b/src/callbacks_step/stepsize_dg2d.jl @@ -6,7 +6,7 @@ #! format: noindent function max_dt(u, t, mesh::TreeMesh{2}, - constant_speed::False, have_auxiliary_node_vars::False, + constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection @@ -29,9 +29,9 @@ function max_dt(u, t, mesh::TreeMesh{2}, end function max_dt(u, t, mesh::TreeMesh{2}, - constant_speed::False, have_auxiliary_node_vars::True, + constant_speed::False, have_aux_node_vars::True, equations, dg::DG, cache) - @unpack auxiliary_node_vars = cache.auxiliary_variables + @unpack aux_node_vars = cache.aux_vars # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection max_scaled_speed = nextfloat(zero(t)) @@ -40,7 +40,7 @@ function max_dt(u, t, mesh::TreeMesh{2}, max_lambda1 = max_lambda2 = zero(max_scaled_speed) for j in eachnode(dg), i in eachnode(dg) u_node = get_node_vars(u, equations, dg, i, j, element) - aux_node = get_auxiliary_node_vars(auxiliary_node_vars, + aux_node = get_aux_node_vars(aux_node_vars, equations, dg, i, j, element) lambda1, lambda2 = max_abs_speeds(u_node, aux_node, equations) max_lambda1 = max(max_lambda1, lambda1) @@ -55,7 +55,7 @@ function max_dt(u, t, mesh::TreeMesh{2}, end function max_dt(u, t, mesh::TreeMesh{2}, - constant_speed::True, have_auxiliary_node_vars::False, + constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection @@ -72,7 +72,7 @@ function max_dt(u, t, mesh::TreeMesh{2}, end function max_dt(u, t, mesh::ParallelTreeMesh{2}, - constant_speed::False, have_auxiliary_node_vars::False, + constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::TreeMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -80,9 +80,9 @@ function max_dt(u, t, mesh::ParallelTreeMesh{2}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), TreeMesh{2}, - typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -91,7 +91,7 @@ function max_dt(u, t, mesh::ParallelTreeMesh{2}, end function max_dt(u, t, mesh::ParallelTreeMesh{2}, - constant_speed::True, have_auxiliary_node_vars::False, + constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::TreeMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -99,9 +99,9 @@ function max_dt(u, t, mesh::ParallelTreeMesh{2}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), TreeMesh{2}, - typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -112,7 +112,7 @@ end function max_dt(u, t, mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}, StructuredMeshView{2}}, - constant_speed::False, have_auxiliary_node_vars::False, + constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection @@ -149,7 +149,7 @@ end function max_dt(u, t, mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, P4estMeshView{2}, T8codeMesh{2}, StructuredMeshView{2}}, - constant_speed::True, have_auxiliary_node_vars::False, + constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) @unpack contravariant_vectors, inverse_jacobian = cache.elements @@ -180,7 +180,7 @@ function max_dt(u, t, end function max_dt(u, t, mesh::ParallelP4estMesh{2}, - constant_speed::False, have_auxiliary_node_vars::False, + constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::P4estMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -188,9 +188,9 @@ function max_dt(u, t, mesh::ParallelP4estMesh{2}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), P4estMesh{2}, - typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -199,7 +199,7 @@ function max_dt(u, t, mesh::ParallelP4estMesh{2}, end function max_dt(u, t, mesh::ParallelP4estMesh{2}, - constant_speed::True, have_auxiliary_node_vars::False, + constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::P4estMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -207,9 +207,9 @@ function max_dt(u, t, mesh::ParallelP4estMesh{2}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), P4estMesh{2}, - typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -218,7 +218,7 @@ function max_dt(u, t, mesh::ParallelP4estMesh{2}, end function max_dt(u, t, mesh::ParallelT8codeMesh{2}, - constant_speed::False, have_auxiliary_node_vars::False, + constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::T8codeMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -226,9 +226,9 @@ function max_dt(u, t, mesh::ParallelT8codeMesh{2}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), T8codeMesh{2}, - typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -237,7 +237,7 @@ function max_dt(u, t, mesh::ParallelT8codeMesh{2}, end function max_dt(u, t, mesh::ParallelT8codeMesh{2}, - constant_speed::True, have_auxiliary_node_vars::False, + constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::T8codeMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -245,9 +245,9 @@ function max_dt(u, t, mesh::ParallelT8codeMesh{2}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), T8codeMesh{2}, - typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] diff --git a/src/callbacks_step/stepsize_dg3d.jl b/src/callbacks_step/stepsize_dg3d.jl index e3e7f40a065..7fe1d19cc3f 100644 --- a/src/callbacks_step/stepsize_dg3d.jl +++ b/src/callbacks_step/stepsize_dg3d.jl @@ -6,7 +6,7 @@ #! format: noindent function max_dt(u, t, mesh::TreeMesh{3}, - constant_speed::False, have_auxiliary_node_vars::False, + constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection @@ -30,7 +30,7 @@ function max_dt(u, t, mesh::TreeMesh{3}, end function max_dt(u, t, mesh::TreeMesh{3}, - constant_speed::True, have_auxiliary_node_vars::False, + constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection @@ -47,7 +47,7 @@ function max_dt(u, t, mesh::TreeMesh{3}, end function max_dt(u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - constant_speed::False, have_auxiliary_node_vars::False, + constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection @@ -86,7 +86,7 @@ function max_dt(u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3} end function max_dt(u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - constant_speed::True, have_auxiliary_node_vars::False, + constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # to avoid a division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection @@ -124,7 +124,7 @@ function max_dt(u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3} end function max_dt(u, t, mesh::ParallelP4estMesh{3}, - constant_speed::False, have_auxiliary_node_vars::False, + constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::P4estMesh{3}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -132,9 +132,9 @@ function max_dt(u, t, mesh::ParallelP4estMesh{3}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), P4estMesh{3}, - typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -143,7 +143,7 @@ function max_dt(u, t, mesh::ParallelP4estMesh{3}, end function max_dt(u, t, mesh::ParallelP4estMesh{3}, - constant_speed::True, have_auxiliary_node_vars::False, + constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::P4estMesh{3}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -151,9 +151,9 @@ function max_dt(u, t, mesh::ParallelP4estMesh{3}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), P4estMesh{3}, - typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -162,7 +162,7 @@ function max_dt(u, t, mesh::ParallelP4estMesh{3}, end function max_dt(u, t, mesh::ParallelT8codeMesh{3}, - constant_speed::False, have_auxiliary_node_vars::False, + constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::T8codeMesh{3}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -170,9 +170,9 @@ function max_dt(u, t, mesh::ParallelT8codeMesh{3}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), T8codeMesh{3}, - typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -181,7 +181,7 @@ function max_dt(u, t, mesh::ParallelT8codeMesh{3}, end function max_dt(u, t, mesh::ParallelT8codeMesh{3}, - constant_speed::True, have_auxiliary_node_vars::False, + constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::T8codeMesh{3}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -189,9 +189,9 @@ function max_dt(u, t, mesh::ParallelT8codeMesh{3}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), T8codeMesh{3}, - typeof(constant_speed), typeof(have_auxiliary_node_vars), + typeof(constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_auxiliary_node_vars, equations, dg, + u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] diff --git a/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl b/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl index e4b571d4c6a..31855d53e19 100644 --- a/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl +++ b/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl @@ -32,8 +32,8 @@ function AcousticPerturbationEquations2DAuxVars(; v_mean_global::NTuple{2, <:Rea rho_mean_global) end -have_auxiliary_node_vars(::AcousticPerturbationEquations2DAuxVars) = True() -n_auxiliary_node_vars(::AcousticPerturbationEquations2DAuxVars) = 4 +have_aux_node_vars(::AcousticPerturbationEquations2DAuxVars) = True() +n_aux_node_vars(::AcousticPerturbationEquations2DAuxVars) = 4 """ global_mean_vars(equations::AcousticPerturbationEquations2DAuxVars) diff --git a/src/equations/equations.jl b/src/equations/equations.jl index d9118052b47..5c16f98d484 100644 --- a/src/equations/equations.jl +++ b/src/equations/equations.jl @@ -81,9 +81,9 @@ function Base.show(io::IO, ::MIME"text/plain", equations::AbstractEquations) "variable " * string(variable), varnames(cons2cons, equations)[variable]) end - if have_auxiliary_node_vars(equations) == Trixi.True() - summary_line(io, "#auxiliary variables", n_auxiliary_node_vars(equations)) - for variable in eachauxiliaryvariable(equations) + if have_aux_node_vars(equations) == Trixi.True() + summary_line(io, "#auxiliary variables", n_aux_node_vars(equations)) + for variable in eachauxvariable(equations) summary_line(increment_indent(io), "variable " * string(variable), varnames(cons2aux, equations)[variable]) @@ -316,20 +316,20 @@ function n_nonconservative_terms end have_constant_speed(::AbstractEquations) = False() """ - have_auxiliary_node_vars(equations) + have_aux_node_vars(equations) Trait function determining whether `equations` need to access additional auxiliary variables. The return value will be `True()` or `False()` to allow dispatching on the return type. """ -have_auxiliary_node_vars(::AbstractEquations) = False() +have_aux_node_vars(::AbstractEquations) = False() """ - n_auxiliary_node_vars(equations) + n_aux_node_vars(equations) Number of auxiliary variables used by `equations`. This function needs to be specialized only if equations has auxiliary variables. """ -function n_auxiliary_node_vars end -@inline eachauxiliaryvariable(equations::AbstractEquations) = Base.OneTo(n_auxiliary_node_vars(equations)) +function n_aux_node_vars end +@inline eachauxvariable(equations::AbstractEquations) = Base.OneTo(n_aux_node_vars(equations)) """ default_analysis_errors(equations) @@ -689,7 +689,7 @@ include("lattice_boltzmann_3d.jl") abstract type AbstractAcousticPerturbationEquations{NDIMS, NVARS} <: AbstractEquations{NDIMS, NVARS} end include("acoustic_perturbation_2d.jl") -include("acoustic_perturbation_2d_auxiliary_variables.jl") +include("acoustic_perturbation_2d_aux_vars.jl") # Linearized Euler equations abstract type AbstractLinearizedEulerEquations{NDIMS, NVARS} <: diff --git a/src/semidiscretization/semidiscretization_euler_gravity.jl b/src/semidiscretization/semidiscretization_euler_gravity.jl index 8e2dc2b61a6..99e79156340 100644 --- a/src/semidiscretization/semidiscretization_euler_gravity.jl +++ b/src/semidiscretization/semidiscretization_euler_gravity.jl @@ -299,7 +299,7 @@ function update_gravity!(semi::SemidiscretizationEulerGravity, u_ode) while !finalstep dtau = @trixi_timeit timer() "calculate dtau" begin cfl * max_dt(u_gravity, tau, semi_gravity.mesh, - have_constant_speed(equations), have_auxiliary_node_vars(equations), + have_constant_speed(equations), have_aux_node_vars(equations), equations, semi_gravity.solver, semi_gravity.cache) end diff --git a/src/semidiscretization/semidiscretization_hyperbolic.jl b/src/semidiscretization/semidiscretization_hyperbolic.jl index 9a17e00eec8..2db50e1d166 100644 --- a/src/semidiscretization/semidiscretization_hyperbolic.jl +++ b/src/semidiscretization/semidiscretization_hyperbolic.jl @@ -74,7 +74,7 @@ function SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver # Add specialized parts of the cache for auxiliary node variables cache = (; cache..., create_cache_auxiliary(mesh, equations, solver, cache, - have_auxiliary_node_vars(equations), + have_aux_node_vars(equations), auxiliary_field)...) _boundary_conditions = digest_boundary_conditions(boundary_conditions, mesh, solver, @@ -113,15 +113,15 @@ end # If there are auxiliary variables, initialize them function create_cache_auxiliary(mesh, equations, solver, cache, - have_auxiliary_node_vars::True, auxiliary_field) - auxiliary_variables = init_auxiliary_node_variables(mesh, equations, solver, cache, + have_aux_node_vars::True, auxiliary_field) + aux_vars = init_aux_node_vars(mesh, equations, solver, cache, auxiliary_field) - return (; auxiliary_variables) + return (; aux_vars) end # Do nothing if there are no auxiliary variables function create_cache_auxiliary(mesh, equations, solver, cache, - have_auxiliary_node_vars::False, auxiliary_field) + have_aux_node_vars::False, auxiliary_field) return NamedTuple() end @@ -338,9 +338,9 @@ function Base.show(io::IO, ::MIME"text/plain", semi::SemidiscretizationHyperboli print_boundary_conditions(io, semi) summary_line(io, "source terms", semi.source_terms) - if have_auxiliary_node_vars(semi.equations) == Trixi.True() + if have_aux_node_vars(semi.equations) == Trixi.True() summary_line(io, "auxiliary variables", - semi.cache.auxiliary_variables.auxiliary_field) + semi.cache.aux_vars.auxiliary_field) end summary_line(io, "solver", semi.solver |> typeof |> nameof) summary_line(io, "total #DOFs per field", ndofsglobal(semi)) diff --git a/src/solvers/dg.jl b/src/solvers/dg.jl index 234a0960491..45b72087965 100644 --- a/src/solvers/dg.jl +++ b/src/solvers/dg.jl @@ -560,10 +560,10 @@ end end # Return the auxiliary variables at a given volume node index -@inline function get_auxiliary_node_vars(auxiliary_node_vars, equations, ::DG, +@inline function get_aux_node_vars(aux_node_vars, equations, ::DG, indices...) - return SVector(ntuple(@inline(v->auxiliary_node_vars[v, indices...]), - Val(n_auxiliary_node_vars(equations)))) + return SVector(ntuple(@inline(v->aux_node_vars[v, indices...]), + Val(n_aux_node_vars(equations)))) end @inline function get_surface_node_vars(u, equations, solver::DG, indices...) @@ -578,12 +578,12 @@ end end # Return the auxiliary variables at a given surface node index -@inline function get_auxiliary_surface_node_vars(aux_surface_node_vars, equations, ::DG, +@inline function get_aux_surface_node_vars(aux_surface_node_vars, equations, ::DG, indices...) aux_vars_ll = SVector(ntuple(@inline(v->aux_surface_node_vars[1, v, indices...]), - Val(n_auxiliary_node_vars(equations)))) + Val(n_aux_node_vars(equations)))) aux_vars_rr = SVector(ntuple(@inline(v->aux_surface_node_vars[2, v, indices...]), - Val(n_auxiliary_node_vars(equations)))) + Val(n_aux_node_vars(equations)))) return aux_vars_ll, aux_vars_rr end @@ -594,10 +594,10 @@ end return nothing end -@inline function set_auxiliary_node_vars!(auxiliary_node_vars, aux_node, equations, +@inline function set_aux_node_vars!(aux_node_vars, aux_node, equations, solver::DG, indices...) - for v in 1:n_auxiliary_node_vars(equations) - auxiliary_node_vars[v, indices...] = aux_node[v] + for v in 1:n_aux_node_vars(equations) + aux_node_vars[v, indices...] = aux_node[v] end return nothing end diff --git a/src/solvers/dgmulti/dg.jl b/src/solvers/dgmulti/dg.jl index 6858121891c..aad912ddb13 100644 --- a/src/solvers/dgmulti/dg.jl +++ b/src/solvers/dgmulti/dg.jl @@ -237,7 +237,7 @@ end # for the stepsize callback function max_dt(u, t, mesh::DGMultiMesh, - constant_speed::False, have_auxiliary_node_vars::False, + constant_speed::False, have_aux_node_vars::False, equations, dg::DGMulti{NDIMS}, cache) where {NDIMS} @unpack md = mesh @@ -261,7 +261,7 @@ function max_dt(u, t, mesh::DGMultiMesh, end function max_dt(u, t, mesh::DGMultiMesh, - constant_speed::True, have_auxiliary_node_vars::False, + constant_speed::True, have_aux_node_vars::False, equations, dg::DGMulti{NDIMS}, cache) where {NDIMS} @unpack md = mesh diff --git a/src/solvers/dgsem_p4est/dg_2d.jl b/src/solvers/dgsem_p4est/dg_2d.jl index 96d8c298838..29c31d3f143 100644 --- a/src/solvers/dgsem_p4est/dg_2d.jl +++ b/src/solvers/dgsem_p4est/dg_2d.jl @@ -120,7 +120,7 @@ end function calc_interface_flux!(surface_flux_values, mesh::Union{P4estMesh{2}, P4estMeshView{2}, T8codeMesh{2}}, - nonconservative_terms, have_auxiliary_node_vars, + nonconservative_terms, have_aux_node_vars, equations, surface_integral, dg::DG, cache) @unpack neighbor_ids, node_indices = cache.interfaces @unpack contravariant_vectors = cache.elements diff --git a/src/solvers/dgsem_p4est/dg_2d_parallel.jl b/src/solvers/dgsem_p4est/dg_2d_parallel.jl index 0f4c79f790f..16fa0b0e13e 100644 --- a/src/solvers/dgsem_p4est/dg_2d_parallel.jl +++ b/src/solvers/dgsem_p4est/dg_2d_parallel.jl @@ -47,7 +47,7 @@ function calc_mpi_interface_flux!(surface_flux_values, mesh::Union{ParallelP4estMesh{2}, ParallelT8codeMesh{2}}, nonconservative_terms, - have_auxiliary_node_vars, + have_aux_node_vars, equations, surface_integral, dg::DG, cache) @unpack local_neighbor_ids, node_indices, local_sides = cache.mpi_interfaces @unpack contravariant_vectors = cache.elements @@ -89,7 +89,7 @@ function calc_mpi_interface_flux!(surface_flux_values, i_element, j_element, local_element) calc_mpi_interface_flux!(surface_flux_values, mesh, nonconservative_terms, - have_auxiliary_node_vars, equations, + have_aux_node_vars, equations, surface_integral, dg, cache, interface, normal_direction, node, local_side, @@ -112,7 +112,7 @@ end mesh::Union{ParallelP4estMesh{2}, ParallelT8codeMesh{2}}, nonconservative_terms::False, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, surface_integral, dg::DG, cache, interface_index, normal_direction, interface_node_index, local_side, diff --git a/src/solvers/dgsem_structured/dg_2d.jl b/src/solvers/dgsem_structured/dg_2d.jl index 484a015a170..66e39a65d4f 100644 --- a/src/solvers/dgsem_structured/dg_2d.jl +++ b/src/solvers/dgsem_structured/dg_2d.jl @@ -42,7 +42,7 @@ function rhs!(du, u, t, # Calculate source terms @trixi_timeit timer() "source terms" begin - calc_sources!(du, u, t, source_terms, have_auxiliary_node_vars(equations), + calc_sources!(du, u, t, source_terms, have_aux_node_vars(equations), equations, dg, cache) end @@ -62,7 +62,7 @@ See also https://github.com/trixi-framework/Trixi.jl/issues/1671#issuecomment-17 UnstructuredMesh2D, P4estMesh{2}, P4estMeshView{2}, T8codeMesh{2}}, nonconservative_terms::False, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -106,7 +106,7 @@ end UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, nonconservative_terms::False, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) @unpack derivative_split = dg.basis @unpack contravariant_vectors = cache.elements @@ -165,7 +165,7 @@ end UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, nonconservative_terms::True, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) @unpack derivative_split = dg.basis @unpack contravariant_vectors = cache.elements diff --git a/src/solvers/dgsem_structured/dg_2d_compressible_euler.jl b/src/solvers/dgsem_structured/dg_2d_compressible_euler.jl index 8cd6d8d19b2..d22997b76a2 100644 --- a/src/solvers/dgsem_structured/dg_2d_compressible_euler.jl +++ b/src/solvers/dgsem_structured/dg_2d_compressible_euler.jl @@ -22,7 +22,7 @@ mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}}, nonconservative_terms::False, - have_auxiliary_node_vars::False, + have_aux_node_vars::False, equations::CompressibleEulerEquations2D, volume_flux::typeof(flux_shima_etal_turbo), dg::DGSEM, cache, alpha) @@ -230,7 +230,7 @@ end mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}}, nonconservative_terms::False, - have_auxiliary_node_vars::False, + have_aux_node_vars::False, equations::CompressibleEulerEquations2D, volume_flux::typeof(flux_ranocha_turbo), dg::DGSEM, cache, alpha) diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index 6ae5e4f86ce..8d2c630b5e5 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -35,12 +35,12 @@ function reinitialize_containers!(mesh::TreeMesh, equations, dg::DGSEM, cache) end # re-initialize auxiliary variables container - if hasproperty(cache, :auxiliary_variables) - @unpack auxiliary_variables = cache - resize!(auxiliary_variables, length(leaf_cell_ids), + if hasproperty(cache, :aux_vars) + @unpack aux_vars = cache + resize!(aux_vars, length(leaf_cell_ids), count_required_interfaces(mesh, leaf_cell_ids)) - init_auxiliary_node_variables!(auxiliary_variables, mesh, equations, dg, cache) - init_auxiliary_surface_node_variables!(auxiliary_variables, mesh, equations, dg, + init_aux_node_vars!(aux_vars, mesh, equations, dg, cache) + init_auxiliary_surface_node_variables!(aux_vars, mesh, equations, dg, cache) end @@ -65,24 +65,24 @@ end # Container for storing values of auxiliary variables at volume/surface quadrature nodes mutable struct AuxiliaryNodeVariablesContainer{NDIMS, uEltype <: Real, NDIMSP2, AuxiliaryVariables} - auxiliary_node_vars::Array{uEltype, NDIMSP2} # [var, i, j, element] - auxiliary_surface_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] + aux_node_vars::Array{uEltype, NDIMSP2} # [var, i, j, element] + aux_surface_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] # internal `resize!`able storage - _auxiliary_node_vars::Vector{uEltype} - _auxiliary_surface_node_vars::Vector{uEltype} + _aux_node_vars::Vector{uEltype} + _aux_surface_node_vars::Vector{uEltype} # save initialization function auxiliary_field::AuxiliaryVariables end -nvariables(auxiliary_variables::AuxiliaryNodeVariablesContainer) = size(auxiliary_variables.auxiliary_node_vars, +nvariables(aux_vars::AuxiliaryNodeVariablesContainer) = size(aux_vars.aux_node_vars, 1) -nnodes(auxiliary_variables::AuxiliaryNodeVariablesContainer) = size(auxiliary_variables.auxiliary_node_vars, +nnodes(aux_vars::AuxiliaryNodeVariablesContainer) = size(aux_vars.aux_node_vars, 2) # Create auxiliary node variable container -function init_auxiliary_node_variables(mesh, equations, solver, cache, +function init_aux_node_vars(mesh, equations, solver, cache, auxiliary_field) @unpack elements, interfaces = cache @@ -92,35 +92,35 @@ function init_auxiliary_node_variables(mesh, equations, solver, cache, uEltype = eltype(elements) nan_uEltype = convert(uEltype, NaN) - _auxiliary_node_vars = fill(nan_uEltype, - n_auxiliary_node_vars(equations) * + _aux_node_vars = fill(nan_uEltype, + n_aux_node_vars(equations) * nnodes(solver)^NDIMS * n_elements) - auxiliary_node_vars = unsafe_wrap(Array, pointer(_auxiliary_node_vars), - (n_auxiliary_node_vars(equations), + aux_node_vars = unsafe_wrap(Array, pointer(_aux_node_vars), + (n_aux_node_vars(equations), ntuple(_ -> nnodes(solver), NDIMS)..., n_elements)) - _auxiliary_surface_node_vars = fill(nan_uEltype, - 2 * n_auxiliary_node_vars(equations) * + _aux_surface_node_vars = fill(nan_uEltype, + 2 * n_aux_node_vars(equations) * nnodes(solver)^(NDIMS - 1) * n_interfaces) - auxiliary_surface_node_vars = unsafe_wrap(Array, - pointer(_auxiliary_surface_node_vars), - (2, n_auxiliary_node_vars(equations), + aux_surface_node_vars = unsafe_wrap(Array, + pointer(_aux_surface_node_vars), + (2, n_aux_node_vars(equations), ntuple(_ -> nnodes(solver), NDIMS - 1)..., n_interfaces)) - auxiliary_variables = AuxiliaryNodeVariablesContainer{NDIMS, uEltype, NDIMS + 2, - typeof(auxiliary_field)}(auxiliary_node_vars, - auxiliary_surface_node_vars, - _auxiliary_node_vars, - _auxiliary_surface_node_vars, + aux_vars = AuxiliaryNodeVariablesContainer{NDIMS, uEltype, NDIMS + 2, + typeof(auxiliary_field)}(aux_node_vars, + aux_surface_node_vars, + _aux_node_vars, + _aux_surface_node_vars, auxiliary_field) - init_auxiliary_node_variables!(auxiliary_variables, mesh, equations, solver, cache) - init_auxiliary_surface_node_variables!(auxiliary_variables, mesh, equations, solver, + init_aux_node_vars!(aux_vars, mesh, equations, solver, cache) + init_auxiliary_surface_node_variables!(aux_vars, mesh, equations, solver, cache) - return auxiliary_variables + return aux_vars end # Only one-dimensional `Array`s are `resize!`able in Julia. @@ -128,25 +128,25 @@ end # them whenever needed. Then, we reuse the same memory by # `unsafe_wrap`ping multi-dimensional `Array`s around the # internal storage. -function Base.resize!(auxiliary_variables::AuxiliaryNodeVariablesContainer{NDIMS}, +function Base.resize!(aux_vars::AuxiliaryNodeVariablesContainer{NDIMS}, capacity_node_vars, capacity_node_surface_vars) where {NDIMS} - @unpack _auxiliary_node_vars, _auxiliary_surface_node_vars = auxiliary_variables - n_nodes = nnodes(auxiliary_variables) - n_variables = nvariables(auxiliary_variables) + @unpack _aux_node_vars, _aux_surface_node_vars = aux_vars + n_nodes = nnodes(aux_vars) + n_variables = nvariables(aux_vars) - resize!(_auxiliary_node_vars, n_variables * n_nodes^NDIMS * capacity_node_vars) - auxiliary_variables.auxiliary_node_vars = unsafe_wrap(Array, - pointer(_auxiliary_node_vars), + resize!(_aux_node_vars, n_variables * n_nodes^NDIMS * capacity_node_vars) + aux_vars.aux_node_vars = unsafe_wrap(Array, + pointer(_aux_node_vars), (n_variables, ntuple(_ -> n_nodes, NDIMS)..., capacity_node_vars)) - resize!(_auxiliary_surface_node_vars, + resize!(_aux_surface_node_vars, 2 * n_variables * n_nodes^(NDIMS - 1) * capacity_node_surface_vars) - auxiliary_variables.auxiliary_surface_node_vars = unsafe_wrap(Array, - pointer(_auxiliary_surface_node_vars), + aux_vars.aux_surface_node_vars = unsafe_wrap(Array, + pointer(_aux_surface_node_vars), (2, n_variables, ntuple(_ -> n_nodes, NDIMS - 1)..., diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index 97f6245f728..5896629f24c 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1424,16 +1424,16 @@ function Base.resize!(container::ContainerSubcellLimiterIDP2D, capacity) end # Initialize auxiliary node variables (2D implementation) -function init_auxiliary_node_variables!(auxiliary_variables, mesh, equations, solver, +function init_aux_node_vars!(aux_vars, mesh, equations, solver, cache) - @unpack auxiliary_node_vars, auxiliary_field = auxiliary_variables + @unpack aux_node_vars, auxiliary_field = aux_vars @unpack node_coordinates = cache.elements @threaded for element in eachelement(solver, cache) for j in eachnode(solver), i in eachnode(solver) x_local = get_node_coords(node_coordinates, equations, solver, i, j, element) - set_auxiliary_node_vars!(auxiliary_node_vars, + set_aux_node_vars!(aux_node_vars, auxiliary_field(x_local, equations), equations, solver, i, j, element) end @@ -1442,9 +1442,9 @@ function init_auxiliary_node_variables!(auxiliary_variables, mesh, equations, so end # Initialize auxiliary surface node variables (2D implementation) -function init_auxiliary_surface_node_variables!(auxiliary_variables, mesh, equations, +function init_auxiliary_surface_node_variables!(aux_vars, mesh, equations, solver, cache) - @unpack auxiliary_node_vars, auxiliary_surface_node_vars = auxiliary_variables + @unpack aux_node_vars, aux_surface_node_vars = aux_vars @unpack orientations, neighbor_ids = cache.interfaces @threaded for interface in eachinterface(solver, cache) @@ -1454,12 +1454,12 @@ function init_auxiliary_surface_node_variables!(auxiliary_variables, mesh, equat if orientations[interface] == 1 # interface in x-direction for j in eachnode(solver) - for v in axes(auxiliary_surface_node_vars, 2) - auxiliary_surface_node_vars[1, v, j, interface] = auxiliary_node_vars[v, + for v in axes(aux_surface_node_vars, 2) + aux_surface_node_vars[1, v, j, interface] = aux_node_vars[v, nnodes(solver), j, left_element] - auxiliary_surface_node_vars[2, v, j, interface] = auxiliary_node_vars[v, + aux_surface_node_vars[2, v, j, interface] = aux_node_vars[v, 1, j, right_element] @@ -1468,12 +1468,12 @@ function init_auxiliary_surface_node_variables!(auxiliary_variables, mesh, equat else # if orientations[interface] == 2 # interface in y-direction for i in eachnode(solver) - for v in axes(auxiliary_surface_node_vars, 2) - auxiliary_surface_node_vars[1, v, i, interface] = auxiliary_node_vars[v, + for v in axes(aux_surface_node_vars, 2) + aux_surface_node_vars[1, v, i, interface] = aux_node_vars[v, i, nnodes(solver), left_element] - auxiliary_surface_node_vars[2, v, i, interface] = auxiliary_node_vars[v, + aux_surface_node_vars[2, v, i, interface] = aux_node_vars[v, i, 1, right_element] diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 3d47604cbda..c412ee062d0 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -134,7 +134,7 @@ function rhs!(du, u, t, @trixi_timeit timer() "interface flux" begin calc_interface_flux!(cache.elements.surface_flux_values, mesh, have_nonconservative_terms(equations), - have_auxiliary_node_vars(equations), equations, + have_aux_node_vars(equations), equations, dg.surface_integral, dg, cache) end @@ -174,7 +174,7 @@ function rhs!(du, u, t, # Calculate source terms @trixi_timeit timer() "source terms" begin - calc_sources!(du, u, t, source_terms, have_auxiliary_node_vars(equations), + calc_sources!(du, u, t, source_terms, have_aux_node_vars(equations), equations, dg, cache) end @@ -191,7 +191,7 @@ function calc_volume_integral!(du, u, @threaded for element in eachelement(dg, cache) weak_form_kernel!(du, u, element, mesh, have_nonconservative_terms(equations), - have_auxiliary_node_vars(equations), equations, + have_aux_node_vars(equations), equations, dg, cache) end @@ -208,7 +208,7 @@ See also https://github.com/trixi-framework/Trixi.jl/issues/1671#issuecomment-17 @inline function weak_form_kernel!(du, u, element, mesh::TreeMesh{2}, nonconservative_terms::False, - auxiliary_node_var::False, equations, + have_aux_node_vars::False, equations, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -237,17 +237,17 @@ end @inline function weak_form_kernel!(du, u, element, mesh::TreeMesh{2}, nonconservative_terms::False, - auxiliary_node_var::True, equations, + have_aux_node_vars::True, equations, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @unpack derivative_dhat = dg.basis - @unpack auxiliary_node_vars = cache.auxiliary_variables + @unpack aux_node_vars = cache.aux_vars # Calculate volume terms in one element for j in eachnode(dg), i in eachnode(dg) u_node = get_node_vars(u, equations, dg, i, j, element) - aux_node = get_auxiliary_node_vars(auxiliary_node_vars, + aux_node = get_aux_node_vars(aux_node_vars, equations, dg, i, j, element) flux1 = flux(u_node, aux_node, 1, equations) @@ -280,7 +280,7 @@ function calc_volume_integral!(du, u, @threaded for element in eachelement(dg, cache) flux_differencing_kernel!(du, u, element, mesh, have_nonconservative_terms(equations), - have_auxiliary_node_vars(equations), equations, + have_aux_node_vars(equations), equations, volume_integral.volume_flux, dg, cache) end end @@ -288,7 +288,7 @@ end @inline function flux_differencing_kernel!(du, u, element, mesh::TreeMesh{2}, nonconservative_terms::False, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -328,17 +328,17 @@ end @inline function flux_differencing_kernel!(du, u, element, mesh::TreeMesh{2}, nonconservative_terms::False, - have_auxiliary_node_vars::True, equations, + have_aux_node_vars::True, equations, volume_flux, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @unpack derivative_split = dg.basis - @unpack auxiliary_node_vars = cache.auxiliary_variables + @unpack aux_node_vars = cache.aux_vars # Calculate volume integral in one element for j in eachnode(dg), i in eachnode(dg) u_node = get_node_vars(u, equations, dg, i, j, element) - aux_node = get_auxiliary_node_vars(auxiliary_node_vars, equations, dg, + aux_node = get_aux_node_vars(aux_node_vars, equations, dg, i, j, element) # All diagonal entries of `derivative_split` are zero. Thus, we can skip @@ -349,7 +349,7 @@ end # x direction for ii in (i + 1):nnodes(dg) u_node_ii = get_node_vars(u, equations, dg, ii, j, element) - aux_node_ii = get_auxiliary_node_vars(auxiliary_node_vars, equations, dg, + aux_node_ii = get_aux_node_vars(aux_node_vars, equations, dg, ii, j, element) flux1 = volume_flux(u_node, u_node_ii, aux_node, aux_node_ii, 1, equations) multiply_add_to_node_vars!(du, alpha * derivative_split[i, ii], flux1, @@ -361,7 +361,7 @@ end # y direction for jj in (j + 1):nnodes(dg) u_node_jj = get_node_vars(u, equations, dg, i, jj, element) - aux_node_jj = get_auxiliary_node_vars(auxiliary_node_vars, equations, dg, + aux_node_jj = get_aux_node_vars(aux_node_vars, equations, dg, i, jj, element) flux2 = volume_flux(u_node, u_node_jj, aux_node, aux_node_jj, 2, equations) multiply_add_to_node_vars!(du, alpha * derivative_split[j, jj], flux2, @@ -375,7 +375,7 @@ end @inline function flux_differencing_kernel!(du, u, element, mesh::TreeMesh{2}, nonconservative_terms::True, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -442,13 +442,13 @@ function calc_volume_integral!(du, u, if dg_only flux_differencing_kernel!(du, u, element, mesh, have_nonconservative_terms(equations), - have_auxiliary_node_vars(equations), equations, + have_aux_node_vars(equations), equations, volume_flux_dg, dg, cache) else # Calculate DG volume integral contribution flux_differencing_kernel!(du, u, element, mesh, have_nonconservative_terms(equations), - have_auxiliary_node_vars(equations), equations, + have_aux_node_vars(equations), equations, volume_flux_dg, dg, cache, 1 - alpha_element) # Calculate FV volume integral contribution @@ -660,7 +660,7 @@ end function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{2}, nonconservative_terms::False, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, surface_integral, dg::DG, cache) @unpack surface_flux = surface_integral @unpack u, neighbor_ids, orientations = cache.interfaces @@ -695,11 +695,11 @@ end function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{2}, nonconservative_terms::False, - have_auxiliary_node_vars::True, equations, + have_aux_node_vars::True, equations, surface_integral, dg::DG, cache) @unpack surface_flux = surface_integral @unpack u, neighbor_ids, orientations = cache.interfaces - @unpack auxiliary_surface_node_vars = cache.auxiliary_variables + @unpack aux_surface_node_vars = cache.aux_vars @threaded for interface in eachinterface(dg, cache) # Get neighboring elements @@ -715,7 +715,7 @@ function calc_interface_flux!(surface_flux_values, for i in eachnode(dg) # Call pointwise Riemann solver u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) - aux_ll, aux_rr = get_auxiliary_surface_node_vars(auxiliary_surface_node_vars, + aux_ll, aux_rr = get_aux_surface_node_vars(aux_surface_node_vars, equations, dg, i, interface) flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, @@ -734,7 +734,7 @@ end function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{2}, nonconservative_terms::True, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, surface_integral, dg::DG, cache) surface_flux, nonconservative_flux = surface_integral.surface_flux @unpack u, neighbor_ids, orientations = cache.interfaces @@ -834,29 +834,29 @@ function calc_boundary_flux!(cache, t, boundary_conditions::NamedTuple, # Calc boundary fluxes in each direction calc_boundary_flux_by_direction!(t, boundary_conditions[1], have_nonconservative_terms(equations), - have_auxiliary_node_vars(equations), + have_aux_node_vars(equations), equations, surface_integral, dg, cache, 1, firsts[1], lasts[1]) calc_boundary_flux_by_direction!(t, boundary_conditions[2], have_nonconservative_terms(equations), - have_auxiliary_node_vars(equations), + have_aux_node_vars(equations), equations, surface_integral, dg, cache, 2, firsts[2], lasts[2]) calc_boundary_flux_by_direction!(t, boundary_conditions[3], have_nonconservative_terms(equations), - have_auxiliary_node_vars(equations), + have_aux_node_vars(equations), equations, surface_integral, dg, cache, 3, firsts[3], lasts[3]) calc_boundary_flux_by_direction!(t, boundary_conditions[4], have_nonconservative_terms(equations), - have_auxiliary_node_vars(equations), + have_aux_node_vars(equations), equations, surface_integral, dg, cache, 4, firsts[4], lasts[4]) end function calc_boundary_flux_by_direction!(t, boundary_condition, nonconservative_terms::False, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, surface_integral, dg::DG, cache, direction, first_boundary, last_boundary) @unpack surface_flux_values = cache.elements @@ -892,13 +892,13 @@ end function calc_boundary_flux_by_direction!(t, boundary_condition, nonconservative_terms::False, - have_auxiliary_node_vars::True, equations, + have_aux_node_vars::True, equations, surface_integral, dg::DG, cache, direction, first_boundary, last_boundary) @unpack surface_flux_values = cache.elements @unpack surface_flux = surface_integral @unpack u, neighbor_ids, neighbor_sides, node_coordinates, orientations = cache.boundaries - @unpack auxiliary_surface_node_vars = cache.auxiliary_variables + @unpack aux_surface_node_vars = cache.aux_vars @threaded for boundary in first_boundary:last_boundary # Get neighboring element @@ -907,7 +907,7 @@ function calc_boundary_flux_by_direction!(t, boundary_condition, for i in eachnode(dg) # Get boundary flux u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, boundary) - aux_ll, aux_rr = get_auxiliary_surface_node_vars(auxiliary_surface_node_vars, + aux_ll, aux_rr = get_aux_surface_node_vars(aux_surface_node_vars, equations, dg, i, boundary) if neighbor_sides[boundary] == 1 # Element is on the left, boundary on the right u_inner = u_ll @@ -933,7 +933,7 @@ end function calc_boundary_flux_by_direction!(t, boundary_condition, nonconservative_terms::True, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, surface_integral, dg::DG, cache, direction, first_boundary, last_boundary) @unpack surface_flux_values = cache.elements @@ -1087,13 +1087,13 @@ function calc_mortar_flux!(surface_flux_values, # Calculate fluxes orientation = orientations[mortar] - calc_fstar!(fstar_primary_upper, have_auxiliary_node_vars(equations), equations, + calc_fstar!(fstar_primary_upper, have_aux_node_vars(equations), equations, surface_flux, dg, u_upper, mortar, orientation, cache) - calc_fstar!(fstar_primary_lower, have_auxiliary_node_vars(equations), equations, + calc_fstar!(fstar_primary_lower, have_aux_node_vars(equations), equations, surface_flux, dg, u_lower, mortar, orientation, cache) - calc_fstar!(fstar_secondary_upper, have_auxiliary_node_vars(equations), + calc_fstar!(fstar_secondary_upper, have_aux_node_vars(equations), equations, surface_flux, dg, u_upper, mortar, orientation, cache) - calc_fstar!(fstar_secondary_lower, have_auxiliary_node_vars(equations), + calc_fstar!(fstar_secondary_lower, have_aux_node_vars(equations), equations, surface_flux, dg, u_lower, mortar, orientation, cache) mortar_fluxes_to_elements!(surface_flux_values, @@ -1124,14 +1124,14 @@ function calc_mortar_flux!(surface_flux_values, # Calculate fluxes orientation = orientations[mortar] - calc_fstar!(fstar_primary_upper, have_auxiliary_node_vars(equations), equations, + calc_fstar!(fstar_primary_upper, have_aux_node_vars(equations), equations, surface_flux, dg, u_upper, mortar, orientation, cache) - calc_fstar!(fstar_primary_lower, have_auxiliary_node_vars(equations), equations, + calc_fstar!(fstar_primary_lower, have_aux_node_vars(equations), equations, surface_flux, dg, u_lower, mortar, orientation, cache) - calc_fstar!(fstar_secondary_upper, have_auxiliary_node_vars(equations), + calc_fstar!(fstar_secondary_upper, have_aux_node_vars(equations), equations, surface_flux, dg, u_upper, mortar, orientation, cache) - calc_fstar!(fstar_secondary_lower, have_auxiliary_node_vars(equations), + calc_fstar!(fstar_secondary_lower, have_aux_node_vars(equations), equations, surface_flux, dg, u_lower, mortar, orientation, cache) @@ -1214,7 +1214,7 @@ function calc_mortar_flux!(surface_flux_values, end @inline function calc_fstar!(destination::AbstractArray{<:Any, 2}, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, surface_flux, dg::DGSEM, u_interfaces, interface, orientation, cache) for i in eachnode(dg) @@ -1230,14 +1230,14 @@ end end @inline function calc_fstar!(destination::AbstractArray{<:Any, 2}, - have_auxiliary_node_vars::True, equations, + have_aux_node_vars::True, equations, surface_flux, dg::DGSEM, u_interfaces, interface, orientation, cache) - @unpack auxiliary_surface_node_vars = cache.auxiliary_variables + @unpack aux_surface_node_vars = cache.aux_vars for i in eachnode(dg) # Call pointwise two-point numerical flux function u_ll, u_rr = get_surface_node_vars(u_interfaces, equations, dg, i, interface) - aux_ll, aux_rr = get_auxiliary_surface_node_vars(auxiliary_surface_node_vars, + aux_ll, aux_rr = get_aux_surface_node_vars(aux_surface_node_vars, equations, dg, i, interface) flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, orientation, equations) @@ -1385,17 +1385,17 @@ function apply_jacobian!(du, mesh::TreeMesh{2}, end # TODO: Taal dimension agnostic -function calc_sources!(du, u, t, source_terms::Nothing, have_auxiliary_node_vars::False, +function calc_sources!(du, u, t, source_terms::Nothing, have_aux_node_vars::False, equations::AbstractEquations{2}, dg::DG, cache) return nothing end -function calc_sources!(du, u, t, source_terms::Nothing, have_auxiliary_node_vars::True, +function calc_sources!(du, u, t, source_terms::Nothing, have_aux_node_vars::True, equations::AbstractEquations{2}, dg::DG, cache) return nothing end -function calc_sources!(du, u, t, source_terms, have_auxiliary_node_vars::False, +function calc_sources!(du, u, t, source_terms, have_aux_node_vars::False, equations::AbstractEquations{2}, dg::DG, cache) @unpack node_coordinates = cache.elements @@ -1412,15 +1412,15 @@ function calc_sources!(du, u, t, source_terms, have_auxiliary_node_vars::False, return nothing end -function calc_sources!(du, u, t, source_terms, have_auxiliary_node_vars::True, +function calc_sources!(du, u, t, source_terms, have_aux_node_vars::True, equations::AbstractEquations{2}, dg::DG, cache) @unpack node_coordinates = cache.elements - @unpack auxiliary_node_vars = cache.auxiliary_variables + @unpack aux_node_vars = cache.aux_vars @threaded for element in eachelement(dg, cache) for j in eachnode(dg), i in eachnode(dg) u_local = get_node_vars(u, equations, dg, i, j, element) - aux_local = get_auxiliary_node_vars(auxiliary_node_vars, equations, dg, + aux_local = get_aux_node_vars(aux_node_vars, equations, dg, i, j, element) x_local = get_node_coords(node_coordinates, equations, dg, i, j, element) diff --git a/src/solvers/dgsem_tree/dg_2d_compressible_euler.jl b/src/solvers/dgsem_tree/dg_2d_compressible_euler.jl index 0c014abdf69..b2479190a8f 100644 --- a/src/solvers/dgsem_tree/dg_2d_compressible_euler.jl +++ b/src/solvers/dgsem_tree/dg_2d_compressible_euler.jl @@ -67,7 +67,7 @@ end # muladd @inline function flux_differencing_kernel!(_du::PtrArray, u_cons::PtrArray, element, mesh::TreeMesh{2}, nonconservative_terms::False, - have_auxiliary_node_vars::False, + have_aux_node_vars::False, equations::CompressibleEulerEquations2D, volume_flux::typeof(flux_shima_etal_turbo), dg::DGSEM, cache, alpha) @@ -230,7 +230,7 @@ end @inline function flux_differencing_kernel!(_du::PtrArray, u_cons::PtrArray, element, mesh::TreeMesh{2}, nonconservative_terms::False, - have_auxiliary_node_vars::False, + have_aux_node_vars::False, equations::CompressibleEulerEquations2D, volume_flux::typeof(flux_ranocha_turbo), dg::DGSEM, cache, alpha) diff --git a/src/solvers/dgsem_tree/dg_2d_parallel.jl b/src/solvers/dgsem_tree/dg_2d_parallel.jl index 92cec22aa6c..cc8180654cb 100644 --- a/src/solvers/dgsem_tree/dg_2d_parallel.jl +++ b/src/solvers/dgsem_tree/dg_2d_parallel.jl @@ -491,7 +491,7 @@ function rhs!(du, u, t, @trixi_timeit timer() "interface flux" begin calc_interface_flux!(cache.elements.surface_flux_values, mesh, have_nonconservative_terms(equations), - have_auxiliary_node_vars(equations), equations, + have_aux_node_vars(equations), equations, dg.surface_integral, dg, cache) end @@ -529,7 +529,7 @@ function rhs!(du, u, t, @trixi_timeit timer() "MPI interface flux" begin calc_mpi_interface_flux!(cache.elements.surface_flux_values, mesh, have_nonconservative_terms(equations), - have_auxiliary_node_vars(equations), equations, + have_aux_node_vars(equations), equations, dg.surface_integral, dg, cache) end @@ -551,7 +551,7 @@ function rhs!(du, u, t, # Calculate source terms @trixi_timeit timer() "source terms" begin - calc_sources!(du, u, t, source_terms, have_auxiliary_node_vars(equations), + calc_sources!(du, u, t, source_terms, have_aux_node_vars(equations), equations, dg, cache) end @@ -726,7 +726,7 @@ end function calc_mpi_interface_flux!(surface_flux_values, mesh::ParallelTreeMesh{2}, nonconservative_terms::False, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, surface_integral, dg::DG, cache) @unpack surface_flux = surface_integral @unpack u, local_neighbor_ids, orientations, remote_sides = cache.mpi_interfaces @@ -768,11 +768,11 @@ end function calc_mpi_interface_flux!(surface_flux_values, mesh::ParallelTreeMesh{2}, nonconservative_terms::False, - have_auxiliary_node_vars::True, equations, + have_aux_node_vars::True, equations, surface_integral, dg::DG, cache) @unpack surface_flux = surface_integral @unpack u, local_neighbor_ids, orientations, remote_sides = cache.mpi_interfaces - @unpack auxiliary_surface_node_vars = cache.auxiliary_variables + @unpack aux_surface_node_vars = cache.aux_vars @threaded for interface in eachmpiinterface(dg, cache) # Get local neighboring element @@ -796,7 +796,7 @@ function calc_mpi_interface_flux!(surface_flux_values, for i in eachnode(dg) # Call pointwise Riemann solver u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) - aux_ll, aux_rr = get_auxiliary_surface_node_vars(auxiliary_surface_node_vars, + aux_ll, aux_rr = get_aux_surface_node_vars(aux_surface_node_vars, equations, dg, i, interface) flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, @@ -831,14 +831,14 @@ function calc_mpi_mortar_flux!(surface_flux_values, # Because `nonconservative_terms` is `False` the primary and secondary fluxes # are identical. So, we could possibly save on computation and just pass two copies later. orientation = orientations[mortar] - calc_fstar!(fstar_primary_upper, have_auxiliary_node_vars(equations), equations, + calc_fstar!(fstar_primary_upper, have_aux_node_vars(equations), equations, surface_flux, dg, u_upper, mortar, orientation, cache) - calc_fstar!(fstar_primary_lower, have_auxiliary_node_vars(equations), equations, + calc_fstar!(fstar_primary_lower, have_aux_node_vars(equations), equations, surface_flux, dg, u_lower, mortar, orientation, cache) - calc_fstar!(fstar_secondary_upper, have_auxiliary_node_vars(equations), + calc_fstar!(fstar_secondary_upper, have_aux_node_vars(equations), equations, surface_flux, dg, u_upper, mortar, orientation, cache) - calc_fstar!(fstar_secondary_lower, have_auxiliary_node_vars(equations), + calc_fstar!(fstar_secondary_lower, have_aux_node_vars(equations), equations, surface_flux, dg, u_lower, mortar, orientation, cache) diff --git a/src/solvers/dgsem_unstructured/dg_2d.jl b/src/solvers/dgsem_unstructured/dg_2d.jl index 878b57fafc5..db1f6c49b22 100644 --- a/src/solvers/dgsem_unstructured/dg_2d.jl +++ b/src/solvers/dgsem_unstructured/dg_2d.jl @@ -84,7 +84,7 @@ function rhs!(du, u, t, # Calculate source terms @trixi_timeit timer() "source terms" begin - calc_sources!(du, u, t, source_terms, have_auxiliary_node_vars(equations), + calc_sources!(du, u, t, source_terms, have_aux_node_vars(equations), equations, dg, cache) end diff --git a/src/solvers/fdsbp_tree/fdsbp_2d.jl b/src/solvers/fdsbp_tree/fdsbp_2d.jl index ee043d53e7b..633bc4e75a7 100644 --- a/src/solvers/fdsbp_tree/fdsbp_2d.jl +++ b/src/solvers/fdsbp_tree/fdsbp_2d.jl @@ -215,7 +215,7 @@ end function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{2}, nonconservative_terms::False, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, surface_integral::SurfaceIntegralUpwind, dg::FDSBP, cache) @unpack splitting = surface_integral diff --git a/src/time_integration/paired_explicit_runge_kutta/paired_explicit_runge_kutta.jl b/src/time_integration/paired_explicit_runge_kutta/paired_explicit_runge_kutta.jl index a5eff892da5..57cf5a6a0c8 100644 --- a/src/time_integration/paired_explicit_runge_kutta/paired_explicit_runge_kutta.jl +++ b/src/time_integration/paired_explicit_runge_kutta/paired_explicit_runge_kutta.jl @@ -60,7 +60,7 @@ function calculate_cfl(ode_algorithm::AbstractPairedExplicitRK, ode) cfl_number = dt_opt / max_dt(u, t0, mesh, have_constant_speed(equations), - have_auxiliary_node_vars(equations), + have_aux_node_vars(equations), equations, solver, cache) return cfl_number end diff --git a/src/visualization/utilities.jl b/src/visualization/utilities.jl index 49f688757bd..06128029454 100644 --- a/src/visualization/utilities.jl +++ b/src/visualization/utilities.jl @@ -458,7 +458,7 @@ end # Apply the `solution_variables` function to all node values stored in `u`. @inline function apply_solution_variables(u, solution_variables, - have_auxiliary_node_vars::False, equations, + have_aux_node_vars::False, equations, solver, cache) n_vars_in = nvariables(equations) n_vars = length(solution_variables(get_node_vars(u, equations, solver), @@ -474,24 +474,24 @@ end end # Apply the `solution_variables` function to all node values stored in `u`. -# Dispatch on `have_auxiliary_node_vars` to take into account auxiliary variables. +# Dispatch on `have_aux_node_vars` to take into account auxiliary variables. @inline function apply_solution_variables(u, solution_variables, - have_auxiliary_node_vars::True, equations, + have_aux_node_vars::True, equations, solver, cache) - @unpack auxiliary_node_vars = cache.auxiliary_variables + @unpack aux_node_vars = cache.aux_vars n_vars_in = nvariables(equations) - n_vars_aux = n_auxiliary_node_vars(equations) + n_vars_aux = n_aux_node_vars(equations) n_vars = length(solution_variables(get_node_vars(u, equations, solver), - get_auxiliary_node_vars(auxiliary_node_vars, + get_aux_node_vars(aux_node_vars, equations, solver), equations)) raw_data = Array{eltype(u)}(undef, n_vars, Base.tail(size(u))...) reshaped_u = reshape(u, n_vars_in, :) reshaped_r = reshape(raw_data, n_vars, :) - reshaped_aux = reshape(auxiliary_node_vars, n_vars_aux, :) + reshaped_aux = reshape(aux_node_vars, n_vars_aux, :) for idx in axes(reshaped_u, 2) u_node = get_node_vars(reshaped_u, equations, solver, idx) - aux_node = get_auxiliary_node_vars(reshaped_aux, equations, solver, idx) + aux_node = get_aux_node_vars(reshaped_aux, equations, solver, idx) reshaped_r[:, idx] = solution_variables(u_node, aux_node, equations) end return raw_data @@ -515,7 +515,7 @@ function get_unstructured_data(u, solution_variables, mesh, equations, solver, c # Ref(equations)))) # n_vars = size(raw_data, 1) raw_data = apply_solution_variables(u, solution_variables, - have_auxiliary_node_vars(equations), + have_aux_node_vars(equations), equations, solver, cache) n_vars = size(raw_data, 1) end diff --git a/test/test_performance_specializations_2d.jl b/test/test_performance_specializations_2d.jl index 91ae68e89d7..846244e7aa7 100644 --- a/test/test_performance_specializations_2d.jl +++ b/test/test_performance_specializations_2d.jl @@ -27,12 +27,12 @@ isdir(outdir) && rm(outdir, recursive = true) u = Trixi.wrap_array(u_ode, semi) du = Trixi.wrap_array(du_ode, semi) nonconservative_terms = Trixi.have_nonconservative_terms(semi.equations) - have_auxiliary_node_vars = Trixi.have_auxiliary_node_vars(semi.equations) + have_aux_node_vars = Trixi.have_aux_node_vars(semi.equations) # Call the optimized default version du .= 0 Trixi.flux_differencing_kernel!(du, u, 1, semi.mesh, - nonconservative_terms, have_auxiliary_node_vars, + nonconservative_terms, have_aux_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) @@ -43,11 +43,11 @@ isdir(outdir) && rm(outdir, recursive = true) du .= 0 invoke(Trixi.flux_differencing_kernel!, Tuple{typeof(du), typeof(u), Integer, typeof(semi.mesh), - typeof(nonconservative_terms), typeof(have_auxiliary_node_vars), + typeof(nonconservative_terms), typeof(have_aux_node_vars), typeof(semi.equations), Function, typeof(semi.solver), typeof(semi.cache), Bool}, du, u, 1, semi.mesh, - nonconservative_terms, have_auxiliary_node_vars, semi.equations, + nonconservative_terms, have_aux_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, 1] @@ -69,12 +69,12 @@ end u = Trixi.wrap_array(u_ode, semi) du = Trixi.wrap_array(du_ode, semi) nonconservative_terms = Trixi.have_nonconservative_terms(semi.equations) - have_auxiliary_node_vars = Trixi.have_auxiliary_node_vars(semi.equations) + have_aux_node_vars = Trixi.have_aux_node_vars(semi.equations) # Call the optimized default version du .= 0 Trixi.flux_differencing_kernel!(du, u, 1, semi.mesh, - nonconservative_terms, have_auxiliary_node_vars, + nonconservative_terms, have_aux_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) @@ -85,11 +85,11 @@ end du .= 0 invoke(Trixi.flux_differencing_kernel!, Tuple{typeof(du), typeof(u), Integer, typeof(semi.mesh), - typeof(nonconservative_terms), typeof(have_auxiliary_node_vars), + typeof(nonconservative_terms), typeof(have_aux_node_vars), typeof(semi.equations), Function, typeof(semi.solver), typeof(semi.cache), Bool}, du, u, 1, semi.mesh, - nonconservative_terms, have_auxiliary_node_vars, semi.equations, + nonconservative_terms, have_aux_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, 1] @@ -112,12 +112,12 @@ end u = Trixi.wrap_array(u_ode, semi) du = Trixi.wrap_array(du_ode, semi) nonconservative_terms = Trixi.have_nonconservative_terms(semi.equations) - have_auxiliary_node_vars = Trixi.have_auxiliary_node_vars(semi.equations) + have_aux_node_vars = Trixi.have_aux_node_vars(semi.equations) # Call the optimized default version du .= 0 Trixi.flux_differencing_kernel!(du, u, 1, semi.mesh, - nonconservative_terms, have_auxiliary_node_vars, + nonconservative_terms, have_aux_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) @@ -128,11 +128,11 @@ end du .= 0 invoke(Trixi.flux_differencing_kernel!, Tuple{typeof(du), typeof(u), Integer, typeof(semi.mesh), - typeof(nonconservative_terms), typeof(have_auxiliary_node_vars), + typeof(nonconservative_terms), typeof(have_aux_node_vars), typeof(semi.equations), Function, typeof(semi.solver), typeof(semi.cache), Bool}, du, u, 1, semi.mesh, - nonconservative_terms, have_auxiliary_node_vars, semi.equations, + nonconservative_terms, have_aux_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, 1] @@ -154,12 +154,12 @@ end u = Trixi.wrap_array(u_ode, semi) du = Trixi.wrap_array(du_ode, semi) nonconservative_terms = Trixi.have_nonconservative_terms(semi.equations) - have_auxiliary_node_vars = Trixi.have_auxiliary_node_vars(semi.equations) + have_aux_node_vars = Trixi.have_aux_node_vars(semi.equations) # Call the optimized default version du .= 0 Trixi.flux_differencing_kernel!(du, u, 1, semi.mesh, - nonconservative_terms, have_auxiliary_node_vars, + nonconservative_terms, have_aux_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) @@ -170,11 +170,11 @@ end du .= 0 invoke(Trixi.flux_differencing_kernel!, Tuple{typeof(du), typeof(u), Integer, typeof(semi.mesh), - typeof(nonconservative_terms), typeof(have_auxiliary_node_vars), + typeof(nonconservative_terms), typeof(have_aux_node_vars), typeof(semi.equations), Function, typeof(semi.solver), typeof(semi.cache), Bool}, du, u, 1, semi.mesh, - nonconservative_terms, have_auxiliary_node_vars, semi.equations, + nonconservative_terms, have_aux_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, 1] From 0b2a08df37ff26045f430074e40999e92e69b893 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 7 May 2025 17:41:05 +0200 Subject: [PATCH 20/83] add comment that only TreeMesh2D is currently supported --- src/equations/equations.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/equations/equations.jl b/src/equations/equations.jl index 5c16f98d484..85b97905289 100644 --- a/src/equations/equations.jl +++ b/src/equations/equations.jl @@ -320,6 +320,7 @@ have_constant_speed(::AbstractEquations) = False() Trait function determining whether `equations` need to access additional auxiliary variables. The return value will be `True()` or `False()` to allow dispatching on the return type. +Currently, only TreeMesh in 2D is supported. """ have_aux_node_vars(::AbstractEquations) = False() """ From 14868f305d17ab476cc6a7e87168cca0300d66c7 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 7 May 2025 17:42:37 +0200 Subject: [PATCH 21/83] comment --- src/equations/equations.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/equations/equations.jl b/src/equations/equations.jl index 85b97905289..09fdee8b271 100644 --- a/src/equations/equations.jl +++ b/src/equations/equations.jl @@ -327,7 +327,7 @@ have_aux_node_vars(::AbstractEquations) = False() n_aux_node_vars(equations) Number of auxiliary variables used by `equations`. This function needs to be specialized -only if equations has auxiliary variables. +only if `equations` has auxiliary variables. """ function n_aux_node_vars end @inline eachauxvariable(equations::AbstractEquations) = Base.OneTo(n_aux_node_vars(equations)) From 64b4f51e57ae3eef232144483baf7497e7d445fb Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 7 May 2025 17:43:33 +0200 Subject: [PATCH 22/83] fmt --- src/callbacks_step/stepsize_dg2d.jl | 2 +- .../semidiscretization_hyperbolic.jl | 2 +- src/solvers/dg.jl | 6 +- src/solvers/dgsem_p4est/dg_2d.jl | 3 +- src/solvers/dgsem_tree/containers.jl | 62 +++++++++---------- src/solvers/dgsem_tree/containers_2d.jl | 30 ++++----- src/solvers/dgsem_tree/dg_2d.jl | 21 ++++--- src/solvers/dgsem_tree/dg_2d_parallel.jl | 4 +- src/visualization/utilities.jl | 2 +- 9 files changed, 67 insertions(+), 65 deletions(-) diff --git a/src/callbacks_step/stepsize_dg2d.jl b/src/callbacks_step/stepsize_dg2d.jl index 716e5ed4832..51bf06bdf75 100644 --- a/src/callbacks_step/stepsize_dg2d.jl +++ b/src/callbacks_step/stepsize_dg2d.jl @@ -41,7 +41,7 @@ function max_dt(u, t, mesh::TreeMesh{2}, for j in eachnode(dg), i in eachnode(dg) u_node = get_node_vars(u, equations, dg, i, j, element) aux_node = get_aux_node_vars(aux_node_vars, - equations, dg, i, j, element) + equations, dg, i, j, element) lambda1, lambda2 = max_abs_speeds(u_node, aux_node, equations) max_lambda1 = max(max_lambda1, lambda1) max_lambda2 = max(max_lambda2, lambda2) diff --git a/src/semidiscretization/semidiscretization_hyperbolic.jl b/src/semidiscretization/semidiscretization_hyperbolic.jl index 2db50e1d166..c5041be5388 100644 --- a/src/semidiscretization/semidiscretization_hyperbolic.jl +++ b/src/semidiscretization/semidiscretization_hyperbolic.jl @@ -115,7 +115,7 @@ end function create_cache_auxiliary(mesh, equations, solver, cache, have_aux_node_vars::True, auxiliary_field) aux_vars = init_aux_node_vars(mesh, equations, solver, cache, - auxiliary_field) + auxiliary_field) return (; aux_vars) end diff --git a/src/solvers/dg.jl b/src/solvers/dg.jl index 45b72087965..2727eced74b 100644 --- a/src/solvers/dg.jl +++ b/src/solvers/dg.jl @@ -561,7 +561,7 @@ end # Return the auxiliary variables at a given volume node index @inline function get_aux_node_vars(aux_node_vars, equations, ::DG, - indices...) + indices...) return SVector(ntuple(@inline(v->aux_node_vars[v, indices...]), Val(n_aux_node_vars(equations)))) end @@ -579,7 +579,7 @@ end # Return the auxiliary variables at a given surface node index @inline function get_aux_surface_node_vars(aux_surface_node_vars, equations, ::DG, - indices...) + indices...) aux_vars_ll = SVector(ntuple(@inline(v->aux_surface_node_vars[1, v, indices...]), Val(n_aux_node_vars(equations)))) aux_vars_rr = SVector(ntuple(@inline(v->aux_surface_node_vars[2, v, indices...]), @@ -595,7 +595,7 @@ end end @inline function set_aux_node_vars!(aux_node_vars, aux_node, equations, - solver::DG, indices...) + solver::DG, indices...) for v in 1:n_aux_node_vars(equations) aux_node_vars[v, indices...] = aux_node[v] end diff --git a/src/solvers/dgsem_p4est/dg_2d.jl b/src/solvers/dgsem_p4est/dg_2d.jl index 29c31d3f143..2f6a01cb297 100644 --- a/src/solvers/dgsem_p4est/dg_2d.jl +++ b/src/solvers/dgsem_p4est/dg_2d.jl @@ -119,7 +119,8 @@ function prolong2interfaces!(cache, u, end function calc_interface_flux!(surface_flux_values, - mesh::Union{P4estMesh{2}, P4estMeshView{2}, T8codeMesh{2}}, + mesh::Union{P4estMesh{2}, P4estMeshView{2}, + T8codeMesh{2}}, nonconservative_terms, have_aux_node_vars, equations, surface_integral, dg::DG, cache) @unpack neighbor_ids, node_indices = cache.interfaces diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index 8d2c630b5e5..957e107957f 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -77,13 +77,13 @@ mutable struct AuxiliaryNodeVariablesContainer{NDIMS, uEltype <: Real, NDIMSP2, end nvariables(aux_vars::AuxiliaryNodeVariablesContainer) = size(aux_vars.aux_node_vars, - 1) + 1) nnodes(aux_vars::AuxiliaryNodeVariablesContainer) = size(aux_vars.aux_node_vars, - 2) + 2) # Create auxiliary node variable container function init_aux_node_vars(mesh, equations, solver, cache, - auxiliary_field) + auxiliary_field) @unpack elements, interfaces = cache n_elements = nelements(elements) @@ -93,29 +93,29 @@ function init_aux_node_vars(mesh, equations, solver, cache, nan_uEltype = convert(uEltype, NaN) _aux_node_vars = fill(nan_uEltype, - n_aux_node_vars(equations) * - nnodes(solver)^NDIMS * n_elements) + n_aux_node_vars(equations) * + nnodes(solver)^NDIMS * n_elements) aux_node_vars = unsafe_wrap(Array, pointer(_aux_node_vars), - (n_aux_node_vars(equations), - ntuple(_ -> nnodes(solver), NDIMS)..., - n_elements)) + (n_aux_node_vars(equations), + ntuple(_ -> nnodes(solver), NDIMS)..., + n_elements)) _aux_surface_node_vars = fill(nan_uEltype, - 2 * n_aux_node_vars(equations) * - nnodes(solver)^(NDIMS - 1) * - n_interfaces) + 2 * n_aux_node_vars(equations) * + nnodes(solver)^(NDIMS - 1) * + n_interfaces) aux_surface_node_vars = unsafe_wrap(Array, - pointer(_aux_surface_node_vars), - (2, n_aux_node_vars(equations), - ntuple(_ -> nnodes(solver), - NDIMS - 1)..., - n_interfaces)) + pointer(_aux_surface_node_vars), + (2, n_aux_node_vars(equations), + ntuple(_ -> nnodes(solver), + NDIMS - 1)..., + n_interfaces)) aux_vars = AuxiliaryNodeVariablesContainer{NDIMS, uEltype, NDIMS + 2, - typeof(auxiliary_field)}(aux_node_vars, - aux_surface_node_vars, - _aux_node_vars, - _aux_surface_node_vars, - auxiliary_field) + typeof(auxiliary_field)}(aux_node_vars, + aux_surface_node_vars, + _aux_node_vars, + _aux_surface_node_vars, + auxiliary_field) init_aux_node_vars!(aux_vars, mesh, equations, solver, cache) init_auxiliary_surface_node_variables!(aux_vars, mesh, equations, solver, @@ -136,21 +136,21 @@ function Base.resize!(aux_vars::AuxiliaryNodeVariablesContainer{NDIMS}, resize!(_aux_node_vars, n_variables * n_nodes^NDIMS * capacity_node_vars) aux_vars.aux_node_vars = unsafe_wrap(Array, - pointer(_aux_node_vars), - (n_variables, - ntuple(_ -> n_nodes, - NDIMS)..., - capacity_node_vars)) + pointer(_aux_node_vars), + (n_variables, + ntuple(_ -> n_nodes, + NDIMS)..., + capacity_node_vars)) resize!(_aux_surface_node_vars, 2 * n_variables * n_nodes^(NDIMS - 1) * capacity_node_surface_vars) aux_vars.aux_surface_node_vars = unsafe_wrap(Array, - pointer(_aux_surface_node_vars), - (2, n_variables, - ntuple(_ -> n_nodes, - NDIMS - 1)..., - capacity_node_surface_vars)) + pointer(_aux_surface_node_vars), + (2, n_variables, + ntuple(_ -> n_nodes, + NDIMS - 1)..., + capacity_node_surface_vars)) return nothing end diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index 5896629f24c..b229e51cc54 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1425,7 +1425,7 @@ end # Initialize auxiliary node variables (2D implementation) function init_aux_node_vars!(aux_vars, mesh, equations, solver, - cache) + cache) @unpack aux_node_vars, auxiliary_field = aux_vars @unpack node_coordinates = cache.elements @@ -1434,8 +1434,8 @@ function init_aux_node_vars!(aux_vars, mesh, equations, solver, x_local = get_node_coords(node_coordinates, equations, solver, i, j, element) set_aux_node_vars!(aux_node_vars, - auxiliary_field(x_local, equations), - equations, solver, i, j, element) + auxiliary_field(x_local, equations), + equations, solver, i, j, element) end end return nothing @@ -1456,13 +1456,13 @@ function init_auxiliary_surface_node_variables!(aux_vars, mesh, equations, for j in eachnode(solver) for v in axes(aux_surface_node_vars, 2) aux_surface_node_vars[1, v, j, interface] = aux_node_vars[v, - nnodes(solver), - j, - left_element] + nnodes(solver), + j, + left_element] aux_surface_node_vars[2, v, j, interface] = aux_node_vars[v, - 1, - j, - right_element] + 1, + j, + right_element] end end else # if orientations[interface] == 2 @@ -1470,13 +1470,13 @@ function init_auxiliary_surface_node_variables!(aux_vars, mesh, equations, for i in eachnode(solver) for v in axes(aux_surface_node_vars, 2) aux_surface_node_vars[1, v, i, interface] = aux_node_vars[v, - i, - nnodes(solver), - left_element] + i, + nnodes(solver), + left_element] aux_surface_node_vars[2, v, i, interface] = aux_node_vars[v, - i, - 1, - right_element] + i, + 1, + right_element] end end end diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index c412ee062d0..59bb62993a8 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -184,7 +184,8 @@ end function calc_volume_integral!(du, u, mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2}, UnstructuredMesh2D, - P4estMesh{2}, P4estMeshView{2}, T8codeMesh{2}}, + P4estMesh{2}, P4estMeshView{2}, + T8codeMesh{2}}, equations, volume_integral::VolumeIntegralWeakForm, dg::DGSEM, cache) @@ -248,7 +249,7 @@ end for j in eachnode(dg), i in eachnode(dg) u_node = get_node_vars(u, equations, dg, i, j, element) aux_node = get_aux_node_vars(aux_node_vars, - equations, dg, i, j, element) + equations, dg, i, j, element) flux1 = flux(u_node, aux_node, 1, equations) for ii in eachnode(dg) @@ -339,7 +340,7 @@ end for j in eachnode(dg), i in eachnode(dg) u_node = get_node_vars(u, equations, dg, i, j, element) aux_node = get_aux_node_vars(aux_node_vars, equations, dg, - i, j, element) + i, j, element) # All diagonal entries of `derivative_split` are zero. Thus, we can skip # the computation of the diagonal terms. In addition, we use the symmetry @@ -350,7 +351,7 @@ end for ii in (i + 1):nnodes(dg) u_node_ii = get_node_vars(u, equations, dg, ii, j, element) aux_node_ii = get_aux_node_vars(aux_node_vars, equations, dg, - ii, j, element) + ii, j, element) flux1 = volume_flux(u_node, u_node_ii, aux_node, aux_node_ii, 1, equations) multiply_add_to_node_vars!(du, alpha * derivative_split[i, ii], flux1, equations, dg, i, j, element) @@ -362,7 +363,7 @@ end for jj in (j + 1):nnodes(dg) u_node_jj = get_node_vars(u, equations, dg, i, jj, element) aux_node_jj = get_aux_node_vars(aux_node_vars, equations, dg, - i, jj, element) + i, jj, element) flux2 = volume_flux(u_node, u_node_jj, aux_node, aux_node_jj, 2, equations) multiply_add_to_node_vars!(du, alpha * derivative_split[j, jj], flux2, equations, dg, i, j, element) @@ -716,8 +717,8 @@ function calc_interface_flux!(surface_flux_values, # Call pointwise Riemann solver u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) aux_ll, aux_rr = get_aux_surface_node_vars(aux_surface_node_vars, - equations, dg, i, - interface) + equations, dg, i, + interface) flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, orientations[interface], equations) # Copy flux to left and right element storage @@ -908,7 +909,7 @@ function calc_boundary_flux_by_direction!(t, boundary_condition, # Get boundary flux u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, boundary) aux_ll, aux_rr = get_aux_surface_node_vars(aux_surface_node_vars, - equations, dg, i, boundary) + equations, dg, i, boundary) if neighbor_sides[boundary] == 1 # Element is on the left, boundary on the right u_inner = u_ll aux_inner = aux_ll @@ -1238,7 +1239,7 @@ end # Call pointwise two-point numerical flux function u_ll, u_rr = get_surface_node_vars(u_interfaces, equations, dg, i, interface) aux_ll, aux_rr = get_aux_surface_node_vars(aux_surface_node_vars, - equations, dg, i, interface) + equations, dg, i, interface) flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, orientation, equations) # Copy flux to left and right element storage @@ -1421,7 +1422,7 @@ function calc_sources!(du, u, t, source_terms, have_aux_node_vars::True, for j in eachnode(dg), i in eachnode(dg) u_local = get_node_vars(u, equations, dg, i, j, element) aux_local = get_aux_node_vars(aux_node_vars, equations, dg, - i, j, element) + i, j, element) x_local = get_node_coords(node_coordinates, equations, dg, i, j, element) du_local = source_terms(u_local, aux_local, x_local, t, equations) diff --git a/src/solvers/dgsem_tree/dg_2d_parallel.jl b/src/solvers/dgsem_tree/dg_2d_parallel.jl index cc8180654cb..807d27e3ce7 100644 --- a/src/solvers/dgsem_tree/dg_2d_parallel.jl +++ b/src/solvers/dgsem_tree/dg_2d_parallel.jl @@ -797,8 +797,8 @@ function calc_mpi_interface_flux!(surface_flux_values, # Call pointwise Riemann solver u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) aux_ll, aux_rr = get_aux_surface_node_vars(aux_surface_node_vars, - equations, dg, i, - interface) + equations, dg, i, + interface) flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, orientations[interface], equations) diff --git a/src/visualization/utilities.jl b/src/visualization/utilities.jl index 06128029454..aabc9257841 100644 --- a/src/visualization/utilities.jl +++ b/src/visualization/utilities.jl @@ -483,7 +483,7 @@ end n_vars_aux = n_aux_node_vars(equations) n_vars = length(solution_variables(get_node_vars(u, equations, solver), get_aux_node_vars(aux_node_vars, - equations, solver), + equations, solver), equations)) raw_data = Array{eltype(u)}(undef, n_vars, Base.tail(size(u))...) reshaped_u = reshape(u, n_vars_in, :) From 9de7add41630aa058ed2bc4069dcbfd58a68f5b6 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 7 May 2025 17:59:18 +0200 Subject: [PATCH 23/83] rename file as well --- ...uxiliary_variables.jl => acoustic_perturbation_2d_aux_vars.jl} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/equations/{acoustic_perturbation_2d_auxiliary_variables.jl => acoustic_perturbation_2d_aux_vars.jl} (100%) diff --git a/src/equations/acoustic_perturbation_2d_auxiliary_variables.jl b/src/equations/acoustic_perturbation_2d_aux_vars.jl similarity index 100% rename from src/equations/acoustic_perturbation_2d_auxiliary_variables.jl rename to src/equations/acoustic_perturbation_2d_aux_vars.jl From 468a5dbeaead7cc7c1f237668a58231b4b59458b Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Sat, 10 May 2025 00:25:07 +0200 Subject: [PATCH 24/83] add have_aux_node_vars to analysis callback --- src/callbacks_step/analysis.jl | 5 ++-- src/callbacks_step/analysis_dg1d.jl | 7 +++--- src/callbacks_step/analysis_dg2d.jl | 25 +++++++++++++++---- src/callbacks_step/analysis_dg3d.jl | 10 ++++---- src/callbacks_step/analysis_dgmulti.jl | 7 +++--- .../acoustic_perturbation_2d_aux_vars.jl | 2 +- 6 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/callbacks_step/analysis.jl b/src/callbacks_step/analysis.jl index bbc2ac4c8fe..0ae74878623 100644 --- a/src/callbacks_step/analysis.jl +++ b/src/callbacks_step/analysis.jl @@ -617,9 +617,10 @@ end # Trixi.analyze, Trixi.pretty_form_utf, Trixi.pretty_form_ascii function analyze(quantity, du, u, t, semi::AbstractSemidiscretization) mesh, equations, solver, cache = mesh_equations_solver_cache(semi) - analyze(quantity, du, u, t, mesh, equations, solver, cache) + analyze(quantity, du, u, t, mesh, equations, have_aux_node_vars(equations), solver, + cache) end -function analyze(quantity, du, u, t, mesh, equations, solver, cache) +function analyze(quantity, du, u, t, mesh, equations, have_aux_node_vars, solver, cache) integrate(quantity, u, mesh, equations, solver, cache, normalize = true) end pretty_form_utf(quantity) = get_name(quantity) diff --git a/src/callbacks_step/analysis_dg1d.jl b/src/callbacks_step/analysis_dg1d.jl index 444d218f119..0440be0f533 100644 --- a/src/callbacks_step/analysis_dg1d.jl +++ b/src/callbacks_step/analysis_dg1d.jl @@ -182,7 +182,8 @@ function integrate(func::Func, u, end function analyze(::typeof(entropy_timederivative), du, u, t, - mesh::Union{TreeMesh{1}, StructuredMesh{1}}, equations, dg::DG, cache) + mesh::Union{TreeMesh{1}, StructuredMesh{1}}, equations, + have_aux_node_vars::False, dg::DG, cache) # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ integrate_via_indices(u, mesh, equations, dg, cache, du) do u, i, element, equations, dg, du @@ -194,7 +195,7 @@ end function analyze(::Val{:l2_divb}, du, u, t, mesh::TreeMesh{1}, equations::IdealGlmMhdEquations1D, - dg::DG, cache) + have_aux_node_vars::False, dg::DG, cache) integrate_via_indices(u, mesh, equations, dg, cache, dg.basis.derivative_matrix) do u, i, element, equations, dg, derivative_matrix @@ -209,7 +210,7 @@ end function analyze(::Val{:linf_divb}, du, u, t, mesh::TreeMesh{1}, equations::IdealGlmMhdEquations1D, - dg::DG, cache) + have_aux_node_vars::False, dg::DG, cache) @unpack derivative_matrix, weights = dg.basis # integrate over all elements to get the divergence-free condition errors diff --git a/src/callbacks_step/analysis_dg2d.jl b/src/callbacks_step/analysis_dg2d.jl index dd166bbe389..e8553560ad3 100644 --- a/src/callbacks_step/analysis_dg2d.jl +++ b/src/callbacks_step/analysis_dg2d.jl @@ -274,7 +274,7 @@ end function analyze(::typeof(entropy_timederivative), du, u, t, mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - equations, dg::DG, cache) + equations, have_aux_node_vars::False, dg::DG, cache) # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ integrate_via_indices(u, mesh, equations, dg, cache, du) do u, i, j, element, equations, dg, du @@ -284,9 +284,24 @@ function analyze(::typeof(entropy_timederivative), du, u, t, end end +function analyze(::typeof(entropy_timederivative), du, u, t, + mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2}, + UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, + equations, have_auxiliary_node_vars::True, dg::DG, cache) + @unpack aux_node_vars = cache.aux_vars + # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ + integrate_via_indices(u, mesh, equations, dg, cache, + du) do u, i, j, element, equations, dg, du + u_node = get_node_vars(u, equations, dg, i, j, element) + aux_node = get_aux_node_vars(aux_node_vars, equations, dg, i, j, element) + du_node = get_node_vars(du, equations, dg, i, j, element) + dot(cons2entropy(u_node, aux_node, equations), du_node) + end +end + function analyze(::Val{:l2_divb}, du, u, t, mesh::TreeMesh{2}, - equations, dg::DGSEM, cache) + equations, have_aux_node_vars::False, dg::DGSEM, cache) integrate_via_indices(u, mesh, equations, dg, cache, cache, dg.basis.derivative_matrix) do u, i, j, element, equations, dg, cache, derivative_matrix @@ -309,7 +324,7 @@ end function analyze(::Val{:l2_divb}, du, u, t, mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - equations, dg::DGSEM, cache) + equations, have_aux_node_vars::False, dg::DGSEM, cache) @unpack contravariant_vectors = cache.elements integrate_via_indices(u, mesh, equations, dg, cache, cache, dg.basis.derivative_matrix) do u, i, j, element, equations, @@ -338,7 +353,7 @@ end function analyze(::Val{:linf_divb}, du, u, t, mesh::TreeMesh{2}, - equations, dg::DGSEM, cache) + equations, have_aux_node_vars::False, dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis # integrate over all elements to get the divergence-free condition errors @@ -367,7 +382,7 @@ end function analyze(::Val{:linf_divb}, du, u, t, mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - equations, dg::DGSEM, cache) + equations, have_aux_node_vars::False, dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis @unpack contravariant_vectors = cache.elements diff --git a/src/callbacks_step/analysis_dg3d.jl b/src/callbacks_step/analysis_dg3d.jl index c5011d558df..65ea89b6dd1 100644 --- a/src/callbacks_step/analysis_dg3d.jl +++ b/src/callbacks_step/analysis_dg3d.jl @@ -298,7 +298,7 @@ end function analyze(::typeof(entropy_timederivative), du, u, t, mesh::Union{TreeMesh{3}, StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - equations, dg::DG, cache) + equations, have_aux_node_vars::False, dg::DG, cache) # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ integrate_via_indices(u, mesh, equations, dg, cache, du) do u, i, j, k, element, equations, dg, du @@ -309,7 +309,7 @@ function analyze(::typeof(entropy_timederivative), du, u, t, end function analyze(::Val{:l2_divb}, du, u, t, - mesh::TreeMesh{3}, equations, + mesh::TreeMesh{3}, equations, have_aux_node_vars::False, dg::DGSEM, cache) integrate_via_indices(u, mesh, equations, dg, cache, cache, dg.basis.derivative_matrix) do u, i, j, k, element, equations, @@ -335,7 +335,7 @@ end function analyze(::Val{:l2_divb}, du, u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - equations, + equations, have_aux_node_vars::False, dg::DGSEM, cache) @unpack contravariant_vectors = cache.elements integrate_via_indices(u, mesh, equations, dg, cache, cache, @@ -372,7 +372,7 @@ function analyze(::Val{:l2_divb}, du, u, t, end function analyze(::Val{:linf_divb}, du, u, t, - mesh::TreeMesh{3}, equations, + mesh::TreeMesh{3}, equations, have_aux_node_vars::False, dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis @@ -409,7 +409,7 @@ end function analyze(::Val{:linf_divb}, du, u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - equations, + equations, have_aux_node_vars::False, dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis @unpack contravariant_vectors = cache.elements diff --git a/src/callbacks_step/analysis_dgmulti.jl b/src/callbacks_step/analysis_dgmulti.jl index b3223340ae5..778643b9792 100644 --- a/src/callbacks_step/analysis_dgmulti.jl +++ b/src/callbacks_step/analysis_dgmulti.jl @@ -45,7 +45,8 @@ function integrate(func::Func, u, end function analyze(::typeof(entropy_timederivative), du, u, t, - mesh::DGMultiMesh, equations, dg::DGMulti, cache) + mesh::DGMultiMesh, equations, have_aux_node_vars::False, dg::DGMulti, + cache) rd = dg.basis md = mesh.md @unpack u_values = cache @@ -93,7 +94,7 @@ get_component(u::AbstractArray{<:SVector}, i::Int) = getindex.(u, i) function analyze(::Val{:l2_divb}, du, u, t, mesh::DGMultiMesh, equations::IdealGlmMhdEquations2D, - dg::DGMulti, cache) + have_aux_node_vars::False, dg::DGMulti, cache) @unpack md = mesh rd = dg.basis B1 = get_component(u, 6) @@ -117,7 +118,7 @@ end function analyze(::Val{:linf_divb}, du, u, t, mesh::DGMultiMesh, equations::IdealGlmMhdEquations2D, - dg::DGMulti, cache) + have_aux_node_vars::False, dg::DGMulti, cache) B1 = get_component(u, 6) B2 = get_component(u, 7) B = (B1, B2) diff --git a/src/equations/acoustic_perturbation_2d_aux_vars.jl b/src/equations/acoustic_perturbation_2d_aux_vars.jl index 31855d53e19..30a45236148 100644 --- a/src/equations/acoustic_perturbation_2d_aux_vars.jl +++ b/src/equations/acoustic_perturbation_2d_aux_vars.jl @@ -367,5 +367,5 @@ end end # Convert conservative variables to entropy variables -@inline cons2entropy(u, equations::AcousticPerturbationEquations2DAuxVars) = u +@inline cons2entropy(u, aux, equations::AcousticPerturbationEquations2DAuxVars) = u end # @muladd From 1d739fd4f8c3c183659b9d0849811ebba1bf6d9a Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Sat, 10 May 2025 00:26:34 +0200 Subject: [PATCH 25/83] renamed --- src/callbacks_step/analysis_dg2d.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/callbacks_step/analysis_dg2d.jl b/src/callbacks_step/analysis_dg2d.jl index e8553560ad3..7cf3e695082 100644 --- a/src/callbacks_step/analysis_dg2d.jl +++ b/src/callbacks_step/analysis_dg2d.jl @@ -287,7 +287,7 @@ end function analyze(::typeof(entropy_timederivative), du, u, t, mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - equations, have_auxiliary_node_vars::True, dg::DG, cache) + equations, have_aux_node_vars::True, dg::DG, cache) @unpack aux_node_vars = cache.aux_vars # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ integrate_via_indices(u, mesh, equations, dg, cache, From 2e19fe7f6e552a6922bc75fc3f266482631c8b90 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Sat, 10 May 2025 00:47:02 +0200 Subject: [PATCH 26/83] rename init_auxiliary_surface_node_variables --- src/solvers/dgsem_tree/containers.jl | 6 ++---- src/solvers/dgsem_tree/containers_2d.jl | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index 957e107957f..f3db7e1a61e 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -40,8 +40,7 @@ function reinitialize_containers!(mesh::TreeMesh, equations, dg::DGSEM, cache) resize!(aux_vars, length(leaf_cell_ids), count_required_interfaces(mesh, leaf_cell_ids)) init_aux_node_vars!(aux_vars, mesh, equations, dg, cache) - init_auxiliary_surface_node_variables!(aux_vars, mesh, equations, dg, - cache) + init_aux_surface_node_vars!(aux_vars, mesh, equations, dg, cache) end if mpi_isparallel() @@ -118,8 +117,7 @@ function init_aux_node_vars(mesh, equations, solver, cache, auxiliary_field) init_aux_node_vars!(aux_vars, mesh, equations, solver, cache) - init_auxiliary_surface_node_variables!(aux_vars, mesh, equations, solver, - cache) + init_aux_surface_node_vars!(aux_vars, mesh, equations, solver, cache) return aux_vars end diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index b229e51cc54..47949e594ba 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1442,8 +1442,7 @@ function init_aux_node_vars!(aux_vars, mesh, equations, solver, end # Initialize auxiliary surface node variables (2D implementation) -function init_auxiliary_surface_node_variables!(aux_vars, mesh, equations, - solver, cache) +function init_aux_surface_node_vars!(aux_vars, mesh, equations, solver, cache) @unpack aux_node_vars, aux_surface_node_vars = aux_vars @unpack orientations, neighbor_ids = cache.interfaces From 258c5e4666937591fc2bbddfbd0308ee27d23600 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Mon, 12 May 2025 09:37:37 +0200 Subject: [PATCH 27/83] more aux renaming --- .../elixir_acoustics_convergence_auxvars.jl | 2 +- ...elixir_acoustics_gauss_wall_amr_auxvars.jl | 2 +- .../elixir_acoustics_gauss_wall_auxvars.jl | 2 +- .../semidiscretization_hyperbolic.jl | 19 +++++++------- src/solvers/dgsem_tree/containers.jl | 25 ++++++++----------- src/solvers/dgsem_tree/containers_2d.jl | 4 +-- 6 files changed, 24 insertions(+), 30 deletions(-) diff --git a/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl b/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl index 6dc5fbb48a4..fc0d7eb31c9 100644 --- a/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl +++ b/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl @@ -29,7 +29,7 @@ mesh = TreeMesh(coordinates_min, coordinates_max, # A semidiscretization collects data structures and functions for the spatial discretization semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, source_terms = source_terms_convergence_test, - auxiliary_field = auxiliary_variables_mean_values) + aux_field = auxiliary_variables_mean_values) ############################################################################### # ODE solvers, callbacks etc. diff --git a/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_amr_auxvars.jl b/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_amr_auxvars.jl index d62a3e4a30a..6377e452910 100644 --- a/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_amr_auxvars.jl +++ b/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_amr_auxvars.jl @@ -51,7 +51,7 @@ end # A semidiscretization collects data structures and functions for the spatial discretization semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, boundary_conditions = boundary_condition_wall, - auxiliary_field = auxiliary_variables_mean_values) + aux_field = auxiliary_variables_mean_values) ############################################################################### # ODE solvers, callbacks etc. diff --git a/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_auxvars.jl b/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_auxvars.jl index a4673035947..c22a637fcaa 100644 --- a/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_auxvars.jl +++ b/examples/tree_2d_dgsem/elixir_acoustics_gauss_wall_auxvars.jl @@ -46,7 +46,7 @@ end # A semidiscretization collects data structures and functions for the spatial discretization semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, boundary_conditions = boundary_condition_wall, - auxiliary_field = auxiliary_variables_mean_values) + aux_field = auxiliary_variables_mean_values) ############################################################################### # ODE solvers, callbacks etc. diff --git a/src/semidiscretization/semidiscretization_hyperbolic.jl b/src/semidiscretization/semidiscretization_hyperbolic.jl index c5041be5388..879126ad3c5 100644 --- a/src/semidiscretization/semidiscretization_hyperbolic.jl +++ b/src/semidiscretization/semidiscretization_hyperbolic.jl @@ -65,7 +65,7 @@ function SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver # while `uEltype` is used as element type of solutions etc. RealT = real(solver), uEltype = RealT, initial_cache = NamedTuple(), - auxiliary_field = nothing) + aux_field = nothing) @assert ndims(mesh) == ndims(equations) cache = (; create_cache(mesh, equations, solver, RealT, uEltype)..., @@ -73,9 +73,8 @@ function SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver # Add specialized parts of the cache for auxiliary node variables cache = (; cache..., - create_cache_auxiliary(mesh, equations, solver, cache, - have_aux_node_vars(equations), - auxiliary_field)...) + create_cache_aux(mesh, equations, solver, cache, have_aux_node_vars(equations), + aux_field)...) _boundary_conditions = digest_boundary_conditions(boundary_conditions, mesh, solver, cache) @@ -112,16 +111,16 @@ function remake(semi::SemidiscretizationHyperbolic; uEltype = real(semi.solver), end # If there are auxiliary variables, initialize them -function create_cache_auxiliary(mesh, equations, solver, cache, - have_aux_node_vars::True, auxiliary_field) +function create_cache_aux(mesh, equations, solver, cache, have_aux_node_vars::True, + aux_field) aux_vars = init_aux_node_vars(mesh, equations, solver, cache, - auxiliary_field) + aux_field) return (; aux_vars) end # Do nothing if there are no auxiliary variables -function create_cache_auxiliary(mesh, equations, solver, cache, - have_aux_node_vars::False, auxiliary_field) +function create_cache_aux(mesh, equations, solver, cache, have_aux_node_vars::False, + aux_field) return NamedTuple() end @@ -340,7 +339,7 @@ function Base.show(io::IO, ::MIME"text/plain", semi::SemidiscretizationHyperboli summary_line(io, "source terms", semi.source_terms) if have_aux_node_vars(semi.equations) == Trixi.True() summary_line(io, "auxiliary variables", - semi.cache.aux_vars.auxiliary_field) + semi.cache.aux_vars.aux_field) end summary_line(io, "solver", semi.solver |> typeof |> nameof) summary_line(io, "total #DOFs per field", ndofsglobal(semi)) diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index f3db7e1a61e..a6d0b506c22 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -62,8 +62,7 @@ function reinitialize_containers!(mesh::TreeMesh, equations, dg::DGSEM, cache) end # Container for storing values of auxiliary variables at volume/surface quadrature nodes -mutable struct AuxiliaryNodeVariablesContainer{NDIMS, uEltype <: Real, NDIMSP2, - AuxiliaryVariables} +mutable struct AuxNodeVarsContainer{NDIMS, uEltype <: Real, NDIMSP2, AuxField} aux_node_vars::Array{uEltype, NDIMSP2} # [var, i, j, element] aux_surface_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] @@ -72,17 +71,15 @@ mutable struct AuxiliaryNodeVariablesContainer{NDIMS, uEltype <: Real, NDIMSP2, _aux_surface_node_vars::Vector{uEltype} # save initialization function - auxiliary_field::AuxiliaryVariables + aux_field::AuxField end -nvariables(aux_vars::AuxiliaryNodeVariablesContainer) = size(aux_vars.aux_node_vars, - 1) -nnodes(aux_vars::AuxiliaryNodeVariablesContainer) = size(aux_vars.aux_node_vars, - 2) +nvariables(aux_vars::AuxNodeVarsContainer) = size(aux_vars.aux_node_vars, 1) +nnodes(aux_vars::AuxNodeVarsContainer) = size(aux_vars.aux_node_vars, 2) # Create auxiliary node variable container function init_aux_node_vars(mesh, equations, solver, cache, - auxiliary_field) + aux_field) @unpack elements, interfaces = cache n_elements = nelements(elements) @@ -109,12 +106,10 @@ function init_aux_node_vars(mesh, equations, solver, cache, NDIMS - 1)..., n_interfaces)) - aux_vars = AuxiliaryNodeVariablesContainer{NDIMS, uEltype, NDIMS + 2, - typeof(auxiliary_field)}(aux_node_vars, - aux_surface_node_vars, - _aux_node_vars, - _aux_surface_node_vars, - auxiliary_field) + aux_vars = AuxNodeVarsContainer{NDIMS, uEltype, NDIMS + 2, typeof(aux_field)} + (aux_node_vars, aux_surface_node_vars, + _aux_node_vars,_aux_surface_node_vars, + aux_field) init_aux_node_vars!(aux_vars, mesh, equations, solver, cache) init_aux_surface_node_vars!(aux_vars, mesh, equations, solver, cache) @@ -126,7 +121,7 @@ end # them whenever needed. Then, we reuse the same memory by # `unsafe_wrap`ping multi-dimensional `Array`s around the # internal storage. -function Base.resize!(aux_vars::AuxiliaryNodeVariablesContainer{NDIMS}, +function Base.resize!(aux_vars::AuxNodeVarsContainer{NDIMS}, capacity_node_vars, capacity_node_surface_vars) where {NDIMS} @unpack _aux_node_vars, _aux_surface_node_vars = aux_vars n_nodes = nnodes(aux_vars) diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index 47949e594ba..4180e378cec 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1426,7 +1426,7 @@ end # Initialize auxiliary node variables (2D implementation) function init_aux_node_vars!(aux_vars, mesh, equations, solver, cache) - @unpack aux_node_vars, auxiliary_field = aux_vars + @unpack aux_node_vars, aux_field = aux_vars @unpack node_coordinates = cache.elements @threaded for element in eachelement(solver, cache) @@ -1434,7 +1434,7 @@ function init_aux_node_vars!(aux_vars, mesh, equations, solver, x_local = get_node_coords(node_coordinates, equations, solver, i, j, element) set_aux_node_vars!(aux_node_vars, - auxiliary_field(x_local, equations), + aux_field(x_local, equations), equations, solver, i, j, element) end end From 1a32cf490c0f513fac28c67d2b48a542c99edf8c Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 16 May 2025 14:13:13 +0200 Subject: [PATCH 28/83] add aux_boundary_node_vars --- .../semidiscretization_hyperbolic.jl | 3 +- src/solvers/dgsem_tree/containers.jl | 71 +++++++++++++++---- src/solvers/dgsem_tree/containers_2d.jl | 61 ++++++++++------ src/solvers/dgsem_tree/dg_2d.jl | 8 +-- 4 files changed, 105 insertions(+), 38 deletions(-) diff --git a/src/semidiscretization/semidiscretization_hyperbolic.jl b/src/semidiscretization/semidiscretization_hyperbolic.jl index 879126ad3c5..a1f1cdec85b 100644 --- a/src/semidiscretization/semidiscretization_hyperbolic.jl +++ b/src/semidiscretization/semidiscretization_hyperbolic.jl @@ -113,8 +113,7 @@ end # If there are auxiliary variables, initialize them function create_cache_aux(mesh, equations, solver, cache, have_aux_node_vars::True, aux_field) - aux_vars = init_aux_node_vars(mesh, equations, solver, cache, - aux_field) + aux_vars = init_aux_vars(mesh, equations, solver, cache, aux_field) return (; aux_vars) end diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index a6d0b506c22..14b460f7085 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -39,8 +39,7 @@ function reinitialize_containers!(mesh::TreeMesh, equations, dg::DGSEM, cache) @unpack aux_vars = cache resize!(aux_vars, length(leaf_cell_ids), count_required_interfaces(mesh, leaf_cell_ids)) - init_aux_node_vars!(aux_vars, mesh, equations, dg, cache) - init_aux_surface_node_vars!(aux_vars, mesh, equations, dg, cache) + init_aux_vars!(aux_vars, mesh, equations, dg, cache) end if mpi_isparallel() @@ -63,12 +62,14 @@ end # Container for storing values of auxiliary variables at volume/surface quadrature nodes mutable struct AuxNodeVarsContainer{NDIMS, uEltype <: Real, NDIMSP2, AuxField} - aux_node_vars::Array{uEltype, NDIMSP2} # [var, i, j, element] - aux_surface_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] + aux_node_vars::Array{uEltype, NDIMSP2} # [var, i, j, element] + aux_surface_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] + aux_boundary_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] # internal `resize!`able storage _aux_node_vars::Vector{uEltype} _aux_surface_node_vars::Vector{uEltype} + _aux_boundary_node_vars::Vector{uEltype} # save initialization function aux_field::AuxField @@ -78,12 +79,12 @@ nvariables(aux_vars::AuxNodeVarsContainer) = size(aux_vars.aux_node_vars, 1) nnodes(aux_vars::AuxNodeVarsContainer) = size(aux_vars.aux_node_vars, 2) # Create auxiliary node variable container -function init_aux_node_vars(mesh, equations, solver, cache, - aux_field) - @unpack elements, interfaces = cache +function init_aux_vars(mesh, equations, solver, cache, aux_field) + @unpack elements, interfaces, boundaries = cache n_elements = nelements(elements) n_interfaces = ninterfaces(interfaces) + n_boundaries = nboundaries(boundaries) NDIMS = ndims(mesh) uEltype = eltype(elements) nan_uEltype = convert(uEltype, NaN) @@ -105,15 +106,51 @@ function init_aux_node_vars(mesh, equations, solver, cache, ntuple(_ -> nnodes(solver), NDIMS - 1)..., n_interfaces)) + _aux_boundary_node_vars = fill(nan_uEltype, + 2 * n_aux_node_vars(equations) * + nnodes(solver)^(NDIMS - 1) * + n_boundaries) + aux_boundary_node_vars = unsafe_wrap(Array, + pointer(_aux_boundary_node_vars), + (2, n_aux_node_vars(equations), + ntuple(_ -> nnodes(solver), + NDIMS - 1)..., + n_boundaries)) - aux_vars = AuxNodeVarsContainer{NDIMS, uEltype, NDIMS + 2, typeof(aux_field)} - (aux_node_vars, aux_surface_node_vars, + aux_vars = AuxNodeVarsContainer{NDIMS, uEltype, NDIMS + 2, typeof(aux_field)}( + aux_node_vars, aux_surface_node_vars, + aux_boundary_node_vars, _aux_node_vars,_aux_surface_node_vars, - aux_field) + _aux_boundary_node_vars, + aux_field) + init_aux_vars!(aux_vars, mesh, equations, solver, cache) + return aux_vars +end +function init_aux_vars!(aux_vars, mesh, equations, solver, cache) init_aux_node_vars!(aux_vars, mesh, equations, solver, cache) init_aux_surface_node_vars!(aux_vars, mesh, equations, solver, cache) - return aux_vars + init_aux_boundary_node_vars!(aux_vars, mesh, equations, solver, cache) +end + +# Initialize auxiliary node variables (generic implementation) +function init_aux_node_vars!(aux_vars, mesh, equations, solver, cache) + @unpack aux_node_vars, aux_field = aux_vars + @unpack node_coordinates = cache.elements + + # all permutations of nodes indices for arbitrary dimension + node_cis = CartesianIndices(ntuple(i -> nnodes(solver), ndims(mesh))) + + @threaded for element in eachelement(solver, cache) + for node_ci in node_cis + x_local = get_node_coords(node_coordinates, equations, solver, + node_ci, element) + set_aux_node_vars!(aux_node_vars, + aux_field(x_local, equations), + equations, solver, node_ci, element) + end + end + return nothing end # Only one-dimensional `Array`s are `resize!`able in Julia. @@ -122,7 +159,8 @@ end # `unsafe_wrap`ping multi-dimensional `Array`s around the # internal storage. function Base.resize!(aux_vars::AuxNodeVarsContainer{NDIMS}, - capacity_node_vars, capacity_node_surface_vars) where {NDIMS} + capacity_node_vars, capacity_node_surface_vars, + capacity_node_boundary_vars) where {NDIMS} @unpack _aux_node_vars, _aux_surface_node_vars = aux_vars n_nodes = nnodes(aux_vars) n_variables = nvariables(aux_vars) @@ -144,6 +182,15 @@ function Base.resize!(aux_vars::AuxNodeVarsContainer{NDIMS}, ntuple(_ -> n_nodes, NDIMS - 1)..., capacity_node_surface_vars)) + resize!(_aux_boundary_node_vars, + 2 * n_variables * n_nodes^(NDIMS - 1) * + capacity_node_boundary_vars) + aux_vars.aux_surface_node_vars = unsafe_wrap(Array, + pointer(_aux_boundary_node_vars), + (2, n_variables, + ntuple(_ -> n_nodes, + NDIMS - 1)..., + capacity_node_boundary_vars)) return nothing end diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index 4180e378cec..5b6f95d99a0 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1423,26 +1423,9 @@ function Base.resize!(container::ContainerSubcellLimiterIDP2D, capacity) return nothing end -# Initialize auxiliary node variables (2D implementation) -function init_aux_node_vars!(aux_vars, mesh, equations, solver, - cache) - @unpack aux_node_vars, aux_field = aux_vars - @unpack node_coordinates = cache.elements - - @threaded for element in eachelement(solver, cache) - for j in eachnode(solver), i in eachnode(solver) - x_local = get_node_coords(node_coordinates, equations, solver, - i, j, element) - set_aux_node_vars!(aux_node_vars, - aux_field(x_local, equations), - equations, solver, i, j, element) - end - end - return nothing -end - -# Initialize auxiliary surface node variables (2D implementation) -function init_aux_surface_node_vars!(aux_vars, mesh, equations, solver, cache) +# Initialize auxiliary surface node variables +# 2D TreeMesh implementation, similar to prolong2interfaces +function init_aux_surface_node_vars!(aux_vars, mesh::TreeMesh2D, equations, solver, cache) @unpack aux_node_vars, aux_surface_node_vars = aux_vars @unpack orientations, neighbor_ids = cache.interfaces @@ -1482,4 +1465,42 @@ function init_aux_surface_node_vars!(aux_vars, mesh, equations, solver, cache) end return nothing end + +# Initialize auxiliary boundary node variables +# 2D TreeMesh implementation, similar to prolong2boundaries +function init_aux_boundary_node_vars!(aux_vars, mesh::TreeMesh2D, equations, solver, cache) + @unpack aux_node_vars, aux_boundary_node_vars = aux_vars + @unpack orientations, neighbor_ids, neighbor_sides = cache.boundaries + + @threaded for boundary in eachboundary(dg, cache) + element = boundaries.neighbor_ids[boundary] + if orientations[boundary] == 1 + # boundary in x-direction + if neighbor_sides[boundary] == 1 + # element in -x direction of boundary + for l in eachnode(dg), v in eachvariable(equations) + aux_boundary_node_vars[1, v, l, boundary] = aux_node_vars[v, nnodes(dg), l, element] + end + else # Element in +x direction of boundary + for l in eachnode(dg), v in eachvariable(equations) + aux_boundary_node_vars[2, v, l, boundary] = aux_node_vars[v, 1, l, element] + end + end + else # if orientations[boundary] == 2 + # boundary in y-direction + if neighbor_sides[boundary] == 1 + # element in -y direction of boundary + for l in eachnode(dg), v in eachvariable(equations) + aux_boundary_node_vars[1, v, l, boundary] = aux_node_vars[v, l, nnodes(dg), element] + end + else + # element in +y direction of boundary + for l in eachnode(dg), v in eachvariable(equations) + aux_boundary_node_vars[2, v, l, boundary] = aux_node_vars[v, l, 1, element] + end + end + end + end + return nothing +end end # @muladd diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 59bb62993a8..7ae9af88d61 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -112,8 +112,7 @@ end function rhs!(du, u, t, mesh::Union{TreeMesh{2}, P4estMesh{2}, P4estMeshView{2}, T8codeMesh{2}}, - equations, - boundary_conditions, source_terms::Source, + equations, boundary_conditions, source_terms::Source, dg::DG, cache) where {Source} # Reset du @trixi_timeit timer() "reset ∂u/∂t" reset_du!(du, dg, cache) @@ -326,6 +325,7 @@ end end end + @inline function flux_differencing_kernel!(du, u, element, mesh::TreeMesh{2}, nonconservative_terms::False, @@ -899,7 +899,7 @@ function calc_boundary_flux_by_direction!(t, boundary_condition, @unpack surface_flux_values = cache.elements @unpack surface_flux = surface_integral @unpack u, neighbor_ids, neighbor_sides, node_coordinates, orientations = cache.boundaries - @unpack aux_surface_node_vars = cache.aux_vars + @unpack aux_boundary_node_vars = cache.aux_vars @threaded for boundary in first_boundary:last_boundary # Get neighboring element @@ -908,7 +908,7 @@ function calc_boundary_flux_by_direction!(t, boundary_condition, for i in eachnode(dg) # Get boundary flux u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, boundary) - aux_ll, aux_rr = get_aux_surface_node_vars(aux_surface_node_vars, + aux_ll, aux_rr = get_aux_surface_node_vars(aux_boundary_node_vars, equations, dg, i, boundary) if neighbor_sides[boundary] == 1 # Element is on the left, boundary on the right u_inner = u_ll From 1af6698ea25a1a5901a2f5fab43c1f59142ebfca Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 16 May 2025 14:21:21 +0200 Subject: [PATCH 29/83] changed order of arguments --- src/callbacks_step/analysis.jl | 4 ++-- src/callbacks_step/analysis_dg1d.jl | 12 ++++++------ src/callbacks_step/analysis_dg2d.jl | 12 ++++++------ src/callbacks_step/analysis_dg3d.jl | 10 +++++----- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/callbacks_step/analysis.jl b/src/callbacks_step/analysis.jl index 0ae74878623..9bf55f82cd8 100644 --- a/src/callbacks_step/analysis.jl +++ b/src/callbacks_step/analysis.jl @@ -617,10 +617,10 @@ end # Trixi.analyze, Trixi.pretty_form_utf, Trixi.pretty_form_ascii function analyze(quantity, du, u, t, semi::AbstractSemidiscretization) mesh, equations, solver, cache = mesh_equations_solver_cache(semi) - analyze(quantity, du, u, t, mesh, equations, have_aux_node_vars(equations), solver, + analyze(quantity, du, u, t, mesh, have_aux_node_vars(equations), equations, solver, cache) end -function analyze(quantity, du, u, t, mesh, equations, have_aux_node_vars, solver, cache) +function analyze(quantity, du, u, t, mesh, have_aux_node_vars, equations, solver, cache) integrate(quantity, u, mesh, equations, solver, cache, normalize = true) end pretty_form_utf(quantity) = get_name(quantity) diff --git a/src/callbacks_step/analysis_dg1d.jl b/src/callbacks_step/analysis_dg1d.jl index 0440be0f533..ff03ecb3839 100644 --- a/src/callbacks_step/analysis_dg1d.jl +++ b/src/callbacks_step/analysis_dg1d.jl @@ -182,8 +182,8 @@ function integrate(func::Func, u, end function analyze(::typeof(entropy_timederivative), du, u, t, - mesh::Union{TreeMesh{1}, StructuredMesh{1}}, equations, - have_aux_node_vars::False, dg::DG, cache) + mesh::Union{TreeMesh{1}, StructuredMesh{1}}, + have_aux_node_vars::False, equations, dg::DG, cache) # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ integrate_via_indices(u, mesh, equations, dg, cache, du) do u, i, element, equations, dg, du @@ -194,8 +194,8 @@ function analyze(::typeof(entropy_timederivative), du, u, t, end function analyze(::Val{:l2_divb}, du, u, t, - mesh::TreeMesh{1}, equations::IdealGlmMhdEquations1D, - have_aux_node_vars::False, dg::DG, cache) + mesh::TreeMesh{1}, have_aux_node_vars::False, + equations::IdealGlmMhdEquations1D, dg::DG, cache) integrate_via_indices(u, mesh, equations, dg, cache, dg.basis.derivative_matrix) do u, i, element, equations, dg, derivative_matrix @@ -209,8 +209,8 @@ function analyze(::Val{:l2_divb}, du, u, t, end function analyze(::Val{:linf_divb}, du, u, t, - mesh::TreeMesh{1}, equations::IdealGlmMhdEquations1D, - have_aux_node_vars::False, dg::DG, cache) + mesh::TreeMesh{1}, have_aux_node_vars::False, + equations::IdealGlmMhdEquations1D, dg::DG, cache) @unpack derivative_matrix, weights = dg.basis # integrate over all elements to get the divergence-free condition errors diff --git a/src/callbacks_step/analysis_dg2d.jl b/src/callbacks_step/analysis_dg2d.jl index 7cf3e695082..62127bfea6e 100644 --- a/src/callbacks_step/analysis_dg2d.jl +++ b/src/callbacks_step/analysis_dg2d.jl @@ -274,7 +274,7 @@ end function analyze(::typeof(entropy_timederivative), du, u, t, mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - equations, have_aux_node_vars::False, dg::DG, cache) + have_aux_node_vars::False, equations, dg::DG, cache) # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ integrate_via_indices(u, mesh, equations, dg, cache, du) do u, i, j, element, equations, dg, du @@ -287,7 +287,7 @@ end function analyze(::typeof(entropy_timederivative), du, u, t, mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - equations, have_aux_node_vars::True, dg::DG, cache) + have_aux_node_vars::True, equations, dg::DG, cache) @unpack aux_node_vars = cache.aux_vars # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ integrate_via_indices(u, mesh, equations, dg, cache, @@ -301,7 +301,7 @@ end function analyze(::Val{:l2_divb}, du, u, t, mesh::TreeMesh{2}, - equations, have_aux_node_vars::False, dg::DGSEM, cache) + have_aux_node_vars::False, equations, dg::DGSEM, cache) integrate_via_indices(u, mesh, equations, dg, cache, cache, dg.basis.derivative_matrix) do u, i, j, element, equations, dg, cache, derivative_matrix @@ -324,7 +324,7 @@ end function analyze(::Val{:l2_divb}, du, u, t, mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - equations, have_aux_node_vars::False, dg::DGSEM, cache) + have_aux_node_vars::False, equations, dg::DGSEM, cache) @unpack contravariant_vectors = cache.elements integrate_via_indices(u, mesh, equations, dg, cache, cache, dg.basis.derivative_matrix) do u, i, j, element, equations, @@ -353,7 +353,7 @@ end function analyze(::Val{:linf_divb}, du, u, t, mesh::TreeMesh{2}, - equations, have_aux_node_vars::False, dg::DGSEM, cache) + have_aux_node_vars::False, equations, dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis # integrate over all elements to get the divergence-free condition errors @@ -382,7 +382,7 @@ end function analyze(::Val{:linf_divb}, du, u, t, mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - equations, have_aux_node_vars::False, dg::DGSEM, cache) + have_aux_node_vars::False, equations, dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis @unpack contravariant_vectors = cache.elements diff --git a/src/callbacks_step/analysis_dg3d.jl b/src/callbacks_step/analysis_dg3d.jl index 65ea89b6dd1..0b3cbfe3f62 100644 --- a/src/callbacks_step/analysis_dg3d.jl +++ b/src/callbacks_step/analysis_dg3d.jl @@ -298,7 +298,7 @@ end function analyze(::typeof(entropy_timederivative), du, u, t, mesh::Union{TreeMesh{3}, StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - equations, have_aux_node_vars::False, dg::DG, cache) + have_aux_node_vars::False, equations, dg::DG, cache) # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ integrate_via_indices(u, mesh, equations, dg, cache, du) do u, i, j, k, element, equations, dg, du @@ -309,7 +309,7 @@ function analyze(::typeof(entropy_timederivative), du, u, t, end function analyze(::Val{:l2_divb}, du, u, t, - mesh::TreeMesh{3}, equations, have_aux_node_vars::False, + mesh::TreeMesh{3}, have_aux_node_vars::False, equations, dg::DGSEM, cache) integrate_via_indices(u, mesh, equations, dg, cache, cache, dg.basis.derivative_matrix) do u, i, j, k, element, equations, @@ -335,7 +335,7 @@ end function analyze(::Val{:l2_divb}, du, u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - equations, have_aux_node_vars::False, + have_aux_node_vars::False, equations, dg::DGSEM, cache) @unpack contravariant_vectors = cache.elements integrate_via_indices(u, mesh, equations, dg, cache, cache, @@ -372,7 +372,7 @@ function analyze(::Val{:l2_divb}, du, u, t, end function analyze(::Val{:linf_divb}, du, u, t, - mesh::TreeMesh{3}, equations, have_aux_node_vars::False, + mesh::TreeMesh{3}, have_aux_node_vars::False, equations, dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis @@ -409,7 +409,7 @@ end function analyze(::Val{:linf_divb}, du, u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - equations, have_aux_node_vars::False, + have_aux_node_vars::False, equations, dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis @unpack contravariant_vectors = cache.elements From 63849f9839951785d24500e68f9aa0f53bc972ac Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 16 May 2025 14:34:04 +0200 Subject: [PATCH 30/83] some documentation --- src/semidiscretization/semidiscretization_hyperbolic.jl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/semidiscretization/semidiscretization_hyperbolic.jl b/src/semidiscretization/semidiscretization_hyperbolic.jl index a1f1cdec85b..952af0d6d28 100644 --- a/src/semidiscretization/semidiscretization_hyperbolic.jl +++ b/src/semidiscretization/semidiscretization_hyperbolic.jl @@ -57,6 +57,14 @@ end initial_cache=NamedTuple()) Construct a semidiscretization of a hyperbolic PDE. + +`aux_field` is an optional function taking a coordinate vector `x` and the current +`equations` as arguments. It is used to fill an additional field `aux_vars` in the `cache`, +which will be available, e.g., in flux computations. The current `equations` need to set +`have_aux_node_vars to `True()` and `n_aux_node_vars` to the number of auxiliary variables +per node. +Currently only TreeMesh in 2D is supported. +Upon refinement, `aux_field` will be called again to recompute the auxiliary variables. """ function SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver; source_terms = nothing, From d3328d22b376bda865dae4130b399e994a8c7ce1 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 16 May 2025 14:39:19 +0200 Subject: [PATCH 31/83] news entry --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index 637b46b692c..c6191a44e04 100644 --- a/NEWS.md +++ b/NEWS.md @@ -16,6 +16,8 @@ for human readability. paired explicit Runge-Kutta method with [Convex.jl](https://github.com/jump-dev/Convex.jl) and [ECOS.jl](https://github.com/jump-dev/ECOS.jl) ([#2147]) - Passive tracers for arbitrary equations with density and flow variables ([#2364]) +- Auxiliary variables, which can, e.g., be used to store a steady state and solve + for perturbations only ([#2348]) #### Deprecated From 4ab46ba8a565c99ddafefbc90f2dd1c7cc733218 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 16 May 2025 14:39:47 +0200 Subject: [PATCH 32/83] fmt --- .../semidiscretization_hyperbolic.jl | 3 +- src/solvers/dgsem_tree/containers.jl | 31 ++++++++++--------- src/solvers/dgsem_tree/containers_2d.jl | 21 +++++++++---- src/solvers/dgsem_tree/dg_2d.jl | 1 - 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/semidiscretization/semidiscretization_hyperbolic.jl b/src/semidiscretization/semidiscretization_hyperbolic.jl index 952af0d6d28..24abdd647b4 100644 --- a/src/semidiscretization/semidiscretization_hyperbolic.jl +++ b/src/semidiscretization/semidiscretization_hyperbolic.jl @@ -81,7 +81,8 @@ function SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver # Add specialized parts of the cache for auxiliary node variables cache = (; cache..., - create_cache_aux(mesh, equations, solver, cache, have_aux_node_vars(equations), + create_cache_aux(mesh, equations, solver, cache, + have_aux_node_vars(equations), aux_field)...) _boundary_conditions = digest_boundary_conditions(boundary_conditions, mesh, solver, diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index 14b460f7085..abb40287cbf 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -107,22 +107,23 @@ function init_aux_vars(mesh, equations, solver, cache, aux_field) NDIMS - 1)..., n_interfaces)) _aux_boundary_node_vars = fill(nan_uEltype, - 2 * n_aux_node_vars(equations) * - nnodes(solver)^(NDIMS - 1) * - n_boundaries) + 2 * n_aux_node_vars(equations) * + nnodes(solver)^(NDIMS - 1) * + n_boundaries) aux_boundary_node_vars = unsafe_wrap(Array, - pointer(_aux_boundary_node_vars), - (2, n_aux_node_vars(equations), - ntuple(_ -> nnodes(solver), - NDIMS - 1)..., - n_boundaries)) - - aux_vars = AuxNodeVarsContainer{NDIMS, uEltype, NDIMS + 2, typeof(aux_field)}( - aux_node_vars, aux_surface_node_vars, - aux_boundary_node_vars, - _aux_node_vars,_aux_surface_node_vars, - _aux_boundary_node_vars, - aux_field) + pointer(_aux_boundary_node_vars), + (2, n_aux_node_vars(equations), + ntuple(_ -> nnodes(solver), + NDIMS - 1)..., + n_boundaries)) + + aux_vars = AuxNodeVarsContainer{NDIMS, uEltype, NDIMS + 2, typeof(aux_field)}(aux_node_vars, + aux_surface_node_vars, + aux_boundary_node_vars, + _aux_node_vars, + _aux_surface_node_vars, + _aux_boundary_node_vars, + aux_field) init_aux_vars!(aux_vars, mesh, equations, solver, cache) return aux_vars end diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index 5b6f95d99a0..cb867e930df 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1425,7 +1425,8 @@ end # Initialize auxiliary surface node variables # 2D TreeMesh implementation, similar to prolong2interfaces -function init_aux_surface_node_vars!(aux_vars, mesh::TreeMesh2D, equations, solver, cache) +function init_aux_surface_node_vars!(aux_vars, mesh::TreeMesh2D, equations, solver, + cache) @unpack aux_node_vars, aux_surface_node_vars = aux_vars @unpack orientations, neighbor_ids = cache.interfaces @@ -1468,7 +1469,8 @@ end # Initialize auxiliary boundary node variables # 2D TreeMesh implementation, similar to prolong2boundaries -function init_aux_boundary_node_vars!(aux_vars, mesh::TreeMesh2D, equations, solver, cache) +function init_aux_boundary_node_vars!(aux_vars, mesh::TreeMesh2D, equations, solver, + cache) @unpack aux_node_vars, aux_boundary_node_vars = aux_vars @unpack orientations, neighbor_ids, neighbor_sides = cache.boundaries @@ -1479,11 +1481,15 @@ function init_aux_boundary_node_vars!(aux_vars, mesh::TreeMesh2D, equations, sol if neighbor_sides[boundary] == 1 # element in -x direction of boundary for l in eachnode(dg), v in eachvariable(equations) - aux_boundary_node_vars[1, v, l, boundary] = aux_node_vars[v, nnodes(dg), l, element] + aux_boundary_node_vars[1, v, l, boundary] = aux_node_vars[v, + nnodes(dg), + l, + element] end else # Element in +x direction of boundary for l in eachnode(dg), v in eachvariable(equations) - aux_boundary_node_vars[2, v, l, boundary] = aux_node_vars[v, 1, l, element] + aux_boundary_node_vars[2, v, l, boundary] = aux_node_vars[v, 1, l, + element] end end else # if orientations[boundary] == 2 @@ -1491,12 +1497,15 @@ function init_aux_boundary_node_vars!(aux_vars, mesh::TreeMesh2D, equations, sol if neighbor_sides[boundary] == 1 # element in -y direction of boundary for l in eachnode(dg), v in eachvariable(equations) - aux_boundary_node_vars[1, v, l, boundary] = aux_node_vars[v, l, nnodes(dg), element] + aux_boundary_node_vars[1, v, l, boundary] = aux_node_vars[v, l, + nnodes(dg), + element] end else # element in +y direction of boundary for l in eachnode(dg), v in eachvariable(equations) - aux_boundary_node_vars[2, v, l, boundary] = aux_node_vars[v, l, 1, element] + aux_boundary_node_vars[2, v, l, boundary] = aux_node_vars[v, l, 1, + element] end end end diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 7ae9af88d61..351b2dc4fcc 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -325,7 +325,6 @@ end end end - @inline function flux_differencing_kernel!(du, u, element, mesh::TreeMesh{2}, nonconservative_terms::False, From dc893e9701b96f3b31bc0b9e73cede2e43756899 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 16 May 2025 15:14:45 +0200 Subject: [PATCH 33/83] !fixup --- src/callbacks_step/analysis_dgmulti.jl | 10 +++++----- src/equations/equations.jl | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/callbacks_step/analysis_dgmulti.jl b/src/callbacks_step/analysis_dgmulti.jl index 778643b9792..fa146fcb5b0 100644 --- a/src/callbacks_step/analysis_dgmulti.jl +++ b/src/callbacks_step/analysis_dgmulti.jl @@ -45,7 +45,7 @@ function integrate(func::Func, u, end function analyze(::typeof(entropy_timederivative), du, u, t, - mesh::DGMultiMesh, equations, have_aux_node_vars::False, dg::DGMulti, + mesh::DGMultiMesh, have_aux_node_vars::False, equations, dg::DGMulti, cache) rd = dg.basis md = mesh.md @@ -93,8 +93,8 @@ get_component(u::StructArray, i::Int) = StructArrays.component(u, i) get_component(u::AbstractArray{<:SVector}, i::Int) = getindex.(u, i) function analyze(::Val{:l2_divb}, du, u, t, - mesh::DGMultiMesh, equations::IdealGlmMhdEquations2D, - have_aux_node_vars::False, dg::DGMulti, cache) + mesh::DGMultiMesh, have_aux_node_vars::False, + equations::IdealGlmMhdEquations2D, dg::DGMulti, cache) @unpack md = mesh rd = dg.basis B1 = get_component(u, 6) @@ -117,8 +117,8 @@ function analyze(::Val{:l2_divb}, du, u, t, end function analyze(::Val{:linf_divb}, du, u, t, - mesh::DGMultiMesh, equations::IdealGlmMhdEquations2D, - have_aux_node_vars::False, dg::DGMulti, cache) + mesh::DGMultiMesh, have_aux_node_vars::False, + equations::IdealGlmMhdEquations2D, dg::DGMulti, cache) B1 = get_component(u, 6) B2 = get_component(u, 7) B = (B1, B2) diff --git a/src/equations/equations.jl b/src/equations/equations.jl index 09fdee8b271..b3e525c8979 100644 --- a/src/equations/equations.jl +++ b/src/equations/equations.jl @@ -320,7 +320,6 @@ have_constant_speed(::AbstractEquations) = False() Trait function determining whether `equations` need to access additional auxiliary variables. The return value will be `True()` or `False()` to allow dispatching on the return type. -Currently, only TreeMesh in 2D is supported. """ have_aux_node_vars(::AbstractEquations) = False() """ From e731a0123c615042a04c85f03364d62bcf1908ef Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 16 May 2025 22:46:25 +0200 Subject: [PATCH 34/83] !fixup --- src/solvers/dgsem_tree/containers_2d.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index cb867e930df..d84f3a2059c 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1474,20 +1474,20 @@ function init_aux_boundary_node_vars!(aux_vars, mesh::TreeMesh2D, equations, sol @unpack aux_node_vars, aux_boundary_node_vars = aux_vars @unpack orientations, neighbor_ids, neighbor_sides = cache.boundaries - @threaded for boundary in eachboundary(dg, cache) + @threaded for boundary in eachboundary(solver, cache) element = boundaries.neighbor_ids[boundary] if orientations[boundary] == 1 # boundary in x-direction if neighbor_sides[boundary] == 1 # element in -x direction of boundary - for l in eachnode(dg), v in eachvariable(equations) + for l in eachnode(solver), v in eachvariable(equations) aux_boundary_node_vars[1, v, l, boundary] = aux_node_vars[v, - nnodes(dg), + nnodes(solver), l, element] end else # Element in +x direction of boundary - for l in eachnode(dg), v in eachvariable(equations) + for l in eachnode(solver), v in eachvariable(equations) aux_boundary_node_vars[2, v, l, boundary] = aux_node_vars[v, 1, l, element] end @@ -1496,14 +1496,14 @@ function init_aux_boundary_node_vars!(aux_vars, mesh::TreeMesh2D, equations, sol # boundary in y-direction if neighbor_sides[boundary] == 1 # element in -y direction of boundary - for l in eachnode(dg), v in eachvariable(equations) + for l in eachnode(solver), v in eachvariable(equations) aux_boundary_node_vars[1, v, l, boundary] = aux_node_vars[v, l, - nnodes(dg), + nnodes(solver), element] end else # element in +y direction of boundary - for l in eachnode(dg), v in eachvariable(equations) + for l in eachnode(solver), v in eachvariable(equations) aux_boundary_node_vars[2, v, l, boundary] = aux_node_vars[v, l, 1, element] end From 8c770ced2c9f2efe682919e2a1267769ef93965a Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Mon, 19 May 2025 11:43:36 +0200 Subject: [PATCH 35/83] !fixup --- src/solvers/dgsem_tree/containers_2d.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index d84f3a2059c..115dd71534f 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1475,7 +1475,7 @@ function init_aux_boundary_node_vars!(aux_vars, mesh::TreeMesh2D, equations, sol @unpack orientations, neighbor_ids, neighbor_sides = cache.boundaries @threaded for boundary in eachboundary(solver, cache) - element = boundaries.neighbor_ids[boundary] + element = neighbor_ids[boundary] if orientations[boundary] == 1 # boundary in x-direction if neighbor_sides[boundary] == 1 From 3bc28ad3ecdd518dc3294244749b88794318d6b6 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Mon, 19 May 2025 14:23:32 +0200 Subject: [PATCH 36/83] fix variables range evil copy&paste --- src/solvers/dgsem_tree/containers_2d.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index 115dd71534f..b2954d65970 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1480,14 +1480,14 @@ function init_aux_boundary_node_vars!(aux_vars, mesh::TreeMesh2D, equations, sol # boundary in x-direction if neighbor_sides[boundary] == 1 # element in -x direction of boundary - for l in eachnode(solver), v in eachvariable(equations) + for l in eachnode(solver), v in 1:n_aux_node_vars(equations) aux_boundary_node_vars[1, v, l, boundary] = aux_node_vars[v, nnodes(solver), l, element] end else # Element in +x direction of boundary - for l in eachnode(solver), v in eachvariable(equations) + for l in eachnode(solver), v in 1:n_aux_node_vars(equations) aux_boundary_node_vars[2, v, l, boundary] = aux_node_vars[v, 1, l, element] end @@ -1496,14 +1496,14 @@ function init_aux_boundary_node_vars!(aux_vars, mesh::TreeMesh2D, equations, sol # boundary in y-direction if neighbor_sides[boundary] == 1 # element in -y direction of boundary - for l in eachnode(solver), v in eachvariable(equations) + for l in eachnode(solver), v in 1:n_aux_node_vars(equations) aux_boundary_node_vars[1, v, l, boundary] = aux_node_vars[v, l, nnodes(solver), element] end else # element in +y direction of boundary - for l in eachnode(solver), v in eachvariable(equations) + for l in eachnode(solver), v in 1:n_aux_node_vars(equations) aux_boundary_node_vars[2, v, l, boundary] = aux_node_vars[v, l, 1, element] end From 17cb3259404e496d4443e124534b5a499bd96686 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Mon, 19 May 2025 14:28:19 +0200 Subject: [PATCH 37/83] fmt --- src/solvers/dgsem_tree/containers.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index abb40287cbf..ae6620e203e 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -117,13 +117,13 @@ function init_aux_vars(mesh, equations, solver, cache, aux_field) NDIMS - 1)..., n_boundaries)) - aux_vars = AuxNodeVarsContainer{NDIMS, uEltype, NDIMS + 2, typeof(aux_field)}(aux_node_vars, - aux_surface_node_vars, - aux_boundary_node_vars, - _aux_node_vars, - _aux_surface_node_vars, - _aux_boundary_node_vars, - aux_field) + aux_vars = AuxNodeVarsContainer{NDIMS, uEltype, NDIMS + 2, + typeof(aux_field)}(aux_node_vars, aux_surface_node_vars, + aux_boundary_node_vars, + _aux_node_vars, + _aux_surface_node_vars, + _aux_boundary_node_vars, + aux_field) init_aux_vars!(aux_vars, mesh, equations, solver, cache) return aux_vars end From 2d152097f527acd5ab05503f1e02763ac6efa0f1 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Thu, 22 May 2025 10:23:46 +0200 Subject: [PATCH 38/83] enabled more features --- src/solvers/dgsem_tree/dg_2d.jl | 270 +++++++++++++++++++++++- src/solvers/dgsem_tree/indicators.jl | 4 +- src/solvers/dgsem_tree/indicators_2d.jl | 25 ++- 3 files changed, 286 insertions(+), 13 deletions(-) diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 351b2dc4fcc..082084d7aff 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -416,6 +416,59 @@ end end end +@inline function flux_differencing_kernel!(du, u, + element, mesh::TreeMesh{2}, + nonconservative_terms::True, + have_aux_node_vars::True, equations, + volume_flux, dg::DGSEM, cache, alpha = true) + # true * [some floating point value] == [exactly the same floating point value] + # This can (hopefully) be optimized away due to constant propagation. + @unpack derivative_split = dg.basis + @unpack aux_node_vars = cache.aux_vars + symmetric_flux, nonconservative_flux = volume_flux + + # Apply the symmetric flux as usual + flux_differencing_kernel!(du, u, element, mesh, False(), True(), equations, + symmetric_flux, dg, cache, alpha) + + # Calculate the remaining volume terms using the nonsymmetric generalized flux + for j in eachnode(dg), i in eachnode(dg) + u_node = get_node_vars(u, equations, dg, i, j, element) + aux_node = get_aux_node_vars(aux_node_vars, equations, dg, + i, j, element) + + # The diagonal terms are zero since the diagonal of `derivative_split` + # is zero. We ignore this for now. + + # x direction + integral_contribution = zero(u_node) + for ii in eachnode(dg) + u_node_ii = get_node_vars(u, equations, dg, ii, j, element) + aux_node_ii = get_aux_node_vars(aux_node_vars, equations, dg, + ii, j, element) + noncons_flux1 = nonconservative_flux(u_node, u_node_ii, aux_node, aux_node_ii, + 1, equations) + integral_contribution = integral_contribution + + derivative_split[i, ii] * noncons_flux1 + end + + # y direction + for jj in eachnode(dg) + u_node_jj = get_node_vars(u, equations, dg, i, jj, element) + aux_node_jj = get_aux_node_vars(aux_node_vars, equations, dg, + i, jj, element) + noncons_flux2 = nonconservative_flux(u_node, u_node_jj, aux_node, aux_node_jj, + 2, equations) + integral_contribution = integral_contribution + + derivative_split[j, jj] * noncons_flux2 + end + + # The factor 0.5 cancels the factor 2 in the flux differencing form + multiply_add_to_node_vars!(du, alpha * 0.5f0, integral_contribution, equations, + dg, i, j, element) + end +end + # TODO: Taal dimension agnostic function calc_volume_integral!(du, u, mesh::Union{TreeMesh{2}, StructuredMesh{2}, @@ -452,9 +505,8 @@ function calc_volume_integral!(du, u, volume_flux_dg, dg, cache, 1 - alpha_element) # Calculate FV volume integral contribution - fv_kernel!(du, u, mesh, have_nonconservative_terms(equations), equations, - volume_flux_fv, - dg, cache, element, alpha_element) + fv_kernel!(du, u, mesh, equations, + volume_flux_fv, dg, cache, element, alpha_element) end end @@ -485,8 +537,8 @@ end mesh::Union{TreeMesh{2}, StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - nonconservative_terms, equations, - volume_flux_fv, dg::DGSEM, cache, element, alpha = true) + equations, volume_flux_fv, dg::DGSEM, cache, element, + alpha = true) @unpack fstar1_L_threaded, fstar1_R_threaded, fstar2_L_threaded, fstar2_R_threaded = cache @unpack inverse_weights = dg.basis @@ -496,7 +548,8 @@ end fstar1_R = fstar1_R_threaded[Threads.threadid()] fstar2_R = fstar2_R_threaded[Threads.threadid()] calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, u, mesh, - nonconservative_terms, equations, volume_flux_fv, dg, element, cache) + have_nonconservative_terms(equations), have_aux_node_vars(equations), + equations, volume_flux_fv, dg, element, cache) # Calculate FV volume integral contribution for j in eachnode(dg), i in eachnode(dg) @@ -526,7 +579,7 @@ end @inline function calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, u::AbstractArray{<:Any, 4}, mesh::TreeMesh{2}, nonconservative_terms::False, - equations, + have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) fstar1_L[:, 1, :] .= zero(eltype(fstar1_L)) fstar1_L[:, nnodes(dg) + 1, :] .= zero(eltype(fstar1_L)) @@ -557,6 +610,45 @@ end return nothing end +@inline function calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, + u::AbstractArray{<:Any, 4}, + mesh::TreeMesh{2}, nonconservative_terms::False, + have_aux_node_vars::True, equations, + volume_flux_fv, dg::DGSEM, element, cache) + @unpack aux_node_vars = cache.aux_vars + fstar1_L[:, 1, :] .= zero(eltype(fstar1_L)) + fstar1_L[:, nnodes(dg) + 1, :] .= zero(eltype(fstar1_L)) + fstar1_R[:, 1, :] .= zero(eltype(fstar1_R)) + fstar1_R[:, nnodes(dg) + 1, :] .= zero(eltype(fstar1_R)) + + for j in eachnode(dg), i in 2:nnodes(dg) + u_ll = get_node_vars(u, equations, dg, i - 1, j, element) + u_rr = get_node_vars(u, equations, dg, i, j, element) + aux_ll = get_node_vars(aux_node_vars, equations, dg, i - 1, j, element) + aux_rr = get_node_vars(aux_node_vars, equations, dg, i, j, element) + flux = volume_flux_fv(u_ll, u_rr, aux_ll, aux_rr, 1, equations) # orientation 1: x direction + set_node_vars!(fstar1_L, flux, equations, dg, i, j) + set_node_vars!(fstar1_R, flux, equations, dg, i, j) + end + + fstar2_L[:, :, 1] .= zero(eltype(fstar2_L)) + fstar2_L[:, :, nnodes(dg) + 1] .= zero(eltype(fstar2_L)) + fstar2_R[:, :, 1] .= zero(eltype(fstar2_R)) + fstar2_R[:, :, nnodes(dg) + 1] .= zero(eltype(fstar2_R)) + + for j in 2:nnodes(dg), i in eachnode(dg) + u_ll = get_node_vars(u, equations, dg, i, j - 1, element) + u_rr = get_node_vars(u, equations, dg, i, j, element) + aux_ll = get_node_vars(aux_node_vars, equations, dg, i, j - 1, element) + aux_rr = get_node_vars(aux_node_vars, equations, dg, i, j, element) + flux = volume_flux_fv(u_ll, u_rr, aux_ll, aux_rr, 2, equations) # orientation 2: y direction + set_node_vars!(fstar2_L, flux, equations, dg, i, j) + set_node_vars!(fstar2_R, flux, equations, dg, i, j) + end + + return nothing +end + # calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, u_leftright, # nonconservative_terms::True, equations, # volume_flux_fv, dg, element) @@ -571,7 +663,8 @@ end # - `u_leftright::AbstractArray{<:Real, 4}` @inline function calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, u::AbstractArray{<:Any, 4}, - mesh::TreeMesh{2}, nonconservative_terms::True, equations, + mesh::TreeMesh{2}, nonconservative_terms::True, + have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) volume_flux, nonconservative_flux = volume_flux_fv @@ -629,6 +722,72 @@ end return nothing end +@inline function calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, + u::AbstractArray{<:Any, 4}, + mesh::TreeMesh{2}, nonconservative_terms::True, + have_aux_node_vars::True, equations, + volume_flux_fv, dg::DGSEM, element, cache) + @unpack aux_node_vars = cache.aux_vars + volume_flux, nonconservative_flux = volume_flux_fv + + # Fluxes in x + fstar1_L[:, 1, :] .= zero(eltype(fstar1_L)) + fstar1_L[:, nnodes(dg) + 1, :] .= zero(eltype(fstar1_L)) + fstar1_R[:, 1, :] .= zero(eltype(fstar1_R)) + fstar1_R[:, nnodes(dg) + 1, :] .= zero(eltype(fstar1_R)) + + for j in eachnode(dg), i in 2:nnodes(dg) + u_ll = get_node_vars(u, equations, dg, i - 1, j, element) + u_rr = get_node_vars(u, equations, dg, i, j, element) + aux_ll = get_aux_node_vars(aux_node_vars, equations, dg, i - 1, j, element) + aux_rr = get_aux_node_vars(aux_node_vars, equations, dg, i, j, element) + + # Compute conservative part + f1 = volume_flux(u_ll, u_rr, aux_ll, aux_rr, 1, equations) # orientation 1: x direction + + # Compute nonconservative part + # Note the factor 0.5 necessary for the nonconservative fluxes based on + # the interpretation of global SBP operators coupled discontinuously via + # central fluxes/SATs + f1_L = f1 + 0.5f0 * nonconservative_flux(u_ll, u_rr, aux_ll, aux_rr, 1, equations) + f1_R = f1 + 0.5f0 * nonconservative_flux(u_rr, u_ll, aux_ll, aux_rr, 1, equations) + + # Copy to temporary storage + set_node_vars!(fstar1_L, f1_L, equations, dg, i, j) + set_node_vars!(fstar1_R, f1_R, equations, dg, i, j) + end + + # Fluxes in y + fstar2_L[:, :, 1] .= zero(eltype(fstar2_L)) + fstar2_L[:, :, nnodes(dg) + 1] .= zero(eltype(fstar2_L)) + fstar2_R[:, :, 1] .= zero(eltype(fstar2_R)) + fstar2_R[:, :, nnodes(dg) + 1] .= zero(eltype(fstar2_R)) + + # Compute inner fluxes + for j in 2:nnodes(dg), i in eachnode(dg) + u_ll = get_node_vars(u, equations, dg, i, j - 1, element) + u_rr = get_node_vars(u, equations, dg, i, j, element) + aux_ll = get_aux_node_vars(aux_node_vars, equations, dg, i, j - 1, element) + aux_rr = get_aux_node_vars(aux_node_vars, equations, dg, i, j, element) + + # Compute conservative part + f2 = volume_flux(u_ll, u_rr, aux_ll, aux_rr, 2, equations) # orientation 2: y direction + + # Compute nonconservative part + # Note the factor 0.5 necessary for the nonconservative fluxes based on + # the interpretation of global SBP operators coupled discontinuously via + # central fluxes/SATs + f2_L = f2 + 0.5f0 * nonconservative_flux(u_ll, u_rr, aux_ll, aux_rr, 2, equations) + f2_R = f2 + 0.5f0 * nonconservative_flux(u_rr, u_ll, aux_ll, aux_rr, 2, equations) + + # Copy to temporary storage + set_node_vars!(fstar2_L, f2_L, equations, dg, i, j) + set_node_vars!(fstar2_R, f2_R, equations, dg, i, j) + end + + return nothing +end + function prolong2interfaces!(cache, u, mesh::TreeMesh{2}, equations, surface_integral, dg::DG) @unpack interfaces = cache @@ -778,6 +937,59 @@ function calc_interface_flux!(surface_flux_values, return nothing end +function calc_interface_flux!(surface_flux_values, + mesh::TreeMesh{2}, + nonconservative_terms::True, + have_aux_node_vars::True, equations, + surface_integral, dg::DG, cache) + surface_flux, nonconservative_flux = surface_integral.surface_flux + @unpack u, neighbor_ids, orientations = cache.interfaces + @unpack aux_surface_node_vars = cache.aux_vars + + @threaded for interface in eachinterface(dg, cache) + # Get neighboring elements + left_id = neighbor_ids[1, interface] + right_id = neighbor_ids[2, interface] + + # Determine interface direction with respect to elements: + # orientation = 1: left -> 2, right -> 1 + # orientation = 2: left -> 4, right -> 3 + left_direction = 2 * orientations[interface] + right_direction = 2 * orientations[interface] - 1 + + for i in eachnode(dg) + # Call pointwise Riemann solver + orientation = orientations[interface] + u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) + aux_ll, aux_rr = get_aux_surface_node_vars(aux_surface_node_vars, + equations, dg, i, + interface) + flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, orientation, equations) + + # Compute both nonconservative fluxes + noncons_left = nonconservative_flux(u_ll, u_rr, aux_ll, aux_rr, + orientation, equations) + noncons_right = nonconservative_flux(u_rr, u_ll, aux_ll, aux_rr, + orientation, equations) + + # Copy flux to left and right element storage + for v in eachvariable(equations) + # Note the factor 0.5 necessary for the nonconservative fluxes based on + # the interpretation of global SBP operators coupled discontinuously via + # central fluxes/SATs + surface_flux_values[v, i, left_direction, left_id] = flux[v] + + 0.5f0 * + noncons_left[v] + surface_flux_values[v, i, right_direction, right_id] = flux[v] + + 0.5f0 * + noncons_right[v] + end + end + end + + return nothing +end + function prolong2boundaries!(cache, u, mesh::TreeMesh{2}, equations, surface_integral, dg::DG) @unpack boundaries = cache @@ -968,6 +1180,48 @@ function calc_boundary_flux_by_direction!(t, boundary_condition, return nothing end +function calc_boundary_flux_by_direction!(t, boundary_condition, + nonconservative_terms::True, + have_aux_node_vars::True, equations, + surface_integral, dg::DG, cache, + direction, first_boundary, last_boundary) + @unpack surface_flux_values = cache.elements + @unpack u, neighbor_ids, neighbor_sides, node_coordinates, orientations = cache.boundaries + @unpack aux_boundary_node_vars = cache.aux_vars + + @threaded for boundary in first_boundary:last_boundary + # Get neighboring element + neighbor = neighbor_ids[boundary] + + for i in eachnode(dg) + # Get boundary flux + u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, boundary) + aux_ll, aux_rr = get_aux_surface_node_vars(aux_boundary_node_vars, + equations, dg, i, boundary) + if neighbor_sides[boundary] == 1 # Element is on the left, boundary on the right + u_inner = u_ll + aux_inner = aux_ll + else # Element is on the right, boundary on the left + u_inner = u_rr + aux_inner = aux_rr + end + x = get_node_coords(node_coordinates, equations, dg, i, boundary) + flux, noncons_flux = boundary_condition(u_inner, aux_inner, + orientations[boundary], direction, x, t, + surface_integral.surface_flux, + equations) + + # Copy flux to left and right element storage + for v in eachvariable(equations) + surface_flux_values[v, i, direction, neighbor] = flux[v] + + 0.5f0 * noncons_flux[v] + end + end + end + + return nothing +end + function prolong2mortars!(cache, u, mesh::TreeMesh{2}, equations, mortar_l2::LobattoLegendreMortarL2, diff --git a/src/solvers/dgsem_tree/indicators.jl b/src/solvers/dgsem_tree/indicators.jl index 59847739c43..d08244ccccf 100644 --- a/src/solvers/dgsem_tree/indicators.jl +++ b/src/solvers/dgsem_tree/indicators.jl @@ -127,7 +127,9 @@ function (indicator_hg::IndicatorHennemannGassner)(u, mesh, equations, dg::DGSEM # Otherwise, `@threaded` does not work here with Julia ARM on macOS. # See https://github.com/JuliaSIMD/Polyester.jl/issues/88. calc_indicator_hennemann_gassner!(indicator_hg, threshold, parameter_s, u, - element, mesh, equations, dg, cache) + element, mesh, + have_aux_node_vars(equations), equations, + dg, cache) end if alpha_smooth diff --git a/src/solvers/dgsem_tree/indicators_2d.jl b/src/solvers/dgsem_tree/indicators_2d.jl index 5fb3098c050..5ce91a74e7f 100644 --- a/src/solvers/dgsem_tree/indicators_2d.jl +++ b/src/solvers/dgsem_tree/indicators_2d.jl @@ -35,6 +35,7 @@ end @inline function calc_indicator_hennemann_gassner!(indicator_hg, threshold, parameter_s, u, element, mesh::AbstractMesh{2}, + have_aux_node_vars, equations, dg, cache) @unpack alpha_max, alpha_min, alpha_smooth, variable = indicator_hg @unpack alpha, alpha_tmp, indicator_threaded, modal_threaded, @@ -45,10 +46,8 @@ end modal_tmp1 = modal_tmp1_threaded[Threads.threadid()] # Calculate indicator variables at Gauss-Lobatto nodes - for j in eachnode(dg), i in eachnode(dg) - u_local = get_node_vars(u, equations, dg, i, j, element) - indicator[i, j] = indicator_hg.variable(u_local, equations) - end + calc_indicator_inner!(indicator, u, element, indicator_hg.variable, + have_aux_node_vars, equations, dg, cache) # Convert to modal representation multiply_scalar_dimensionwise!(modal, dg.basis.inverse_vandermonde_legendre, @@ -97,6 +96,24 @@ end alpha[element] = min(alpha_max, alpha_element) end +@inline function calc_indicator_inner!(indicator, u, element, indicator_variable, + have_aux_node_vars::False, equations, solver, cache) + for j in eachnode(solver), i in eachnode(solver) + u_local = get_node_vars(u, equations, solver, i, j, element) + indicator[i, j] = indicator_variable(u_local, equations) + end +end + +@inline function calc_indicator_inner!(indicator, u, element, indicator_variable, + have_aux_node_vars::True, equations, solver, cache) + @unpack aux_node_vars = cache.aux_vars + for j in eachnode(solver), i in eachnode(solver) + u_local = get_node_vars(u, equations, solver, i, j, element) + aux_local = get_aux_node_vars(aux_node_vars, equations, solver, i, j, element) + indicator[i, j] = indicator_variable(u_local, aux_local, equations) + end +end + # Diffuse alpha values by setting each alpha to at least 50% of neighboring elements' alpha function apply_smoothing!(mesh::Union{TreeMesh{2}, P4estMesh{2}, T8codeMesh{2}}, alpha, alpha_tmp, dg, From 809a57a84b200f08fb94c55577126391088bd429 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Thu, 22 May 2025 10:26:07 +0200 Subject: [PATCH 39/83] fmt --- src/solvers/dgsem_tree/containers.jl | 3 ++- src/solvers/dgsem_tree/dg_2d.jl | 21 ++++++++++++++------- src/solvers/dgsem_tree/indicators_2d.jl | 6 ++++-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index ae6620e203e..41654b84559 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -118,7 +118,8 @@ function init_aux_vars(mesh, equations, solver, cache, aux_field) n_boundaries)) aux_vars = AuxNodeVarsContainer{NDIMS, uEltype, NDIMS + 2, - typeof(aux_field)}(aux_node_vars, aux_surface_node_vars, + typeof(aux_field)}(aux_node_vars, + aux_surface_node_vars, aux_boundary_node_vars, _aux_node_vars, _aux_surface_node_vars, diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 082084d7aff..4618e7d7c8a 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -446,7 +446,8 @@ end u_node_ii = get_node_vars(u, equations, dg, ii, j, element) aux_node_ii = get_aux_node_vars(aux_node_vars, equations, dg, ii, j, element) - noncons_flux1 = nonconservative_flux(u_node, u_node_ii, aux_node, aux_node_ii, + noncons_flux1 = nonconservative_flux(u_node, u_node_ii, aux_node, + aux_node_ii, 1, equations) integral_contribution = integral_contribution + derivative_split[i, ii] * noncons_flux1 @@ -457,7 +458,8 @@ end u_node_jj = get_node_vars(u, equations, dg, i, jj, element) aux_node_jj = get_aux_node_vars(aux_node_vars, equations, dg, i, jj, element) - noncons_flux2 = nonconservative_flux(u_node, u_node_jj, aux_node, aux_node_jj, + noncons_flux2 = nonconservative_flux(u_node, u_node_jj, aux_node, + aux_node_jj, 2, equations) integral_contribution = integral_contribution + derivative_split[j, jj] * noncons_flux2 @@ -749,8 +751,10 @@ end # Note the factor 0.5 necessary for the nonconservative fluxes based on # the interpretation of global SBP operators coupled discontinuously via # central fluxes/SATs - f1_L = f1 + 0.5f0 * nonconservative_flux(u_ll, u_rr, aux_ll, aux_rr, 1, equations) - f1_R = f1 + 0.5f0 * nonconservative_flux(u_rr, u_ll, aux_ll, aux_rr, 1, equations) + f1_L = f1 + + 0.5f0 * nonconservative_flux(u_ll, u_rr, aux_ll, aux_rr, 1, equations) + f1_R = f1 + + 0.5f0 * nonconservative_flux(u_rr, u_ll, aux_ll, aux_rr, 1, equations) # Copy to temporary storage set_node_vars!(fstar1_L, f1_L, equations, dg, i, j) @@ -777,8 +781,10 @@ end # Note the factor 0.5 necessary for the nonconservative fluxes based on # the interpretation of global SBP operators coupled discontinuously via # central fluxes/SATs - f2_L = f2 + 0.5f0 * nonconservative_flux(u_ll, u_rr, aux_ll, aux_rr, 2, equations) - f2_R = f2 + 0.5f0 * nonconservative_flux(u_rr, u_ll, aux_ll, aux_rr, 2, equations) + f2_L = f2 + + 0.5f0 * nonconservative_flux(u_ll, u_rr, aux_ll, aux_rr, 2, equations) + f2_R = f2 + + 0.5f0 * nonconservative_flux(u_rr, u_ll, aux_ll, aux_rr, 2, equations) # Copy to temporary storage set_node_vars!(fstar2_L, f2_L, equations, dg, i, j) @@ -1207,7 +1213,8 @@ function calc_boundary_flux_by_direction!(t, boundary_condition, end x = get_node_coords(node_coordinates, equations, dg, i, boundary) flux, noncons_flux = boundary_condition(u_inner, aux_inner, - orientations[boundary], direction, x, t, + orientations[boundary], direction, + x, t, surface_integral.surface_flux, equations) diff --git a/src/solvers/dgsem_tree/indicators_2d.jl b/src/solvers/dgsem_tree/indicators_2d.jl index 5ce91a74e7f..21b8c5f661b 100644 --- a/src/solvers/dgsem_tree/indicators_2d.jl +++ b/src/solvers/dgsem_tree/indicators_2d.jl @@ -97,7 +97,8 @@ end end @inline function calc_indicator_inner!(indicator, u, element, indicator_variable, - have_aux_node_vars::False, equations, solver, cache) + have_aux_node_vars::False, equations, solver, + cache) for j in eachnode(solver), i in eachnode(solver) u_local = get_node_vars(u, equations, solver, i, j, element) indicator[i, j] = indicator_variable(u_local, equations) @@ -105,7 +106,8 @@ end end @inline function calc_indicator_inner!(indicator, u, element, indicator_variable, - have_aux_node_vars::True, equations, solver, cache) + have_aux_node_vars::True, equations, solver, + cache) @unpack aux_node_vars = cache.aux_vars for j in eachnode(solver), i in eachnode(solver) u_local = get_node_vars(u, equations, solver, i, j, element) From b3ea5f963ca48a983b43d5f0e2a36e6ec78e53e3 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Thu, 22 May 2025 14:51:45 +0200 Subject: [PATCH 40/83] fixes --- src/solvers/dgsem_tree/containers_2d.jl | 8 ++++---- src/solvers/dgsem_tree/dg_2d.jl | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index b2954d65970..b9d2f93e4c0 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1480,14 +1480,14 @@ function init_aux_boundary_node_vars!(aux_vars, mesh::TreeMesh2D, equations, sol # boundary in x-direction if neighbor_sides[boundary] == 1 # element in -x direction of boundary - for l in eachnode(solver), v in 1:n_aux_node_vars(equations) + for l in eachnode(solver), v in axes(aux_boundary_node_vars, 2) aux_boundary_node_vars[1, v, l, boundary] = aux_node_vars[v, nnodes(solver), l, element] end else # Element in +x direction of boundary - for l in eachnode(solver), v in 1:n_aux_node_vars(equations) + for l in eachnode(solver), v in axes(aux_boundary_node_vars, 2) aux_boundary_node_vars[2, v, l, boundary] = aux_node_vars[v, 1, l, element] end @@ -1496,14 +1496,14 @@ function init_aux_boundary_node_vars!(aux_vars, mesh::TreeMesh2D, equations, sol # boundary in y-direction if neighbor_sides[boundary] == 1 # element in -y direction of boundary - for l in eachnode(solver), v in 1:n_aux_node_vars(equations) + for l in eachnode(solver), v in axes(aux_boundary_node_vars, 2) aux_boundary_node_vars[1, v, l, boundary] = aux_node_vars[v, l, nnodes(solver), element] end else # element in +y direction of boundary - for l in eachnode(solver), v in 1:n_aux_node_vars(equations) + for l in eachnode(solver), v in axes(aux_boundary_node_vars, 2) aux_boundary_node_vars[2, v, l, boundary] = aux_node_vars[v, l, 1, element] end diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 4618e7d7c8a..a32eede8d47 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -626,8 +626,8 @@ end for j in eachnode(dg), i in 2:nnodes(dg) u_ll = get_node_vars(u, equations, dg, i - 1, j, element) u_rr = get_node_vars(u, equations, dg, i, j, element) - aux_ll = get_node_vars(aux_node_vars, equations, dg, i - 1, j, element) - aux_rr = get_node_vars(aux_node_vars, equations, dg, i, j, element) + aux_ll = get_aux_node_vars(aux_node_vars, equations, dg, i - 1, j, element) + aux_rr = get_aux_node_vars(aux_node_vars, equations, dg, i, j, element) flux = volume_flux_fv(u_ll, u_rr, aux_ll, aux_rr, 1, equations) # orientation 1: x direction set_node_vars!(fstar1_L, flux, equations, dg, i, j) set_node_vars!(fstar1_R, flux, equations, dg, i, j) @@ -641,8 +641,8 @@ end for j in 2:nnodes(dg), i in eachnode(dg) u_ll = get_node_vars(u, equations, dg, i, j - 1, element) u_rr = get_node_vars(u, equations, dg, i, j, element) - aux_ll = get_node_vars(aux_node_vars, equations, dg, i, j - 1, element) - aux_rr = get_node_vars(aux_node_vars, equations, dg, i, j, element) + aux_ll = get_aux_node_vars(aux_node_vars, equations, dg, i, j - 1, element) + aux_rr = get_aux_node_vars(aux_node_vars, equations, dg, i, j, element) flux = volume_flux_fv(u_ll, u_rr, aux_ll, aux_rr, 2, equations) # orientation 2: y direction set_node_vars!(fstar2_L, flux, equations, dg, i, j) set_node_vars!(fstar2_R, flux, equations, dg, i, j) @@ -975,7 +975,7 @@ function calc_interface_flux!(surface_flux_values, # Compute both nonconservative fluxes noncons_left = nonconservative_flux(u_ll, u_rr, aux_ll, aux_rr, orientation, equations) - noncons_right = nonconservative_flux(u_rr, u_ll, aux_ll, aux_rr, + noncons_right = nonconservative_flux(u_rr, u_ll, aux_rr, aux_ll, orientation, equations) # Copy flux to left and right element storage From dc0c5b9bd7520e6a7e5b33fc0a8a913f754ddd06 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Thu, 22 May 2025 15:01:16 +0200 Subject: [PATCH 41/83] fixes --- src/solvers/dgsem_structured/dg_2d.jl | 6 ++++-- src/solvers/dgsem_tree/indicators_1d.jl | 2 +- src/solvers/dgsem_tree/indicators_3d.jl | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/solvers/dgsem_structured/dg_2d.jl b/src/solvers/dgsem_structured/dg_2d.jl index b55d4e984c9..b869d8eca33 100644 --- a/src/solvers/dgsem_structured/dg_2d.jl +++ b/src/solvers/dgsem_structured/dg_2d.jl @@ -234,7 +234,8 @@ end mesh::Union{StructuredMesh{2}, StructuredMeshView{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - nonconservative_terms::False, equations, + nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) @unpack contravariant_vectors = cache.elements @unpack weights, derivative_matrix = dg.basis @@ -305,7 +306,8 @@ end mesh::Union{StructuredMesh{2}, StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - nonconservative_terms::True, equations, + nonconservative_terms::True, + have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) @unpack contravariant_vectors = cache.elements @unpack weights, derivative_matrix = dg.basis diff --git a/src/solvers/dgsem_tree/indicators_1d.jl b/src/solvers/dgsem_tree/indicators_1d.jl index bdc0c265220..26c3b21d54b 100644 --- a/src/solvers/dgsem_tree/indicators_1d.jl +++ b/src/solvers/dgsem_tree/indicators_1d.jl @@ -31,7 +31,7 @@ end @inline function calc_indicator_hennemann_gassner!(indicator_hg, threshold, parameter_s, u, element, mesh::AbstractMesh{1}, - equations, dg, cache) + have_aux_node_vars, equations, dg, cache) @unpack alpha_max, alpha_min, alpha_smooth, variable = indicator_hg @unpack alpha, alpha_tmp, indicator_threaded, modal_threaded = indicator_hg.cache diff --git a/src/solvers/dgsem_tree/indicators_3d.jl b/src/solvers/dgsem_tree/indicators_3d.jl index 8fa8b9e3c03..6019ce80f63 100644 --- a/src/solvers/dgsem_tree/indicators_3d.jl +++ b/src/solvers/dgsem_tree/indicators_3d.jl @@ -38,7 +38,7 @@ end @inline function calc_indicator_hennemann_gassner!(indicator_hg, threshold, parameter_s, u, element, mesh::AbstractMesh{3}, - equations, dg, cache) + have_aux_node_vars, equations, dg, cache) @unpack alpha_max, alpha_min, alpha_smooth, variable = indicator_hg @unpack alpha, alpha_tmp, indicator_threaded, modal_threaded, modal_tmp1_threaded, modal_tmp2_threaded = indicator_hg.cache From 4518f8699256271036d56f6b99019b32c2de8ae6 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Thu, 22 May 2025 15:03:16 +0200 Subject: [PATCH 42/83] fmt --- src/solvers/dgsem_tree/indicators_1d.jl | 3 ++- src/solvers/dgsem_tree/indicators_3d.jl | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/solvers/dgsem_tree/indicators_1d.jl b/src/solvers/dgsem_tree/indicators_1d.jl index 26c3b21d54b..126cf3ff2c3 100644 --- a/src/solvers/dgsem_tree/indicators_1d.jl +++ b/src/solvers/dgsem_tree/indicators_1d.jl @@ -31,7 +31,8 @@ end @inline function calc_indicator_hennemann_gassner!(indicator_hg, threshold, parameter_s, u, element, mesh::AbstractMesh{1}, - have_aux_node_vars, equations, dg, cache) + have_aux_node_vars, equations, dg, + cache) @unpack alpha_max, alpha_min, alpha_smooth, variable = indicator_hg @unpack alpha, alpha_tmp, indicator_threaded, modal_threaded = indicator_hg.cache diff --git a/src/solvers/dgsem_tree/indicators_3d.jl b/src/solvers/dgsem_tree/indicators_3d.jl index 6019ce80f63..898ddc5bcd4 100644 --- a/src/solvers/dgsem_tree/indicators_3d.jl +++ b/src/solvers/dgsem_tree/indicators_3d.jl @@ -38,7 +38,8 @@ end @inline function calc_indicator_hennemann_gassner!(indicator_hg, threshold, parameter_s, u, element, mesh::AbstractMesh{3}, - have_aux_node_vars, equations, dg, cache) + have_aux_node_vars, equations, dg, + cache) @unpack alpha_max, alpha_min, alpha_smooth, variable = indicator_hg @unpack alpha, alpha_tmp, indicator_threaded, modal_threaded, modal_tmp1_threaded, modal_tmp2_threaded = indicator_hg.cache From 528d23aa7ee5462d54ce2223c5500a6bc22c551a Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Sat, 24 May 2025 02:31:04 +0200 Subject: [PATCH 43/83] mortars --- src/solvers/dgsem_p4est/containers.jl | 10 ++ src/solvers/dgsem_tree/dg_2d.jl | 224 +++++++++++++++++++++--- src/solvers/dgsem_tree/indicators_2d.jl | 16 +- 3 files changed, 216 insertions(+), 34 deletions(-) diff --git a/src/solvers/dgsem_p4est/containers.jl b/src/solvers/dgsem_p4est/containers.jl index a070db6b701..eb9f72b74f1 100644 --- a/src/solvers/dgsem_p4est/containers.jl +++ b/src/solvers/dgsem_p4est/containers.jl @@ -445,6 +445,16 @@ function reinitialize_containers!(mesh::P4estMesh, equations, dg::DGSEM, cache) else init_surfaces!(interfaces, nothing, boundaries, mesh) end + + # re-initialize auxiliary variables container + if hasproperty(cache, :aux_vars) + @unpack aux_vars = cache + resize!(aux_vars, ncells(mesh), + required.interfaces, + required.boundaries, + required.mortars) + init_aux_vars!(aux_vars, mesh, equations, dg, cache) + end end # A helper struct used in initialization methods below diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index a32eede8d47..bfec3ba3c34 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -158,7 +158,8 @@ function rhs!(du, u, t, # Calculate mortar fluxes @trixi_timeit timer() "mortar flux" begin calc_mortar_flux!(cache.elements.surface_flux_values, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_aux_node_vars(equations), equations, dg.mortar, dg.surface_integral, dg, cache) end @@ -527,9 +528,8 @@ function calc_volume_integral!(du, u, # Calculate LGL FV volume integral @threaded for element in eachelement(dg, cache) - fv_kernel!(du, u, mesh, have_nonconservative_terms(equations), equations, - volume_flux_fv, - dg, cache, element, true) + fv_kernel!(du, u, mesh, equations, + volume_flux_fv, dg, cache, element, true) end return nothing @@ -1331,7 +1331,8 @@ end function calc_mortar_flux!(surface_flux_values, mesh::TreeMesh{2}, - nonconservative_terms::False, equations, + nonconservative_terms::False, + have_aux_node_vars::False, equations, mortar_l2::LobattoLegendreMortarL2, surface_integral, dg::DG, cache) @unpack surface_flux = surface_integral @@ -1348,27 +1349,69 @@ function calc_mortar_flux!(surface_flux_values, # Calculate fluxes orientation = orientations[mortar] - calc_fstar!(fstar_primary_upper, have_aux_node_vars(equations), equations, + calc_fstar!(fstar_primary_upper, equations, surface_flux, dg, u_upper, mortar, orientation, cache) - calc_fstar!(fstar_primary_lower, have_aux_node_vars(equations), equations, + calc_fstar!(fstar_primary_lower, equations, + surface_flux, dg, u_lower, mortar, orientation, cache) + calc_fstar!(fstar_secondary_upper, equations, + surface_flux, dg, u_upper, mortar, orientation, cache) + calc_fstar!(fstar_secondary_lower, equations, surface_flux, dg, u_lower, mortar, orientation, cache) - calc_fstar!(fstar_secondary_upper, have_aux_node_vars(equations), - equations, surface_flux, dg, u_upper, mortar, orientation, cache) - calc_fstar!(fstar_secondary_lower, have_aux_node_vars(equations), - equations, surface_flux, dg, u_lower, mortar, orientation, cache) mortar_fluxes_to_elements!(surface_flux_values, mesh, equations, mortar_l2, dg, cache, mortar, fstar_primary_upper, fstar_primary_lower, fstar_secondary_upper, fstar_secondary_lower) end + return nothing +end +function calc_mortar_flux!(surface_flux_values, + mesh::TreeMesh{2}, + nonconservative_terms::False, + have_aux_node_vars::True, equations, + mortar_l2::LobattoLegendreMortarL2, + surface_integral, dg::DG, cache) + @unpack surface_flux = surface_integral + @unpack u_lower, u_upper, orientations = cache.mortars + @unpack (fstar_primary_upper_threaded, fstar_primary_lower_threaded, + fstar_secondary_upper_threaded, fstar_secondary_lower_threaded) = cache + @unpack aux_mortar_node_vars = cache.aux_vars + + @threaded for mortar in eachmortar(dg, cache) + # Choose thread-specific pre-allocated container + fstar_primary_upper = fstar_primary_upper_threaded[Threads.threadid()] + fstar_primary_lower = fstar_primary_lower_threaded[Threads.threadid()] + fstar_secondary_upper = fstar_secondary_upper_threaded[Threads.threadid()] + fstar_secondary_lower = fstar_secondary_lower_threaded[Threads.threadid()] + + # Calculate fluxes + orientation = orientations[mortar] + calc_fstar!(fstar_primary_upper, equations, + surface_flux, dg, u_upper, aux_mortar_node_vars, 2, mortar, + orientation, cache) + calc_fstar!(fstar_primary_lower, equations, + surface_flux, dg, u_lower, aux_mortar_node_vars, 1, mortar, + orientation, cache) + calc_fstar!(fstar_secondary_upper, equations, + surface_flux, dg, u_upper, aux_mortar_node_vars, 2, mortar, + orientation, cache) + calc_fstar!(fstar_secondary_lower, equations, + surface_flux, dg, u_lower, aux_mortar_node_vars, 1, mortar, + orientation, cache) + + mortar_fluxes_to_elements!(surface_flux_values, + mesh, equations, mortar_l2, dg, cache, + mortar, fstar_primary_upper, fstar_primary_lower, + fstar_secondary_upper, fstar_secondary_lower) + end return nothing end function calc_mortar_flux!(surface_flux_values, mesh::TreeMesh{2}, - nonconservative_terms::True, equations, + nonconservative_terms::True, + have_aux_node_vars::False, equations, mortar_l2::LobattoLegendreMortarL2, surface_integral, dg::DG, cache) surface_flux, nonconservative_flux = surface_integral.surface_flux @@ -1385,15 +1428,13 @@ function calc_mortar_flux!(surface_flux_values, # Calculate fluxes orientation = orientations[mortar] - calc_fstar!(fstar_primary_upper, have_aux_node_vars(equations), equations, + calc_fstar!(fstar_primary_upper, equations, surface_flux, dg, u_upper, mortar, orientation, cache) - calc_fstar!(fstar_primary_lower, have_aux_node_vars(equations), equations, + calc_fstar!(fstar_primary_lower, equations, surface_flux, dg, u_lower, mortar, orientation, cache) - calc_fstar!(fstar_secondary_upper, have_aux_node_vars(equations), - equations, + calc_fstar!(fstar_secondary_upper, equations, surface_flux, dg, u_upper, mortar, orientation, cache) - calc_fstar!(fstar_secondary_lower, have_aux_node_vars(equations), - equations, + calc_fstar!(fstar_secondary_lower, equations, surface_flux, dg, u_lower, mortar, orientation, cache) # Add nonconservative fluxes. @@ -1470,13 +1511,144 @@ function calc_mortar_flux!(surface_flux_values, mortar, fstar_primary_upper, fstar_primary_lower, fstar_secondary_upper, fstar_secondary_lower) end + return nothing +end + +function calc_mortar_flux!(surface_flux_values, + mesh::TreeMesh{2}, + nonconservative_terms::True, + have_aux_node_vars::True, equations, + mortar_l2::LobattoLegendreMortarL2, + surface_integral, dg::DG, cache) + surface_flux, nonconservative_flux = surface_integral.surface_flux + @unpack u_lower, u_upper, orientations, large_sides = cache.mortars + @unpack (fstar_primary_upper_threaded, fstar_primary_lower_threaded, + fstar_secondary_upper_threaded, fstar_secondary_lower_threaded) = cache + @unpack aux_mortar_node_vars = cache.aux_vars + + @threaded for mortar in eachmortar(dg, cache) + # Choose thread-specific pre-allocated container + fstar_primary_upper = fstar_primary_upper_threaded[Threads.threadid()] + fstar_primary_lower = fstar_primary_lower_threaded[Threads.threadid()] + fstar_secondary_upper = fstar_secondary_upper_threaded[Threads.threadid()] + fstar_secondary_lower = fstar_secondary_lower_threaded[Threads.threadid()] + + # Calculate fluxes + orientation = orientations[mortar] + calc_fstar!(fstar_primary_upper, equations, surface_flux, dg, u_upper, + aux_mortar_node_vars, 2, mortar, orientation, cache) + calc_fstar!(fstar_primary_lower, equations, surface_flux, dg, u_lower, + aux_mortar_node_vars, 1, mortar, orientation, cache) + calc_fstar!(fstar_secondary_upper, equations, surface_flux, dg, u_upper, + aux_mortar_node_vars, 2, mortar, orientation, cache) + calc_fstar!(fstar_secondary_lower, equations, surface_flux, dg, u_lower, + aux_mortar_node_vars, 1, mortar, orientation, cache) + + # Add nonconservative fluxes. + # These need to be adapted on the geometry (left/right) since the order of + # the arguments matters, based on the global SBP operator interpretation. + # The same interpretation (global SBP operators coupled discontinuously via + # central fluxes/SATs) explains why we need the factor 0.5. + # Alternatively, you can also follow the argumentation of Bohm et al. 2018 + # ("nonconservative diamond flux") + if large_sides[mortar] == 1 # -> small elements on right side + for i in eachnode(dg) + # Pull the left and right solutions + u_upper_ll, u_upper_rr = get_surface_node_vars(u_upper, equations, dg, + i, mortar) + u_lower_ll, u_lower_rr = get_surface_node_vars(u_lower, equations, dg, + i, mortar) + aux_upper_ll, aux_upper_rr = get_aux_surface_node_vars(aux_mortar_node_vars, + equations, dg, 2, + i, mortar) + aux_lower_ll, aux_lower_rr = get_aux_surface_node_vars(aux_mortar_node_vars, + equations, dg, 1, + i, mortar) + # Call pointwise nonconservative term + noncons_primary_upper = nonconservative_flux(u_upper_ll, u_upper_rr, + aux_upper_ll, aux_upper_rr, + orientation, equations) + noncons_primary_lower = nonconservative_flux(u_lower_ll, u_lower_rr, + aux_lower_ll, aux_lower_rr, + orientation, equations) + noncons_secondary_upper = nonconservative_flux(u_upper_rr, u_upper_ll, + aux_upper_rr, + aux_upper_ll, + orientation, equations) + noncons_secondary_lower = nonconservative_flux(u_lower_rr, u_lower_ll, + aux_lower_rr, + aux_lower_ll, + orientation, equations) + # Add to primary and secondary temporary storage + multiply_add_to_node_vars!(fstar_primary_upper, 0.5f0, + noncons_primary_upper, equations, + dg, i) + multiply_add_to_node_vars!(fstar_primary_lower, 0.5f0, + noncons_primary_lower, equations, + dg, i) + multiply_add_to_node_vars!(fstar_secondary_upper, 0.5f0, + noncons_secondary_upper, equations, + dg, i) + multiply_add_to_node_vars!(fstar_secondary_lower, 0.5f0, + noncons_secondary_lower, equations, + dg, i) + end + else # large_sides[mortar] == 2 -> small elements on the left + for i in eachnode(dg) + # Pull the left and right solutions + u_upper_ll, u_upper_rr = get_surface_node_vars(u_upper, equations, dg, + i, mortar) + u_lower_ll, u_lower_rr = get_surface_node_vars(u_lower, equations, dg, + i, mortar) + aux_upper_ll, aux_upper_rr = get_aux_surface_node_vars(aux_mortar_node_vars, + equations, dg, 2, + i, mortar) + aux_lower_ll, aux_lower_rr = get_aux_surface_node_vars(aux_mortar_node_vars, + equations, dg, 1, + i, mortar) + + # Call pointwise nonconservative term + noncons_primary_upper = nonconservative_flux(u_upper_rr, u_upper_ll, + aux_upper_rr, aux_upper_ll, + orientation, equations) + noncons_primary_lower = nonconservative_flux(u_lower_rr, u_lower_ll, + aux_lower_rr, aux_lower_ll, + orientation, equations) + noncons_secondary_upper = nonconservative_flux(u_upper_ll, u_upper_rr, + aux_upper_ll, + aux_upper_rr, + orientation, equations) + noncons_secondary_lower = nonconservative_flux(u_lower_ll, u_lower_rr, + aux_lower_ll, + aux_lower_rr, + orientation, equations) + # Add to primary and secondary temporary storage + multiply_add_to_node_vars!(fstar_primary_upper, 0.5f0, + noncons_primary_upper, equations, + dg, i) + multiply_add_to_node_vars!(fstar_primary_lower, 0.5f0, + noncons_primary_lower, equations, + dg, i) + multiply_add_to_node_vars!(fstar_secondary_upper, 0.5f0, + noncons_secondary_upper, equations, + dg, i) + multiply_add_to_node_vars!(fstar_secondary_lower, 0.5f0, + noncons_secondary_lower, equations, + dg, i) + end + end + + mortar_fluxes_to_elements!(surface_flux_values, + mesh, equations, mortar_l2, dg, cache, + mortar, fstar_primary_upper, fstar_primary_lower, + fstar_secondary_upper, fstar_secondary_lower) + end return nothing end @inline function calc_fstar!(destination::AbstractArray{<:Any, 2}, - have_aux_node_vars::False, equations, - surface_flux, dg::DGSEM, + equations, surface_flux, dg::DGSEM, u_interfaces, interface, orientation, cache) for i in eachnode(dg) # Call pointwise two-point numerical flux function @@ -1491,15 +1663,13 @@ end end @inline function calc_fstar!(destination::AbstractArray{<:Any, 2}, - have_aux_node_vars::True, equations, - surface_flux, dg::DGSEM, - u_interfaces, interface, orientation, cache) - @unpack aux_surface_node_vars = cache.aux_vars + equations, surface_flux, dg::DGSEM, + u, aux, position, interface, orientation, cache) for i in eachnode(dg) # Call pointwise two-point numerical flux function - u_ll, u_rr = get_surface_node_vars(u_interfaces, equations, dg, i, interface) - aux_ll, aux_rr = get_aux_surface_node_vars(aux_surface_node_vars, - equations, dg, i, interface) + u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) + aux_ll, aux_rr = get_aux_surface_node_vars(aux, equations, dg, + position, i, interface) flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, orientation, equations) # Copy flux to left and right element storage diff --git a/src/solvers/dgsem_tree/indicators_2d.jl b/src/solvers/dgsem_tree/indicators_2d.jl index 21b8c5f661b..7d3b9396ac7 100644 --- a/src/solvers/dgsem_tree/indicators_2d.jl +++ b/src/solvers/dgsem_tree/indicators_2d.jl @@ -46,7 +46,7 @@ end modal_tmp1 = modal_tmp1_threaded[Threads.threadid()] # Calculate indicator variables at Gauss-Lobatto nodes - calc_indicator_inner!(indicator, u, element, indicator_hg.variable, + calc_indicator_inner!(indicator, u, element, mesh, indicator_hg.variable, have_aux_node_vars, equations, dg, cache) # Convert to modal representation @@ -96,18 +96,20 @@ end alpha[element] = min(alpha_max, alpha_element) end -@inline function calc_indicator_inner!(indicator, u, element, indicator_variable, - have_aux_node_vars::False, equations, solver, - cache) +@inline function calc_indicator_inner!(indicator, u, element, mesh::AbstractMesh{2}, + indicator_variable, + have_aux_node_vars::False, equations, + solver, cache) for j in eachnode(solver), i in eachnode(solver) u_local = get_node_vars(u, equations, solver, i, j, element) indicator[i, j] = indicator_variable(u_local, equations) end end -@inline function calc_indicator_inner!(indicator, u, element, indicator_variable, - have_aux_node_vars::True, equations, solver, - cache) +@inline function calc_indicator_inner!(indicator, u, element, mesh::AbstractMesh{2}, + indicator_variable, + have_aux_node_vars::True, equations, + solver, cache) @unpack aux_node_vars = cache.aux_vars for j in eachnode(solver), i in eachnode(solver) u_local = get_node_vars(u, equations, solver, i, j, element) From 2c1c8b8389f4e20d0f5dee6874fb710df0895eae Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Sat, 24 May 2025 02:42:34 +0200 Subject: [PATCH 44/83] aux mortar container --- src/solvers/dgsem_tree/containers.jl | 62 ++++++++++++++------ src/solvers/dgsem_tree/containers_2d.jl | 75 +++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 18 deletions(-) diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index 41654b84559..691e7f1dc6a 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -38,7 +38,9 @@ function reinitialize_containers!(mesh::TreeMesh, equations, dg::DGSEM, cache) if hasproperty(cache, :aux_vars) @unpack aux_vars = cache resize!(aux_vars, length(leaf_cell_ids), - count_required_interfaces(mesh, leaf_cell_ids)) + count_required_interfaces(mesh, leaf_cell_ids), + count_required_boundaries(mesh, leaf_cell_ids), + count_required_mortars(mesh, leaf_cell_ids)) init_aux_vars!(aux_vars, mesh, equations, dg, cache) end @@ -61,15 +63,17 @@ function reinitialize_containers!(mesh::TreeMesh, equations, dg::DGSEM, cache) end # Container for storing values of auxiliary variables at volume/surface quadrature nodes -mutable struct AuxNodeVarsContainer{NDIMS, uEltype <: Real, NDIMSP2, AuxField} +mutable struct AuxNodeVarsContainer{NDIMS, uEltype <: Real, NDIMSP2, NDIMSP3, AuxField} aux_node_vars::Array{uEltype, NDIMSP2} # [var, i, j, element] aux_surface_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] - aux_boundary_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] + aux_boundary_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, boundary] + aux_mortar_node_vars::Array{uEltype, NDIMSP3} # [leftright, var, pos, i, mortar] # internal `resize!`able storage _aux_node_vars::Vector{uEltype} _aux_surface_node_vars::Vector{uEltype} _aux_boundary_node_vars::Vector{uEltype} + _aux_mortar_node_vars::Vector{uEltype} # save initialization function aux_field::AuxField @@ -80,11 +84,12 @@ nnodes(aux_vars::AuxNodeVarsContainer) = size(aux_vars.aux_node_vars, 2) # Create auxiliary node variable container function init_aux_vars(mesh, equations, solver, cache, aux_field) - @unpack elements, interfaces, boundaries = cache + @unpack elements, interfaces, boundaries, mortars = cache n_elements = nelements(elements) n_interfaces = ninterfaces(interfaces) n_boundaries = nboundaries(boundaries) + n_mortars = nmortars(mortars) NDIMS = ndims(mesh) uEltype = eltype(elements) nan_uEltype = convert(uEltype, NaN) @@ -116,14 +121,27 @@ function init_aux_vars(mesh, equations, solver, cache, aux_field) ntuple(_ -> nnodes(solver), NDIMS - 1)..., n_boundaries)) - - aux_vars = AuxNodeVarsContainer{NDIMS, uEltype, NDIMS + 2, + _aux_mortar_node_vars = fill(nan_uEltype, + 2 * n_aux_node_vars(equations) * + 2^(NDIMS - 1) * nnodes(solver)^(NDIMS - 1) * + n_mortars) + aux_mortar_node_vars = unsafe_wrap(Array, + pointer(_aux_mortar_node_vars), + (2, n_aux_node_vars(equations), + 2^(NDIMS - 1), + ntuple(_ -> nnodes(solver), + NDIMS - 1)..., + n_mortars)) + + aux_vars = AuxNodeVarsContainer{NDIMS, uEltype, NDIMS + 2, NDIMS + 3, typeof(aux_field)}(aux_node_vars, aux_surface_node_vars, aux_boundary_node_vars, + aux_mortar_node_vars, _aux_node_vars, _aux_surface_node_vars, _aux_boundary_node_vars, + _aux_mortar_node_vars, aux_field) init_aux_vars!(aux_vars, mesh, equations, solver, cache) return aux_vars @@ -133,6 +151,7 @@ function init_aux_vars!(aux_vars, mesh, equations, solver, cache) init_aux_node_vars!(aux_vars, mesh, equations, solver, cache) init_aux_surface_node_vars!(aux_vars, mesh, equations, solver, cache) init_aux_boundary_node_vars!(aux_vars, mesh, equations, solver, cache) + init_aux_mortar_node_vars!(aux_vars, mesh, equations, solver, cache) end # Initialize auxiliary node variables (generic implementation) @@ -162,8 +181,10 @@ end # internal storage. function Base.resize!(aux_vars::AuxNodeVarsContainer{NDIMS}, capacity_node_vars, capacity_node_surface_vars, - capacity_node_boundary_vars) where {NDIMS} - @unpack _aux_node_vars, _aux_surface_node_vars = aux_vars + capacity_node_boundary_vars, + capacity_node_mortar_vars) where {NDIMS} + @unpack _aux_node_vars, _aux_surface_node_vars, _aux_boundary_node_vars, + _aux_mortar_node_vars = aux_vars n_nodes = nnodes(aux_vars) n_variables = nvariables(aux_vars) @@ -171,8 +192,7 @@ function Base.resize!(aux_vars::AuxNodeVarsContainer{NDIMS}, aux_vars.aux_node_vars = unsafe_wrap(Array, pointer(_aux_node_vars), (n_variables, - ntuple(_ -> n_nodes, - NDIMS)..., + ntuple(_ -> n_nodes, NDIMS)..., capacity_node_vars)) resize!(_aux_surface_node_vars, @@ -181,18 +201,24 @@ function Base.resize!(aux_vars::AuxNodeVarsContainer{NDIMS}, aux_vars.aux_surface_node_vars = unsafe_wrap(Array, pointer(_aux_surface_node_vars), (2, n_variables, - ntuple(_ -> n_nodes, - NDIMS - 1)..., + ntuple(_ -> n_nodes, NDIMS - 1)..., capacity_node_surface_vars)) resize!(_aux_boundary_node_vars, 2 * n_variables * n_nodes^(NDIMS - 1) * capacity_node_boundary_vars) - aux_vars.aux_surface_node_vars = unsafe_wrap(Array, - pointer(_aux_boundary_node_vars), - (2, n_variables, - ntuple(_ -> n_nodes, - NDIMS - 1)..., - capacity_node_boundary_vars)) + aux_vars.aux_boundary_node_vars = unsafe_wrap(Array, + pointer(_aux_boundary_node_vars), + (2, n_variables, + ntuple(_ -> n_nodes, NDIMS - 1)..., + capacity_node_boundary_vars)) + resize!(_aux_mortar_node_vars, + 2 * n_variables * 2^(NDIMS - 1) * n_nodes^(NDIMS - 1) * + capacity_node_mortar_vars) + aux_vars.aux_mortar_node_vars = unsafe_wrap(Array, + pointer(_aux_mortar_node_vars), + (2, n_variables, 2^(NDIMS - 1), + ntuple(_ -> n_nodes, NDIMS - 1)..., + capacity_node_mortar_vars)) return nothing end diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index b9d2f93e4c0..ecd19410b10 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1512,4 +1512,79 @@ function init_aux_boundary_node_vars!(aux_vars, mesh::TreeMesh2D, equations, sol end return nothing end + +# Initialize auxiliary mortar node variables +# 2D TreeMesh implementation, similar to prolong2mortars +# Each mortar has two sides (indentified by first variable of u_upper / u_lower) +# On the side with two small elements, values can be copied from the aux vars field +# On the side with one large element, values are usually interpolated to small elements +# We do this differently here and use the same small element values on both side. This +# assumes that the aux_field computes a smooth variable field with no jumps +function init_aux_mortar_node_vars!(aux_vars, mesh::TreeMesh2D, equations, solver, + cache) + @unpack aux_node_vars, aux_mortar_node_vars = aux_vars + + @threaded for mortar in eachmortar(solver, cache) + upper_element = cache.mortars.neighbor_ids[2, mortar] + lower_element = cache.mortars.neighbor_ids[1, mortar] + + # Copy solution small to small + if cache.mortars.large_sides[mortar] == 1 # -> small elements on right side + if cache.mortars.orientations[mortar] == 1 + # L2 mortars in x-direction + for l in eachnode(solver) + for v in axes(aux_mortar_node_vars, 2) + aux_mortar_node_vars[:, v, 2, l, mortar] .= aux_node_vars[v, 1, + l, + upper_element] + aux_mortar_node_vars[:, v, 1, l, mortar] .= aux_node_vars[v, 1, + l, + lower_element] + end + end + else + # L2 mortars in y-direction + for l in eachnode(solver) + for v in axes(aux_mortar_node_vars, 2) + aux_mortar_node_vars[:, v, 2, l, mortar] .= aux_node_vars[v, l, + 1, + upper_element] + aux_mortar_node_vars[:, v, 1, l, mortar] .= aux_node_vars[v, l, + 1, + lower_element] + end + end + end + else # large_sides[mortar] == 2 -> small elements on left side + if cache.mortars.orientations[mortar] == 1 + # L2 mortars in x-direction + for l in eachnode(solver) + for v in axes(aux_mortar_node_vars, 2) + aux_mortar_node_vars[:, v, 2, l, mortar] .= aux_node_vars[v, + nnodes(solver), + l, + upper_element] + aux_mortar_node_vars[:, v, 1, l, mortar] .= aux_node_vars[v, + nnodes(solver), + l, + lower_element] + end + end + else + # L2 mortars in y-direction + for l in eachnode(solver) + for v in axes(aux_mortar_node_vars, 2) + aux_mortar_node_vars[:, v, 2, l, mortar] .= aux_node_vars[v, l, + nnodes(solver), + upper_element] + aux_mortar_node_vars[:, v, 1, l, mortar] .= aux_node_vars[v, l, + nnodes(solver), + lower_element] + end + end + end + end + end + return nothing +end end # @muladd From 2a8dab4faad22cff857a92ef8974b192bfbe9a44 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Mon, 25 Aug 2025 15:25:18 +0200 Subject: [PATCH 45/83] aux vars for MPI interfaces --- src/callbacks_step/save_solution_dg.jl | 11 ++--- src/solvers/dgsem_tree/containers.jl | 63 ++++++++++++++++++------ src/solvers/dgsem_tree/containers_2d.jl | 49 ++++++++++++++++++ src/solvers/dgsem_tree/dg_2d_parallel.jl | 7 +-- 4 files changed, 104 insertions(+), 26 deletions(-) diff --git a/src/callbacks_step/save_solution_dg.jl b/src/callbacks_step/save_solution_dg.jl index c99949be2cc..10708857977 100644 --- a/src/callbacks_step/save_solution_dg.jl +++ b/src/callbacks_step/save_solution_dg.jl @@ -137,14 +137,9 @@ function save_solution_file(u, time, dt, timestep, data = u n_vars = nvariables(equations) else - # Reinterpret the solution array as an array of conservative variables, - # compute the solution variables via broadcasting, and reinterpret the - # result as a plain array of floating point numbers - data = Array(reinterpret(eltype(u), - solution_variables.(reinterpret(SVector{nvariables(equations), - eltype(u)}, u), - Ref(equations)))) - + data = convert_to_solution_variables(u, solution_variables, cache, + have_aux_node_vars(equations), + equations) # Find out variable count by looking at output from `solution_variables` function n_vars = size(data, 1) end diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index 691e7f1dc6a..943626d919b 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -40,7 +40,8 @@ function reinitialize_containers!(mesh::TreeMesh, equations, dg::DGSEM, cache) resize!(aux_vars, length(leaf_cell_ids), count_required_interfaces(mesh, leaf_cell_ids), count_required_boundaries(mesh, leaf_cell_ids), - count_required_mortars(mesh, leaf_cell_ids)) + count_required_mortars(mesh, leaf_cell_ids), + count_required_mpi_interfaces(mesh, leaf_cell_ids)) init_aux_vars!(aux_vars, mesh, equations, dg, cache) end @@ -64,16 +65,18 @@ end # Container for storing values of auxiliary variables at volume/surface quadrature nodes mutable struct AuxNodeVarsContainer{NDIMS, uEltype <: Real, NDIMSP2, NDIMSP3, AuxField} - aux_node_vars::Array{uEltype, NDIMSP2} # [var, i, j, element] - aux_surface_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] - aux_boundary_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, boundary] - aux_mortar_node_vars::Array{uEltype, NDIMSP3} # [leftright, var, pos, i, mortar] + aux_node_vars::Array{uEltype, NDIMSP2} # [var, i, j, element] + aux_surface_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] + aux_boundary_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, boundary] + aux_mortar_node_vars::Array{uEltype, NDIMSP3} # [leftright, var, pos, i, mortar] + aux_mpiinterface_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] # internal `resize!`able storage _aux_node_vars::Vector{uEltype} _aux_surface_node_vars::Vector{uEltype} _aux_boundary_node_vars::Vector{uEltype} _aux_mortar_node_vars::Vector{uEltype} + _aux_mpiinterface_node_vars::Vector{uEltype} # save initialization function aux_field::AuxField @@ -90,6 +93,11 @@ function init_aux_vars(mesh, equations, solver, cache, aux_field) n_interfaces = ninterfaces(interfaces) n_boundaries = nboundaries(boundaries) n_mortars = nmortars(mortars) + if mpi_isparallel() + n_mpiinterfaces = nmpiinterfaces(cache.mpi_interfaces) + else + n_mpiinterfaces = 0 + end NDIMS = ndims(mesh) uEltype = eltype(elements) nan_uEltype = convert(uEltype, NaN) @@ -132,16 +140,28 @@ function init_aux_vars(mesh, equations, solver, cache, aux_field) ntuple(_ -> nnodes(solver), NDIMS - 1)..., n_mortars)) + _aux_mpiinterface_node_vars = fill(nan_uEltype, + 2 * n_aux_node_vars(equations) * + nnodes(solver)^(NDIMS - 1) * + n_mpiinterfaces) + aux_mpiinterface_node_vars = unsafe_wrap(Array, + pointer(_aux_mpiinterface_node_vars), + (2, n_aux_node_vars(equations), + ntuple(_ -> nnodes(solver), + NDIMS - 1)..., + n_mpiinterfaces)) aux_vars = AuxNodeVarsContainer{NDIMS, uEltype, NDIMS + 2, NDIMS + 3, typeof(aux_field)}(aux_node_vars, aux_surface_node_vars, aux_boundary_node_vars, aux_mortar_node_vars, + aux_mpiinterface_node_vars, _aux_node_vars, _aux_surface_node_vars, _aux_boundary_node_vars, _aux_mortar_node_vars, + _aux_mpiinterface_node_vars, aux_field) init_aux_vars!(aux_vars, mesh, equations, solver, cache) return aux_vars @@ -152,6 +172,9 @@ function init_aux_vars!(aux_vars, mesh, equations, solver, cache) init_aux_surface_node_vars!(aux_vars, mesh, equations, solver, cache) init_aux_boundary_node_vars!(aux_vars, mesh, equations, solver, cache) init_aux_mortar_node_vars!(aux_vars, mesh, equations, solver, cache) + if mpi_isparallel() + init_aux_mpiinterface_node_vars!(aux_vars, mesh, equations, solver, cache) + end end # Initialize auxiliary node variables (generic implementation) @@ -180,11 +203,12 @@ end # `unsafe_wrap`ping multi-dimensional `Array`s around the # internal storage. function Base.resize!(aux_vars::AuxNodeVarsContainer{NDIMS}, - capacity_node_vars, capacity_node_surface_vars, - capacity_node_boundary_vars, - capacity_node_mortar_vars) where {NDIMS} + capacity_node_vars, capacity_surface_node_vars, + capacity_boundary_node_vars, + capacity_mortar_node_vars, + capacity_mpiinterface_node_vars) where {NDIMS} @unpack _aux_node_vars, _aux_surface_node_vars, _aux_boundary_node_vars, - _aux_mortar_node_vars = aux_vars + _aux_mortar_node_vars, _aux_mpiinterface_node_vars = aux_vars n_nodes = nnodes(aux_vars) n_variables = nvariables(aux_vars) @@ -197,28 +221,37 @@ function Base.resize!(aux_vars::AuxNodeVarsContainer{NDIMS}, resize!(_aux_surface_node_vars, 2 * n_variables * n_nodes^(NDIMS - 1) * - capacity_node_surface_vars) + capacity_surface_node_vars) aux_vars.aux_surface_node_vars = unsafe_wrap(Array, pointer(_aux_surface_node_vars), (2, n_variables, ntuple(_ -> n_nodes, NDIMS - 1)..., - capacity_node_surface_vars)) + capacity_surface_node_vars)) resize!(_aux_boundary_node_vars, 2 * n_variables * n_nodes^(NDIMS - 1) * - capacity_node_boundary_vars) + capacity_boundary_node_vars) aux_vars.aux_boundary_node_vars = unsafe_wrap(Array, pointer(_aux_boundary_node_vars), (2, n_variables, ntuple(_ -> n_nodes, NDIMS - 1)..., - capacity_node_boundary_vars)) + capacity_boundary_node_vars)) resize!(_aux_mortar_node_vars, 2 * n_variables * 2^(NDIMS - 1) * n_nodes^(NDIMS - 1) * - capacity_node_mortar_vars) + capacity_mortar_node_vars) aux_vars.aux_mortar_node_vars = unsafe_wrap(Array, pointer(_aux_mortar_node_vars), (2, n_variables, 2^(NDIMS - 1), ntuple(_ -> n_nodes, NDIMS - 1)..., - capacity_node_mortar_vars)) + capacity_mortar_node_vars)) + resize!(_aux_mpiinterface_node_vars, + 2 * n_variables * n_nodes^(NDIMS - 1) * + capacity_mpiinterface_node_vars) + aux_vars.aux_mpiinterface_node_vars = unsafe_wrap(Array, + pointer(_aux_mpiinterface_node_vars), + (2, n_variables, + ntuple(_ -> n_nodes, + NDIMS - 1)..., + capacity_mpiinterface_node_vars)) return nothing end diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index ecd19410b10..7b0a59c3ad4 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1587,4 +1587,53 @@ function init_aux_mortar_node_vars!(aux_vars, mesh::TreeMesh2D, equations, solve end return nothing end + +# Initialize auxiliary MPI interface node variables +# 2D TreeMesh implementation, similar to prolong2mpiinterfaces +# However we directly assign to both sides, assuming the aux field had no jumps. Therefore +# we do not need any exchange. +function init_aux_mpiinterface_node_vars!(aux_vars, mesh::TreeMesh2D, equations, solver, + cache) + @unpack aux_node_vars, aux_mpiinterface_node_vars = aux_vars + @unpack mpi_interfaces = cache + + @threaded for interface in eachmpiinterface(solver, cache) + local_element = mpi_interfaces.local_neighbor_ids[interface] + + if mpi_interfaces.orientations[interface] == 1 # interface in x-direction + if mpi_interfaces.remote_sides[interface] == 1 # local element in positive direction + for j in eachnode(solver), v in axes(aux_mpiinterface_node_vars, 2) + aux_mpiinterface_node_vars[:, v, j, interface] .= aux_node_vars[v, + 1, + j, + local_element] + end + else # local element in negative direction + for j in eachnode(solver), v in axes(aux_mpiinterface_node_vars, 2) + aux_mpiinterface_node_vars[:, v, j, interface] .= aux_node_vars[v, + nnodes(solver), + j, + local_element] + end + end + else # interface in y-direction + if mpi_interfaces.remote_sides[interface] == 1 # local element in positive direction + for i in eachnode(solver), v in axes(aux_mpiinterface_node_vars, 2) + aux_mpiinterface_node_vars[:, v, i, interface] .= aux_node_vars[v, + i, + 1, + local_element] + end + else # local element in negative direction + for i in eachnode(solver), v in axes(aux_mpiinterface_node_vars, 2) + aux_mpiinterface_node_vars[:, v, i, interface] .= aux_node_vars[v, + i, + nnodes(solver), + local_element] + end + end + end + end + return nothing +end end # @muladd diff --git a/src/solvers/dgsem_tree/dg_2d_parallel.jl b/src/solvers/dgsem_tree/dg_2d_parallel.jl index 807d27e3ce7..583295fd278 100644 --- a/src/solvers/dgsem_tree/dg_2d_parallel.jl +++ b/src/solvers/dgsem_tree/dg_2d_parallel.jl @@ -516,7 +516,8 @@ function rhs!(du, u, t, # Calculate mortar fluxes @trixi_timeit timer() "mortar flux" begin calc_mortar_flux!(cache.elements.surface_flux_values, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_aux_node_vars(equations), equations, dg.mortar, dg.surface_integral, dg, cache) end @@ -772,7 +773,7 @@ function calc_mpi_interface_flux!(surface_flux_values, surface_integral, dg::DG, cache) @unpack surface_flux = surface_integral @unpack u, local_neighbor_ids, orientations, remote_sides = cache.mpi_interfaces - @unpack aux_surface_node_vars = cache.aux_vars + @unpack aux_mpiinterface_node_vars = cache.aux_vars @threaded for interface in eachmpiinterface(dg, cache) # Get local neighboring element @@ -796,7 +797,7 @@ function calc_mpi_interface_flux!(surface_flux_values, for i in eachnode(dg) # Call pointwise Riemann solver u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) - aux_ll, aux_rr = get_aux_surface_node_vars(aux_surface_node_vars, + aux_ll, aux_rr = get_aux_surface_node_vars(aux_mpiinterface_node_vars, equations, dg, i, interface) flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, From 6af4abcf46a357eab9b40b8da6a84712203fb8c3 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Mon, 1 Sep 2025 15:57:04 +0200 Subject: [PATCH 46/83] add MPI mortars --- src/callbacks_step/stepsize_dg2d.jl | 23 ++++- src/solvers/dgsem_tree/containers.jl | 57 +++++++--- src/solvers/dgsem_tree/containers_2d.jl | 126 ++++++++++++++++++++++- src/solvers/dgsem_tree/dg_2d.jl | 7 +- src/solvers/dgsem_tree/dg_2d_parallel.jl | 56 ++++++++-- 5 files changed, 239 insertions(+), 30 deletions(-) diff --git a/src/callbacks_step/stepsize_dg2d.jl b/src/callbacks_step/stepsize_dg2d.jl index 51bf06bdf75..1bfb3601d26 100644 --- a/src/callbacks_step/stepsize_dg2d.jl +++ b/src/callbacks_step/stepsize_dg2d.jl @@ -82,7 +82,26 @@ function max_dt(u, t, mesh::ParallelTreeMesh{2}, Tuple{typeof(u), typeof(t), TreeMesh{2}, typeof(constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, + u, t, mesh, constant_speed, False(), equations, dg, + cache) + # Base.min instead of min needed, see comment in src/auxiliary/math.jl + dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] + + return dt +end + +function max_dt(u, t, mesh::ParallelTreeMesh{2}, + constant_speed::False, have_aux_node_vars::True, + equations, dg::DG, cache) + # call the method accepting a general `mesh::TreeMesh{2}` + # TODO: MPI, we should improve this; maybe we should dispatch on `u` + # and create some MPI array type, overloading broadcasting and mapreduce etc. + # Then, this specific array type should also work well with DiffEq etc. + dt = invoke(max_dt, + Tuple{typeof(u), typeof(t), TreeMesh{2}, + typeof(constant_speed), typeof(have_aux_node_vars), + typeof(equations), typeof(dg), typeof(cache)}, + u, t, mesh, constant_speed, True(), equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -101,7 +120,7 @@ function max_dt(u, t, mesh::ParallelTreeMesh{2}, Tuple{typeof(u), typeof(t), TreeMesh{2}, typeof(constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, + u, t, mesh, constant_speed, False(), equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] diff --git a/src/solvers/dgsem_tree/containers.jl b/src/solvers/dgsem_tree/containers.jl index e128bda57cf..45704c56768 100644 --- a/src/solvers/dgsem_tree/containers.jl +++ b/src/solvers/dgsem_tree/containers.jl @@ -34,17 +34,6 @@ function reinitialize_containers!(mesh::TreeMesh, equations, dg::DGSEM, cache) init_mortars!(mortars, elements, mesh) end - # re-initialize auxiliary variables container - if hasproperty(cache, :aux_vars) - @unpack aux_vars = cache - resize!(aux_vars, length(leaf_cell_ids), - count_required_interfaces(mesh, leaf_cell_ids), - count_required_boundaries(mesh, leaf_cell_ids), - count_required_mortars(mesh, leaf_cell_ids), - count_required_mpi_interfaces(mesh, leaf_cell_ids)) - init_aux_vars!(aux_vars, mesh, equations, dg, cache) - end - if mpi_isparallel() # re-initialize mpi_interfaces container @unpack mpi_interfaces = cache @@ -62,6 +51,18 @@ function reinitialize_containers!(mesh::TreeMesh, equations, dg::DGSEM, cache) nvariables(equations), nnodes(dg), eltype(elements)) end + # re-initialize auxiliary variables container + if hasproperty(cache, :aux_vars) + @unpack aux_vars = cache + resize!(aux_vars, length(leaf_cell_ids), + count_required_interfaces(mesh, leaf_cell_ids), + count_required_boundaries(mesh, leaf_cell_ids), + count_required_mortars(mesh, leaf_cell_ids), + count_required_mpi_interfaces(mesh, leaf_cell_ids), + count_required_mpi_mortars(mesh, leaf_cell_ids)) + init_aux_vars!(aux_vars, mesh, equations, dg, cache) + end + return nothing end @@ -72,6 +73,7 @@ mutable struct AuxNodeVarsContainer{NDIMS, uEltype <: Real, NDIMSP2, NDIMSP3, Au aux_boundary_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, boundary] aux_mortar_node_vars::Array{uEltype, NDIMSP3} # [leftright, var, pos, i, mortar] aux_mpiinterface_node_vars::Array{uEltype, NDIMSP2} # [leftright, var, i, interface] + aux_mpimortar_node_vars::Array{uEltype, NDIMSP3} # [leftright, var, pos, i, mortar] # internal `resize!`able storage _aux_node_vars::Vector{uEltype} @@ -79,6 +81,7 @@ mutable struct AuxNodeVarsContainer{NDIMS, uEltype <: Real, NDIMSP2, NDIMSP3, Au _aux_boundary_node_vars::Vector{uEltype} _aux_mortar_node_vars::Vector{uEltype} _aux_mpiinterface_node_vars::Vector{uEltype} + _aux_mpimortar_node_vars::Vector{uEltype} # save initialization function aux_field::AuxField @@ -97,8 +100,10 @@ function init_aux_vars(mesh, equations, solver, cache, aux_field) n_mortars = nmortars(mortars) if mpi_isparallel() n_mpiinterfaces = nmpiinterfaces(cache.mpi_interfaces) + n_mpimortars = nmpimortars(cache.mpi_mortars) else n_mpiinterfaces = 0 + n_mpimortars = 0 end NDIMS = ndims(mesh) uEltype = eltype(elements) @@ -152,6 +157,17 @@ function init_aux_vars(mesh, equations, solver, cache, aux_field) ntuple(_ -> nnodes(solver), NDIMS - 1)..., n_mpiinterfaces)) + _aux_mpimortar_node_vars = fill(nan_uEltype, + 2 * n_aux_node_vars(equations) * + 2^(NDIMS - 1) * nnodes(solver)^(NDIMS - 1) * + n_mpimortars) + aux_mpimortar_node_vars = unsafe_wrap(Array, + pointer(_aux_mpimortar_node_vars), + (2, n_aux_node_vars(equations), + 2^(NDIMS - 1), + ntuple(_ -> nnodes(solver), + NDIMS - 1)..., + n_mpimortars)) aux_vars = AuxNodeVarsContainer{NDIMS, uEltype, NDIMS + 2, NDIMS + 3, typeof(aux_field)}(aux_node_vars, @@ -159,11 +175,13 @@ function init_aux_vars(mesh, equations, solver, cache, aux_field) aux_boundary_node_vars, aux_mortar_node_vars, aux_mpiinterface_node_vars, + aux_mpimortar_node_vars, _aux_node_vars, _aux_surface_node_vars, _aux_boundary_node_vars, _aux_mortar_node_vars, _aux_mpiinterface_node_vars, + _aux_mpimortar_node_vars, aux_field) init_aux_vars!(aux_vars, mesh, equations, solver, cache) return aux_vars @@ -176,6 +194,7 @@ function init_aux_vars!(aux_vars, mesh, equations, solver, cache) init_aux_mortar_node_vars!(aux_vars, mesh, equations, solver, cache) if mpi_isparallel() init_aux_mpiinterface_node_vars!(aux_vars, mesh, equations, solver, cache) + init_aux_mpimortar_node_vars!(aux_vars, mesh, equations, solver, cache) end end @@ -208,11 +227,12 @@ function Base.resize!(aux_vars::AuxNodeVarsContainer{NDIMS}, capacity_node_vars, capacity_surface_node_vars, capacity_boundary_node_vars, capacity_mortar_node_vars, - capacity_mpiinterface_node_vars) where {NDIMS} - @unpack _aux_node_vars, _aux_surface_node_vars, _aux_boundary_node_vars, - _aux_mortar_node_vars, _aux_mpiinterface_node_vars = aux_vars + capacity_mpiinterface_node_vars, + capacity_mpimortar_node_vars) where {NDIMS} + @unpack _aux_node_vars, _aux_surface_node_vars, _aux_boundary_node_vars, _aux_mortar_node_vars, _aux_mpiinterface_node_vars, _aux_mpimortar_node_vars = aux_vars n_nodes = nnodes(aux_vars) n_variables = nvariables(aux_vars) + nan_uEltype = convert(eltype(_aux_node_vars), NaN) resize!(_aux_node_vars, n_variables * n_nodes^NDIMS * capacity_node_vars) aux_vars.aux_node_vars = unsafe_wrap(Array, @@ -254,6 +274,15 @@ function Base.resize!(aux_vars::AuxNodeVarsContainer{NDIMS}, ntuple(_ -> n_nodes, NDIMS - 1)..., capacity_mpiinterface_node_vars)) + resize!(_aux_mpimortar_node_vars, + 2 * n_variables * 2^(NDIMS - 1) * n_nodes^(NDIMS - 1) * + capacity_mpimortar_node_vars) + _aux_mpimortar_node_vars .= nan_uEltype + aux_vars.aux_mpimortar_node_vars = unsafe_wrap(Array, + pointer(_aux_mpimortar_node_vars), + (2, n_variables, 2^(NDIMS - 1), + ntuple(_ -> n_nodes, NDIMS - 1)..., + capacity_mpimortar_node_vars)) return nothing end diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index 7b0a59c3ad4..a6b9dad42fa 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1592,8 +1592,9 @@ end # 2D TreeMesh implementation, similar to prolong2mpiinterfaces # However we directly assign to both sides, assuming the aux field had no jumps. Therefore # we do not need any exchange. -function init_aux_mpiinterface_node_vars!(aux_vars, mesh::TreeMesh2D, equations, solver, - cache) +function init_aux_mpiinterface_node_vars!(aux_vars, mesh::ParallelTreeMesh{2}, + equations, + solver, cache) @unpack aux_node_vars, aux_mpiinterface_node_vars = aux_vars @unpack mpi_interfaces = cache @@ -1636,4 +1637,125 @@ function init_aux_mpiinterface_node_vars!(aux_vars, mesh::TreeMesh2D, equations, end return nothing end + +# Initialize auxiliary MPI mortar node variables +# 2D TreeMesh implementation, similar to prolong2mpimortars +# However: - We only assign the small element values (only leftright = 1 is used) +# - These have to be communicated +function init_aux_mpimortar_node_vars!(aux_vars, mesh::ParallelTreeMesh{2}, equations, + solver, cache) + @unpack aux_node_vars, aux_mpimortar_node_vars = aux_vars + @unpack mpi_mortars = cache + + @threaded for mortar in eachmpimortar(solver, cache) + local_neighbor_ids = mpi_mortars.local_neighbor_ids[mortar] + local_neighbor_positions = mpi_mortars.local_neighbor_positions[mortar] + for (element, position) in zip(local_neighbor_ids, local_neighbor_positions) + if position in (1, 2) # small element + if mpi_mortars.large_sides[mortar] == 1 # -> small elements on right side + if mpi_mortars.orientations[mortar] == 1 + # L2 mortars in x-direction + for l in eachnode(solver) + for v in axes(aux_mpimortar_node_vars, 2) + aux_mpimortar_node_vars[1, v, position, l, mortar] = aux_node_vars[v, + 1, + l, + element] + end + end + else + # L2 mortars in y-direction + for l in eachnode(solver) + for v in axes(aux_mpimortar_node_vars, 2) + aux_mpimortar_node_vars[1, v, position, l, mortar] = aux_node_vars[v, + l, + 1, + element] + end + end + end + else # large_sides[mortar] == 2 -> small elements on left side + if mpi_mortars.orientations[mortar] == 1 + # L2 mortars in x-direction + for l in eachnode(solver) + for v in axes(aux_mpimortar_node_vars, 2) + aux_mpimortar_node_vars[1, v, position, l, mortar] = aux_node_vars[v, + nnodes(solver), + l, + element] + end + end + else + # L2 mortars in y-direction + for l in eachnode(solver) + for v in axes(aux_mpimortar_node_vars, 2) + aux_mpimortar_node_vars[1, v, position, l, mortar] = aux_node_vars[v, + l, + nnodes(solver), + element] + end + end + end + end + end + end + end + + data_size = nnodes(solver) * n_aux_node_vars(equations) + exchange_aux_mpimortars!(aux_mpimortar_node_vars, cache, data_size) + return nothing +end + +function exchange_aux_mpimortars!(aux_mpimortar_node_vars, cache, data_size) + @unpack mpi_cache = cache + + for rank in 1:length(mpi_cache.mpi_neighbor_ranks) + send_buffer = mpi_cache.mpi_send_buffers[rank] + mortars_data_size = length(mpi_cache.mpi_neighbor_mortars[rank]) * data_size * 2 + send_buffer[1:mortars_data_size] .= NaN + for (index, mortar) in enumerate(mpi_cache.mpi_neighbor_mortars[rank]) + base_index = (index - 1) * 2 * data_size + 1 + for position in cache.mpi_mortars.local_neighbor_positions[mortar] + # Determine whether the data belongs to the left or right side + if position in (1, 2) # small element + first = base_index + (position - 1) * data_size + last = first - 1 + data_size + @views send_buffer[first:last] .= vec(aux_mpimortar_node_vars[1, :, + position, + :, + mortar]) + end + end + end + end + + # Start data exchange + for (index, rank) in enumerate(mpi_cache.mpi_neighbor_ranks) + mpi_cache.mpi_send_requests[index] = MPI.Isend(mpi_cache.mpi_send_buffers[index], + rank, mpi_rank(), mpi_comm()) + mpi_cache.mpi_recv_requests[index] = MPI.Irecv!(mpi_cache.mpi_recv_buffers[index], + rank, rank, mpi_comm()) + end + + data = MPI.Waitany(mpi_cache.mpi_recv_requests) + while data !== nothing + recv_buffer = mpi_cache.mpi_recv_buffers[data] + for (index, mortar) in enumerate(mpi_cache.mpi_neighbor_mortars[data]) + base_index = (index - 1) * 2 * data_size + 1 + for position in 1:2 + first = base_index + (position - 1) * data_size + last = first - 1 + data_size + # Skip if received data for `position` is NaN as no real data has been sent for the + # corresponding element + if !isnan(recv_buffer[first]) + @views vec(aux_mpimortar_node_vars[1, :, position, :, mortar]) .= recv_buffer[first:last] + end + end + end + data = MPI.Waitany(mpi_cache.mpi_recv_requests) + end + + # Finish sending + MPI.Waitall(mpi_cache.mpi_send_requests, MPI.Status) +end end # @muladd diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index cc32d533f4a..7cc83d14988 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -1670,9 +1670,10 @@ end for i in eachnode(dg) # Call pointwise two-point numerical flux function u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) - aux_ll, aux_rr = get_aux_surface_node_vars(aux, equations, dg, - position, i, interface) - flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, orientation, equations) + aux_ll, _ = get_aux_surface_node_vars(aux, equations, dg, + position, i, interface) + # TODO: currently only leftright = 1 is used + flux = surface_flux(u_ll, u_rr, aux_ll, aux_ll, orientation, equations) # Copy flux to left and right element storage set_node_vars!(destination, flux, equations, dg, i) diff --git a/src/solvers/dgsem_tree/dg_2d_parallel.jl b/src/solvers/dgsem_tree/dg_2d_parallel.jl index 90e514b19e0..6d098374082 100644 --- a/src/solvers/dgsem_tree/dg_2d_parallel.jl +++ b/src/solvers/dgsem_tree/dg_2d_parallel.jl @@ -536,7 +536,8 @@ function rhs!(du, u, t, # Calculate MPI mortar fluxes @trixi_timeit timer() "MPI mortar flux" begin calc_mpi_mortar_flux!(cache.elements.surface_flux_values, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_aux_node_vars(equations), equations, dg.mortar, dg.surface_integral, dg, cache) end @@ -814,7 +815,8 @@ end function calc_mpi_mortar_flux!(surface_flux_values, mesh::ParallelTreeMesh{2}, - nonconservative_terms::False, equations, + nonconservative_terms::False, + have_aux_node_vars::False, equations, mortar_l2::LobattoLegendreMortarL2, surface_integral, dg::DG, cache) @unpack surface_flux = surface_integral @@ -831,15 +833,13 @@ function calc_mpi_mortar_flux!(surface_flux_values, # Because `nonconservative_terms` is `False` the primary and secondary fluxes # are identical. So, we could possibly save on computation and just pass two copies later. orientation = orientations[mortar] - calc_fstar!(fstar_primary_upper, have_aux_node_vars(equations), equations, + calc_fstar!(fstar_primary_upper, equations, surface_flux, dg, u_upper, mortar, orientation, cache) - calc_fstar!(fstar_primary_lower, have_aux_node_vars(equations), equations, + calc_fstar!(fstar_primary_lower, equations, surface_flux, dg, u_lower, mortar, orientation, cache) - calc_fstar!(fstar_secondary_upper, have_aux_node_vars(equations), - equations, + calc_fstar!(fstar_secondary_upper, equations, surface_flux, dg, u_upper, mortar, orientation, cache) - calc_fstar!(fstar_secondary_lower, have_aux_node_vars(equations), - equations, + calc_fstar!(fstar_secondary_lower, equations, surface_flux, dg, u_lower, mortar, orientation, cache) mpi_mortar_fluxes_to_elements!(surface_flux_values, @@ -851,6 +851,45 @@ function calc_mpi_mortar_flux!(surface_flux_values, return nothing end +function calc_mpi_mortar_flux!(surface_flux_values, + mesh::ParallelTreeMesh{2}, + nonconservative_terms::False, + have_aux_node_vars::True, equations, + mortar_l2::LobattoLegendreMortarL2, + surface_integral, dg::DG, cache) + @unpack surface_flux = surface_integral + @unpack u_lower, u_upper, orientations = cache.mpi_mortars + @unpack fstar_primary_upper_threaded, fstar_primary_lower_threaded, fstar_secondary_upper_threaded, fstar_secondary_lower_threaded = cache + @unpack aux_mpimortar_node_vars = cache.aux_vars + + @threaded for mortar in eachmpimortar(dg, cache) + # Choose thread-specific pre-allocated container + fstar_primary_upper = fstar_primary_upper_threaded[Threads.threadid()] + fstar_primary_lower = fstar_primary_lower_threaded[Threads.threadid()] + fstar_secondary_upper = fstar_secondary_upper_threaded[Threads.threadid()] + fstar_secondary_lower = fstar_secondary_lower_threaded[Threads.threadid()] + + # Because `nonconservative_terms` is `False` the primary and secondary fluxes + # are identical. So, we could possibly save on computation and just pass two copies later. + orientation = orientations[mortar] + calc_fstar!(fstar_primary_upper, equations, surface_flux, dg, u_upper, + aux_mpimortar_node_vars, 2, mortar, orientation, cache) + calc_fstar!(fstar_primary_lower, equations, surface_flux, dg, u_lower, + aux_mpimortar_node_vars, 1, mortar, orientation, cache) + calc_fstar!(fstar_secondary_upper, equations, surface_flux, dg, u_upper, + aux_mpimortar_node_vars, 2, mortar, orientation, cache) + calc_fstar!(fstar_secondary_lower, equations, surface_flux, dg, u_lower, + aux_mpimortar_node_vars, 1, mortar, orientation, cache) + + mpi_mortar_fluxes_to_elements!(surface_flux_values, + mesh, equations, mortar_l2, dg, cache, + mortar, fstar_primary_upper, fstar_primary_lower, + fstar_secondary_upper, fstar_secondary_lower) + end + + return nothing +end + @inline function mpi_mortar_fluxes_to_elements!(surface_flux_values, mesh::ParallelTreeMesh{2}, equations, mortar_l2::LobattoLegendreMortarL2, @@ -907,7 +946,6 @@ end direction = 3 end end - multiply_dimensionwise!(view(surface_flux_values, :, :, direction, element), mortar_l2.reverse_upper, fstar_secondary_upper, mortar_l2.reverse_lower, fstar_secondary_lower) From b209dae8b2d7463f96c88106337a219345207308 Mon Sep 17 00:00:00 2001 From: Benedict <135045760+benegee@users.noreply.github.com> Date: Tue, 23 Sep 2025 14:32:34 +0200 Subject: [PATCH 47/83] Apply suggestions from code review Co-authored-by: Joshua Lampert <51029046+JoshuaLampert@users.noreply.github.com> --- test/test_tree_2d_acoustics.jl | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/test/test_tree_2d_acoustics.jl b/test/test_tree_2d_acoustics.jl index 7fb602db349..f5314f906d1 100644 --- a/test/test_tree_2d_acoustics.jl +++ b/test/test_tree_2d_acoustics.jl @@ -55,12 +55,7 @@ end ]) # Ensure that we do not have excessive memory allocations # (e.g., from type instabilities) - let - t = sol.t[end] - u_ode = sol.u[end] - du_ode = similar(u_ode) - @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 - end + @test_allocations(Trixi.rhs!, semi, sol, 1000) end @trixi_testset "elixir_acoustics_gauss.jl" begin @@ -152,12 +147,7 @@ end 1.0355388011792845]) # Ensure that we do not have excessive memory allocations # (e.g., from type instabilities) - let - t = sol.t[end] - u_ode = sol.u[end] - du_ode = similar(u_ode) - @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 - end + @test_allocations(Trixi.rhs!, semi, sol, 1000) end @trixi_testset "elixir_acoustics_gauss_wall_amr_auxvars.jl" begin @@ -167,12 +157,7 @@ end linf=[0.183057645, 0.190845961, 1.03618809]) # Ensure that we do not have excessive memory allocations # (e.g., from type instabilities) - let - t = sol.t[end] - u_ode = sol.u[end] - du_ode = similar(u_ode) - @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 - end + @test_allocations(Trixi.rhs!, semi, sol, 1000) end @trixi_testset "elixir_acoustics_monopole.jl" begin From 590898692f3f8175eea74d20fc00c6b7e2a69e03 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Tue, 30 Sep 2025 11:02:36 +0200 Subject: [PATCH 48/83] fmt --- src/solvers/dgsem_p4est/dg_2d_parallel.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/solvers/dgsem_p4est/dg_2d_parallel.jl b/src/solvers/dgsem_p4est/dg_2d_parallel.jl index 5f72bebec4b..90cc183489d 100644 --- a/src/solvers/dgsem_p4est/dg_2d_parallel.jl +++ b/src/solvers/dgsem_p4est/dg_2d_parallel.jl @@ -87,7 +87,8 @@ function calc_mpi_interface_flux!(surface_flux_values, contravariant_vectors, i_element, j_element, local_element) - calc_mpi_interface_flux!(surface_flux_values, mesh, have_nonconservative_terms, + calc_mpi_interface_flux!(surface_flux_values, mesh, + have_nonconservative_terms, have_aux_node_vars, equations, surface_integral, dg, cache, interface, normal_direction, From 4782e38479f7b33e8eb06ae118a246101f760596 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Tue, 30 Sep 2025 16:13:33 +0200 Subject: [PATCH 49/83] after merge fixes --- src/callbacks_step/stepsize.jl | 3 ++- src/solvers/dgsem_p4est/dg_2d.jl | 2 +- src/solvers/dgsem_tree/containers_2d.jl | 2 +- src/solvers/dgsem_tree/dg_2d_subcell_limiters.jl | 3 ++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/callbacks_step/stepsize.jl b/src/callbacks_step/stepsize.jl index 7e41ceab520..b1e3924425c 100644 --- a/src/callbacks_step/stepsize.jl +++ b/src/callbacks_step/stepsize.jl @@ -170,7 +170,8 @@ function calculate_dt(u_ode, t, cfl_advective, cfl_diffusive, u = wrap_array(u_ode, mesh, equations, solver, cache) dt_advective = cfl_advective(t) * max_dt(u, t, mesh, - have_constant_speed(equations), equations, + have_constant_speed(equations), + have_aux_node_vars(equations), equations, solver, cache) cfl_diff = cfl_diffusive(t) diff --git a/src/solvers/dgsem_p4est/dg_2d.jl b/src/solvers/dgsem_p4est/dg_2d.jl index 373ab52bd5b..0c8eee308c2 100644 --- a/src/solvers/dgsem_p4est/dg_2d.jl +++ b/src/solvers/dgsem_p4est/dg_2d.jl @@ -461,7 +461,7 @@ end function calc_mortar_flux!(surface_flux_values, mesh::Union{P4estMesh{2}, P4estMeshView{2}, T8codeMesh{2}}, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, mortar_l2::LobattoLegendreMortarL2, surface_integral, dg::DG, cache) @unpack neighbor_ids, node_indices = cache.mortars diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index d37d121c8e4..4738aaf5ce9 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1528,7 +1528,7 @@ end # Initialize auxiliary mortar node variables # 2D TreeMesh implementation, similar to prolong2mortars -# Each mortar has two sides (indentified by first variable of u_upper / u_lower) +# Each mortar has two sides (identified by first variable of u_upper / u_lower) # On the side with two small elements, values can be copied from the aux vars field # On the side with one large element, values are usually interpolated to small elements # We do this differently here and use the same small element values on both side. This diff --git a/src/solvers/dgsem_tree/dg_2d_subcell_limiters.jl b/src/solvers/dgsem_tree/dg_2d_subcell_limiters.jl index 1f2eb3bbb78..2f45725d6c7 100644 --- a/src/solvers/dgsem_tree/dg_2d_subcell_limiters.jl +++ b/src/solvers/dgsem_tree/dg_2d_subcell_limiters.jl @@ -104,7 +104,8 @@ end fstar1_R = fstar1_R_threaded[Threads.threadid()] fstar2_R = fstar2_R_threaded[Threads.threadid()] calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, u, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_aux_node_vars(equations), equations, volume_flux_fv, dg, element, cache) # antidiffusive flux From 1707894e2b2ae04fe925c3bcc8140b3c7d639106 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 1 Oct 2025 07:39:46 +0200 Subject: [PATCH 50/83] more fixes --- src/solvers/dgsem_p4est/dg_2d_parabolic.jl | 1 + src/solvers/fdsbp_tree/fdsbp.jl | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/solvers/dgsem_p4est/dg_2d_parabolic.jl b/src/solvers/dgsem_p4est/dg_2d_parabolic.jl index c6243576b81..5d64071c13f 100644 --- a/src/solvers/dgsem_p4est/dg_2d_parabolic.jl +++ b/src/solvers/dgsem_p4est/dg_2d_parabolic.jl @@ -259,6 +259,7 @@ function calc_gradient!(gradients, u_transformed, t, @trixi_timeit timer() "mortar flux" begin calc_mortar_flux!(cache_parabolic.elements.surface_flux_values, mesh, False(), # False() = no nonconservative terms + False(), # False() = no auxiliary variables equations_parabolic, dg.mortar, dg.surface_integral, dg, cache) end diff --git a/src/solvers/fdsbp_tree/fdsbp.jl b/src/solvers/fdsbp_tree/fdsbp.jl index acf38425b04..4c78f090ee4 100644 --- a/src/solvers/fdsbp_tree/fdsbp.jl +++ b/src/solvers/fdsbp_tree/fdsbp.jl @@ -56,7 +56,8 @@ function prolong2mortars!(cache, u, mesh, equations, mortar::Nothing, end function calc_mortar_flux!(surface_flux_values, mesh, - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, mortar::Nothing, surface_integral, dg::DG, cache) @assert isempty(eachmortar(dg, cache)) From 94e97cfdc2fc0af6d6440e4d3023c4e65623350d Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 1 Oct 2025 14:59:09 +0200 Subject: [PATCH 51/83] post merge fixes --- src/solvers/dgsem_structured/dg_3d.jl | 9 ++++++--- .../dg_3d_compressible_euler.jl | 2 ++ src/solvers/dgsem_tree/dg_1d.jl | 17 +++++++++++------ src/solvers/dgsem_tree/dg_3d.jl | 13 ++++++++----- .../dgsem_tree/dg_3d_compressible_euler.jl | 2 ++ src/solvers/fdsbp_tree/fdsbp_1d.jl | 6 ++---- src/solvers/fdsbp_tree/fdsbp_3d.jl | 6 ++---- 7 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/solvers/dgsem_structured/dg_3d.jl b/src/solvers/dgsem_structured/dg_3d.jl index bcce0a56006..1f5da79293f 100644 --- a/src/solvers/dgsem_structured/dg_3d.jl +++ b/src/solvers/dgsem_structured/dg_3d.jl @@ -59,7 +59,8 @@ See also https://github.com/trixi-framework/Trixi.jl/issues/1671#issuecomment-17 element, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -117,7 +118,8 @@ end element, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -200,7 +202,8 @@ end element, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - have_nonconservative_terms::True, equations, + have_nonconservative_terms::True, + have_aux_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) @unpack derivative_split = dg.basis @unpack contravariant_vectors = cache.elements diff --git a/src/solvers/dgsem_structured/dg_3d_compressible_euler.jl b/src/solvers/dgsem_structured/dg_3d_compressible_euler.jl index 6c267582601..990d051071f 100644 --- a/src/solvers/dgsem_structured/dg_3d_compressible_euler.jl +++ b/src/solvers/dgsem_structured/dg_3d_compressible_euler.jl @@ -21,6 +21,7 @@ element, mesh::Union{StructuredMesh{3}, P4estMesh{3}}, have_nonconservative_terms::False, + have_aux_node_vars::False, equations::CompressibleEulerEquations3D, volume_flux::typeof(flux_shima_etal_turbo), dg::DGSEM, cache, alpha) @@ -353,6 +354,7 @@ end element, mesh::Union{StructuredMesh{3}, P4estMesh{3}}, have_nonconservative_terms::False, + have_aux_node_vars::False, equations::CompressibleEulerEquations3D, volume_flux::typeof(flux_ranocha_turbo), dg::DGSEM, cache, alpha) diff --git a/src/solvers/dgsem_tree/dg_1d.jl b/src/solvers/dgsem_tree/dg_1d.jl index 9686fa4ecfe..92c371c1665 100644 --- a/src/solvers/dgsem_tree/dg_1d.jl +++ b/src/solvers/dgsem_tree/dg_1d.jl @@ -126,7 +126,8 @@ See also https://github.com/trixi-framework/Trixi.jl/issues/1671#issuecomment-17 =# @inline function weak_form_kernel!(du, u, element, mesh::Union{TreeMesh{1}, StructuredMesh{1}}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -148,7 +149,8 @@ end @inline function flux_differencing_kernel!(du, u, element, mesh::Union{TreeMesh{1}, StructuredMesh{1}}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -178,7 +180,8 @@ end @inline function flux_differencing_kernel!(du, u, element, mesh::Union{TreeMesh{1}, StructuredMesh{1}}, - have_nonconservative_terms::True, equations, + have_nonconservative_terms::True, + have_aux_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -186,7 +189,8 @@ end symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, mesh, False(), equations, symmetric_flux, + flux_differencing_kernel!(du, u, element, mesh, False(), False(), equations, + symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux @@ -213,7 +217,7 @@ end @inline function fv_kernel!(du, u, mesh::Union{TreeMesh{1}, StructuredMesh{1}}, - have_nonconservative_terms, equations, + equations, volume_flux_fv, dg::DGSEM, cache, element, alpha = true) @unpack fstar1_L_threaded, fstar1_R_threaded = cache @unpack inverse_weights = dg.basis @@ -221,7 +225,8 @@ end # Calculate FV two-point fluxes fstar1_L = fstar1_L_threaded[Threads.threadid()] fstar1_R = fstar1_R_threaded[Threads.threadid()] - calcflux_fv!(fstar1_L, fstar1_R, u, mesh, have_nonconservative_terms, equations, + calcflux_fv!(fstar1_L, fstar1_R, u, mesh, have_nonconservative_terms(equations), + equations, volume_flux_fv, dg, element, cache) diff --git a/src/solvers/dgsem_tree/dg_3d.jl b/src/solvers/dgsem_tree/dg_3d.jl index 75eb55ea591..9c0489528d9 100644 --- a/src/solvers/dgsem_tree/dg_3d.jl +++ b/src/solvers/dgsem_tree/dg_3d.jl @@ -200,7 +200,8 @@ See also https://github.com/trixi-framework/Trixi.jl/issues/1671#issuecomment-17 =# @inline function weak_form_kernel!(du, u, element, mesh::TreeMesh{3}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -233,7 +234,8 @@ end @inline function flux_differencing_kernel!(du, u, element, mesh::TreeMesh{3}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -284,7 +286,8 @@ end @inline function flux_differencing_kernel!(du, u, element, mesh::TreeMesh{3}, - have_nonconservative_terms::True, equations, + have_nonconservative_terms::True, + have_aux_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) # true * [some floating point value] == [exactly the same floating point value] # This can (hopefully) be optimized away due to constant propagation. @@ -338,7 +341,7 @@ end @inline function fv_kernel!(du, u, mesh::Union{TreeMesh{3}, StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - have_nonconservative_terms, equations, + equations, volume_flux_fv, dg::DGSEM, cache, element, alpha = true) @unpack fstar1_L_threaded, fstar1_R_threaded, fstar2_L_threaded, fstar2_R_threaded, fstar3_L_threaded, fstar3_R_threaded = cache @unpack inverse_weights = dg.basis @@ -352,7 +355,7 @@ end fstar3_R = fstar3_R_threaded[Threads.threadid()] calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, fstar3_L, fstar3_R, u, - mesh, have_nonconservative_terms, equations, + mesh, have_nonconservative_terms(equations), equations, volume_flux_fv, dg, element, cache) # Calculate FV volume integral contribution diff --git a/src/solvers/dgsem_tree/dg_3d_compressible_euler.jl b/src/solvers/dgsem_tree/dg_3d_compressible_euler.jl index 8d2514e65d9..916e6570835 100644 --- a/src/solvers/dgsem_tree/dg_3d_compressible_euler.jl +++ b/src/solvers/dgsem_tree/dg_3d_compressible_euler.jl @@ -19,6 +19,7 @@ @inline function flux_differencing_kernel!(_du::PtrArray, u_cons::PtrArray, element, mesh::TreeMesh{3}, have_nonconservative_terms::False, + have_aux_node_vars::False, equations::CompressibleEulerEquations3D, volume_flux::typeof(flux_shima_etal_turbo), dg::DGSEM, cache, alpha) @@ -265,6 +266,7 @@ end @inline function flux_differencing_kernel!(_du::PtrArray, u_cons::PtrArray, element, mesh::TreeMesh{3}, have_nonconservative_terms::False, + have_aux_node_vars::False, equations::CompressibleEulerEquations3D, volume_flux::typeof(flux_ranocha_turbo), dg::DGSEM, cache, alpha) diff --git a/src/solvers/fdsbp_tree/fdsbp_1d.jl b/src/solvers/fdsbp_tree/fdsbp_1d.jl index 051e488d08c..d772baafd36 100644 --- a/src/solvers/fdsbp_tree/fdsbp_1d.jl +++ b/src/solvers/fdsbp_tree/fdsbp_1d.jl @@ -41,8 +41,7 @@ end # 2D volume integral contributions for `VolumeIntegralStrongForm` function calc_volume_integral!(du, u, - mesh::TreeMesh{1}, - have_nonconservative_terms::False, equations, + mesh::TreeMesh{1}, equations, volume_integral::VolumeIntegralStrongForm, dg::FDSBP, cache) D = dg.basis # SBP derivative operator @@ -88,8 +87,7 @@ end # part of the flux splitting f^+ and the D^+ operator acts on the negative part # of the flux splitting f^-. function calc_volume_integral!(du, u, - mesh::TreeMesh{1}, - have_nonconservative_terms::False, equations, + mesh::TreeMesh{1}, equations, volume_integral::VolumeIntegralUpwind, dg::FDSBP, cache) # Assume that diff --git a/src/solvers/fdsbp_tree/fdsbp_3d.jl b/src/solvers/fdsbp_tree/fdsbp_3d.jl index 8d220217216..da05a1a8a6f 100644 --- a/src/solvers/fdsbp_tree/fdsbp_3d.jl +++ b/src/solvers/fdsbp_tree/fdsbp_3d.jl @@ -41,8 +41,7 @@ end # 3D volume integral contributions for `VolumeIntegralStrongForm` function calc_volume_integral!(du, u, - mesh::TreeMesh{3}, - have_nonconservative_terms::False, equations, + mesh::TreeMesh{3}, equations, volume_integral::VolumeIntegralStrongForm, dg::FDSBP, cache) D = dg.basis # SBP derivative operator @@ -104,8 +103,7 @@ end # part of the flux splitting f^+ and the D^+ operator acts on the negative part # of the flux splitting f^-. function calc_volume_integral!(du, u, - mesh::TreeMesh{3}, - have_nonconservative_terms::False, equations, + mesh::TreeMesh{3}, equations, volume_integral::VolumeIntegralUpwind, dg::FDSBP, cache) # Assume that From 3b5bb64b35256773afd39bcaaabfcb46ca48a215 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Tue, 7 Oct 2025 17:57:42 +0200 Subject: [PATCH 52/83] next merge --- src/solvers/dgsem_structured/dg.jl | 2 +- src/solvers/dgsem_tree/dg_1d.jl | 10 ++++++---- src/solvers/dgsem_tree/dg_3d.jl | 8 +++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/solvers/dgsem_structured/dg.jl b/src/solvers/dgsem_structured/dg.jl index 6cc2791c27e..2da719e1f03 100644 --- a/src/solvers/dgsem_structured/dg.jl +++ b/src/solvers/dgsem_structured/dg.jl @@ -45,7 +45,7 @@ function rhs!(du, u, t, # Calculate volume integral @trixi_timeit timer() "volume integral" begin calc_volume_integral!(du, u, mesh, - have_nonconservative_terms(equations), equations, + equations, dg.volume_integral, dg, cache) end diff --git a/src/solvers/dgsem_tree/dg_1d.jl b/src/solvers/dgsem_tree/dg_1d.jl index 312cb81b288..db2fff9fbcc 100644 --- a/src/solvers/dgsem_tree/dg_1d.jl +++ b/src/solvers/dgsem_tree/dg_1d.jl @@ -271,7 +271,7 @@ end # Calculate FV two-point fluxes fstar1_L = fstar1_L_threaded[Threads.threadid()] fstar1_R = fstar1_R_threaded[Threads.threadid()] - calcflux_fvO2!(fstar1_L, fstar1_R, u, mesh, nonconservative_terms(equations), equations, + calcflux_fvO2!(fstar1_L, fstar1_R, u, mesh, have_nonconservative_terms(equations), equations, volume_flux_fv, dg, element, cache, x_interfaces, reconstruction_mode, slope_limiter) @@ -342,7 +342,7 @@ end @inline function calcflux_fvO2!(fstar1_L, fstar1_R, u::AbstractArray{<:Any, 3}, mesh::Union{TreeMesh{1}, StructuredMesh{1}}, - nonconservative_terms::False, + have_nonconservative_terms::False, equations, volume_flux_fv, dg::DGSEM, element, cache, x_interfaces, reconstruction_mode, slope_limiter) fstar1_L[:, 1] .= zero(eltype(fstar1_L)) @@ -429,7 +429,8 @@ end function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{1}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, surface_integral, dg::DG, cache) @unpack surface_flux = surface_integral @unpack u, neighbor_ids, orientations = cache.interfaces @@ -460,7 +461,8 @@ end function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{1}, - have_nonconservative_terms::True, equations, + have_nonconservative_terms::True, + have_aux_node_vars::False, equations, surface_integral, dg::DG, cache) surface_flux, nonconservative_flux = surface_integral.surface_flux @unpack u, neighbor_ids, orientations = cache.interfaces diff --git a/src/solvers/dgsem_tree/dg_3d.jl b/src/solvers/dgsem_tree/dg_3d.jl index 76c0e759346..8e734c26640 100644 --- a/src/solvers/dgsem_tree/dg_3d.jl +++ b/src/solvers/dgsem_tree/dg_3d.jl @@ -226,7 +226,7 @@ end symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, mesh, False(), equations, symmetric_flux, + flux_differencing_kernel!(du, u, element, mesh, False(), False(), equations, symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux @@ -476,7 +476,8 @@ end function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{3}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, surface_integral, dg::DG, cache) @unpack surface_flux = surface_integral @unpack u, neighbor_ids, orientations = cache.interfaces @@ -511,7 +512,8 @@ end function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{3}, - have_nonconservative_terms::True, equations, + have_nonconservative_terms::True, + have_aux_node_vars::False, equations, surface_integral, dg::DG, cache) surface_flux, nonconservative_flux = surface_integral.surface_flux @unpack u, neighbor_ids, orientations = cache.interfaces From 9bab9d08e4f3f24e30a640e139b3685e6ca0274f Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 8 Oct 2025 09:50:41 +0200 Subject: [PATCH 53/83] more --- src/solvers/dgsem_structured/dg.jl | 3 ++- src/solvers/dgsem_tree/dg_1d.jl | 7 ++++--- src/solvers/dgsem_tree/dg_3d.jl | 13 ++++++++----- src/solvers/fdsbp_tree/fdsbp_3d.jl | 3 ++- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/solvers/dgsem_structured/dg.jl b/src/solvers/dgsem_structured/dg.jl index 2da719e1f03..08d1112e7e0 100644 --- a/src/solvers/dgsem_structured/dg.jl +++ b/src/solvers/dgsem_structured/dg.jl @@ -73,7 +73,8 @@ function rhs!(du, u, t, # Calculate source terms @trixi_timeit timer() "source terms" begin - calc_sources!(du, u, t, source_terms, equations, dg, cache) + calc_sources!(du, u, t, source_terms, have_aux_node_vars(equations), equations, + dg, cache) end return nothing diff --git a/src/solvers/dgsem_tree/dg_1d.jl b/src/solvers/dgsem_tree/dg_1d.jl index db2fff9fbcc..26d834996ad 100644 --- a/src/solvers/dgsem_tree/dg_1d.jl +++ b/src/solvers/dgsem_tree/dg_1d.jl @@ -271,7 +271,8 @@ end # Calculate FV two-point fluxes fstar1_L = fstar1_L_threaded[Threads.threadid()] fstar1_R = fstar1_R_threaded[Threads.threadid()] - calcflux_fvO2!(fstar1_L, fstar1_R, u, mesh, have_nonconservative_terms(equations), equations, + calcflux_fvO2!(fstar1_L, fstar1_R, u, mesh, have_nonconservative_terms(equations), + equations, volume_flux_fv, dg, element, cache, x_interfaces, reconstruction_mode, slope_limiter) @@ -430,7 +431,7 @@ end function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{1}, have_nonconservative_terms::False, - have_aux_node_vars::False, equations, + equations, surface_integral, dg::DG, cache) @unpack surface_flux = surface_integral @unpack u, neighbor_ids, orientations = cache.interfaces @@ -462,7 +463,7 @@ end function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{1}, have_nonconservative_terms::True, - have_aux_node_vars::False, equations, + equations, surface_integral, dg::DG, cache) surface_flux, nonconservative_flux = surface_integral.surface_flux @unpack u, neighbor_ids, orientations = cache.interfaces diff --git a/src/solvers/dgsem_tree/dg_3d.jl b/src/solvers/dgsem_tree/dg_3d.jl index 8e734c26640..3fb19454b4b 100644 --- a/src/solvers/dgsem_tree/dg_3d.jl +++ b/src/solvers/dgsem_tree/dg_3d.jl @@ -226,7 +226,8 @@ end symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, mesh, False(), False(), equations, symmetric_flux, + flux_differencing_kernel!(du, u, element, mesh, False(), False(), equations, + symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux @@ -868,7 +869,8 @@ end function calc_mortar_flux!(surface_flux_values, mesh::TreeMesh{3}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, mortar_l2::LobattoLegendreMortarL2, surface_integral, dg::DG, cache) @unpack surface_flux = surface_integral @@ -926,7 +928,8 @@ end function calc_mortar_flux!(surface_flux_values, mesh::TreeMesh{3}, - have_nonconservative_terms::True, equations, + have_nonconservative_terms::True, + have_aux_node_vars::False, equations, mortar_l2::LobattoLegendreMortarL2, surface_integral, dg::DG, cache) surface_flux, nonconservative_flux = surface_integral.surface_flux @@ -1322,12 +1325,12 @@ function apply_jacobian!(du, mesh::TreeMesh{3}, end # Need dimension specific version to avoid error at dispatching -function calc_sources!(du, u, t, source_terms::Nothing, +function calc_sources!(du, u, t, source_terms::Nothing, have_aux_node_vars::False, equations::AbstractEquations{3}, dg::DG, cache) return nothing end -function calc_sources!(du, u, t, source_terms, +function calc_sources!(du, u, t, source_terms, have_aux_node_vars::False, equations::AbstractEquations{3}, dg::DG, cache) @unpack node_coordinates = cache.elements diff --git a/src/solvers/fdsbp_tree/fdsbp_3d.jl b/src/solvers/fdsbp_tree/fdsbp_3d.jl index da05a1a8a6f..a915997b9da 100644 --- a/src/solvers/fdsbp_tree/fdsbp_3d.jl +++ b/src/solvers/fdsbp_tree/fdsbp_3d.jl @@ -250,7 +250,8 @@ end # flux information at each side of an interface. function calc_interface_flux!(surface_flux_values, mesh::TreeMesh{3}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, surface_integral::SurfaceIntegralUpwind, dg::FDSBP, cache) @unpack splitting = surface_integral From 900914f39c2a36f34fcaf4059252a241b01fc8ca Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 8 Oct 2025 10:45:45 +0200 Subject: [PATCH 54/83] more --- src/solvers/dgsem_p4est/dg_3d.jl | 2 +- src/solvers/dgsem_structured/dg_3d.jl | 4 ++-- src/solvers/dgsem_tree/dg_1d.jl | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/solvers/dgsem_p4est/dg_3d.jl b/src/solvers/dgsem_p4est/dg_3d.jl index e39d537b371..e9d448f5cdc 100644 --- a/src/solvers/dgsem_p4est/dg_3d.jl +++ b/src/solvers/dgsem_p4est/dg_3d.jl @@ -171,7 +171,7 @@ end function calc_interface_flux!(surface_flux_values, mesh::Union{P4estMesh{3}, T8codeMesh{3}}, - have_nonconservative_terms, + have_nonconservative_terms, have_aux_node_vars, equations, surface_integral, dg::DG, cache) @unpack neighbor_ids, node_indices = cache.interfaces @unpack contravariant_vectors = cache.elements diff --git a/src/solvers/dgsem_structured/dg_3d.jl b/src/solvers/dgsem_structured/dg_3d.jl index 9171da011fd..dfcd10d56c0 100644 --- a/src/solvers/dgsem_structured/dg_3d.jl +++ b/src/solvers/dgsem_structured/dg_3d.jl @@ -167,8 +167,8 @@ end symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, mesh, False(), equations, symmetric_flux, - dg, cache, alpha) + flux_differencing_kernel!(du, u, element, mesh, False(), False(), equations, + symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux for k in eachnode(dg), j in eachnode(dg), i in eachnode(dg) diff --git a/src/solvers/dgsem_tree/dg_1d.jl b/src/solvers/dgsem_tree/dg_1d.jl index 26d834996ad..57832f7bf6f 100644 --- a/src/solvers/dgsem_tree/dg_1d.jl +++ b/src/solvers/dgsem_tree/dg_1d.jl @@ -111,7 +111,8 @@ function rhs!(du, u, t, # Calculate source terms @trixi_timeit timer() "source terms" begin - calc_sources!(du, u, t, source_terms, equations, dg, cache) + calc_sources!(du, u, t, source_terms, have_aux_node_vars(equations), equations, + dg, cache) end return nothing @@ -662,12 +663,12 @@ function apply_jacobian!(du, mesh::Union{TreeMesh{1}, StructuredMesh{1}}, end # Need dimension specific version to avoid error at dispatching -function calc_sources!(du, u, t, source_terms::Nothing, +function calc_sources!(du, u, t, source_terms::Nothing, have_aux_node_vars::False, equations::AbstractEquations{1}, dg::DG, cache) return nothing end -function calc_sources!(du, u, t, source_terms, +function calc_sources!(du, u, t, source_terms, have_aux_node_vars::False, equations::AbstractEquations{1}, dg::DG, cache) @unpack node_coordinates = cache.elements From 34dc3bbd78226244023c1993de19d56a2a9eb943 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 8 Oct 2025 10:46:08 +0200 Subject: [PATCH 55/83] more #2 --- test/test_performance_specializations_3d.jl | 44 +++++++++++++-------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/test/test_performance_specializations_3d.jl b/test/test_performance_specializations_3d.jl index f4e1f552e67..dc2e277d0af 100644 --- a/test/test_performance_specializations_3d.jl +++ b/test/test_performance_specializations_3d.jl @@ -29,11 +29,13 @@ isdir(outdir) && rm(outdir, recursive = true) u = Trixi.wrap_array(u_ode, semi) du = Trixi.wrap_array(du_ode, semi) have_nonconservative_terms = Trixi.have_nonconservative_terms(semi.equations) + have_aux_node_vars = Trixi.have_aux_node_vars(semi.equations) # Call the optimized default version du .= 0 Trixi.flux_differencing_kernel!(du, u, 1, semi.mesh, - have_nonconservative_terms, semi.equations, + have_nonconservative_terms, have_aux_node_vars, + semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_specialized = du[:, :, :, :, 1] @@ -43,10 +45,11 @@ isdir(outdir) && rm(outdir, recursive = true) du .= 0 invoke(Trixi.flux_differencing_kernel!, Tuple{typeof(du), typeof(u), Integer, typeof(semi.mesh), - typeof(have_nonconservative_terms), typeof(semi.equations), - Function, typeof(semi.solver), typeof(semi.cache), Bool}, + typeof(have_nonconservative_terms), typeof(have_aux_node_vars), + typeof(semi.equations), Function, typeof(semi.solver), + typeof(semi.cache), Bool}, du, u, 1, semi.mesh, - have_nonconservative_terms, semi.equations, + have_nonconservative_terms, have_aux_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, :, 1] @@ -68,11 +71,13 @@ end u = Trixi.wrap_array(u_ode, semi) du = Trixi.wrap_array(du_ode, semi) have_nonconservative_terms = Trixi.have_nonconservative_terms(semi.equations) + have_aux_node_vars = Trixi.have_aux_node_vars(semi.equations) # Call the optimized default version du .= 0 Trixi.flux_differencing_kernel!(du, u, 1, semi.mesh, - have_nonconservative_terms, semi.equations, + have_nonconservative_terms, have_aux_node_vars, + semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_specialized = du[:, :, :, :, 1] @@ -82,10 +87,11 @@ end du .= 0 invoke(Trixi.flux_differencing_kernel!, Tuple{typeof(du), typeof(u), Integer, typeof(semi.mesh), - typeof(have_nonconservative_terms), typeof(semi.equations), - Function, typeof(semi.solver), typeof(semi.cache), Bool}, + typeof(have_nonconservative_terms), typeof(have_aux_node_vars), + typeof(semi.equations), Function, typeof(semi.solver), + typeof(semi.cache), Bool}, du, u, 1, semi.mesh, - have_nonconservative_terms, semi.equations, + have_nonconservative_terms, have_aux_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, :, 1] @@ -108,11 +114,13 @@ end u = Trixi.wrap_array(u_ode, semi) du = Trixi.wrap_array(du_ode, semi) have_nonconservative_terms = Trixi.have_nonconservative_terms(semi.equations) + have_aux_node_vars = Trixi.have_aux_node_vars(semi.equations) # Call the optimized default version du .= 0 Trixi.flux_differencing_kernel!(du, u, 1, semi.mesh, - have_nonconservative_terms, semi.equations, + have_nonconservative_terms, have_aux_node_vars, + semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_specialized = du[:, :, :, :, 1] @@ -122,10 +130,11 @@ end du .= 0 invoke(Trixi.flux_differencing_kernel!, Tuple{typeof(du), typeof(u), Integer, typeof(semi.mesh), - typeof(have_nonconservative_terms), typeof(semi.equations), - Function, typeof(semi.solver), typeof(semi.cache), Bool}, + typeof(have_nonconservative_terms), typeof(have_aux_node_vars), + typeof(semi.equations), Function, typeof(semi.solver), + typeof(semi.cache), Bool}, du, u, 1, semi.mesh, - have_nonconservative_terms, semi.equations, + have_nonconservative_terms, have_aux_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, :, 1] @@ -147,11 +156,13 @@ end u = Trixi.wrap_array(u_ode, semi) du = Trixi.wrap_array(du_ode, semi) have_nonconservative_terms = Trixi.have_nonconservative_terms(semi.equations) + have_aux_node_vars = Trixi.have_aux_node_vars(semi.equations) # Call the optimized default version du .= 0 Trixi.flux_differencing_kernel!(du, u, 1, semi.mesh, - have_nonconservative_terms, semi.equations, + have_nonconservative_terms, have_aux_node_vars, + semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_specialized = du[:, :, :, :, 1] @@ -161,10 +172,11 @@ end du .= 0 invoke(Trixi.flux_differencing_kernel!, Tuple{typeof(du), typeof(u), Integer, typeof(semi.mesh), - typeof(have_nonconservative_terms), typeof(semi.equations), - Function, typeof(semi.solver), typeof(semi.cache), Bool}, + typeof(have_nonconservative_terms), typeof(have_aux_node_vars), + typeof(semi.equations), Function, typeof(semi.solver), + typeof(semi.cache), Bool}, du, u, 1, semi.mesh, - have_nonconservative_terms, semi.equations, + have_nonconservative_terms, have_aux_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, :, 1] From 3b594993b9dea11ec27cb089eb861f9afeae9917 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 8 Oct 2025 11:38:20 +0200 Subject: [PATCH 56/83] fixes --- src/solvers/dgsem_p4est/dg_3d.jl | 3 ++- src/solvers/dgsem_p4est/dg_3d_parallel.jl | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/solvers/dgsem_p4est/dg_3d.jl b/src/solvers/dgsem_p4est/dg_3d.jl index e9d448f5cdc..08773e00d5e 100644 --- a/src/solvers/dgsem_p4est/dg_3d.jl +++ b/src/solvers/dgsem_p4est/dg_3d.jl @@ -591,7 +591,8 @@ end function calc_mortar_flux!(surface_flux_values, mesh::Union{P4estMesh{3}, T8codeMesh{3}}, - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, mortar_l2::LobattoLegendreMortarL2, surface_integral, dg::DG, cache) @unpack neighbor_ids, node_indices = cache.mortars diff --git a/src/solvers/dgsem_p4est/dg_3d_parallel.jl b/src/solvers/dgsem_p4est/dg_3d_parallel.jl index 64430b06801..db158e50ea7 100644 --- a/src/solvers/dgsem_p4est/dg_3d_parallel.jl +++ b/src/solvers/dgsem_p4est/dg_3d_parallel.jl @@ -45,7 +45,8 @@ function rhs!(du, u, t, # Calculate interface fluxes @trixi_timeit timer() "interface flux" begin calc_interface_flux!(cache.elements.surface_flux_values, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_aux_node_vars(equations), equations, dg.surface_integral, dg, cache) end @@ -69,7 +70,8 @@ function rhs!(du, u, t, # Calculate mortar fluxes @trixi_timeit timer() "mortar flux" begin calc_mortar_flux!(cache.elements.surface_flux_values, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_aux_node_vars(equations), equations, dg.mortar, dg.surface_integral, dg, cache) end @@ -94,7 +96,8 @@ function rhs!(du, u, t, # Calculate surface integrals @trixi_timeit timer() "surface integral" begin - calc_surface_integral!(du, u, mesh, equations, dg.surface_integral, dg, cache) + calc_surface_integral!(du, u, mesh, have_aux_node_vars(equations), equations, + dg.surface_integral, dg, cache) end # Apply Jacobian from mapping to reference element From 19d0a72b3a7f503aa9407b304496886198011277 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 8 Oct 2025 12:13:00 +0200 Subject: [PATCH 57/83] fix parallel + parabolic --- src/solvers/dgsem_p4est/dg_2d_parallel.jl | 3 ++- src/solvers/dgsem_p4est/dg_3d_parabolic.jl | 2 ++ src/solvers/dgsem_p4est/dg_3d_parallel.jl | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/solvers/dgsem_p4est/dg_2d_parallel.jl b/src/solvers/dgsem_p4est/dg_2d_parallel.jl index 90cc183489d..74da2307ba9 100644 --- a/src/solvers/dgsem_p4est/dg_2d_parallel.jl +++ b/src/solvers/dgsem_p4est/dg_2d_parallel.jl @@ -241,7 +241,8 @@ end function calc_mpi_mortar_flux!(surface_flux_values, mesh::Union{ParallelP4estMesh{2}, ParallelT8codeMesh{2}}, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, + equations, mortar_l2::LobattoLegendreMortarL2, surface_integral, dg::DG, cache) @unpack local_neighbor_ids, local_neighbor_positions, node_indices = cache.mpi_mortars diff --git a/src/solvers/dgsem_p4est/dg_3d_parabolic.jl b/src/solvers/dgsem_p4est/dg_3d_parabolic.jl index 6703d3014de..7757c75b3ff 100644 --- a/src/solvers/dgsem_p4est/dg_3d_parabolic.jl +++ b/src/solvers/dgsem_p4est/dg_3d_parabolic.jl @@ -123,6 +123,7 @@ function calc_gradient!(gradients, u_transformed, t, @trixi_timeit timer() "interface flux" begin calc_interface_flux!(cache_parabolic.elements.surface_flux_values, mesh, False(), # False() = no nonconservative terms + False(), # False() = no auxiliary variablesterms equations_parabolic, dg.surface_integral, dg, cache_parabolic) end @@ -154,6 +155,7 @@ function calc_gradient!(gradients, u_transformed, t, @trixi_timeit timer() "mortar flux" begin calc_mortar_flux!(cache_parabolic.elements.surface_flux_values, mesh, False(), # False() = no nonconservative terms + False(), # False() = no auxiliary variables equations_parabolic, dg.mortar, dg.surface_integral, dg, cache) end diff --git a/src/solvers/dgsem_p4est/dg_3d_parallel.jl b/src/solvers/dgsem_p4est/dg_3d_parallel.jl index db158e50ea7..b74a0768c2d 100644 --- a/src/solvers/dgsem_p4est/dg_3d_parallel.jl +++ b/src/solvers/dgsem_p4est/dg_3d_parallel.jl @@ -96,7 +96,7 @@ function rhs!(du, u, t, # Calculate surface integrals @trixi_timeit timer() "surface integral" begin - calc_surface_integral!(du, u, mesh, have_aux_node_vars(equations), equations, + calc_surface_integral!(du, u, mesh, equations, dg.surface_integral, dg, cache) end @@ -105,7 +105,8 @@ function rhs!(du, u, t, # Calculate source terms @trixi_timeit timer() "source terms" begin - calc_sources!(du, u, t, source_terms, equations, dg, cache) + calc_sources!(du, u, t, source_terms, have_aux_node_vars(equations), equations, + dg, cache) end # Finish to send MPI data From 9318af85abbada90f280d65fdd878441f9afefb0 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 8 Oct 2025 14:50:52 +0200 Subject: [PATCH 58/83] news --- NEWS.md | 14 ++++++++++++-- src/solvers/dgsem_tree/containers_2d.jl | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 110105c67f2..ae8350559a6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,18 @@ Trixi.jl follows the interpretation of used in the Julia ecosystem. Notable changes will be documented in this file for human readability. +## Changes in the v0.13 lifecycle + +#### Added + +- Auxiliary variables ([#2348]). + An additional container in `cache` is made available to central functions like flux + computations. Possible applications are steady background states, variable velocity + fields, geometrical information, or any other pointwise, passive quantity that is + required in addition to the unknows in the governing equations. The auxiliary variables + are set up by supplying a function to the `SemidiscretizationHyperbolic` constructor via + the keyword argument `aux_field`. + ## Changes when updating to v0.13 from v0.12.x @@ -80,8 +92,6 @@ for human readability. paired explicit Runge-Kutta method with [Convex.jl](https://github.com/jump-dev/Convex.jl) and [ECOS.jl](https://github.com/jump-dev/ECOS.jl) ([#2147]) - Passive tracers for arbitrary equations with density and flow variables ([#2364]) -- Auxiliary variables, which can, e.g., be used to store a steady state and solve - for perturbations only ([#2348]) #### Deprecated diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index 44dbcfe080e..87f6ee07464 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1461,7 +1461,7 @@ end # On the side with two small elements, values can be copied from the aux vars field # On the side with one large element, values are usually interpolated to small elements # We do this differently here and use the same small element values on both side. This -# assumes that the aux_field computes a smooth variable field with no jumps +# assumes that the `aux_field` function computes a field with no jumps. function init_aux_mortar_node_vars!(aux_vars, mesh::TreeMesh2D, equations, solver, cache) @unpack aux_node_vars, aux_mortar_node_vars = aux_vars From 21b38d1aa0c7469261158bb4eca0936a8e9df78a Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 8 Oct 2025 14:51:23 +0200 Subject: [PATCH 59/83] another fix --- src/solvers/dgsem_p4est/dg_2d_parallel.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/solvers/dgsem_p4est/dg_2d_parallel.jl b/src/solvers/dgsem_p4est/dg_2d_parallel.jl index 74da2307ba9..52639a7950c 100644 --- a/src/solvers/dgsem_p4est/dg_2d_parallel.jl +++ b/src/solvers/dgsem_p4est/dg_2d_parallel.jl @@ -141,7 +141,8 @@ end @inline function calc_mpi_interface_flux!(surface_flux_values, mesh::Union{ParallelP4estMesh{2}, ParallelT8codeMesh{2}}, - have_nonconservative_terms::True, equations, + have_nonconservative_terms::True, + have_aux_node_vars::False, equations, surface_integral, dg::DG, cache, interface_index, normal_direction, interface_node_index, local_side, From 87ff3436cc7cb30dbea0b1d699675bbe2ea167f1 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Mon, 13 Oct 2025 16:15:41 +0200 Subject: [PATCH 60/83] only leftright = 1 used for mortar atm --- src/solvers/dgsem_tree/containers_2d.jl | 52 ++++++++++++------------- src/solvers/dgsem_tree/dg_2d.jl | 2 +- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index 87f6ee07464..cc5a064f8e6 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1476,24 +1476,24 @@ function init_aux_mortar_node_vars!(aux_vars, mesh::TreeMesh2D, equations, solve # L2 mortars in x-direction for l in eachnode(solver) for v in axes(aux_mortar_node_vars, 2) - aux_mortar_node_vars[:, v, 2, l, mortar] .= aux_node_vars[v, 1, - l, - upper_element] - aux_mortar_node_vars[:, v, 1, l, mortar] .= aux_node_vars[v, 1, - l, - lower_element] + aux_mortar_node_vars[1, v, 2, l, mortar] = aux_node_vars[v, 1, + l, + upper_element] + aux_mortar_node_vars[1, v, 1, l, mortar] = aux_node_vars[v, 1, + l, + lower_element] end end else # L2 mortars in y-direction for l in eachnode(solver) for v in axes(aux_mortar_node_vars, 2) - aux_mortar_node_vars[:, v, 2, l, mortar] .= aux_node_vars[v, l, - 1, - upper_element] - aux_mortar_node_vars[:, v, 1, l, mortar] .= aux_node_vars[v, l, - 1, - lower_element] + aux_mortar_node_vars[1, v, 2, l, mortar] = aux_node_vars[v, l, + 1, + upper_element] + aux_mortar_node_vars[1, v, 1, l, mortar] = aux_node_vars[v, l, + 1, + lower_element] end end end @@ -1502,26 +1502,26 @@ function init_aux_mortar_node_vars!(aux_vars, mesh::TreeMesh2D, equations, solve # L2 mortars in x-direction for l in eachnode(solver) for v in axes(aux_mortar_node_vars, 2) - aux_mortar_node_vars[:, v, 2, l, mortar] .= aux_node_vars[v, - nnodes(solver), - l, - upper_element] - aux_mortar_node_vars[:, v, 1, l, mortar] .= aux_node_vars[v, - nnodes(solver), - l, - lower_element] + aux_mortar_node_vars[1, v, 2, l, mortar] = aux_node_vars[v, + nnodes(solver), + l, + upper_element] + aux_mortar_node_vars[1, v, 1, l, mortar] = aux_node_vars[v, + nnodes(solver), + l, + lower_element] end end else # L2 mortars in y-direction for l in eachnode(solver) for v in axes(aux_mortar_node_vars, 2) - aux_mortar_node_vars[:, v, 2, l, mortar] .= aux_node_vars[v, l, - nnodes(solver), - upper_element] - aux_mortar_node_vars[:, v, 1, l, mortar] .= aux_node_vars[v, l, - nnodes(solver), - lower_element] + aux_mortar_node_vars[1, v, 2, l, mortar] = aux_node_vars[v, l, + nnodes(solver), + upper_element] + aux_mortar_node_vars[1, v, 1, l, mortar] = aux_node_vars[v, l, + nnodes(solver), + lower_element] end end end diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index a69538ebe4d..9f604dfbae9 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -1558,7 +1558,7 @@ end u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) aux_ll, _ = get_aux_surface_node_vars(aux, equations, dg, position, i, interface) - # TODO: currently only leftright = 1 is used + # only leftright = 1 is used flux = surface_flux(u_ll, u_rr, aux_ll, aux_ll, orientation, equations) # Copy flux to left and right element storage From 29646aeecb9c25b225ac25f57769ec25878fe173 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Tue, 12 May 2026 21:03:12 +0200 Subject: [PATCH 61/83] fix TreeMesh tests --- src/callbacks_step/stepsize.jl | 2 +- src/callbacks_step/stepsize_dg3d.jl | 5 -- src/solvers/dgsem/calc_volume_integral.jl | 70 +++++++++++-------- src/solvers/dgsem/indicators.jl | 3 +- src/solvers/dgsem_structured/dg_2d.jl | 4 +- src/solvers/dgsem_structured/dg_3d.jl | 5 +- src/solvers/dgsem_tree/containers_2d.jl | 4 +- src/solvers/dgsem_tree/dg_1d.jl | 11 +-- src/solvers/dgsem_tree/dg_2d.jl | 69 +++++++++++++----- src/solvers/dgsem_tree/dg_2d_parallel.jl | 4 +- .../dgsem_tree/dg_2d_subcell_limiters.jl | 5 +- src/solvers/dgsem_tree/dg_3d.jl | 15 ++-- .../dgsem_tree/dg_3d_subcell_limiters.jl | 11 +-- src/solvers/fdsbp_tree/fdsbp_1d.jl | 6 +- src/solvers/fdsbp_tree/fdsbp_2d.jl | 6 +- src/solvers/fdsbp_tree/fdsbp_3d.jl | 6 +- src/solvers/fdsbp_unstructured/fdsbp_2d.jl | 6 +- 17 files changed, 144 insertions(+), 88 deletions(-) diff --git a/src/callbacks_step/stepsize.jl b/src/callbacks_step/stepsize.jl index 8eb9efdf6ed..e667b676893 100644 --- a/src/callbacks_step/stepsize.jl +++ b/src/callbacks_step/stepsize.jl @@ -185,7 +185,7 @@ function calculate_dt(u_ode, t, cfl_hyperbolic, cfl_parabolic, u = wrap_array(u_ode, mesh, equations, solver, cache) - dt_advective = cfl_hyperbolic(t) * max_dt(u, t, mesh, + dt_hyperbolic = cfl_hyperbolic(t) * max_dt(u, t, mesh, have_constant_speed(equations), have_aux_node_vars(equations), equations, solver, cache) diff --git a/src/callbacks_step/stepsize_dg3d.jl b/src/callbacks_step/stepsize_dg3d.jl index daa22c92c1f..1e4e9f59fd1 100644 --- a/src/callbacks_step/stepsize_dg3d.jl +++ b/src/callbacks_step/stepsize_dg3d.jl @@ -37,11 +37,6 @@ function max_dt(u, t, mesh::TreeMesh{3}, equations_parabolic::AbstractEquationsParabolic, dg::DG, cache) # Avoid division by zero if the diffusivity vanishes everywhere - # to avoid a division by zero if the speed vanishes everywhere, - constant_diffusivity::False, equations, - equations_parabolic::AbstractEquationsParabolic, - dg::DG, cache) - # Avoid division by zero if the diffusivity vanishes everywhere max_scaled_diffusivity = nextfloat(zero(t)) @batch reduction=(max, max_scaled_diffusivity) for element in eachelement(dg, cache) diff --git a/src/solvers/dgsem/calc_volume_integral.jl b/src/solvers/dgsem/calc_volume_integral.jl index 32787a5eb30..eeb9f35756f 100644 --- a/src/solvers/dgsem/calc_volume_integral.jl +++ b/src/solvers/dgsem/calc_volume_integral.jl @@ -9,44 +9,48 @@ # dimension and meshtype agnostic, i.e., valid for all 1D, 2D, and 3D meshes. @inline function volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral::VolumeIntegralWeakForm, dg, cache, alpha = true) weak_form_kernel!(du, u, element, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, dg, cache, alpha) return nothing end @inline function volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral::VolumeIntegralFluxDifferencing, dg, cache, alpha = true) @unpack volume_flux = volume_integral # Volume integral specific data flux_differencing_kernel!(du, u, element, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_flux, dg, cache, alpha) return nothing end @inline function volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral::VolumeIntegralPureLGLFiniteVolume, dg::DGSEM, cache, alpha = true) @unpack volume_flux_fv = volume_integral # Volume integral specific data fv_kernel!(du, u, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_flux_fv, dg, cache, element, alpha) return nothing end @inline function volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral::VolumeIntegralPureLGLFiniteVolumeO2, dg::DGSEM, cache, alpha = true) # Unpack volume integral specific data @@ -54,7 +58,7 @@ end cons2recon, recon2cons) = volume_integral fvO2_kernel!(du, u, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_flux_fv, dg, cache, element, sc_interface_coords, reconstruction_mode, slope_limiter, cons2recon, recon2cons, @@ -64,14 +68,15 @@ end end @inline function volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral::VolumeIntegralAdaptive{<:IndicatorEntropyChange}, dg::DGSEM, cache) @unpack volume_integral_default, volume_integral_stabilized, indicator = volume_integral @unpack maximum_entropy_increase = indicator volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_integral_default, dg, cache) # Compute entropy production of the default volume integral. @@ -93,7 +98,7 @@ end du[.., element] .= zero(eltype(du)) volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_integral_stabilized, dg, cache) end @@ -101,7 +106,8 @@ end end @inline function volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral::VolumeIntegralEntropyCorrection, dg::DGSEM, cache) @unpack volume_integral_default, volume_integral_stabilized, indicator = volume_integral @@ -111,7 +117,7 @@ end # run default volume integral volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_integral_default, dg, cache) # Check entropy production of "high order" volume integral. @@ -148,7 +154,7 @@ end # Calculate entropy stable volume integral contribution volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_integral_stabilized, dg, cache) dS_volume_integral_stabilized = -entropy_change_reference_element(du, u, @@ -178,11 +184,11 @@ end end function calc_volume_integral!(backend::Nothing, du, u, mesh, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_integral, dg::DGSEM, cache) @threaded for element in eachelement(dg, cache) volume_integral_kernel!(du, u, element, typeof(mesh), - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_integral, dg, cache) end @@ -196,18 +202,18 @@ function calc_volume_integral!(backend::Backend, du, u, mesh, nelements(dg, cache) == 0 && return nothing kernel! = volume_integral_KAkernel!(backend) kernel_cache = kernel_filter_cache(cache) - kernel!(du, u, typeof(mesh), have_nonconservative_terms, equations, + kernel!(du, u, typeof(mesh), have_nonconservative_terms, have_aux_node_vars, equations, volume_integral, dg, kernel_cache, ndrange = nelements(dg, cache)) return nothing end @kernel function volume_integral_KAkernel!(du, u, MeshT, - have_nonconservative_terms, equations, - volume_integral, dg::DGSEM, cache) + have_nonconservative_terms, have_aux_node_vars, + equations, volume_integral, dg::DGSEM, cache) element = @index(Global) volume_integral_kernel!(du, u, element, MeshT, have_nonconservative_terms, - equations, volume_integral, dg, cache) + have_aux_node_vars, equations, volume_integral, dg, cache) end @inline function calc_volume_integral!(backend::Nothing, du, u, mesh, @@ -232,11 +238,13 @@ end if default_volume_integral volume_integral_kernel!(du, u, element, typeof(mesh), - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral_default, dg, cache) else volume_integral_kernel!(du, u, element, typeof(mesh), - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral_stabilized, dg, cache) end end @@ -245,7 +253,7 @@ end end function calc_volume_integral!(backend::Nothing, du, u, mesh, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_integral::VolumeIntegralShockCapturingHGType, dg::DGSEM, cache) @unpack (indicator, volume_integral_default, @@ -266,18 +274,21 @@ function calc_volume_integral!(backend::Nothing, du, u, mesh, if dg_only volume_integral_kernel!(du, u, element, typeof(mesh), - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral_default, dg, cache) else # Calculate DG volume integral contribution volume_integral_kernel!(du, u, element, typeof(mesh), - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral_blend_high_order, dg, cache, 1 - alpha_element) # Calculate FV volume integral contribution volume_integral_kernel!(du, u, element, typeof(mesh), - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral_blend_low_order, dg, cache, alpha_element) end @@ -287,7 +298,7 @@ function calc_volume_integral!(backend::Nothing, du, u, mesh, end function calc_volume_integral!(backend::Nothing, du, u, mesh, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_integral::VolumeIntegralEntropyCorrectionShockCapturingCombined, dg::DGSEM, cache) (; volume_integral_default, volume_integral_stabilized, indicator) = volume_integral @@ -306,7 +317,7 @@ function calc_volume_integral!(backend::Nothing, du, u, mesh, @threaded for element in eachelement(dg, cache) # run default volume integral volume_integral_kernel!(du, u, element, typeof(mesh), - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_integral_default, dg, cache) # Check entropy production of "high order" volume integral. @@ -343,7 +354,8 @@ function calc_volume_integral!(backend::Nothing, du, u, mesh, # Calculate entropy stable volume integral contribution volume_integral_kernel!(du, u, element, typeof(mesh), - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral_stabilized, dg, cache) dS_volume_integral_stabilized = -entropy_change_reference_element(du, u, diff --git a/src/solvers/dgsem/indicators.jl b/src/solvers/dgsem/indicators.jl index 5399e077ffb..2c756fbfea4 100644 --- a/src/solvers/dgsem/indicators.jl +++ b/src/solvers/dgsem/indicators.jl @@ -137,7 +137,8 @@ function (indicator_hg::IndicatorHennemannGassner)(u, mesh, equations, dg::DGSEM # Otherwise, `@threaded` does not work here with Julia ARM on macOS. # See https://github.com/JuliaSIMD/Polyester.jl/issues/88. calc_indicator_hennemann_gassner!(indicator_hg, threshold, parameter_s, u, - element, mesh, equations, dg, cache) + element, mesh, have_aux_node_vars(equations), + equations, dg, cache) end if alpha_smooth diff --git a/src/solvers/dgsem_structured/dg_2d.jl b/src/solvers/dgsem_structured/dg_2d.jl index ed83f7e27de..f46897a1ec5 100644 --- a/src/solvers/dgsem_structured/dg_2d.jl +++ b/src/solvers/dgsem_structured/dg_2d.jl @@ -149,7 +149,8 @@ end have_nonconservative_terms::True, have_aux_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) - flux_differencing_kernel!(du, u, element, MeshT, have_nonconservative_terms, + flux_differencing_kernel!(du, u, element, MeshT, + have_nonconservative_terms, have_aux_node_vars, combine_conservative_and_nonconservative_fluxes(volume_flux, equations), equations, @@ -165,6 +166,7 @@ end P4estMesh{2}, T8codeMesh{2}}}, have_nonconservative_terms::True, + have_aux_node_vars::False, combine_conservative_and_nonconservative_fluxes::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) diff --git a/src/solvers/dgsem_structured/dg_3d.jl b/src/solvers/dgsem_structured/dg_3d.jl index 5c500f71ea0..d17909262e2 100644 --- a/src/solvers/dgsem_structured/dg_3d.jl +++ b/src/solvers/dgsem_structured/dg_3d.jl @@ -196,6 +196,7 @@ end P4estMesh{3}, T8codeMesh{3}}}, have_nonconservative_terms::True, + have_aux_node_vars::False, combine_conservative_and_nonconservative_fluxes::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) @@ -381,7 +382,7 @@ end fstar3_L, fstar3_R, u, ::Type{<:Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}}, - have_nonconservative_terms::False, + have_nonconservative_terms::False, have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) @unpack contravariant_vectors = cache.elements @unpack weights, derivative_matrix = dg.basis @@ -442,7 +443,7 @@ end fstar3_L, fstar3_R, u, ::Type{<:Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}}, - have_nonconservative_terms::True, + have_nonconservative_terms::True, have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) @unpack contravariant_vectors = cache.elements @unpack weights, derivative_matrix = dg.basis diff --git a/src/solvers/dgsem_tree/containers_2d.jl b/src/solvers/dgsem_tree/containers_2d.jl index d5f04f5beb1..5de70bca1fb 100644 --- a/src/solvers/dgsem_tree/containers_2d.jl +++ b/src/solvers/dgsem_tree/containers_2d.jl @@ -1636,7 +1636,7 @@ end # 2D TreeMesh implementation, similar to prolong2mpiinterfaces # However we directly assign to both sides, assuming the aux field had no jumps. Therefore # we do not need any exchange. -function init_aux_mpiinterface_node_vars!(aux_vars, mesh::ParallelTreeMesh{2}, +function init_aux_mpiinterface_node_vars!(aux_vars, mesh::TreeMeshParallel{2}, equations, solver, cache) @unpack aux_node_vars, aux_mpiinterface_node_vars = aux_vars @@ -1686,7 +1686,7 @@ end # 2D TreeMesh implementation, similar to prolong2mpimortars # However: - We only assign the small element values (only leftright = 1 is used) # - These have to be communicated -function init_aux_mpimortar_node_vars!(aux_vars, mesh::ParallelTreeMesh{2}, equations, +function init_aux_mpimortar_node_vars!(aux_vars, mesh::TreeMeshParallel{2}, equations, solver, cache) @unpack aux_node_vars, aux_mpimortar_node_vars = aux_vars @unpack mpi_mortars = cache diff --git a/src/solvers/dgsem_tree/dg_1d.jl b/src/solvers/dgsem_tree/dg_1d.jl index f972af86ee8..5499be64362 100644 --- a/src/solvers/dgsem_tree/dg_1d.jl +++ b/src/solvers/dgsem_tree/dg_1d.jl @@ -72,7 +72,8 @@ function rhs!(du, u, t, # Calculate volume integral @trixi_timeit timer() "volume integral" begin calc_volume_integral!(backend, du, u, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_aux_node_vars(equations), equations, dg.volume_integral, dg, cache) end @@ -218,7 +219,7 @@ end @inline function fv_kernel!(du, u, MeshT::Type{<:Union{TreeMesh{1}, StructuredMesh{1}}}, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_flux_fv, dg::DGSEM, cache, element, alpha = true) @unpack fstar1_L_threaded, fstar1_R_threaded = cache @unpack inverse_weights = dg.basis # Plays role of inverse DG-subcell sizes @@ -244,7 +245,7 @@ end @inline function fvO2_kernel!(du, u, MeshT::Type{<:Union{TreeMesh{1}, StructuredMesh{1}}}, - nonconservative_terms, equations, + nonconservative_terms, have_aux_node_vars, equations, volume_flux_fv, dg::DGSEM, cache, element, sc_interface_coords, reconstruction_mode, slope_limiter, cons2recon, recon2cons, @@ -278,7 +279,7 @@ end # [arXiv: 2008.12044v2](https://arxiv.org/pdf/2008.12044) @inline function calcflux_fv!(fstar1_L, fstar1_R, u, ::Type{<:Union{TreeMesh{1}, StructuredMesh{1}}}, - have_nonconservative_terms::False, + have_nonconservative_terms::False, have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) for i in 2:nnodes(dg) u_ll = get_node_vars(u, equations, dg, i - 1, element) @@ -293,7 +294,7 @@ end @inline function calcflux_fv!(fstar1_L, fstar1_R, u, ::Type{<:TreeMesh{1}}, - have_nonconservative_terms::True, + have_nonconservative_terms::True, have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) volume_flux, nonconservative_flux = volume_flux_fv for i in 2:nnodes(dg) diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 321e6c424b3..55696215980 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -224,6 +224,39 @@ See also https://github.com/trixi-framework/Trixi.jl/issues/1671#issuecomment-17 return nothing end +@inline function weak_form_kernel!(du, u, + element, ::Type{<:TreeMesh{2}}, + have_nonconservative_terms::False, + have_aux_node_vars::True, equations, + dg::DGSEM, cache, alpha = true) + # true * [some floating point value] == [exactly the same floating point value] + # This can (hopefully) be optimized away due to constant propagation. + @unpack derivative_hat = dg.basis + @unpack aux_node_vars = cache.aux_vars + + # Calculate volume terms in one element + for j in eachnode(dg), i in eachnode(dg) + u_node = get_node_vars(u, equations, dg, i, j, element) + aux_node = get_aux_node_vars(aux_node_vars, + equations, dg, i, j, element) + + flux1 = flux(u_node, aux_node, 1, equations) + for ii in eachnode(dg) + multiply_add_to_node_vars!(du, alpha * derivative_hat[ii, i], flux1, + equations, dg, ii, j, element) + end + + flux2 = flux(u_node, aux_node, 2, equations) + for jj in eachnode(dg) + multiply_add_to_node_vars!(du, alpha * derivative_hat[jj, j], flux2, + equations, dg, i, jj, element) + end + end + + return nothing +end + + @inline function flux_differencing_kernel!(du, u, element, ::Type{<:TreeMesh{2}}, have_nonconservative_terms::False, have_aux_node_vars::False, equations, @@ -310,7 +343,7 @@ end MeshT::Type{<:Union{TreeMesh{2}, StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}}, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_flux_fv, dg::DGSEM, cache, element, sc_interface_coords, reconstruction_mode, slope_limiter, cons2recon, recon2cons, @@ -414,7 +447,7 @@ end MeshT::Type{<:Union{TreeMesh{2}, StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}}, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_flux_fv, dg::DGSEM, cache, element, alpha = true) @unpack fstar1_L_threaded, fstar1_R_threaded, fstar2_L_threaded, fstar2_R_threaded = cache @unpack inverse_weights = dg.basis # Plays role of inverse DG-subcell sizes @@ -425,7 +458,7 @@ end fstar1_R = fstar1_R_threaded[Threads.threadid()] fstar2_R = fstar2_R_threaded[Threads.threadid()] calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, u, MeshT, - have_nonconservative_terms, have_aux_node_vars(equations), equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_flux_fv, dg, element, cache) # Calculate FV volume integral contribution @@ -679,7 +712,7 @@ function calc_interface_flux!(backend::Nothing, surface_flux_values, return nothing end -function calc_interface_flux!(surface_flux_values, +function calc_interface_flux!(backend::Nothing, surface_flux_values, mesh::TreeMesh{2}, have_nonconservative_terms::True, have_aux_node_vars::False, equations, @@ -726,7 +759,7 @@ function calc_interface_flux!(surface_flux_values, return nothing end -function calc_interface_flux!(surface_flux_values, +function calc_interface_flux!(backend::Nothing, surface_flux_values, mesh::TreeMesh{2}, have_nonconservative_terms::True, have_aux_node_vars::True, equations, @@ -1205,13 +1238,13 @@ function calc_mortar_flux!(surface_flux_values, # Calculate fluxes orientation = orientations[mortar] calc_fstar!(fstar_primary_upper, equations, - surface_flux, dg, u_upper, mortar, orientation, cache) + surface_flux, dg, u_upper, mortar, orientation) calc_fstar!(fstar_primary_lower, equations, - surface_flux, dg, u_lower, mortar, orientation, cache) + surface_flux, dg, u_lower, mortar, orientation) calc_fstar!(fstar_secondary_upper, equations, - surface_flux, dg, u_upper, mortar, orientation, cache) + surface_flux, dg, u_upper, mortar, orientation) calc_fstar!(fstar_secondary_lower, equations, - surface_flux, dg, u_lower, mortar, orientation, cache) + surface_flux, dg, u_lower, mortar, orientation) mortar_fluxes_to_elements!(surface_flux_values, mesh, equations, mortar_l2, dg, cache, @@ -1244,16 +1277,16 @@ function calc_mortar_flux!(surface_flux_values, orientation = orientations[mortar] calc_fstar!(fstar_primary_upper, equations, surface_flux, dg, u_upper, aux_mortar_node_vars, 2, mortar, - orientation, cache) + orientation) calc_fstar!(fstar_primary_lower, equations, surface_flux, dg, u_lower, aux_mortar_node_vars, 1, mortar, - orientation, cache) + orientation) calc_fstar!(fstar_secondary_upper, equations, surface_flux, dg, u_upper, aux_mortar_node_vars, 2, mortar, - orientation, cache) + orientation) calc_fstar!(fstar_secondary_lower, equations, surface_flux, dg, u_lower, aux_mortar_node_vars, 1, mortar, - orientation, cache) + orientation) mortar_fluxes_to_elements!(surface_flux_values, mesh, equations, mortar_l2, dg, cache, @@ -1284,13 +1317,13 @@ function calc_mortar_flux!(surface_flux_values, # Calculate fluxes orientation = orientations[mortar] calc_fstar!(fstar_primary_upper, equations, - surface_flux, dg, u_upper, mortar, orientation, cache) + surface_flux, dg, u_upper, mortar, orientation) calc_fstar!(fstar_primary_lower, equations, - surface_flux, dg, u_lower, mortar, orientation, cache) + surface_flux, dg, u_lower, mortar, orientation) calc_fstar!(fstar_secondary_upper, equations, - surface_flux, dg, u_upper, mortar, orientation, cache) + surface_flux, dg, u_upper, mortar, orientation) calc_fstar!(fstar_secondary_lower, equations, - surface_flux, dg, u_lower, mortar, orientation, cache) + surface_flux, dg, u_lower, mortar, orientation) # Add nonconservative fluxes. # These need to be adapted on the geometry (left/right) since the order of @@ -1396,7 +1429,7 @@ end @inline function calc_fstar!(destination::AbstractArray{<:Any, 2}, equations, surface_flux, dg::DGSEM, - u, aux, position, interface, orientation, cache) + u, aux, position, interface, orientation) for i in eachnode(dg) # Call pointwise two-point numerical flux function u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) diff --git a/src/solvers/dgsem_tree/dg_2d_parallel.jl b/src/solvers/dgsem_tree/dg_2d_parallel.jl index 787e9441989..9c2de478e1c 100644 --- a/src/solvers/dgsem_tree/dg_2d_parallel.jl +++ b/src/solvers/dgsem_tree/dg_2d_parallel.jl @@ -774,7 +774,7 @@ function calc_mpi_interface_flux!(surface_flux_values, end function calc_mpi_interface_flux!(surface_flux_values, - mesh::ParallelTreeMesh{2}, + mesh::TreeMeshParallel{2}, have_nonconservative_terms::False, have_aux_node_vars::True, equations, surface_integral, dg::DG, cache) @@ -859,7 +859,7 @@ function calc_mpi_mortar_flux!(surface_flux_values, end function calc_mpi_mortar_flux!(surface_flux_values, - mesh::ParallelTreeMesh{2}, + mesh::TreeMeshParallel{2}, have_nonconservative_terms::False, have_aux_node_vars::True, equations, mortar_l2::LobattoLegendreMortarL2, diff --git a/src/solvers/dgsem_tree/dg_2d_subcell_limiters.jl b/src/solvers/dgsem_tree/dg_2d_subcell_limiters.jl index c8e67c85abc..5531f5ee320 100644 --- a/src/solvers/dgsem_tree/dg_2d_subcell_limiters.jl +++ b/src/solvers/dgsem_tree/dg_2d_subcell_limiters.jl @@ -65,7 +65,8 @@ end MeshT::Type{<:Union{TreeMesh{2}, StructuredMesh{2}, P4estMesh{2}}}, - have_nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral::VolumeIntegralSubcellLimiting, dg::DGSEM, cache) @unpack inverse_weights = dg.basis # Plays role of inverse DG-subcell sizes @@ -90,7 +91,7 @@ end fstar1_R = fstar1_R_threaded[Threads.threadid()] fstar2_R = fstar2_R_threaded[Threads.threadid()] calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, u, MeshT, - have_nonconservative_terms, have_aux_node_vars(equations), equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_flux_fv, dg, element, cache) # antidiffusive flux diff --git a/src/solvers/dgsem_tree/dg_3d.jl b/src/solvers/dgsem_tree/dg_3d.jl index 6c9809aeafe..5a52ab48291 100644 --- a/src/solvers/dgsem_tree/dg_3d.jl +++ b/src/solvers/dgsem_tree/dg_3d.jl @@ -272,7 +272,7 @@ end MeshT::Type{<:Union{TreeMesh{3}, StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}}, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_flux_fv, dg::DGSEM, cache, element, alpha = true) @unpack fstar1_L_threaded, fstar1_R_threaded, fstar2_L_threaded, fstar2_R_threaded, fstar3_L_threaded, fstar3_R_threaded = cache @unpack inverse_weights = dg.basis # Plays role of inverse DG-subcell sizes @@ -286,7 +286,7 @@ end fstar3_R = fstar3_R_threaded[Threads.threadid()] calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, fstar3_L, fstar3_R, u, - MeshT, have_nonconservative_terms, equations, + MeshT, have_nonconservative_terms, have_aux_node_vars, equations, volume_flux_fv, dg, element, cache) # Calculate FV volume integral contribution @@ -312,7 +312,7 @@ end MeshT::Type{<:Union{TreeMesh{3}, StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}}, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_flux_fv, dg::DGSEM, cache, element, sc_interface_coords, reconstruction_mode, slope_limiter, cons2recon, recon2cons, @@ -331,7 +331,7 @@ end fstar3_R = fstar3_R_threaded[Threads.threadid()] calcflux_fvO2!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, fstar3_L, fstar3_R, u, - MeshT, have_nonconservative_terms, equations, + MeshT, have_nonconservative_terms, have_aux_node_vars, equations, volume_flux_fv, dg, element, cache, sc_interface_coords, reconstruction_mode, slope_limiter, cons2recon, recon2cons) @@ -362,7 +362,7 @@ end @inline function calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, fstar3_L, fstar3_R, u, ::Type{<:TreeMesh{3}}, have_nonconservative_terms::False, - equations, + have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) for k in eachnode(dg), j in eachnode(dg), i in 2:nnodes(dg) u_ll = get_node_vars(u, equations, dg, i - 1, j, k, element) @@ -394,7 +394,8 @@ end @inline function calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, fstar3_L, fstar3_R, u, ::Type{<:TreeMesh{3}}, - have_nonconservative_terms::True, equations, + have_nonconservative_terms::True, + have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) volume_flux, nonconservative_flux = volume_flux_fv @@ -459,7 +460,7 @@ end fstar3_L, fstar3_R, u, ::Type{<:TreeMesh{3}}, have_nonconservative_terms::False, - equations, + have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache, sc_interface_coords, reconstruction_mode, slope_limiter, cons2recon, recon2cons) diff --git a/src/solvers/dgsem_tree/dg_3d_subcell_limiters.jl b/src/solvers/dgsem_tree/dg_3d_subcell_limiters.jl index 27e5d13049e..95f739119e1 100644 --- a/src/solvers/dgsem_tree/dg_3d_subcell_limiters.jl +++ b/src/solvers/dgsem_tree/dg_3d_subcell_limiters.jl @@ -64,7 +64,8 @@ end # Subcell limiting currently only implemented for certain mesh types @inline function volume_integral_kernel!(du, u, element, MeshT::Type{<:Union{TreeMesh{3}, P4estMesh{3}}}, - nonconservative_terms, equations, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral::VolumeIntegralSubcellLimiting, dg::DGSEM, cache) @unpack inverse_weights = dg.basis # Plays role of DG subcell sizes @@ -80,7 +81,7 @@ end fhat3_L = fhat3_L_threaded[Threads.threadid()] fhat3_R = fhat3_R_threaded[Threads.threadid()] calcflux_fhat!(fhat1_L, fhat1_R, fhat2_L, fhat2_R, fhat3_L, fhat3_R, - u, MeshT, nonconservative_terms, equations, volume_flux_dg, + u, MeshT, have_nonconservative_terms, equations, volume_flux_dg, dg, element, cache) # low-order FV fluxes @@ -93,13 +94,13 @@ end fstar3_L = fstar3_L_threaded[Threads.threadid()] fstar3_R = fstar3_R_threaded[Threads.threadid()] calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, fstar3_L, fstar3_R, - u, MeshT, nonconservative_terms, equations, volume_flux_fv, - dg, element, cache) + u, MeshT, have_nonconservative_terms, have_aux_node_vars, equations, + volume_flux_fv, dg, element, cache) # antidiffusive flux calcflux_antidiffusive!(fhat1_L, fhat1_R, fhat2_L, fhat2_R, fhat3_L, fhat3_R, fstar1_L, fstar1_R, fstar2_L, fstar2_R, fstar3_L, fstar3_R, - u, MeshT, nonconservative_terms, equations, limiter, + u, MeshT, have_nonconservative_terms, equations, limiter, dg, element, cache) # Calculate volume integral contribution of low-order FV flux diff --git a/src/solvers/fdsbp_tree/fdsbp_1d.jl b/src/solvers/fdsbp_tree/fdsbp_1d.jl index 002093121a7..6b7fb37ac63 100644 --- a/src/solvers/fdsbp_tree/fdsbp_1d.jl +++ b/src/solvers/fdsbp_tree/fdsbp_1d.jl @@ -44,7 +44,8 @@ end # 2D volume integral contributions for `VolumeIntegralStrongForm` function calc_volume_integral!(backend::Nothing, du, u, mesh::TreeMesh{1}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_integral::VolumeIntegralStrongForm, dg::FDSBP, cache) D = dg.basis # SBP derivative operator @@ -91,7 +92,8 @@ end # of the flux splitting f^-. function calc_volume_integral!(backend::Nothing, du, u, mesh::TreeMesh{1}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_integral::VolumeIntegralUpwind, dg::FDSBP, cache) # Assume that diff --git a/src/solvers/fdsbp_tree/fdsbp_2d.jl b/src/solvers/fdsbp_tree/fdsbp_2d.jl index 794f0b9d13e..b9ff9fb776d 100644 --- a/src/solvers/fdsbp_tree/fdsbp_2d.jl +++ b/src/solvers/fdsbp_tree/fdsbp_2d.jl @@ -44,7 +44,8 @@ end # 2D volume integral contributions for `VolumeIntegralStrongForm` function calc_volume_integral!(backend::Nothing, du, u, mesh::TreeMesh{2}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_integral::VolumeIntegralStrongForm, dg::FDSBP, cache) D = dg.basis # SBP derivative operator @@ -100,7 +101,8 @@ end # of the flux splitting f^-. function calc_volume_integral!(backend::Nothing, du, u, mesh::TreeMesh{2}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_integral::VolumeIntegralUpwind, dg::FDSBP, cache) # Assume that diff --git a/src/solvers/fdsbp_tree/fdsbp_3d.jl b/src/solvers/fdsbp_tree/fdsbp_3d.jl index 45aec3a476e..ec6444e3a89 100644 --- a/src/solvers/fdsbp_tree/fdsbp_3d.jl +++ b/src/solvers/fdsbp_tree/fdsbp_3d.jl @@ -44,7 +44,8 @@ end # 3D volume integral contributions for `VolumeIntegralStrongForm` function calc_volume_integral!(backend::Nothing, du, u, mesh::TreeMesh{3}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_integral::VolumeIntegralStrongForm, dg::FDSBP, cache) D = dg.basis # SBP derivative operator @@ -107,7 +108,8 @@ end # of the flux splitting f^-. function calc_volume_integral!(backend::Nothing, du, u, mesh::TreeMesh{3}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_integral::VolumeIntegralUpwind, dg::FDSBP, cache) # Assume that diff --git a/src/solvers/fdsbp_unstructured/fdsbp_2d.jl b/src/solvers/fdsbp_unstructured/fdsbp_2d.jl index 2d7058b9957..7fe80ef373d 100644 --- a/src/solvers/fdsbp_unstructured/fdsbp_2d.jl +++ b/src/solvers/fdsbp_unstructured/fdsbp_2d.jl @@ -31,7 +31,8 @@ end # So it is not provably stable for variable coefficients due to the the metric terms. function calc_volume_integral!(backend::Nothing, du, u, mesh::UnstructuredMesh2D, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_integral::VolumeIntegralStrongForm, dg::FDSBP, cache) D = dg.basis # SBP derivative operator @@ -94,7 +95,8 @@ end # of the flux splitting f^-. function calc_volume_integral!(backend::Nothing, du, u, mesh::UnstructuredMesh2D, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_integral::VolumeIntegralUpwind, dg::FDSBP, cache) # Assume that From 0ff3587016cf2ad1c0bdfa1676be153e4f6129b1 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Tue, 12 May 2026 21:04:02 +0200 Subject: [PATCH 62/83] fmt --- src/callbacks_step/stepsize.jl | 6 ++--- src/callbacks_step/stepsize_dg2d.jl | 11 +++++---- src/callbacks_step/stepsize_dg3d.jl | 3 ++- src/solvers/dg.jl | 3 ++- src/solvers/dgsem/calc_volume_integral.jl | 27 +++++++++++++++-------- src/solvers/dgsem_p4est/dg_2d_parallel.jl | 3 ++- src/solvers/dgsem_structured/dg_3d.jl | 6 +++-- src/solvers/dgsem_tree/dg_1d.jl | 6 +++-- src/solvers/dgsem_tree/dg_2d.jl | 1 - 9 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/callbacks_step/stepsize.jl b/src/callbacks_step/stepsize.jl index e667b676893..73ef4c03013 100644 --- a/src/callbacks_step/stepsize.jl +++ b/src/callbacks_step/stepsize.jl @@ -186,9 +186,9 @@ function calculate_dt(u_ode, t, cfl_hyperbolic, cfl_parabolic, u = wrap_array(u_ode, mesh, equations, solver, cache) dt_hyperbolic = cfl_hyperbolic(t) * max_dt(u, t, mesh, - have_constant_speed(equations), - have_aux_node_vars(equations), equations, - solver, cache) + have_constant_speed(equations), + have_aux_node_vars(equations), equations, + solver, cache) cfl_para = cfl_parabolic(t) if cfl_para > 0 # Check if parabolic CFL should be considered diff --git a/src/callbacks_step/stepsize_dg2d.jl b/src/callbacks_step/stepsize_dg2d.jl index 560e9f6b673..efe20a2d774 100644 --- a/src/callbacks_step/stepsize_dg2d.jl +++ b/src/callbacks_step/stepsize_dg2d.jl @@ -80,7 +80,6 @@ function max_dt(u, t, mesh::TreeMesh{2}, return 4 / (nnodes(dg) * max_scaled_speed) end - function max_dt(u, t, mesh::TreeMesh{2}, constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) @@ -167,7 +166,8 @@ function max_dt(u, t, constant_speed, have_aux_node_vars, equations, dg::DG, cache) backend = trixi_backend(u) - max_lambda = calc_max_scaled_speed(backend, u, mesh, constant_speed, have_aux_node_vars, + max_lambda = calc_max_scaled_speed(backend, u, mesh, constant_speed, + have_aux_node_vars, equations, dg, cache) # Avoid division by zero if the speed vanishes everywhere, @@ -183,7 +183,9 @@ end P4estMesh{2}, T8codeMesh{2}, StructuredMeshView{2}}}, - constant_speed::False,have_aux_node_vars::False, equations, dg::DG, + constant_speed::False, + have_aux_node_vars::False, equations, + dg::DG, contravariant_vectors, inverse_jacobian, element) max_lambda1 = max_lambda2 = zero(eltype(u)) @@ -261,7 +263,8 @@ end T8codeMesh{2}, StructuredMeshView{2}}}, constant_speed::True, - have_aux_node_vars::False, equations, dg::DG, + have_aux_node_vars::False, equations, + dg::DG, contravariant_vectors, inverse_jacobian, element) max_scaled_speed = zero(eltype(u)) diff --git a/src/callbacks_step/stepsize_dg3d.jl b/src/callbacks_step/stepsize_dg3d.jl index 1e4e9f59fd1..b257870fc46 100644 --- a/src/callbacks_step/stepsize_dg3d.jl +++ b/src/callbacks_step/stepsize_dg3d.jl @@ -83,7 +83,8 @@ function max_dt(u, t, constant_speed, have_aux_node_vars::False, equations, dg::DG, cache) backend = trixi_backend(u) - max_lambda = calc_max_scaled_speed(backend, u, mesh, constant_speed, have_aux_node_vars, + max_lambda = calc_max_scaled_speed(backend, u, mesh, constant_speed, + have_aux_node_vars, equations, dg, cache) # Avoid division by zero if the speed vanishes everywhere, diff --git a/src/solvers/dg.jl b/src/solvers/dg.jl index c1b0589eecc..f523ba163b2 100644 --- a/src/solvers/dg.jl +++ b/src/solvers/dg.jl @@ -1106,7 +1106,8 @@ end return u_ll, u_rr end -@inline function get_aux_surface_node_vars(aux_surface_node_vars, equations, ::Type{<:DG}, +@inline function get_aux_surface_node_vars(aux_surface_node_vars, equations, + ::Type{<:DG}, indices...) aux_vars_ll = SVector(ntuple(@inline(v->aux_surface_node_vars[1, v, indices...]), Val(n_aux_node_vars(equations)))) diff --git a/src/solvers/dgsem/calc_volume_integral.jl b/src/solvers/dgsem/calc_volume_integral.jl index eeb9f35756f..72295bdb393 100644 --- a/src/solvers/dgsem/calc_volume_integral.jl +++ b/src/solvers/dgsem/calc_volume_integral.jl @@ -98,7 +98,8 @@ end du[.., element] .= zero(eltype(du)) volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, have_aux_node_vars, equations, + have_nonconservative_terms, have_aux_node_vars, + equations, volume_integral_stabilized, dg, cache) end @@ -154,7 +155,8 @@ end # Calculate entropy stable volume integral contribution volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, have_aux_node_vars, equations, + have_nonconservative_terms, have_aux_node_vars, + equations, volume_integral_stabilized, dg, cache) dS_volume_integral_stabilized = -entropy_change_reference_element(du, u, @@ -184,11 +186,13 @@ end end function calc_volume_integral!(backend::Nothing, du, u, mesh, - have_nonconservative_terms, have_aux_node_vars, equations, + have_nonconservative_terms, have_aux_node_vars, + equations, volume_integral, dg::DGSEM, cache) @threaded for element in eachelement(dg, cache) volume_integral_kernel!(du, u, element, typeof(mesh), - have_nonconservative_terms, have_aux_node_vars, equations, + have_nonconservative_terms, have_aux_node_vars, + equations, volume_integral, dg, cache) end @@ -202,14 +206,16 @@ function calc_volume_integral!(backend::Backend, du, u, mesh, nelements(dg, cache) == 0 && return nothing kernel! = volume_integral_KAkernel!(backend) kernel_cache = kernel_filter_cache(cache) - kernel!(du, u, typeof(mesh), have_nonconservative_terms, have_aux_node_vars, equations, + kernel!(du, u, typeof(mesh), have_nonconservative_terms, have_aux_node_vars, + equations, volume_integral, dg, kernel_cache, ndrange = nelements(dg, cache)) return nothing end @kernel function volume_integral_KAkernel!(du, u, MeshT, - have_nonconservative_terms, have_aux_node_vars, + have_nonconservative_terms, + have_aux_node_vars, equations, volume_integral, dg::DGSEM, cache) element = @index(Global) volume_integral_kernel!(du, u, element, MeshT, have_nonconservative_terms, @@ -253,7 +259,8 @@ end end function calc_volume_integral!(backend::Nothing, du, u, mesh, - have_nonconservative_terms, have_aux_node_vars, equations, + have_nonconservative_terms, have_aux_node_vars, + equations, volume_integral::VolumeIntegralShockCapturingHGType, dg::DGSEM, cache) @unpack (indicator, volume_integral_default, @@ -298,7 +305,8 @@ function calc_volume_integral!(backend::Nothing, du, u, mesh, end function calc_volume_integral!(backend::Nothing, du, u, mesh, - have_nonconservative_terms, have_aux_node_vars, equations, + have_nonconservative_terms, have_aux_node_vars, + equations, volume_integral::VolumeIntegralEntropyCorrectionShockCapturingCombined, dg::DGSEM, cache) (; volume_integral_default, volume_integral_stabilized, indicator) = volume_integral @@ -317,7 +325,8 @@ function calc_volume_integral!(backend::Nothing, du, u, mesh, @threaded for element in eachelement(dg, cache) # run default volume integral volume_integral_kernel!(du, u, element, typeof(mesh), - have_nonconservative_terms, have_aux_node_vars, equations, + have_nonconservative_terms, have_aux_node_vars, + equations, volume_integral_default, dg, cache) # Check entropy production of "high order" volume integral. diff --git a/src/solvers/dgsem_p4est/dg_2d_parallel.jl b/src/solvers/dgsem_p4est/dg_2d_parallel.jl index 9e10bf35ea3..97b0f3fe425 100644 --- a/src/solvers/dgsem_p4est/dg_2d_parallel.jl +++ b/src/solvers/dgsem_p4est/dg_2d_parallel.jl @@ -242,7 +242,8 @@ end function calc_mpi_mortar_flux!(surface_flux_values, mesh::Union{P4estMeshParallel{2}, T8codeMeshParallel{2}}, - have_nonconservative_terms, have_aux_node_vars, equations, + have_nonconservative_terms, have_aux_node_vars, + equations, mortar_l2::LobattoLegendreMortarL2, surface_integral, dg::DG, cache) @unpack local_neighbor_ids, local_neighbor_positions, node_indices = cache.mpi_mortars diff --git a/src/solvers/dgsem_structured/dg_3d.jl b/src/solvers/dgsem_structured/dg_3d.jl index d17909262e2..54529549315 100644 --- a/src/solvers/dgsem_structured/dg_3d.jl +++ b/src/solvers/dgsem_structured/dg_3d.jl @@ -382,7 +382,8 @@ end fstar3_L, fstar3_R, u, ::Type{<:Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}}, - have_nonconservative_terms::False, have_aux_node_vars::False, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) @unpack contravariant_vectors = cache.elements @unpack weights, derivative_matrix = dg.basis @@ -443,7 +444,8 @@ end fstar3_L, fstar3_R, u, ::Type{<:Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}}, - have_nonconservative_terms::True, have_aux_node_vars::False, + have_nonconservative_terms::True, + have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) @unpack contravariant_vectors = cache.elements @unpack weights, derivative_matrix = dg.basis diff --git a/src/solvers/dgsem_tree/dg_1d.jl b/src/solvers/dgsem_tree/dg_1d.jl index 5499be64362..d4652708c99 100644 --- a/src/solvers/dgsem_tree/dg_1d.jl +++ b/src/solvers/dgsem_tree/dg_1d.jl @@ -279,7 +279,8 @@ end # [arXiv: 2008.12044v2](https://arxiv.org/pdf/2008.12044) @inline function calcflux_fv!(fstar1_L, fstar1_R, u, ::Type{<:Union{TreeMesh{1}, StructuredMesh{1}}}, - have_nonconservative_terms::False, have_aux_node_vars::False, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) for i in 2:nnodes(dg) u_ll = get_node_vars(u, equations, dg, i - 1, element) @@ -294,7 +295,8 @@ end @inline function calcflux_fv!(fstar1_L, fstar1_R, u, ::Type{<:TreeMesh{1}}, - have_nonconservative_terms::True, have_aux_node_vars::False, + have_nonconservative_terms::True, + have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache) volume_flux, nonconservative_flux = volume_flux_fv for i in 2:nnodes(dg) diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 55696215980..8a5637a2c4c 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -256,7 +256,6 @@ end return nothing end - @inline function flux_differencing_kernel!(du, u, element, ::Type{<:TreeMesh{2}}, have_nonconservative_terms::False, have_aux_node_vars::False, equations, From b1b5ebb39fc209932bb776e5dd43ac3757a51337 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 13 May 2026 09:59:04 +0200 Subject: [PATCH 63/83] more fixes --- .../elixir_acoustics_convergence_auxvars.jl | 1 + src/callbacks_step/stepsize_dg3d.jl | 7 +++++-- src/solvers/dgsem_p4est/dg_2d.jl | 8 +++++--- src/solvers/dgsem_p4est/dg_3d.jl | 2 +- src/solvers/dgsem_structured/dg.jl | 3 ++- src/solvers/dgsem_structured/dg_3d.jl | 4 +++- src/solvers/dgsem_tree/dg_1d.jl | 2 +- src/solvers/dgsem_tree/dg_2d_parallel.jl | 16 ++++++++-------- test/test_performance_specializations_2d.jl | 2 +- 9 files changed, 27 insertions(+), 18 deletions(-) diff --git a/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl b/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl index fc0d7eb31c9..20e925ca0ad 100644 --- a/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl +++ b/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl @@ -29,6 +29,7 @@ mesh = TreeMesh(coordinates_min, coordinates_max, # A semidiscretization collects data structures and functions for the spatial discretization semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, source_terms = source_terms_convergence_test, + boundary_conditions = boundary_condition_periodic, aux_field = auxiliary_variables_mean_values) ############################################################################### diff --git a/src/callbacks_step/stepsize_dg3d.jl b/src/callbacks_step/stepsize_dg3d.jl index b257870fc46..5d8eb5b67c7 100644 --- a/src/callbacks_step/stepsize_dg3d.jl +++ b/src/callbacks_step/stepsize_dg3d.jl @@ -98,7 +98,8 @@ end ::Type{<:Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}}, - constant_speed::False, equations, dg, + constant_speed::False, + have_aux_node_vars::False, equations, dg, contravariant_vectors, inverse_jacobian, element) max_lambda1 = max_lambda2 = max_lambda3 = zero(eltype(u)) @@ -181,7 +182,9 @@ end ::Type{<:Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}}, - constant_speed::True, equations, dg::DG, + constant_speed::True, + have_aux_node_vars::False, equations, + dg::DG, contravariant_vectors, inverse_jacobian, element) max_scaled_speed = zero(eltype(u)) diff --git a/src/solvers/dgsem_p4est/dg_2d.jl b/src/solvers/dgsem_p4est/dg_2d.jl index 3b5e5f376e0..896761b4b1c 100644 --- a/src/solvers/dgsem_p4est/dg_2d.jl +++ b/src/solvers/dgsem_p4est/dg_2d.jl @@ -416,7 +416,7 @@ end function calc_interface_flux!(backend::Nothing, surface_flux_values, mesh::Union{P4estMesh{2}, P4estMeshView{2}}, - have_nonconservative_terms, + have_nonconservative_terms, have_aux_node_vars, equations, surface_integral, dg::DGSEM{<:GaussLegendreBasis}, cache) @unpack neighbor_ids, node_indices = cache.interfaces @@ -1285,7 +1285,8 @@ function rhs!(du, u, t, u_parent, semis, # Calculate volume integral @trixi_timeit timer() "volume integral" begin calc_volume_integral!(backend, du, u, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_aux_node_vars(equations), equations, dg.volume_integral, dg, cache) end @@ -1297,7 +1298,8 @@ function rhs!(du, u, t, u_parent, semis, # Calculate interface fluxes @trixi_timeit timer() "interface flux" begin calc_interface_flux!(backend, cache.elements.surface_flux_values, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_aux_node_vars(equations), equations, dg.surface_integral, dg, cache) end diff --git a/src/solvers/dgsem_p4est/dg_3d.jl b/src/solvers/dgsem_p4est/dg_3d.jl index 4d14a3917e5..7276694f83b 100644 --- a/src/solvers/dgsem_p4est/dg_3d.jl +++ b/src/solvers/dgsem_p4est/dg_3d.jl @@ -225,7 +225,7 @@ end function calc_interface_flux!(backend::Backend, surface_flux_values, mesh::Union{P4estMesh{3}, T8codeMesh{3}}, - have_nonconservative_terms, + have_nonconservative_terms, have_aux_node_vars, equations, surface_integral, dg::DG, cache) @unpack neighbor_ids, node_indices = cache.interfaces @unpack contravariant_vectors = cache.elements diff --git a/src/solvers/dgsem_structured/dg.jl b/src/solvers/dgsem_structured/dg.jl index c40e9997aa3..090073b664e 100644 --- a/src/solvers/dgsem_structured/dg.jl +++ b/src/solvers/dgsem_structured/dg.jl @@ -50,7 +50,8 @@ function rhs!(du, u, t, # Calculate volume integral @trixi_timeit timer() "volume integral" begin calc_volume_integral!(backend, du, u, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_aux_node_vars(equations), equations, dg.volume_integral, dg, cache) end diff --git a/src/solvers/dgsem_structured/dg_3d.jl b/src/solvers/dgsem_structured/dg_3d.jl index 54529549315..047b6a24743 100644 --- a/src/solvers/dgsem_structured/dg_3d.jl +++ b/src/solvers/dgsem_structured/dg_3d.jl @@ -184,6 +184,7 @@ end have_aux_node_vars::False, equations, volume_flux, dg::DGSEM, cache, alpha = true) flux_differencing_kernel!(du, u, element, MeshT, have_nonconservative_terms, + have_aux_node_vars, combine_conservative_and_nonconservative_fluxes(volume_flux, equations), equations, volume_flux, dg, cache, alpha) @@ -541,7 +542,8 @@ end fstar3_L, fstar3_R, u, ::Type{<:Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}}, - have_nonconservative_terms::False, equations, + have_nonconservative_terms::False, + have_aux_node_vars::False, equations, volume_flux_fv, dg::DGSEM, element, cache, sc_interface_coords, reconstruction_mode, slope_limiter, cons2recon, recon2cons) diff --git a/src/solvers/dgsem_tree/dg_1d.jl b/src/solvers/dgsem_tree/dg_1d.jl index d4652708c99..2455d10146f 100644 --- a/src/solvers/dgsem_tree/dg_1d.jl +++ b/src/solvers/dgsem_tree/dg_1d.jl @@ -228,7 +228,7 @@ end fstar1_L = fstar1_L_threaded[Threads.threadid()] fstar1_R = fstar1_R_threaded[Threads.threadid()] calcflux_fv!(fstar1_L, fstar1_R, u, MeshT, - have_nonconservative_terms, equations, + have_nonconservative_terms, have_aux_node_vars, equations, volume_flux_fv, dg, element, cache) # Calculate FV volume integral contribution diff --git a/src/solvers/dgsem_tree/dg_2d_parallel.jl b/src/solvers/dgsem_tree/dg_2d_parallel.jl index 9c2de478e1c..fd360e24713 100644 --- a/src/solvers/dgsem_tree/dg_2d_parallel.jl +++ b/src/solvers/dgsem_tree/dg_2d_parallel.jl @@ -841,13 +841,13 @@ function calc_mpi_mortar_flux!(surface_flux_values, # are identical. So, we could possibly save on computation and just pass two copies later. orientation = orientations[mortar] calc_fstar!(fstar_primary_upper, equations, - surface_flux, dg, u_upper, mortar, orientation, cache) + surface_flux, dg, u_upper, mortar, orientation) calc_fstar!(fstar_primary_lower, equations, - surface_flux, dg, u_lower, mortar, orientation, cache) + surface_flux, dg, u_lower, mortar, orientation) calc_fstar!(fstar_secondary_upper, equations, - surface_flux, dg, u_upper, mortar, orientation, cache) + surface_flux, dg, u_upper, mortar, orientation) calc_fstar!(fstar_secondary_lower, equations, - surface_flux, dg, u_lower, mortar, orientation, cache) + surface_flux, dg, u_lower, mortar, orientation) mpi_mortar_fluxes_to_elements!(surface_flux_values, mesh, equations, mortar_l2, dg, cache, @@ -880,13 +880,13 @@ function calc_mpi_mortar_flux!(surface_flux_values, # are identical. So, we could possibly save on computation and just pass two copies later. orientation = orientations[mortar] calc_fstar!(fstar_primary_upper, equations, surface_flux, dg, u_upper, - aux_mpimortar_node_vars, 2, mortar, orientation, cache) + aux_mpimortar_node_vars, 2, mortar, orientation) calc_fstar!(fstar_primary_lower, equations, surface_flux, dg, u_lower, - aux_mpimortar_node_vars, 1, mortar, orientation, cache) + aux_mpimortar_node_vars, 1, mortar, orientation) calc_fstar!(fstar_secondary_upper, equations, surface_flux, dg, u_upper, - aux_mpimortar_node_vars, 2, mortar, orientation, cache) + aux_mpimortar_node_vars, 2, mortar, orientation) calc_fstar!(fstar_secondary_lower, equations, surface_flux, dg, u_lower, - aux_mpimortar_node_vars, 1, mortar, orientation, cache) + aux_mpimortar_node_vars, 1, mortar, orientation) mpi_mortar_fluxes_to_elements!(surface_flux_values, mesh, equations, mortar_l2, dg, cache, diff --git a/test/test_performance_specializations_2d.jl b/test/test_performance_specializations_2d.jl index 4662ceb761c..3bf00c3e104 100644 --- a/test/test_performance_specializations_2d.jl +++ b/test/test_performance_specializations_2d.jl @@ -49,7 +49,7 @@ isdir(outdir) && rm(outdir, recursive = true) typeof(have_nonconservative_terms), typeof(have_aux_node_vars), typeof(semi.equations), Function, typeof(semi.solver), typeof(semi.cache), Bool}, - du, u, 1, semi.mesh, + du, u, 1, typeof(semi.mesh), have_nonconservative_terms, have_aux_node_vars, semi.equations, semi.solver.volume_integral.volume_flux, semi.solver, semi.cache, true) du_baseline = du[:, :, :, 1] From 0f466c6ba4c87daedcff15f350ad2206ee227801 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 13 May 2026 16:35:55 +0200 Subject: [PATCH 64/83] more --- .../tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl | 2 +- src/solvers/dgsem_p4est/dg_2d.jl | 6 ++++-- src/solvers/dgsem_structured/dg_2d.jl | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl b/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl index 20e925ca0ad..4e5a17f79b9 100644 --- a/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl +++ b/examples/tree_2d_dgsem/elixir_acoustics_convergence_auxvars.jl @@ -24,7 +24,7 @@ coordinates_max = (2.0, 2.0) # maximum coordinates (max(x), max(y)) # Create a uniformly refined mesh with periodic boundaries mesh = TreeMesh(coordinates_min, coordinates_max, initial_refinement_level = 3, - n_cells_max = 30_000) # set maximum capacity of tree data structure + n_cells_max = 30_000, periodicity = true) # set maximum capacity of tree data structure # A semidiscretization collects data structures and functions for the spatial discretization semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, diff --git a/src/solvers/dgsem_p4est/dg_2d.jl b/src/solvers/dgsem_p4est/dg_2d.jl index 896761b4b1c..aba6c8d4dd0 100644 --- a/src/solvers/dgsem_p4est/dg_2d.jl +++ b/src/solvers/dgsem_p4est/dg_2d.jl @@ -1324,7 +1324,8 @@ function rhs!(du, u, t, u_parent, semis, # Calculate mortar fluxes @trixi_timeit timer() "mortar flux" begin calc_mortar_flux!(cache.elements.surface_flux_values, mesh, - have_nonconservative_terms(equations), equations, + have_nonconservative_terms(equations), + have_aux_node_vars(equations), equations, dg.mortar, dg.surface_integral, dg, cache) end @@ -1340,7 +1341,8 @@ function rhs!(du, u, t, u_parent, semis, # Calculate source terms @trixi_timeit timer() "source terms" begin - calc_sources!(du, u, t, source_terms, equations, dg, cache) + calc_sources!(du, u, t, source_terms, have_aux_node_vars(equations), equations, + dg, cache) end return nothing diff --git a/src/solvers/dgsem_structured/dg_2d.jl b/src/solvers/dgsem_structured/dg_2d.jl index f46897a1ec5..10fe6452e8e 100644 --- a/src/solvers/dgsem_structured/dg_2d.jl +++ b/src/solvers/dgsem_structured/dg_2d.jl @@ -241,6 +241,7 @@ end P4estMesh{2}, T8codeMesh{2}}}, have_nonconservative_terms::True, + have_aux_node_vars::False, combine_conservative_and_nonconservative_fluxes::True, equations, volume_flux, dg::DGSEM, cache, alpha = true) From 69411f445d5d69c5f6a2e182f5e06215b079a921 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Thu, 14 May 2026 00:00:08 +0200 Subject: [PATCH 65/83] still some left --- src/callbacks_step/stepsize_dg2d.jl | 3 ++- src/solvers/dgsem_structured/dg_3d.jl | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/callbacks_step/stepsize_dg2d.jl b/src/callbacks_step/stepsize_dg2d.jl index efe20a2d774..6b8590ba061 100644 --- a/src/callbacks_step/stepsize_dg2d.jl +++ b/src/callbacks_step/stepsize_dg2d.jl @@ -334,7 +334,8 @@ function max_dt(u, t, end function max_dt(u, t, mesh::P4estMeshParallel{2}, - constant_speed::False, equations, dg::DG, cache) + constant_speed::False, have_aux_node_vars::False, + equations, dg::DG, cache) # call the method accepting a general `mesh::P4estMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` # and create some MPI array type, overloading broadcasting and mapreduce etc. diff --git a/src/solvers/dgsem_structured/dg_3d.jl b/src/solvers/dgsem_structured/dg_3d.jl index 047b6a24743..cb52ba5950a 100644 --- a/src/solvers/dgsem_structured/dg_3d.jl +++ b/src/solvers/dgsem_structured/dg_3d.jl @@ -289,6 +289,7 @@ end P4estMesh{3}, T8codeMesh{3}}}, have_nonconservative_terms::True, + have_aux_node_vars::False, combine_conservative_and_nonconservative_fluxes::True, equations, volume_flux, dg::DGSEM, cache, alpha = true) From 8f3437c635fedf5676d947343f03fc53dcea2670 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 15 May 2026 09:04:50 +0200 Subject: [PATCH 66/83] add TreeMesh2D aux vars test with MPI and AMR --- test/test_mpi_tree.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/test_mpi_tree.jl b/test/test_mpi_tree.jl index 62c74e2fd3c..46caebaf3ac 100644 --- a/test/test_mpi_tree.jl +++ b/test/test_mpi_tree.jl @@ -103,6 +103,13 @@ CI_ON_WINDOWS = (get(ENV, "GITHUB_ACTIONS", false) == "true") && Sys.iswindows() linf=[0.0253454486893413]) end + @trixi_testset "elixir_acoustics_gauss_wall_amr_auxvars.jl" begin + @test_trixi_include(joinpath(EXAMPLES_DIR, + "elixir_acoustics_gauss_wall_amr_auxvars.jl"), + l2=[0.0194350488, 0.0195225440, 0.04819822538525215], + linf=[0.183057645, 0.190845961, 1.03618809]) + end + # Hyperbolic diffusion if !CI_ON_WINDOWS # see comment on `CI_ON_WINDOWS` in `test/test_mpi.jl` @trixi_testset "elixir_hypdiff_lax_friedrichs.jl" begin From 0b36ca3b7675f4aa7a3d3ff226836fc3f0c68316 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 15 May 2026 09:06:50 +0200 Subject: [PATCH 67/83] fix --- src/equations/acoustic_perturbation_2d_aux_vars.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/equations/acoustic_perturbation_2d_aux_vars.jl b/src/equations/acoustic_perturbation_2d_aux_vars.jl index 30a45236148..069fe43e7ae 100644 --- a/src/equations/acoustic_perturbation_2d_aux_vars.jl +++ b/src/equations/acoustic_perturbation_2d_aux_vars.jl @@ -335,7 +335,7 @@ function varnames(::typeof(cons2state), ::AcousticPerturbationEquations2DAuxVars ("v1_prime", "v2_prime", "p_prime_scaled") end -function cons2aux(u, aux, equations::AcousticPerturbationEquations2D) +function cons2aux(u, aux, ::AcousticPerturbationEquations2DAuxVars) return SVector(aux[1], aux[2], aux[3], aux[4]) end From 9517e98e7b7cc8e5a4d3179e14c81a92eb176868 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 15 May 2026 09:09:57 +0200 Subject: [PATCH 68/83] removed part which are uncovered atm --- .../acoustic_perturbation_2d_aux_vars.jl | 156 ------------------ src/solvers/dg.jl | 10 -- src/solvers/dgsem_p4est/containers.jl | 10 -- src/solvers/dgsem_tree/containers_1d.jl | 12 -- src/solvers/dgsem_tree/dg_2d.jl | 96 ----------- src/solvers/dgsem_tree/indicators_2d.jl | 12 -- src/visualization/utilities.jl | 27 --- 7 files changed, 323 deletions(-) diff --git a/src/equations/acoustic_perturbation_2d_aux_vars.jl b/src/equations/acoustic_perturbation_2d_aux_vars.jl index 069fe43e7ae..7de4780619b 100644 --- a/src/equations/acoustic_perturbation_2d_aux_vars.jl +++ b/src/equations/acoustic_perturbation_2d_aux_vars.jl @@ -18,13 +18,6 @@ struct AcousticPerturbationEquations2DAuxVars{RealT <: Real} <: rho_mean_global::RealT end -function AcousticPerturbationEquations2DAuxVars(v_mean_global::NTuple{2, <:Real}, - c_mean_global::Real, - rho_mean_global::Real) - return AcousticPerturbationEquations2DAuxVars(SVector(v_mean_global), c_mean_global, - rho_mean_global) -end - function AcousticPerturbationEquations2DAuxVars(; v_mean_global::NTuple{2, <:Real}, c_mean_global::Real, rho_mean_global::Real) @@ -47,21 +40,6 @@ function global_mean_vars(equations::AcousticPerturbationEquations2DAuxVars) equations.rho_mean_global end -""" - initial_condition_constant(x, t, equations::AcousticPerturbationEquations2DAuxVars) - -A constant initial condition where the state variables are zero and the mean flow is constant. -Uses the global mean values from `equations`. -""" -function initial_condition_constant(x, t, - equations::AcousticPerturbationEquations2DAuxVars) - v1_prime = 0 - v2_prime = 0 - p_prime_scaled = 0 - - return SVector(v1_prime, v2_prime, p_prime_scaled) -end - """ initial_condition_convergence_test(x, t, equations::AcousticPerturbationEquations2DAuxVars) @@ -115,21 +93,6 @@ function source_terms_convergence_test(u, aux, x, t, return SVector(du1, du2, du3) end -""" - initial_condition_gauss(x, t, equations::AcousticPerturbationEquations2DAuxVars) - -A Gaussian pulse in a constant mean flow. Uses the global mean values from `equations`. -""" -function initial_condition_gauss(x, t, - equations::AcousticPerturbationEquations2DAuxVars) - v1_prime = 0 - v2_prime = 0 - p_prime = exp(-4 * (x[1]^2 + x[2]^2)) - p_prime_scaled = p_prime / equations.c_mean_global^2 - - return SVector(v1_prime, v2_prime, p_prime_scaled) -end - """ boundary_condition_wall(u_inner, aux_inner, orientation, direction, x, t, surface_flux_function, @@ -162,38 +125,6 @@ function boundary_condition_wall(u_inner, aux_inner, orientation, direction, x, return flux end -""" - boundary_condition_slip_wall(u_inner, aux_inner, normal_direction, x, t, - surface_flux_function, - equations::AcousticPerturbationEquations2DAuxVars) - -Use an orthogonal projection of the perturbed velocities to zero out the normal velocity -while retaining the possibility of a tangential velocity in the boundary state. -Further details are available in the paper: -- Marcus Bauer, Jürgen Dierke and Roland Ewert (2011) - Application of a discontinuous Galerkin method to discretize acoustic perturbation equations - [DOI: 10.2514/1.J050333](https://doi.org/10.2514/1.J050333) -""" -function boundary_condition_slip_wall(u_inner, normal_direction::AbstractVector, x, t, - surface_flux_function, - equations::AcousticPerturbationEquations2DAuxVars) - # normalize the outward pointing direction - normal = normal_direction / norm(normal_direction) - - # compute the normal perturbed velocity - u_normal = normal[1] * u_inner[1] + normal[2] * u_inner[2] - - # create the "external" boundary solution state - u_boundary = SVector(u_inner[1] - 2 * u_normal * normal[1], - u_inner[2] - 2 * u_normal * normal[2], - u_inner[3]) - - # calculate the boundary flux - flux = surface_flux_function(u_inner, u_boundary, normal_direction, equations) - - return flux -end - # Calculate 1D flux for a single point @inline function flux(u, aux, orientation::Integer, equations::AcousticPerturbationEquations2DAuxVars) @@ -217,24 +148,6 @@ end return SVector(f1, f2, f3) end -# Calculate maximum wave speed for local Lax-Friedrichs-type dissipation -@inline function max_abs_speed_naive(u_ll, u_rr, aux_ll, aux_rr, orientation::Integer, - equations::AcousticPerturbationEquations2DAuxVars) - # Calculate v = v_prime + v_mean - v_prime_ll = u_ll[orientation] - v_prime_rr = u_rr[orientation] - v_mean_ll = aux_ll[orientation] - v_mean_rr = aux_rr[orientation] - - v_ll = v_prime_ll + v_mean_ll - v_rr = v_prime_rr + v_mean_rr - - c_mean_ll = aux_ll[3] - c_mean_rr = aux_rr[3] - - return max(abs(v_ll), abs(v_rr)) + max(c_mean_ll, c_mean_rr) -end - # Less "cautious", i.e., less overestimating `λ_max` compared to `max_abs_speed_naive` @inline function max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, orientation::Integer, equations::AcousticPerturbationEquations2DAuxVars) @@ -253,66 +166,6 @@ end return max(abs(v_ll) + c_mean_ll, abs(v_rr) + c_mean_rr) end -# Calculate 1D flux for a single point in the normal direction -# Note, this directional vector is not normalized -@inline function flux(u, aux, normal_direction::AbstractVector, - equations::AcousticPerturbationEquations2DAuxVars) - v1_prime, v2_prime, p_prime_scaled = u - v1_mean, v2_mean, c_mean, rho_mean = aux - - f1 = normal_direction[1] * (v1_mean * v1_prime + v2_mean * v2_prime + - c_mean^2 * p_prime_scaled / rho_mean) - f2 = normal_direction[2] * (v1_mean * v1_prime + v2_mean * v2_prime + - c_mean^2 * p_prime_scaled / rho_mean) - f3 = (normal_direction[1] * (rho_mean * v1_prime + v1_mean * p_prime_scaled) - + - normal_direction[2] * (rho_mean * v2_prime + v2_mean * p_prime_scaled)) - - return SVector(f1, f2, f3) -end - -# Calculate maximum wave speed for local Lax-Friedrichs-type dissipation -@inline function max_abs_speed_naive(u_ll, u_rr, aux_ll, aux_rr, - normal_direction::AbstractVector, - equations::AcousticPerturbationEquations2DAuxVars) - # Calculate v = v_prime + v_mean - v_prime_ll = normal_direction[1] * u_ll[1] + normal_direction[2] * u_ll[2] - v_prime_rr = normal_direction[1] * u_rr[1] + normal_direction[2] * u_rr[2] - v_mean_ll = normal_direction[1] * aux_ll[1] + normal_direction[2] * aux_ll[2] - v_mean_rr = normal_direction[1] * aux_rr[1] + normal_direction[2] * aux_rr[2] - - v_ll = v_prime_ll + v_mean_ll - v_rr = v_prime_rr + v_mean_rr - - c_mean_ll = aux_ll[3] - c_mean_rr = aux_rr[3] - - # The v_normals are already scaled by the norm - return (max(abs(v_ll), abs(v_rr)) + - max(c_mean_ll, c_mean_rr) * norm(normal_direction)) -end - -# Less "cautious", i.e., less overestimating `λ_max` compared to `max_abs_speed_naive` -@inline function max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, - normal_direction::AbstractVector, - equations::AcousticPerturbationEquations2DAuxVars) - # Calculate v = v_prime + v_mean - v_prime_ll = normal_direction[1] * u_ll[1] + normal_direction[2] * u_ll[2] - v_prime_rr = normal_direction[1] * u_rr[1] + normal_direction[2] * u_rr[2] - v_mean_ll = normal_direction[1] * aux_ll[1] + normal_direction[2] * aux_ll[2] - v_mean_rr = normal_direction[1] * aux_rr[1] + normal_direction[2] * aux_rr[2] - - v_ll = v_prime_ll + v_mean_ll - v_rr = v_prime_rr + v_mean_rr - - c_mean_ll = aux_ll[3] - c_mean_rr = aux_rr[3] - - norm_ = norm(normal_direction) - # The v_normals are already scaled by the norm - return max(abs(v_ll) + c_mean_ll * norm_, abs(v_rr) + c_mean_rr * norm_) -end - @inline have_constant_speed(::AcousticPerturbationEquations2DAuxVars) = False() @inline function max_abs_speeds(u, aux, @@ -357,15 +210,6 @@ function varnames(::typeof(cons2prim), ::AbstractAcousticPerturbationEquations{2 "v1_mean", "v2_mean", "c_mean", "rho_mean") end -# Convert primitive variables to conservative -@inline function prim2cons(u, aux, equations::AcousticPerturbationEquations2DAuxVars) - p_prime = u[3] - c_mean = aux[3] - p_prime_scaled = p_prime / c_mean^2 - - return SVector(u[1], u[2], p_prime_scaled) -end - # Convert conservative variables to entropy variables @inline cons2entropy(u, aux, equations::AcousticPerturbationEquations2DAuxVars) = u end # @muladd diff --git a/src/solvers/dg.jl b/src/solvers/dg.jl index f523ba163b2..78448b77725 100644 --- a/src/solvers/dg.jl +++ b/src/solvers/dg.jl @@ -1106,16 +1106,6 @@ end return u_ll, u_rr end -@inline function get_aux_surface_node_vars(aux_surface_node_vars, equations, - ::Type{<:DG}, - indices...) - aux_vars_ll = SVector(ntuple(@inline(v->aux_surface_node_vars[1, v, indices...]), - Val(n_aux_node_vars(equations)))) - aux_vars_rr = SVector(ntuple(@inline(v->aux_surface_node_vars[2, v, indices...]), - Val(n_aux_node_vars(equations)))) - return aux_vars_ll, aux_vars_rr -end - @inline function set_node_vars!(u, u_node, equations, solver::DG, indices...) for v in eachvariable(equations) u[v, indices...] = u_node[v] diff --git a/src/solvers/dgsem_p4est/containers.jl b/src/solvers/dgsem_p4est/containers.jl index c4e7c6ad605..c86c2ea3d24 100644 --- a/src/solvers/dgsem_p4est/containers.jl +++ b/src/solvers/dgsem_p4est/containers.jl @@ -714,16 +714,6 @@ function reinitialize_containers!(mesh::P4estMesh, equations, dg::DGSEM, cache) # init_normal_directions! requires that `node_indices` have been initialized init_normal_directions!(interfaces, dg.basis, elements) - # re-initialize auxiliary variables container - if hasproperty(cache, :aux_vars) - @unpack aux_vars = cache - resize!(aux_vars, ncells(mesh), - required.interfaces, - required.boundaries, - required.mortars) - init_aux_vars!(aux_vars, mesh, equations, dg, cache) - end - return nothing end diff --git a/src/solvers/dgsem_tree/containers_1d.jl b/src/solvers/dgsem_tree/containers_1d.jl index c97202b76e3..15ddff369be 100644 --- a/src/solvers/dgsem_tree/containers_1d.jl +++ b/src/solvers/dgsem_tree/containers_1d.jl @@ -505,18 +505,6 @@ function reinitialize_containers!(mesh::TreeMesh{1}, equations, dg::DGSEM, cache resize!(boundaries, count_required_boundaries(mesh, leaf_cell_ids)) init_boundaries!(boundaries, elements, mesh, dg.basis) - # re-initialize auxiliary variables container - if hasproperty(cache, :aux_vars) - @unpack aux_vars = cache - resize!(aux_vars, length(leaf_cell_ids), - count_required_interfaces(mesh, leaf_cell_ids), - count_required_boundaries(mesh, leaf_cell_ids), - count_required_mortars(mesh, leaf_cell_ids), - count_required_mpi_interfaces(mesh, leaf_cell_ids), - count_required_mpi_mortars(mesh, leaf_cell_ids)) - init_aux_vars!(aux_vars, mesh, equations, dg, cache) - end - return nothing end end # @muladd diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 8a5637a2c4c..f845642f261 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -758,59 +758,6 @@ function calc_interface_flux!(backend::Nothing, surface_flux_values, return nothing end -function calc_interface_flux!(backend::Nothing, surface_flux_values, - mesh::TreeMesh{2}, - have_nonconservative_terms::True, - have_aux_node_vars::True, equations, - surface_integral, dg::DG, cache) - surface_flux, nonconservative_flux = surface_integral.surface_flux - @unpack u, neighbor_ids, orientations = cache.interfaces - @unpack aux_surface_node_vars = cache.aux_vars - - @threaded for interface in eachinterface(dg, cache) - # Get neighboring elements - left_id = neighbor_ids[1, interface] - right_id = neighbor_ids[2, interface] - - # Determine interface direction with respect to elements: - # orientation = 1: left -> 2, right -> 1 - # orientation = 2: left -> 4, right -> 3 - left_direction = 2 * orientations[interface] - right_direction = 2 * orientations[interface] - 1 - - for i in eachnode(dg) - # Call pointwise Riemann solver - orientation = orientations[interface] - u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, interface) - aux_ll, aux_rr = get_aux_surface_node_vars(aux_surface_node_vars, - equations, dg, i, - interface) - flux = surface_flux(u_ll, u_rr, aux_ll, aux_rr, orientation, equations) - - # Compute both nonconservative fluxes - noncons_left = nonconservative_flux(u_ll, u_rr, aux_ll, aux_rr, - orientation, equations) - noncons_right = nonconservative_flux(u_rr, u_ll, aux_rr, aux_ll, - orientation, equations) - - # Copy flux to left and right element storage - for v in eachvariable(equations) - # Note the factor 0.5 necessary for the nonconservative fluxes based on - # the interpretation of global SBP operators coupled discontinuously via - # central fluxes/SATs - surface_flux_values[v, i, left_direction, left_id] = flux[v] + - 0.5f0 * - noncons_left[v] - surface_flux_values[v, i, right_direction, right_id] = flux[v] + - 0.5f0 * - noncons_right[v] - end - end - end - - return nothing -end - function prolong2boundaries!(cache, u, mesh::TreeMesh{2}, equations, dg::DG) @unpack boundaries = cache @@ -1073,49 +1020,6 @@ function calc_boundary_flux_by_direction!(t, boundary_condition, return nothing end -function calc_boundary_flux_by_direction!(t, boundary_condition, - have_nonconservative_terms::True, - have_aux_node_vars::True, equations, - surface_integral, dg::DG, cache, - direction, first_boundary, last_boundary) - @unpack surface_flux_values = cache.elements - @unpack u, neighbor_ids, neighbor_sides, node_coordinates, orientations = cache.boundaries - @unpack aux_boundary_node_vars = cache.aux_vars - - @threaded for boundary in first_boundary:last_boundary - # Get neighboring element - neighbor = neighbor_ids[boundary] - - for i in eachnode(dg) - # Get boundary flux - u_ll, u_rr = get_surface_node_vars(u, equations, dg, i, boundary) - aux_ll, aux_rr = get_aux_surface_node_vars(aux_boundary_node_vars, - equations, dg, i, boundary) - if neighbor_sides[boundary] == 1 # Element is on the left, boundary on the right - u_inner = u_ll - aux_inner = aux_ll - else # Element is on the right, boundary on the left - u_inner = u_rr - aux_inner = aux_rr - end - x = get_node_coords(node_coordinates, equations, dg, i, boundary) - flux, noncons_flux = boundary_condition(u_inner, aux_inner, - orientations[boundary], direction, - x, t, - surface_integral.surface_flux, - equations) - - # Copy flux to left and right element storage - for v in eachvariable(equations) - surface_flux_values[v, i, direction, neighbor] = flux[v] + - 0.5f0 * noncons_flux[v] - end - end - end - - return nothing -end - function prolong2mortars!(cache, u, mesh::TreeMesh{2}, equations, mortar_l2::LobattoLegendreMortarL2, diff --git a/src/solvers/dgsem_tree/indicators_2d.jl b/src/solvers/dgsem_tree/indicators_2d.jl index 25bcc8dee4e..37a8d97c288 100644 --- a/src/solvers/dgsem_tree/indicators_2d.jl +++ b/src/solvers/dgsem_tree/indicators_2d.jl @@ -110,18 +110,6 @@ end end end -@inline function calc_indicator_inner!(indicator, u, element, mesh::AbstractMesh{2}, - indicator_variable, - have_aux_node_vars::True, equations, - solver, cache) - @unpack aux_node_vars = cache.aux_vars - for j in eachnode(solver), i in eachnode(solver) - u_local = get_node_vars(u, equations, solver, i, j, element) - aux_local = get_aux_node_vars(aux_node_vars, equations, solver, i, j, element) - indicator[i, j] = indicator_variable(u_local, aux_local, equations) - end -end - # Diffuse alpha values by setting each alpha to at least 50% of neighboring elements' alpha function apply_smoothing!(mesh::Union{TreeMesh{2}, P4estMesh{2}, T8codeMesh{2}}, alpha, alpha_tmp, dg, diff --git a/src/visualization/utilities.jl b/src/visualization/utilities.jl index a9956c19a7f..b1c8c9ac43f 100644 --- a/src/visualization/utilities.jl +++ b/src/visualization/utilities.jl @@ -500,33 +500,6 @@ end return raw_data end -# Apply the `solution_variables` function to all node values stored in `u`. -# Dispatch on `have_aux_node_vars` to take into account auxiliary variables. -# Similar to `save_solution_file` in `callbacks_step/save_solution_dg.jl`. -# However, we cannot use `reinterpret` here as `u` might have a non-bits type. -# See https://github.com/trixi-framework/Trixi.jl/pull/2388 -@inline function apply_solution_variables(u, solution_variables, - have_aux_node_vars::True, equations, - solver, cache) - @unpack aux_node_vars = cache.aux_vars - n_vars_in = nvariables(equations) - n_vars_aux = n_aux_node_vars(equations) - n_vars = length(solution_variables(get_node_vars(u, equations, solver), - get_aux_node_vars(aux_node_vars, - equations, solver), - equations)) - raw_data = Array{eltype(u)}(undef, n_vars, Base.tail(size(u))...) - reshaped_u = reshape(u, n_vars_in, :) - reshaped_r = reshape(raw_data, n_vars, :) - reshaped_aux = reshape(aux_node_vars, n_vars_aux, :) - for idx in axes(reshaped_u, 2) - u_node = get_node_vars(reshaped_u, equations, solver, idx) - aux_node = get_aux_node_vars(reshaped_aux, equations, solver, idx) - reshaped_r[:, idx] = solution_variables(u_node, aux_node, equations) - end - return raw_data -end - # Change order of dimensions (variables are now last) and convert data to `solution_variables` # # Note: This is a low-level function that is not considered as part of Trixi.jl's interface and may From eaa1dfe56cf6b4083b043b756d01690ec900729d Mon Sep 17 00:00:00 2001 From: Benedict <135045760+benegee@users.noreply.github.com> Date: Wed, 27 May 2026 11:46:22 +0200 Subject: [PATCH 69/83] Apply suggestions from code review Co-authored-by: Hendrik Ranocha --- NEWS.md | 2 +- src/callbacks_step/analysis_dg1d.jl | 10 ++++++---- src/equations/equations.jl | 2 +- src/equations/numerical_fluxes.jl | 4 ++-- .../semidiscretization_hyperbolic.jl | 2 +- src/solvers/dgsem_structured/dg_2d.jl | 2 +- src/solvers/dgsem_structured/dg_3d.jl | 2 +- src/solvers/dgsem_tree/dg_1d.jl | 2 +- 8 files changed, 14 insertions(+), 12 deletions(-) diff --git a/NEWS.md b/NEWS.md index 0fddb27b06d..18cdda20727 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,7 +8,7 @@ for human readability. - Auxiliary variables ([#2348]). An additional container in `cache` is made available to central functions like flux computations. Possible applications are steady background states, variable velocity - fields, geometrical information, or any other pointwise, passive quantity that is + fields, geometrical information, or any other pointwise, passive (constant in time) quantity that is required in addition to the unknows in the governing equations. The auxiliary variables are set up by supplying a function to the `SemidiscretizationHyperbolic` constructor via the keyword argument `aux_field`. diff --git a/src/callbacks_step/analysis_dg1d.jl b/src/callbacks_step/analysis_dg1d.jl index 728b418ccf6..5f32502b3f7 100644 --- a/src/callbacks_step/analysis_dg1d.jl +++ b/src/callbacks_step/analysis_dg1d.jl @@ -243,8 +243,9 @@ function analyze(::typeof(entropy_timederivative), du, u, t, end function analyze(::Val{:l2_divb}, du, u, t, - mesh::TreeMesh{1}, have_aux_node_vars::False, - equations::IdealGlmMhdEquations1D, dg::DGSEM, cache) + mesh::TreeMesh{1}, + have_aux_node_vars::False, equations::IdealGlmMhdEquations1D, + dg::DGSEM, cache) integrate_via_indices(u, mesh, equations, dg, cache, dg.basis.derivative_matrix) do u, i, element, equations, dg, derivative_matrix @@ -258,8 +259,9 @@ function analyze(::Val{:l2_divb}, du, u, t, end function analyze(::Val{:linf_divb}, du, u, t, - mesh::TreeMesh{1}, have_aux_node_vars::False, - equations::IdealGlmMhdEquations1D, dg::DGSEM, cache) + mesh::TreeMesh{1}, + have_aux_node_vars::False, equations::IdealGlmMhdEquations1D, + dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis # integrate over all elements to get the divergence-free condition errors diff --git a/src/equations/equations.jl b/src/equations/equations.jl index 4d5c8c09b44..984b5e0dca4 100644 --- a/src/equations/equations.jl +++ b/src/equations/equations.jl @@ -81,7 +81,7 @@ function Base.show(io::IO, ::MIME"text/plain", equations::AbstractEquations) "variable " * string(variable), varnames(cons2cons, equations)[variable]) end - if have_aux_node_vars(equations) == Trixi.True() + if have_aux_node_vars(equations) == True() summary_line(io, "#auxiliary variables", n_aux_node_vars(equations)) for variable in eachauxvariable(equations) summary_line(increment_indent(io), diff --git a/src/equations/numerical_fluxes.jl b/src/equations/numerical_fluxes.jl index 91a609abc2a..56aa80a86c2 100644 --- a/src/equations/numerical_fluxes.jl +++ b/src/equations/numerical_fluxes.jl @@ -202,8 +202,8 @@ DissipationLocalLaxFriedrichs() = DissipationLocalLaxFriedrichs(max_abs_speed) end # same as above for equations with auxiliary variables -@inline function (dissipation::DissipationLocalLaxFriedrichs)(u_ll, u_rr, aux_ll, - aux_rr, +@inline function (dissipation::DissipationLocalLaxFriedrichs)(u_ll, u_rr, + aux_ll, aux_rr, orientation_or_normal_direction, equations) λ = dissipation.max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, diff --git a/src/semidiscretization/semidiscretization_hyperbolic.jl b/src/semidiscretization/semidiscretization_hyperbolic.jl index 1801fd657da..5b9dc9c0db0 100644 --- a/src/semidiscretization/semidiscretization_hyperbolic.jl +++ b/src/semidiscretization/semidiscretization_hyperbolic.jl @@ -510,7 +510,7 @@ function Base.show(io::IO, ::MIME"text/plain", semi::SemidiscretizationHyperboli print_boundary_conditions(io, semi) summary_line(io, "source terms", semi.source_terms) - if have_aux_node_vars(semi.equations) == Trixi.True() + if have_aux_node_vars(semi.equations) == True() summary_line(io, "auxiliary variables", semi.cache.aux_vars.aux_field) end diff --git a/src/solvers/dgsem_structured/dg_2d.jl b/src/solvers/dgsem_structured/dg_2d.jl index 10fe6452e8e..49b8fe4883f 100644 --- a/src/solvers/dgsem_structured/dg_2d.jl +++ b/src/solvers/dgsem_structured/dg_2d.jl @@ -175,7 +175,7 @@ end symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, MeshT, False(), False(), equations, + flux_differencing_kernel!(du, u, element, MeshT, False(), have_aux_node_vars, equations, symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux diff --git a/src/solvers/dgsem_structured/dg_3d.jl b/src/solvers/dgsem_structured/dg_3d.jl index cb52ba5950a..d302aa14ceb 100644 --- a/src/solvers/dgsem_structured/dg_3d.jl +++ b/src/solvers/dgsem_structured/dg_3d.jl @@ -206,7 +206,7 @@ end symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, MeshT, False(), False(), equations, + flux_differencing_kernel!(du, u, element, MeshT, False(), have_aux_node_vars, equations, symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux diff --git a/src/solvers/dgsem_tree/dg_1d.jl b/src/solvers/dgsem_tree/dg_1d.jl index 2455d10146f..122bcbab71e 100644 --- a/src/solvers/dgsem_tree/dg_1d.jl +++ b/src/solvers/dgsem_tree/dg_1d.jl @@ -192,7 +192,7 @@ end symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, MeshT, False(), False(), equations, + flux_differencing_kernel!(du, u, element, MeshT, False(), have_aux_node_vars, equations, symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux From 68071e435ce764258bcb2d5cb47cd141a7ef40f1 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 27 May 2026 12:01:36 +0200 Subject: [PATCH 70/83] revert to passing surface_flux_values --- src/solvers/dgsem_tree/dg_2d.jl | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 7acd689d508..d3e18d76064 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -875,6 +875,7 @@ end function calc_boundary_flux!(cache, t, boundary_conditions::NamedTuple, mesh::TreeMesh{2}, equations, surface_integral, dg::DG) + @unpack surface_flux_values = cache.elements @unpack n_boundaries_per_direction = cache.boundaries # Calculate indices @@ -882,22 +883,22 @@ function calc_boundary_flux!(cache, t, boundary_conditions::NamedTuple, firsts = lasts - n_boundaries_per_direction .+ 1 # Calc boundary fluxes in each direction - calc_boundary_flux_by_direction!(t, boundary_conditions[1], + calc_boundary_flux_by_direction!(surface_flux_values, t, boundary_conditions[1], have_nonconservative_terms(equations), have_aux_node_vars(equations), equations, surface_integral, dg, cache, 1, firsts[1], lasts[1]) - calc_boundary_flux_by_direction!(t, boundary_conditions[2], + calc_boundary_flux_by_direction!(surface_flux_values, t, boundary_conditions[2], have_nonconservative_terms(equations), have_aux_node_vars(equations), equations, surface_integral, dg, cache, 2, firsts[2], lasts[2]) - calc_boundary_flux_by_direction!(t, boundary_conditions[3], + calc_boundary_flux_by_direction!(surface_flux_values, t, boundary_conditions[3], have_nonconservative_terms(equations), have_aux_node_vars(equations), equations, surface_integral, dg, cache, 3, firsts[3], lasts[3]) - calc_boundary_flux_by_direction!(t, boundary_conditions[4], + calc_boundary_flux_by_direction!(surface_flux_values, t, boundary_conditions[4], have_nonconservative_terms(equations), have_aux_node_vars(equations), equations, surface_integral, dg, cache, @@ -906,12 +907,13 @@ function calc_boundary_flux!(cache, t, boundary_conditions::NamedTuple, return nothing end -function calc_boundary_flux_by_direction!(t, boundary_condition, +function calc_boundary_flux_by_direction!(surface_flux_values::AbstractArray{<:Any, 4}, + t, + boundary_condition, have_nonconservative_terms::False, have_aux_node_vars::False, equations, surface_integral, dg::DG, cache, direction, first_boundary, last_boundary) - @unpack surface_flux_values = cache.elements @unpack surface_flux = surface_integral @unpack u, neighbor_ids, neighbor_sides, node_coordinates, orientations = cache.boundaries @@ -942,12 +944,13 @@ function calc_boundary_flux_by_direction!(t, boundary_condition, return nothing end -function calc_boundary_flux_by_direction!(t, boundary_condition, +function calc_boundary_flux_by_direction!(surface_flux_values::AbstractArray{<:Any, 4}, + t, + boundary_condition, have_nonconservative_terms::False, have_aux_node_vars::True, equations, surface_integral, dg::DG, cache, direction, first_boundary, last_boundary) - @unpack surface_flux_values = cache.elements @unpack surface_flux = surface_integral @unpack u, neighbor_ids, neighbor_sides, node_coordinates, orientations = cache.boundaries @unpack aux_boundary_node_vars = cache.aux_vars @@ -983,12 +986,13 @@ function calc_boundary_flux_by_direction!(t, boundary_condition, return nothing end -function calc_boundary_flux_by_direction!(t, boundary_condition, +function calc_boundary_flux_by_direction!(surface_flux_values::AbstractArray{<:Any, 4}, + t, + boundary_condition, have_nonconservative_terms::True, have_aux_node_vars::False, equations, surface_integral, dg::DG, cache, direction, first_boundary, last_boundary) - @unpack surface_flux_values = cache.elements @unpack u, neighbor_ids, neighbor_sides, node_coordinates, orientations = cache.boundaries @threaded for boundary in first_boundary:last_boundary From e40e6b067dbf997743be60a4e0493c3d2fa2caa8 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 27 May 2026 12:10:43 +0200 Subject: [PATCH 71/83] extend news --- NEWS.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/NEWS.md b/NEWS.md index 6463a1bb0ba..0bfa43fed86 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,13 +5,15 @@ Trixi.jl follows the interpretation of used in the Julia ecosystem. Notable changes will be documented in this file for human readability. -- Auxiliary variables ([#2348]). +- Experimental support for auxiliary variables ([#2348]). An additional container in `cache` is made available to central functions like flux computations. Possible applications are steady background states, variable velocity - fields, geometrical information, or any other pointwise, passive (constant in time) quantity that is - required in addition to the unknows in the governing equations. The auxiliary variables - are set up by supplying a function to the `SemidiscretizationHyperbolic` constructor via - the keyword argument `aux_field`. + fields, geometrical information, or any other pointwise, passive (constant in time) + quantity that is required in addition to the unknows in the governing equations. The + auxiliary variables are set up by supplying a function to the + `SemidiscretizationHyperbolic` constructor via the keyword argument `aux_field`. + The current `equations` need to set `have_aux_node_vars to `True()` and `n_aux_node_vars` + to the number of auxiliary variables per node. ## Changes in the v0.16 lifecycle From 9b4beb63cf8f2dc610bb9c775083fc706b22b6f2 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 27 May 2026 14:48:31 +0200 Subject: [PATCH 72/83] comment --- src/semidiscretization/semidiscretization_hyperbolic.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/semidiscretization/semidiscretization_hyperbolic.jl b/src/semidiscretization/semidiscretization_hyperbolic.jl index 5b9dc9c0db0..a07b638c6a7 100644 --- a/src/semidiscretization/semidiscretization_hyperbolic.jl +++ b/src/semidiscretization/semidiscretization_hyperbolic.jl @@ -53,7 +53,7 @@ single boundary condition that gets applied to all boundaries. which will be available, e.g., in flux computations. The current `equations` need to set `have_aux_node_vars to `True()` and `n_aux_node_vars` to the number of auxiliary variables per node. Upon refinement, `aux_field` will be called again to recompute the auxiliary variables. -NOTE: Currently only TreeMesh in 2D is supported. +NOTE: This is experimental! """ function SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver; source_terms = nothing, From a896214e76dcb9057bd6cbe20b5b21aaf5cdf1e9 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 27 May 2026 14:52:46 +0200 Subject: [PATCH 73/83] rename constant_speed to have_constant_speed --- src/callbacks_step/stepsize.jl | 8 ++--- src/callbacks_step/stepsize_dg1d.jl | 8 ++--- src/callbacks_step/stepsize_dg2d.jl | 56 ++++++++++++++--------------- src/callbacks_step/stepsize_dg3d.jl | 37 +++++++++---------- src/solvers/dgmulti/dg.jl | 4 +-- 5 files changed, 57 insertions(+), 56 deletions(-) diff --git a/src/callbacks_step/stepsize.jl b/src/callbacks_step/stepsize.jl index b999054454a..9b3e3d74adc 100644 --- a/src/callbacks_step/stepsize.jl +++ b/src/callbacks_step/stepsize.jl @@ -202,13 +202,13 @@ function calculate_dt(u_ode, t, cfl_hyperbolic, cfl_parabolic, end end -function calc_max_scaled_speed(backend::Nothing, u, mesh, constant_speed, +function calc_max_scaled_speed(backend::Nothing, u, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) @unpack contravariant_vectors, inverse_jacobian = cache.elements max_scaled_speed = zero(eltype(u)) @batch reduction=(max, max_scaled_speed) for element in eachelement(dg, cache) - max_lambda = max_scaled_speed_per_element(u, typeof(mesh), constant_speed, + max_lambda = max_scaled_speed_per_element(u, typeof(mesh), have_constant_speed, have_aux_node_vars, equations, dg, contravariant_vectors, inverse_jacobian, @@ -220,7 +220,7 @@ function calc_max_scaled_speed(backend::Nothing, u, mesh, constant_speed, return max_scaled_speed end -function calc_max_scaled_speed(backend::Backend, u, ::MeshT, constant_speed, +function calc_max_scaled_speed(backend::Backend, u, ::MeshT, have_constant_speed, have_aux_node_vars, equations, dg, cache) where {MeshT} @unpack contravariant_vectors, inverse_jacobian = cache.elements @@ -230,7 +230,7 @@ function calc_max_scaled_speed(backend::Backend, u, ::MeshT, constant_speed, # Provide a custom neutral and init element since we "reduce" over 1:num_elements max_scaled_speed = AcceleratedKernels.mapreduce(Base.max, 1:num_elements, backend; init, neutral) do element - max_scaled_speed_per_element(u, MeshT, constant_speed, have_aux_node_vars, + max_scaled_speed_per_element(u, MeshT, have_constant_speed, have_aux_node_vars, equations, dg, contravariant_vectors, inverse_jacobian, diff --git a/src/callbacks_step/stepsize_dg1d.jl b/src/callbacks_step/stepsize_dg1d.jl index 558f1e5ffbd..1a58fcda407 100644 --- a/src/callbacks_step/stepsize_dg1d.jl +++ b/src/callbacks_step/stepsize_dg1d.jl @@ -6,7 +6,7 @@ #! format: noindent function max_dt(u, t, mesh::TreeMesh{1}, - constant_speed::False, have_aux_node_vars::False, + have_constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # Avoid division by zero if the speed vanishes everywhere max_scaled_speed = nextfloat(zero(t)) @@ -54,7 +54,7 @@ function max_dt(u, t, mesh::TreeMesh{1}, end function max_dt(u, t, mesh::TreeMesh{1}, - constant_speed::True, + have_constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # Avoid division by zero if the speed vanishes everywhere, @@ -97,7 +97,7 @@ function max_dt(u, t, mesh::TreeMesh, # for all dimensions end function max_dt(u, t, mesh::StructuredMesh{1}, - constant_speed::False, have_aux_node_vars::False, + have_constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # Avoid division by zero if the speed vanishes everywhere max_scaled_speed = nextfloat(zero(t)) @@ -124,7 +124,7 @@ function max_dt(u, t, mesh::StructuredMesh{1}, end function max_dt(u, t, mesh::StructuredMesh{1}, - constant_speed::True, have_aux_node_vars::False, + have_constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # Avoid division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection diff --git a/src/callbacks_step/stepsize_dg2d.jl b/src/callbacks_step/stepsize_dg2d.jl index 6b8590ba061..773dfbb29f1 100644 --- a/src/callbacks_step/stepsize_dg2d.jl +++ b/src/callbacks_step/stepsize_dg2d.jl @@ -6,7 +6,7 @@ #! format: noindent function max_dt(u, t, mesh::TreeMesh{2}, - constant_speed::False, have_aux_node_vars::False, + have_constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # Avoid division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection @@ -31,7 +31,7 @@ function max_dt(u, t, mesh::TreeMesh{2}, end function max_dt(u, t, mesh::TreeMesh{2}, - constant_speed::False, have_aux_node_vars::True, + have_constant_speed::False, have_aux_node_vars::True, equations, dg::DG, cache) @unpack aux_node_vars = cache.aux_vars # to avoid a division by zero if the speed vanishes everywhere, @@ -81,7 +81,7 @@ function max_dt(u, t, mesh::TreeMesh{2}, end function max_dt(u, t, mesh::TreeMesh{2}, - constant_speed::True, have_aux_node_vars::False, + have_constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # Avoid division by zero if the speed vanishes everywhere max_scaled_speed = nextfloat(zero(t)) @@ -100,7 +100,7 @@ function max_dt(u, t, mesh::TreeMesh{2}, end function max_dt(u, t, mesh::TreeMeshParallel{2}, - constant_speed::False, have_aux_node_vars::False, + have_constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::TreeMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -108,9 +108,9 @@ function max_dt(u, t, mesh::TreeMeshParallel{2}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), TreeMesh{2}, - typeof(constant_speed), typeof(have_aux_node_vars), + typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, False(), equations, dg, + u, t, mesh, have_constant_speed, False(), equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -119,7 +119,7 @@ function max_dt(u, t, mesh::TreeMeshParallel{2}, end function max_dt(u, t, mesh::TreeMeshParallel{2}, - constant_speed::False, have_aux_node_vars::True, + have_constant_speed::False, have_aux_node_vars::True, equations, dg::DG, cache) # call the method accepting a general `mesh::TreeMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -127,9 +127,9 @@ function max_dt(u, t, mesh::TreeMeshParallel{2}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), TreeMesh{2}, - typeof(constant_speed), typeof(have_aux_node_vars), + typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, True(), equations, dg, + u, t, mesh, have_constant_speed, True(), equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -138,7 +138,7 @@ function max_dt(u, t, mesh::TreeMeshParallel{2}, end function max_dt(u, t, mesh::TreeMeshParallel{2}, - constant_speed::True, have_aux_node_vars::False, + have_constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::TreeMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -146,9 +146,9 @@ function max_dt(u, t, mesh::TreeMeshParallel{2}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), TreeMesh{2}, - typeof(constant_speed), typeof(have_aux_node_vars), + typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, False(), equations, dg, + u, t, mesh, have_constant_speed, False(), equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -163,10 +163,10 @@ end function max_dt(u, t, mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, P4estMeshView{2}, T8codeMesh{2}, StructuredMeshView{2}}, - constant_speed, have_aux_node_vars, equations, dg::DG, cache) + have_constant_speed, have_aux_node_vars, equations, dg::DG, cache) backend = trixi_backend(u) - max_lambda = calc_max_scaled_speed(backend, u, mesh, constant_speed, + max_lambda = calc_max_scaled_speed(backend, u, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) @@ -183,7 +183,7 @@ end P4estMesh{2}, T8codeMesh{2}, StructuredMeshView{2}}}, - constant_speed::False, + have_constant_speed::False, have_aux_node_vars::False, equations, dg::DG, contravariant_vectors, inverse_jacobian, @@ -262,7 +262,7 @@ end P4estMeshView{2}, T8codeMesh{2}, StructuredMeshView{2}}}, - constant_speed::True, + have_constant_speed::True, have_aux_node_vars::False, equations, dg::DG, contravariant_vectors, inverse_jacobian, @@ -334,7 +334,7 @@ function max_dt(u, t, end function max_dt(u, t, mesh::P4estMeshParallel{2}, - constant_speed::False, have_aux_node_vars::False, + have_constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::P4estMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -342,9 +342,9 @@ function max_dt(u, t, mesh::P4estMeshParallel{2}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), P4estMesh{2}, - typeof(constant_speed), typeof(have_aux_node_vars), + typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, + u, t, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -353,7 +353,7 @@ function max_dt(u, t, mesh::P4estMeshParallel{2}, end function max_dt(u, t, mesh::P4estMeshParallel{2}, - constant_speed::True, have_aux_node_vars::False, + have_constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::P4estMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -361,9 +361,9 @@ function max_dt(u, t, mesh::P4estMeshParallel{2}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), P4estMesh{2}, - typeof(constant_speed), typeof(have_aux_node_vars), + typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, + u, t, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -372,7 +372,7 @@ function max_dt(u, t, mesh::P4estMeshParallel{2}, end function max_dt(u, t, mesh::T8codeMeshParallel{2}, - constant_speed::False, have_aux_node_vars::False, + have_constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::T8codeMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -380,9 +380,9 @@ function max_dt(u, t, mesh::T8codeMeshParallel{2}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), T8codeMesh{2}, - typeof(constant_speed), typeof(have_aux_node_vars), + typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, + u, t, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -391,7 +391,7 @@ function max_dt(u, t, mesh::T8codeMeshParallel{2}, end function max_dt(u, t, mesh::T8codeMeshParallel{2}, - constant_speed::True, have_aux_node_vars::False, + have_constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::T8codeMesh{2}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -399,9 +399,9 @@ function max_dt(u, t, mesh::T8codeMeshParallel{2}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), T8codeMesh{2}, - typeof(constant_speed), typeof(have_aux_node_vars), + typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, + u, t, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] diff --git a/src/callbacks_step/stepsize_dg3d.jl b/src/callbacks_step/stepsize_dg3d.jl index 5d8eb5b67c7..5fa8bace5ee 100644 --- a/src/callbacks_step/stepsize_dg3d.jl +++ b/src/callbacks_step/stepsize_dg3d.jl @@ -6,7 +6,7 @@ #! format: noindent function max_dt(u, t, mesh::TreeMesh{3}, - constant_speed::False, have_aux_node_vars::False, + have_constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # Avoid division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection @@ -58,7 +58,7 @@ function max_dt(u, t, mesh::TreeMesh{3}, end function max_dt(u, t, mesh::TreeMesh{3}, - constant_speed::True, have_aux_node_vars::False, + have_constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # Avoid division by zero if the speed vanishes everywhere, # e.g. for steady-state linear advection @@ -80,10 +80,11 @@ end function max_dt(u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - constant_speed, have_aux_node_vars::False, equations, dg::DG, cache) + have_constant_speed, have_aux_node_vars::False, equations, dg::DG, + cache) backend = trixi_backend(u) - max_lambda = calc_max_scaled_speed(backend, u, mesh, constant_speed, + max_lambda = calc_max_scaled_speed(backend, u, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) @@ -98,7 +99,7 @@ end ::Type{<:Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}}, - constant_speed::False, + have_constant_speed::False, have_aux_node_vars::False, equations, dg, contravariant_vectors, inverse_jacobian, element) @@ -182,7 +183,7 @@ end ::Type{<:Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}}, - constant_speed::True, + have_constant_speed::True, have_aux_node_vars::False, equations, dg::DG, contravariant_vectors, inverse_jacobian, @@ -268,7 +269,7 @@ function max_dt(u, t, end function max_dt(u, t, mesh::P4estMeshParallel{3}, - constant_speed::False, have_aux_node_vars::False, + have_constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::P4estMesh{3}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -276,9 +277,9 @@ function max_dt(u, t, mesh::P4estMeshParallel{3}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), P4estMesh{3}, - typeof(constant_speed), typeof(have_aux_node_vars), + typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, + u, t, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -287,7 +288,7 @@ function max_dt(u, t, mesh::P4estMeshParallel{3}, end function max_dt(u, t, mesh::P4estMeshParallel{3}, - constant_speed::True, have_aux_node_vars::False, + have_constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::P4estMesh{3}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -295,9 +296,9 @@ function max_dt(u, t, mesh::P4estMeshParallel{3}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), P4estMesh{3}, - typeof(constant_speed), typeof(have_aux_node_vars), + typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, + u, t, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -306,7 +307,7 @@ function max_dt(u, t, mesh::P4estMeshParallel{3}, end function max_dt(u, t, mesh::T8codeMeshParallel{3}, - constant_speed::False, have_aux_node_vars::False, + have_constant_speed::False, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::T8codeMesh{3}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -314,9 +315,9 @@ function max_dt(u, t, mesh::T8codeMeshParallel{3}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), T8codeMesh{3}, - typeof(constant_speed), typeof(have_aux_node_vars), + typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, + u, t, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -325,7 +326,7 @@ function max_dt(u, t, mesh::T8codeMeshParallel{3}, end function max_dt(u, t, mesh::T8codeMeshParallel{3}, - constant_speed::True, have_aux_node_vars::False, + have_constant_speed::True, have_aux_node_vars::False, equations, dg::DG, cache) # call the method accepting a general `mesh::T8codeMesh{3}` # TODO: MPI, we should improve this; maybe we should dispatch on `u` @@ -333,9 +334,9 @@ function max_dt(u, t, mesh::T8codeMeshParallel{3}, # Then, this specific array type should also work well with DiffEq etc. dt = invoke(max_dt, Tuple{typeof(u), typeof(t), T8codeMesh{3}, - typeof(constant_speed), typeof(have_aux_node_vars), + typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, constant_speed, have_aux_node_vars, equations, dg, + u, t, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] diff --git a/src/solvers/dgmulti/dg.jl b/src/solvers/dgmulti/dg.jl index b27c25f0cd3..e4986e09dd3 100644 --- a/src/solvers/dgmulti/dg.jl +++ b/src/solvers/dgmulti/dg.jl @@ -351,7 +351,7 @@ end # for the stepsize callback function max_dt(u, t, mesh::DGMultiMesh, - constant_speed::False, have_aux_node_vars::False, + have_constant_speed::False, have_aux_node_vars::False, equations, dg::DGMulti{NDIMS}, cache) where {NDIMS} @unpack md = mesh @@ -375,7 +375,7 @@ function max_dt(u, t, mesh::DGMultiMesh, end function max_dt(u, t, mesh::DGMultiMesh, - constant_speed::True, have_aux_node_vars::False, + have_constant_speed::True, have_aux_node_vars::False, equations, dg::DGMulti{NDIMS}, cache) where {NDIMS} @unpack md = mesh From 8909f98855a7730107d7806194fb677927a7b357 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 27 May 2026 15:50:35 +0200 Subject: [PATCH 74/83] fixes --- src/callbacks_step/stepsize_dg2d.jl | 6 ++-- src/solvers/dgsem/calc_volume_integral.jl | 6 ++-- src/solvers/dgsem_p4est/dg_2d.jl | 37 ----------------------- src/solvers/dgsem_p4est/dg_2d_gpu.jl | 2 +- src/solvers/dgsem_p4est/dg_3d.jl | 32 -------------------- src/solvers/dgsem_p4est/dg_3d_gpu.jl | 2 +- src/solvers/dgsem_structured/dg_2d.jl | 3 +- src/solvers/dgsem_structured/dg_3d.jl | 3 +- src/solvers/dgsem_tree/dg_1d.jl | 3 +- src/solvers/dgsem_tree/dg_2d.jl | 5 +-- src/solvers/dgsem_tree/dg_3d.jl | 3 +- 11 files changed, 20 insertions(+), 82 deletions(-) diff --git a/src/callbacks_step/stepsize_dg2d.jl b/src/callbacks_step/stepsize_dg2d.jl index 773dfbb29f1..3d03c27664b 100644 --- a/src/callbacks_step/stepsize_dg2d.jl +++ b/src/callbacks_step/stepsize_dg2d.jl @@ -110,7 +110,7 @@ function max_dt(u, t, mesh::TreeMeshParallel{2}, Tuple{typeof(u), typeof(t), TreeMesh{2}, typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, have_constant_speed, False(), equations, dg, + u, t, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -129,7 +129,7 @@ function max_dt(u, t, mesh::TreeMeshParallel{2}, Tuple{typeof(u), typeof(t), TreeMesh{2}, typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, have_constant_speed, True(), equations, dg, + u, t, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] @@ -148,7 +148,7 @@ function max_dt(u, t, mesh::TreeMeshParallel{2}, Tuple{typeof(u), typeof(t), TreeMesh{2}, typeof(have_constant_speed), typeof(have_aux_node_vars), typeof(equations), typeof(dg), typeof(cache)}, - u, t, mesh, have_constant_speed, False(), equations, dg, + u, t, mesh, have_constant_speed, have_aux_node_vars, equations, dg, cache) # Base.min instead of min needed, see comment in src/auxiliary/math.jl dt = MPI.Allreduce!(Ref(dt), Base.min, mpi_comm())[] diff --git a/src/solvers/dgsem/calc_volume_integral.jl b/src/solvers/dgsem/calc_volume_integral.jl index b1d478f9c94..1b23cf566a5 100644 --- a/src/solvers/dgsem/calc_volume_integral.jl +++ b/src/solvers/dgsem/calc_volume_integral.jl @@ -192,7 +192,8 @@ function calc_volume_integral!(backend::Nothing, du, u, mesh, MeshT = typeof(mesh) @threaded for element in eachelement(dg, cache) volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, have_aux_node_vars, equations, + have_nonconservative_terms, have_aux_node_vars, + equations, volume_integral, dg, cache) end @@ -328,7 +329,8 @@ function calc_volume_integral!(backend::Nothing, du, u, mesh, @threaded for element in eachelement(dg, cache) # run default volume integral volume_integral_kernel!(du, u, element, MeshT, - have_nonconservative_terms, have_aux_node_vars, equations, + have_nonconservative_terms, have_aux_node_vars, + equations, volume_integral_default, dg, cache) # Check entropy production of "high order" volume integral. diff --git a/src/solvers/dgsem_p4est/dg_2d.jl b/src/solvers/dgsem_p4est/dg_2d.jl index 68bf6aad70c..d0360eb17be 100644 --- a/src/solvers/dgsem_p4est/dg_2d.jl +++ b/src/solvers/dgsem_p4est/dg_2d.jl @@ -286,43 +286,6 @@ function calc_interface_flux!(backend::Nothing, surface_flux_values, return nothing end -function calc_interface_flux!(backend::Backend, surface_flux_values, - mesh::Union{P4estMesh{2}, P4estMeshView{2}, - T8codeMesh{2}}, - have_nonconservative_terms, have_aux_node_vars, - equations, surface_integral, - dg::DGSEM{<:LobattoLegendreBasis}, cache) - ninterfaces(cache.interfaces) == 0 && return nothing - @unpack neighbor_ids, node_indices = cache.interfaces - @unpack contravariant_vectors = cache.elements - index_range = eachnode(dg) - - kernel! = calc_interface_flux_KAkernel!(backend) - kernel!(surface_flux_values, typeof(mesh), have_nonconservative_terms, - equations, surface_integral, typeof(dg), cache.interfaces.u, - neighbor_ids, node_indices, contravariant_vectors, index_range, - ndrange = ninterfaces(cache.interfaces)) - - return nothing -end - -@kernel function calc_interface_flux_KAkernel!(surface_flux_values, - MeshT::Type{<:Union{P4estMesh{2}, - P4estMeshView{2}, - T8codeMesh{2}}}, - have_nonconservative_terms, - equations, surface_integral, - SolverT::Type{<:DG}, u_interface, - neighbor_ids, node_indices, - contravariant_vectors, index_range) - interface = @index(Global) - calc_interface_flux_per_interface!(surface_flux_values, MeshT, - have_nonconservative_terms, equations, - surface_integral, SolverT, u_interface, - interface, neighbor_ids, node_indices, - contravariant_vectors, index_range) -end - @inline function calc_interface_flux_per_interface!(surface_flux_values, MeshT::Type{<:Union{P4estMesh{2}, P4estMeshView{2}, diff --git a/src/solvers/dgsem_p4est/dg_2d_gpu.jl b/src/solvers/dgsem_p4est/dg_2d_gpu.jl index 17c5d3c2b9d..bdb8ab786e8 100644 --- a/src/solvers/dgsem_p4est/dg_2d_gpu.jl +++ b/src/solvers/dgsem_p4est/dg_2d_gpu.jl @@ -64,7 +64,7 @@ end function calc_interface_flux!(backend::Backend, surface_flux_values, mesh::Union{P4estMesh{2}, P4estMeshView{2}, T8codeMesh{2}}, - have_nonconservative_terms, + have_nonconservative_terms, have_aux_node_vars, equations, surface_integral, dg::DGSEM{<:LobattoLegendreBasis}, cache) ninterfaces(cache.interfaces) == 0 && return nothing diff --git a/src/solvers/dgsem_p4est/dg_3d.jl b/src/solvers/dgsem_p4est/dg_3d.jl index b1343096eaf..e814621c735 100644 --- a/src/solvers/dgsem_p4est/dg_3d.jl +++ b/src/solvers/dgsem_p4est/dg_3d.jl @@ -205,38 +205,6 @@ function calc_interface_flux!(backend::Nothing, surface_flux_values, return nothing end -function calc_interface_flux!(backend::Backend, surface_flux_values, - mesh::Union{P4estMesh{3}, T8codeMesh{3}}, - have_nonconservative_terms, have_aux_node_vars, - equations, surface_integral, dg::DG, cache) - @unpack neighbor_ids, node_indices = cache.interfaces - @unpack contravariant_vectors = cache.elements - index_range = eachnode(dg) - - kernel! = calc_interface_flux_KAkernel!(backend) - kernel!(surface_flux_values, typeof(mesh), have_nonconservative_terms, equations, - surface_integral, typeof(dg), cache.interfaces.u, - neighbor_ids, node_indices, contravariant_vectors, index_range, - ndrange = ninterfaces(cache.interfaces)) - return nothing -end - -@kernel function calc_interface_flux_KAkernel!(surface_flux_values, MeshT, - have_nonconservative_terms, equations, - surface_integral, SolverT, u_interface, - neighbor_ids, node_indices, - contravariant_vectors, index_range) - interface = @index(Global) - calc_interface_flux_per_interface!(surface_flux_values, - MeshT, - have_nonconservative_terms, - equations, surface_integral, SolverT, - u_interface, - neighbor_ids, node_indices, - contravariant_vectors, - index_range, interface) -end - @inline function calc_interface_flux_per_interface!(surface_flux_values, MeshT::Type{<:Union{P4estMesh{3}, T8codeMesh{3}}}, diff --git a/src/solvers/dgsem_p4est/dg_3d_gpu.jl b/src/solvers/dgsem_p4est/dg_3d_gpu.jl index a3c3b3e79cb..a5da458eb26 100644 --- a/src/solvers/dgsem_p4est/dg_3d_gpu.jl +++ b/src/solvers/dgsem_p4est/dg_3d_gpu.jl @@ -51,7 +51,7 @@ end function calc_interface_flux!(backend::Backend, surface_flux_values, mesh::Union{P4estMesh{3}, T8codeMesh{3}}, - have_nonconservative_terms, + have_nonconservative_terms, have_aux_node_vars, equations, surface_integral, dg::DG, cache) @unpack neighbor_ids, node_indices = cache.interfaces @unpack contravariant_vectors = cache.elements diff --git a/src/solvers/dgsem_structured/dg_2d.jl b/src/solvers/dgsem_structured/dg_2d.jl index 0cebe4311b0..07e95b1d536 100644 --- a/src/solvers/dgsem_structured/dg_2d.jl +++ b/src/solvers/dgsem_structured/dg_2d.jl @@ -175,7 +175,8 @@ end symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, MeshT, False(), have_aux_node_vars, equations, + flux_differencing_kernel!(du, u, element, MeshT, False(), have_aux_node_vars, + equations, symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux diff --git a/src/solvers/dgsem_structured/dg_3d.jl b/src/solvers/dgsem_structured/dg_3d.jl index 2b0c6968ef0..2a2b3b6fd8e 100644 --- a/src/solvers/dgsem_structured/dg_3d.jl +++ b/src/solvers/dgsem_structured/dg_3d.jl @@ -206,7 +206,8 @@ end symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, MeshT, False(), have_aux_node_vars, equations, + flux_differencing_kernel!(du, u, element, MeshT, False(), have_aux_node_vars, + equations, symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux diff --git a/src/solvers/dgsem_tree/dg_1d.jl b/src/solvers/dgsem_tree/dg_1d.jl index af11fe498c2..59202ddad5a 100644 --- a/src/solvers/dgsem_tree/dg_1d.jl +++ b/src/solvers/dgsem_tree/dg_1d.jl @@ -192,7 +192,8 @@ end symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, MeshT, False(), have_aux_node_vars, equations, + flux_differencing_kernel!(du, u, element, MeshT, False(), have_aux_node_vars, + equations, symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index d3e18d76064..4072e3b344b 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -305,7 +305,8 @@ end symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, MeshT, False(), False(), equations, + flux_differencing_kernel!(du, u, element, MeshT, False(), have_aux_node_vars, + equations, symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux @@ -1579,7 +1580,7 @@ function calc_sources!(backend::Nothing, du, u, t, source_terms, return nothing end -function calc_sources!(du, u, t, source_terms, +function calc_sources!(backend::Nothing, du, u, t, source_terms, have_aux_node_vars::True, equations::AbstractEquations{2}, dg::DG, cache) @unpack node_coordinates = cache.elements diff --git a/src/solvers/dgsem_tree/dg_3d.jl b/src/solvers/dgsem_tree/dg_3d.jl index 629b6a78606..fcc45ba5ba4 100644 --- a/src/solvers/dgsem_tree/dg_3d.jl +++ b/src/solvers/dgsem_tree/dg_3d.jl @@ -225,7 +225,8 @@ end symmetric_flux, nonconservative_flux = volume_flux # Apply the symmetric flux as usual - flux_differencing_kernel!(du, u, element, MeshT, False(), False(), equations, + flux_differencing_kernel!(du, u, element, MeshT, False(), have_aux_node_vars, + equations, symmetric_flux, dg, cache, alpha) # Calculate the remaining volume terms using the nonsymmetric generalized flux From d7262a30a03235f1ffd4799857aefe2848e38761 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Tue, 2 Jun 2026 16:03:16 +0200 Subject: [PATCH 75/83] extend NEWS comment --- NEWS.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/NEWS.md b/NEWS.md index 0bfa43fed86..120aea59d72 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,19 +5,21 @@ Trixi.jl follows the interpretation of used in the Julia ecosystem. Notable changes will be documented in this file for human readability. +## Changes in the v0.16 lifecycle + +#### Added - Experimental support for auxiliary variables ([#2348]). - An additional container in `cache` is made available to central functions like flux - computations. Possible applications are steady background states, variable velocity + An additional container `aux_vars` in `cache` is made available in central functions like + flux computations. Possible applications are steady background states, variable velocity fields, geometrical information, or any other pointwise, passive (constant in time) quantity that is required in addition to the unknows in the governing equations. The auxiliary variables are set up by supplying a function to the `SemidiscretizationHyperbolic` constructor via the keyword argument `aux_field`. The current `equations` need to set `have_aux_node_vars to `True()` and `n_aux_node_vars` to the number of auxiliary variables per node. - -## Changes in the v0.16 lifecycle - -#### Added + So far, a simplyfying continuity assumption is made for the auxiliary variables, which + e.g. allows to directly compute values at neighboring (mortar) interfaces instead of + MPI-communicating their values. - `VolumeIntegralAdaptive` is now also available with `VolumeIntegralSubcellLimiting` for `TreeMesh` in 2D and 3D using the heuristic a-priori indicator `IndicatorHennemannGassner` ([#2924], [#2986]). - A new EOS type `AbstractHelmholtzEOS`, with concrete implementation `HelmholtzIdealGas`. This implementation roughly follows Klein et al.'s approach in ([arXiv:2603.15112](https://arxiv.org/abs/2603.15112)). From 82191a65a1d2ae3ed4dce33351b360d74f044f90 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Tue, 2 Jun 2026 16:03:54 +0200 Subject: [PATCH 76/83] dispatch a lot less in analyze --- src/callbacks_step/analysis.jl | 5 ++--- src/callbacks_step/analysis_dg1d.jl | 8 +++---- src/callbacks_step/analysis_dg2d.jl | 34 +++++++++++++++++++---------- src/callbacks_step/analysis_dg3d.jl | 14 +++++------- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/callbacks_step/analysis.jl b/src/callbacks_step/analysis.jl index dc3d9f15bcc..1a6bb399763 100644 --- a/src/callbacks_step/analysis.jl +++ b/src/callbacks_step/analysis.jl @@ -626,10 +626,9 @@ end # Trixi.analyze, Trixi.pretty_form_utf, Trixi.pretty_form_ascii function analyze(quantity, du, u, t, semi::AbstractSemidiscretization) mesh, equations, solver, cache = mesh_equations_solver_cache(semi) - return analyze(quantity, du, u, t, mesh, have_aux_node_vars(equations), equations, - solver, cache) + return analyze(quantity, du, u, t, mesh, equations, solver, cache) end -function analyze(quantity, du, u, t, mesh, have_aux_node_vars, equations, solver, cache) +function analyze(quantity, du, u, t, mesh, equations, solver, cache) return integrate(quantity, u, mesh, equations, solver, cache, normalize = true) end pretty_form_utf(quantity) = get_name(quantity) diff --git a/src/callbacks_step/analysis_dg1d.jl b/src/callbacks_step/analysis_dg1d.jl index 5f32502b3f7..67714ad2985 100644 --- a/src/callbacks_step/analysis_dg1d.jl +++ b/src/callbacks_step/analysis_dg1d.jl @@ -232,7 +232,7 @@ end function analyze(::typeof(entropy_timederivative), du, u, t, mesh::Union{TreeMesh{1}, StructuredMesh{1}}, - have_aux_node_vars::False, equations, dg::Union{DGSEM, FDSBP}, cache) + equations, dg::Union{DGSEM, FDSBP}, cache) # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ integrate_via_indices(u, mesh, equations, dg, cache, du) do u, i, element, equations, dg, du @@ -244,8 +244,7 @@ end function analyze(::Val{:l2_divb}, du, u, t, mesh::TreeMesh{1}, - have_aux_node_vars::False, equations::IdealGlmMhdEquations1D, - dg::DGSEM, cache) + equations::IdealGlmMhdEquations1D, dg::DGSEM, cache) integrate_via_indices(u, mesh, equations, dg, cache, dg.basis.derivative_matrix) do u, i, element, equations, dg, derivative_matrix @@ -260,8 +259,7 @@ end function analyze(::Val{:linf_divb}, du, u, t, mesh::TreeMesh{1}, - have_aux_node_vars::False, equations::IdealGlmMhdEquations1D, - dg::DGSEM, cache) + equations::IdealGlmMhdEquations1D, dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis # integrate over all elements to get the divergence-free condition errors diff --git a/src/callbacks_step/analysis_dg2d.jl b/src/callbacks_step/analysis_dg2d.jl index 9ef05ac3c06..511005441f2 100644 --- a/src/callbacks_step/analysis_dg2d.jl +++ b/src/callbacks_step/analysis_dg2d.jl @@ -459,7 +459,19 @@ end function analyze(::typeof(entropy_timederivative), du, u, t, mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - have_aux_node_vars::False, equations, dg::Union{DGSEM, FDSBP}, cache) + equations, dg::Union{DGSEM, FDSBP}, cache) + # The entropy_timederivative may depend on auxiliary variables. + return analyze(entropy_timederivative, du, u, t, + mesh, + have_aux_node_vars(equations), equations, + dg, cache) +end + +@inline function analyze(::typeof(entropy_timederivative), du, u, t, + mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2}, + UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, + have_aux_node_vars::False, equations, + dg::Union{DGSEM, FDSBP}, cache) # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ integrate_via_indices(u, mesh, equations, dg, cache, du) do u, i, j, element, equations, dg, du @@ -469,10 +481,11 @@ function analyze(::typeof(entropy_timederivative), du, u, t, end end -function analyze(::typeof(entropy_timederivative), du, u, t, - mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2}, - UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - have_aux_node_vars::True, equations, dg::DG, cache) +@inline function analyze(::typeof(entropy_timederivative), du, u, t, + mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2}, + UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, + have_aux_node_vars::True, equations, + dg::Union{DGSEM, FDSBP}, cache) @unpack aux_node_vars = cache.aux_vars # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ integrate_via_indices(u, mesh, equations, dg, cache, @@ -480,13 +493,12 @@ function analyze(::typeof(entropy_timederivative), du, u, t, u_node = get_node_vars(u, equations, dg, i, j, element) aux_node = get_aux_node_vars(aux_node_vars, equations, dg, i, j, element) du_node = get_node_vars(du, equations, dg, i, j, element) - dot(cons2entropy(u_node, aux_node, equations), du_node) + return dot(cons2entropy(u_node, aux_node, equations), du_node) end end function analyze(::Val{:l2_divb}, du, u, t, - mesh::TreeMesh{2}, - have_aux_node_vars::False, equations, dg::DGSEM, cache) + mesh::TreeMesh{2}, equations, dg::DGSEM, cache) integrate_via_indices(u, mesh, equations, dg, cache, cache, dg.basis.derivative_matrix) do u, i, j, element, equations, dg, cache, derivative_matrix @@ -509,7 +521,7 @@ end function analyze(::Val{:l2_divb}, du, u, t, mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - have_aux_node_vars::False, equations, dg::DGSEM, cache) + equations, dg::DGSEM, cache) @unpack contravariant_vectors, inverse_jacobian = cache.elements integrate_via_indices(u, mesh, equations, dg, cache, cache, dg.basis.derivative_matrix) do u, i, j, element, equations, @@ -538,7 +550,7 @@ end function analyze(::Val{:linf_divb}, du, u, t, mesh::TreeMesh{2}, - have_aux_node_vars::False, equations, dg::DGSEM, cache) + equations, dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis # integrate over all elements to get the divergence-free condition errors @@ -567,7 +579,7 @@ end function analyze(::Val{:linf_divb}, du, u, t, mesh::Union{StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, - have_aux_node_vars::False, equations, dg::DGSEM, cache) + equations, dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis @unpack contravariant_vectors, inverse_jacobian = cache.elements diff --git a/src/callbacks_step/analysis_dg3d.jl b/src/callbacks_step/analysis_dg3d.jl index d253ba9eae9..476cb875f9e 100644 --- a/src/callbacks_step/analysis_dg3d.jl +++ b/src/callbacks_step/analysis_dg3d.jl @@ -505,7 +505,7 @@ end function analyze(::typeof(entropy_timederivative), du, u, t, mesh::Union{TreeMesh{3}, StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - have_aux_node_vars::False, equations, dg::Union{DGSEM, FDSBP}, cache) + equations, dg::Union{DGSEM, FDSBP}, cache) # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ integrate_via_indices(u, mesh, equations, dg, cache, du) do u, i, j, k, element, equations, dg, du @@ -516,8 +516,7 @@ function analyze(::typeof(entropy_timederivative), du, u, t, end function analyze(::Val{:l2_divb}, du, u, t, - mesh::TreeMesh{3}, have_aux_node_vars::False, equations, - dg::DGSEM, cache) + mesh::TreeMesh{3}, equations, dg::DGSEM, cache) integrate_via_indices(u, mesh, equations, dg, cache, cache, dg.basis.derivative_matrix) do u, i, j, k, element, equations, dg, cache, derivative_matrix @@ -542,8 +541,7 @@ end function analyze(::Val{:l2_divb}, du, u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - have_aux_node_vars::False, equations, - dg::DGSEM, cache) + equations, dg::DGSEM, cache) @unpack contravariant_vectors, inverse_jacobian = cache.elements integrate_via_indices(u, mesh, equations, dg, cache, cache, dg.basis.derivative_matrix) do u, i, j, k, element, equations, @@ -579,8 +577,7 @@ function analyze(::Val{:l2_divb}, du, u, t, end function analyze(::Val{:linf_divb}, du, u, t, - mesh::TreeMesh{3}, have_aux_node_vars::False, equations, - dg::DGSEM, cache) + mesh::TreeMesh{3}, equations, dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis # integrate over all elements to get the divergence-free condition errors @@ -616,8 +613,7 @@ end function analyze(::Val{:linf_divb}, du, u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - have_aux_node_vars::False, equations, - dg::DGSEM, cache) + equations, dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis @unpack contravariant_vectors, inverse_jacobian = cache.elements From bd27c1c306be469f2f8aef6bd9ddf9593f5da3c5 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Tue, 2 Jun 2026 17:04:03 +0200 Subject: [PATCH 77/83] add LinearVariableScalarAdvectionEquation2D --- src/Trixi.jl | 1 + .../linear_variable_scalar_advection_2d.jl | 75 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 src/equations/linear_variable_scalar_advection_2d.jl diff --git a/src/Trixi.jl b/src/Trixi.jl index 18fab412e7c..f8b4a4574d5 100644 --- a/src/Trixi.jl +++ b/src/Trixi.jl @@ -214,6 +214,7 @@ export AcousticPerturbationEquations2D, AcousticPerturbationEquations2DAuxVars, HyperbolicDiffusionEquations3D, LinearScalarAdvectionEquation1D, LinearScalarAdvectionEquation2D, LinearScalarAdvectionEquation3D, + LinearVariableScalarAdvectionEquation2D, InviscidBurgersEquation1D, LatticeBoltzmannEquations2D, LatticeBoltzmannEquations3D, LinearizedEulerEquations1D, LinearizedEulerEquations2D, LinearizedEulerEquations3D, diff --git a/src/equations/linear_variable_scalar_advection_2d.jl b/src/equations/linear_variable_scalar_advection_2d.jl new file mode 100644 index 00000000000..d8de855fb50 --- /dev/null +++ b/src/equations/linear_variable_scalar_advection_2d.jl @@ -0,0 +1,75 @@ +# By default, Julia/LLVM does not use fused multiply-add operations (FMAs). +# Since these FMAs can increase the performance of many numerical algorithms, +# we need to opt-in explicitly. +# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details. +@muladd begin +#! format: noindent + +struct LinearVariableScalarAdvectionEquation2D{} <: + AbstractLinearScalarAdvectionEquation{2} end + +have_aux_node_vars(::LinearVariableScalarAdvectionEquation2D) = True() +n_aux_node_vars(::LinearVariableScalarAdvectionEquation2D) = 2 + +@inline function flux(u, aux_vars, orientation::Integer, + equations::LinearVariableScalarAdvectionEquation2D) + a = aux_vars[orientation] + return a * u +end + +@inline function flux(u, aux_vars, normal_direction::AbstractVector, + equation::LinearVariableScalarAdvectionEquation2D) + a = dot(aux_vars, normal_direction) # velocity in normal direction + return a * u +end + +function flux_godunov(u_ll, u_rr, aux_ll, aux_rr, normal_direction::AbstractVector, + equation::LinearVariableScalarAdvectionEquation2D) + # velocity in normal direction + v_ll = dot(aux_ll, normal_direction) + v_rr = dot(aux_rr, normal_direction) + + a_normal = 0.5f0 * (v_ll + v_rr) + if a_normal >= 0 + return v_ll * u_ll + else + return v_rr * u_rr + end +end + +# Calculate maximum wave speed for local Lax-Friedrichs-type dissipation +@inline function max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, + orientation::Integer, + equation::LinearVariableScalarAdvectionEquation2D) + v_ll = aux_ll[orientation] + v_rr = aux_rr[orientation] + return max(abs(v_ll), abs(v_rr)) +end + +@inline function max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, + normal_direction::AbstractVector, + equation::LinearVariableScalarAdvectionEquation2D) + # velocity in normal direction + v_ll = dot(aux_ll, normal_direction) + v_rr = dot(aux_rr, normal_direction) + return max(abs(v_ll), abs(v_rr)) +end + +# Maximum wave speeds in each direction for CFL calculation +@inline function Trixi.max_abs_speeds(u, aux_vars, + equations::LinearVariableScalarAdvectionEquation2D) + return abs.(aux_vars) +end + +@inline cons2entropy(u, aux, ::LinearVariableScalarAdvectionEquation2D) = u +@inline cons2prim(u, aux, ::LinearVariableScalarAdvectionEquation2D) = SVector(u[1], + aux[1], + aux[2]) +@inline cons2aux(u, aux, ::LinearVariableScalarAdvectionEquation2D) = SVector(aux[1], + aux[2]) + +varnames(::typeof(cons2cons), ::LinearVariableScalarAdvectionEquation2D) = ("scalar",) +varnames(::typeof(cons2prim), ::LinearVariableScalarAdvectionEquation2D) = ("scalar", + "v1", "v2") +varnames(::typeof(cons2aux), ::LinearVariableScalarAdvectionEquation2D) = ("v1", "v2") +end From b0e45938457a6fda87cb8ba20f4d71e698d6c946 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Tue, 2 Jun 2026 17:04:31 +0200 Subject: [PATCH 78/83] add boundary condition with aux vars --- src/equations/equations.jl | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/equations/equations.jl b/src/equations/equations.jl index 984b5e0dca4..5de688cfae4 100644 --- a/src/equations/equations.jl +++ b/src/equations/equations.jl @@ -189,6 +189,27 @@ end return flux end +@inline function (boundary_condition::BoundaryConditionDirichlet)(u_inner, aux_inner, + orientation_or_normal, + direction, + x, t, + surface_flux_function, + equations) + u_boundary = boundary_condition.boundary_value_function(x, t, equations) + # So far, there are no seperate auxiliary variables on boundaries + + # Calculate boundary flux + if iseven(direction) # u_inner is "left" of boundary, u_boundary is "right" of boundary + flux = surface_flux_function(u_inner, u_boundary, aux_inner, aux_inner, + orientation_or_normal, equations) + else # u_boundary is "left" of boundary, u_inner is "right" of boundary + flux = surface_flux_function(u_boundary, u_inner, aux_inner, aux_inner, + orientation_or_normal, equations) + end + + return flux +end + # Dirichlet-type boundary condition for use with TreeMesh or StructuredMesh # passing a tuple of surface flux functions for nonconservative terms @inline function (boundary_condition::BoundaryConditionDirichlet)(u_inner, @@ -654,6 +675,8 @@ include("linear_scalar_advection_1d.jl") include("linear_scalar_advection_2d.jl") include("linear_scalar_advection_3d.jl") +include("linear_variable_scalar_advection_2d.jl") + # Inviscid Burgers abstract type AbstractInviscidBurgersEquation{NDIMS, NVARS} <: AbstractEquations{NDIMS, NVARS} end From 5971edab0888d0e141698924854943fcae5f57d5 Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Tue, 2 Jun 2026 17:05:10 +0200 Subject: [PATCH 79/83] add test case for LinearVariableScalarAdvectionEquation2D --- ...elixir_advection_variable_swirling_flow.jl | 125 ++++++++++++++++++ test/test_mpi_tree.jl | 6 + test/test_tree_2d_advection.jl | 9 ++ 3 files changed, 140 insertions(+) create mode 100644 examples/tree_2d_dgsem/elixir_advection_variable_swirling_flow.jl diff --git a/examples/tree_2d_dgsem/elixir_advection_variable_swirling_flow.jl b/examples/tree_2d_dgsem/elixir_advection_variable_swirling_flow.jl new file mode 100644 index 00000000000..58384804bfe --- /dev/null +++ b/examples/tree_2d_dgsem/elixir_advection_variable_swirling_flow.jl @@ -0,0 +1,125 @@ +using OrdinaryDiffEqLowStorageRK +using Trixi +using Plots + +# Advection test case following +# Randall J. LeVeque +# High-Resolution Conservative Algorithms for Advection in Incompressible Flow +# https://doi.org/10.1137/0733033 + +############################################################################################ +# initial condition + +equations = LinearVariableScalarAdvectionEquation2D() + +function initial_condition_advected_objects(x, t, equations::LinearVariableScalarAdvectionEquation2D) + RealT = eltype(x) + + # smooth hump + x_0, y_0, r_0 = 0.25f0, 0.5f0, convert(RealT, 0.15) + r = sqrt((x[1] - x_0)^2 + (x[2] - y_0)^2) + r = min(r, r_0) / r_0 + hump = 0.25f0 * (1 + cospi(r)) + + # cone + x_1, y_1, r_1 = 0.5f0, 0.25f0, convert(RealT, 0.15) + r = sqrt((x[1] - x_1)^2 + (x[2] - y_1)^2) + cone = 1.0f0 - min(r, r_1) / r_1 + + # slotted disc + x_2, y_2, r_2 = 0.5f0, 0.75f0, convert(RealT, 0.15) + w, l = 0.05f0, convert(RealT, 0.25) + r = sqrt((x[1] - x_2)^2 + (x[2] - y_2)^2) + disc = 0 + if r <= r_2 && (x[2] >= y_2 - r_2 + l || abs(x[1] - x_2) >= w) + disc = 1.0f0 + end + + return SVector(hump + cone + disc) +end + +# velocity field at time t = 0 (see reference) +@inline function velocity_swirling(x, equations) + u = sinpi(x[1])^2 * sinpi(2 * x[2]) + v = -sinpi(x[2])^2 * sinpi(2 * x[1]) + return SVector(u, v) +end + +############################################################################################ +# semidiscretization +polydeg = 3 + +initial_condition = initial_condition_advected_objects + +surface_flux = flux_lax_friedrichs +solver = DGSEM(polydeg = polydeg, surface_flux = surface_flux) + +coordinates_min = (0.0, 0.0) +coordinates_max = (1.0, 1.0) + +mesh = TreeMesh(coordinates_min, coordinates_max, + initial_refinement_level = 2, + periodicity = false) + +# boundary conditions +boundary_condition_dirichlet = BoundaryConditionDirichlet(initial_condition_advected_objects) +boundary_conditions = (; x_neg = boundary_condition_dirichlet, + x_pos = boundary_condition_dirichlet, + y_neg = boundary_condition_dirichlet, + y_pos = boundary_condition_dirichlet) + +# the velocity is passed as auxiliary_field into the cache +semi = SemidiscretizationHyperbolic(mesh, + equations, + initial_condition, + solver, + boundary_conditions = boundary_conditions, + aux_field = velocity_swirling) + +############################################################################################## +# ODE solvers, callbacks etc. + +tspan = (0.0, 1.0) +ode = semidiscretize(semi, tspan) + +summary_callback = SummaryCallback() + +analysis_interval = 100 +solution_variables = cons2prim + +analysis_callback = AnalysisCallback(semi, + interval = analysis_interval) + +alive_callback = AliveCallback(analysis_interval = analysis_interval) + +save_solution = SaveSolutionCallback(interval = 10, + save_initial_solution = true, + save_final_solution = true, + output_directory = "out_swirling", + solution_variables = solution_variables) + +amr_controller = ControllerThreeLevel(semi, IndicatorMax(semi, variable = first), + base_level = 2, + med_level = 4, med_threshold = 0.3, + max_level = 6, max_threshold = 0.8) +amr_callback = AMRCallback(semi, amr_controller, + interval = 20, + adapt_initial_condition = true, + adapt_initial_condition_only_refine = true) + +stepsize_callback = StepsizeCallback(cfl = 1.0) + +visualization = VisualizationCallback(semi; interval = 20) #, show_mesh = true) + +callbacks = CallbackSet(summary_callback, + analysis_callback, + alive_callback, + stepsize_callback, + amr_callback, + #visualization, + save_solution) + +############################################################################### +# run the simulation +sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false); + dt = 1.0, ode_default_options()..., callback = callbacks); diff --git a/test/test_mpi_tree.jl b/test/test_mpi_tree.jl index c8160dc8a16..2eaa71ad4cc 100644 --- a/test/test_mpi_tree.jl +++ b/test/test_mpi_tree.jl @@ -106,6 +106,12 @@ CI_ON_WINDOWS = (get(ENV, "GITHUB_ACTIONS", false) == "true") && Sys.iswindows() linf=[0.0253454486893413]) end + @trixi_testset "elixir_advection_variable_swirling_flow.jl" begin + @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_variable_swirling_flow.jl"), + l2=[2.90963554e-01], + linf=[1.31858729e+00]) + end + @trixi_testset "elixir_acoustics_gauss_wall_amr_auxvars.jl" begin @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_acoustics_gauss_wall_amr_auxvars.jl"), diff --git a/test/test_tree_2d_advection.jl b/test/test_tree_2d_advection.jl index 53f3aefe71b..9f64b0f3432 100644 --- a/test/test_tree_2d_advection.jl +++ b/test/test_tree_2d_advection.jl @@ -247,6 +247,15 @@ end @test_allocations(Trixi.rhs!, semi, sol, 1000) end +@trixi_testset "elixir_advection_variable_swirling_flow.jl" begin + @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_variable_swirling_flow.jl"), + l2=[2.90963554e-01], + linf=[1.31858729e+00]) + # Ensure that we do not have excessive memory allocations + # (e.g., from type instabilities) + @test_allocations(Trixi.rhs!, semi, sol, 1000) +end + # Coverage test for all initial conditions @testset "Linear scalar advection: Tests for initial conditions" begin # Linear scalar advection From 29a66a9de22dc8a551455fbec300dc53f2e0ef6e Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Tue, 2 Jun 2026 17:28:23 +0200 Subject: [PATCH 80/83] simplify create_cache --- .../semidiscretization_hyperbolic.jl | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/semidiscretization/semidiscretization_hyperbolic.jl b/src/semidiscretization/semidiscretization_hyperbolic.jl index a07b638c6a7..dd51a571d00 100644 --- a/src/semidiscretization/semidiscretization_hyperbolic.jl +++ b/src/semidiscretization/semidiscretization_hyperbolic.jl @@ -66,11 +66,11 @@ function SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver cache = create_cache(mesh, equations, solver, RealT, uEltype) - # Add specialized parts of the cache for auxiliary node variables - cache = (; cache..., - create_cache_aux(mesh, equations, solver, cache, - have_aux_node_vars(equations), - aux_field)...) + # Add auxiliary node variables cache + if have_aux_node_vars(equations) == True() + cache = (; cache..., + create_cache_aux(mesh, equations, solver, cache, aux_field)...) + end _boundary_conditions = digest_boundary_conditions(boundary_conditions, mesh, solver, cache) @@ -113,19 +113,12 @@ function remake(semi::SemidiscretizationHyperbolic; uEltype = real(semi.solver), source_terms, boundary_conditions, uEltype) end -# If there are auxiliary variables, initialize them -function create_cache_aux(mesh, equations, solver, cache, have_aux_node_vars::True, - aux_field) +# auxiliary variables cache +function create_cache_aux(mesh, equations, solver, cache, aux_field) aux_vars = init_aux_vars(mesh, equations, solver, cache, aux_field) return (; aux_vars) end -# Do nothing if there are no auxiliary variables -function create_cache_aux(mesh, equations, solver, cache, have_aux_node_vars::False, - aux_field) - return NamedTuple() -end - # general fallback function digest_boundary_conditions(boundary_conditions, mesh, solver, cache) return boundary_conditions From d1b8ac80d37da8f59246e3dced0111b5dab8965b Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Wed, 3 Jun 2026 09:15:54 +0200 Subject: [PATCH 81/83] fmt --- NEWS.md | 2 +- ...elixir_advection_variable_swirling_flow.jl | 3 ++- src/callbacks_step/analysis_dg2d.jl | 8 ++++--- src/equations/equations.jl | 2 +- .../linear_variable_scalar_advection_2d.jl | 24 +++++++++---------- .../semidiscretization_hyperbolic.jl | 2 +- test/test_mpi_tree.jl | 7 +++--- test/test_tree_2d_advection.jl | 3 ++- 8 files changed, 28 insertions(+), 23 deletions(-) diff --git a/NEWS.md b/NEWS.md index 120aea59d72..e16a8439da5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -17,7 +17,7 @@ for human readability. `SemidiscretizationHyperbolic` constructor via the keyword argument `aux_field`. The current `equations` need to set `have_aux_node_vars to `True()` and `n_aux_node_vars` to the number of auxiliary variables per node. - So far, a simplyfying continuity assumption is made for the auxiliary variables, which + So far, a simplifying continuity assumption is made for the auxiliary variables, which e.g. allows to directly compute values at neighboring (mortar) interfaces instead of MPI-communicating their values. - `VolumeIntegralAdaptive` is now also available with `VolumeIntegralSubcellLimiting` for `TreeMesh` in 2D and 3D using the heuristic a-priori indicator `IndicatorHennemannGassner` ([#2924], [#2986]). diff --git a/examples/tree_2d_dgsem/elixir_advection_variable_swirling_flow.jl b/examples/tree_2d_dgsem/elixir_advection_variable_swirling_flow.jl index 58384804bfe..f1ce704de24 100644 --- a/examples/tree_2d_dgsem/elixir_advection_variable_swirling_flow.jl +++ b/examples/tree_2d_dgsem/elixir_advection_variable_swirling_flow.jl @@ -12,7 +12,8 @@ using Plots equations = LinearVariableScalarAdvectionEquation2D() -function initial_condition_advected_objects(x, t, equations::LinearVariableScalarAdvectionEquation2D) +function initial_condition_advected_objects(x, t, + equations::LinearVariableScalarAdvectionEquation2D) RealT = eltype(x) # smooth hump diff --git a/src/callbacks_step/analysis_dg2d.jl b/src/callbacks_step/analysis_dg2d.jl index 511005441f2..3b9b1432df1 100644 --- a/src/callbacks_step/analysis_dg2d.jl +++ b/src/callbacks_step/analysis_dg2d.jl @@ -464,11 +464,12 @@ function analyze(::typeof(entropy_timederivative), du, u, t, return analyze(entropy_timederivative, du, u, t, mesh, have_aux_node_vars(equations), equations, - dg, cache) + dg, cache) end @inline function analyze(::typeof(entropy_timederivative), du, u, t, - mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2}, + mesh::Union{TreeMesh{2}, StructuredMesh{2}, + StructuredMeshView{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, have_aux_node_vars::False, equations, dg::Union{DGSEM, FDSBP}, cache) @@ -482,7 +483,8 @@ end end @inline function analyze(::typeof(entropy_timederivative), du, u, t, - mesh::Union{TreeMesh{2}, StructuredMesh{2}, StructuredMeshView{2}, + mesh::Union{TreeMesh{2}, StructuredMesh{2}, + StructuredMeshView{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, have_aux_node_vars::True, equations, dg::Union{DGSEM, FDSBP}, cache) diff --git a/src/equations/equations.jl b/src/equations/equations.jl index 5de688cfae4..21987507ce1 100644 --- a/src/equations/equations.jl +++ b/src/equations/equations.jl @@ -196,7 +196,7 @@ end surface_flux_function, equations) u_boundary = boundary_condition.boundary_value_function(x, t, equations) - # So far, there are no seperate auxiliary variables on boundaries + # So far, there are no separate auxiliary variables on boundaries # Calculate boundary flux if iseven(direction) # u_inner is "left" of boundary, u_boundary is "right" of boundary diff --git a/src/equations/linear_variable_scalar_advection_2d.jl b/src/equations/linear_variable_scalar_advection_2d.jl index d8de855fb50..10e6001645b 100644 --- a/src/equations/linear_variable_scalar_advection_2d.jl +++ b/src/equations/linear_variable_scalar_advection_2d.jl @@ -6,25 +6,25 @@ #! format: noindent struct LinearVariableScalarAdvectionEquation2D{} <: - AbstractLinearScalarAdvectionEquation{2} end + AbstractLinearScalarAdvectionEquation{2} end have_aux_node_vars(::LinearVariableScalarAdvectionEquation2D) = True() n_aux_node_vars(::LinearVariableScalarAdvectionEquation2D) = 2 @inline function flux(u, aux_vars, orientation::Integer, - equations::LinearVariableScalarAdvectionEquation2D) + equations::LinearVariableScalarAdvectionEquation2D) a = aux_vars[orientation] return a * u end @inline function flux(u, aux_vars, normal_direction::AbstractVector, - equation::LinearVariableScalarAdvectionEquation2D) + equation::LinearVariableScalarAdvectionEquation2D) a = dot(aux_vars, normal_direction) # velocity in normal direction return a * u end function flux_godunov(u_ll, u_rr, aux_ll, aux_rr, normal_direction::AbstractVector, - equation::LinearVariableScalarAdvectionEquation2D) + equation::LinearVariableScalarAdvectionEquation2D) # velocity in normal direction v_ll = dot(aux_ll, normal_direction) v_rr = dot(aux_rr, normal_direction) @@ -39,16 +39,16 @@ end # Calculate maximum wave speed for local Lax-Friedrichs-type dissipation @inline function max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, - orientation::Integer, - equation::LinearVariableScalarAdvectionEquation2D) + orientation::Integer, + equation::LinearVariableScalarAdvectionEquation2D) v_ll = aux_ll[orientation] v_rr = aux_rr[orientation] return max(abs(v_ll), abs(v_rr)) end @inline function max_abs_speed(u_ll, u_rr, aux_ll, aux_rr, - normal_direction::AbstractVector, - equation::LinearVariableScalarAdvectionEquation2D) + normal_direction::AbstractVector, + equation::LinearVariableScalarAdvectionEquation2D) # velocity in normal direction v_ll = dot(aux_ll, normal_direction) v_rr = dot(aux_rr, normal_direction) @@ -57,16 +57,16 @@ end # Maximum wave speeds in each direction for CFL calculation @inline function Trixi.max_abs_speeds(u, aux_vars, - equations::LinearVariableScalarAdvectionEquation2D) + equations::LinearVariableScalarAdvectionEquation2D) return abs.(aux_vars) end @inline cons2entropy(u, aux, ::LinearVariableScalarAdvectionEquation2D) = u @inline cons2prim(u, aux, ::LinearVariableScalarAdvectionEquation2D) = SVector(u[1], - aux[1], - aux[2]) + aux[1], + aux[2]) @inline cons2aux(u, aux, ::LinearVariableScalarAdvectionEquation2D) = SVector(aux[1], - aux[2]) + aux[2]) varnames(::typeof(cons2cons), ::LinearVariableScalarAdvectionEquation2D) = ("scalar",) varnames(::typeof(cons2prim), ::LinearVariableScalarAdvectionEquation2D) = ("scalar", diff --git a/src/semidiscretization/semidiscretization_hyperbolic.jl b/src/semidiscretization/semidiscretization_hyperbolic.jl index dd51a571d00..659811cc6b8 100644 --- a/src/semidiscretization/semidiscretization_hyperbolic.jl +++ b/src/semidiscretization/semidiscretization_hyperbolic.jl @@ -69,7 +69,7 @@ function SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver # Add auxiliary node variables cache if have_aux_node_vars(equations) == True() cache = (; cache..., - create_cache_aux(mesh, equations, solver, cache, aux_field)...) + create_cache_aux(mesh, equations, solver, cache, aux_field)...) end _boundary_conditions = digest_boundary_conditions(boundary_conditions, mesh, solver, diff --git a/test/test_mpi_tree.jl b/test/test_mpi_tree.jl index 2eaa71ad4cc..bad367a616d 100644 --- a/test/test_mpi_tree.jl +++ b/test/test_mpi_tree.jl @@ -107,9 +107,10 @@ CI_ON_WINDOWS = (get(ENV, "GITHUB_ACTIONS", false) == "true") && Sys.iswindows() end @trixi_testset "elixir_advection_variable_swirling_flow.jl" begin - @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_variable_swirling_flow.jl"), - l2=[2.90963554e-01], - linf=[1.31858729e+00]) + @test_trixi_include(joinpath(EXAMPLES_DIR, + "elixir_advection_variable_swirling_flow.jl"), + l2=[2.90963554e-01], + linf=[1.31858729e+00]) end @trixi_testset "elixir_acoustics_gauss_wall_amr_auxvars.jl" begin diff --git a/test/test_tree_2d_advection.jl b/test/test_tree_2d_advection.jl index 9f64b0f3432..9f02df5dc19 100644 --- a/test/test_tree_2d_advection.jl +++ b/test/test_tree_2d_advection.jl @@ -248,7 +248,8 @@ end end @trixi_testset "elixir_advection_variable_swirling_flow.jl" begin - @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_variable_swirling_flow.jl"), + @test_trixi_include(joinpath(EXAMPLES_DIR, + "elixir_advection_variable_swirling_flow.jl"), l2=[2.90963554e-01], linf=[1.31858729e+00]) # Ensure that we do not have excessive memory allocations From 6a601c8c76fdd384d17b798c6b47b99aed17a7ce Mon Sep 17 00:00:00 2001 From: Benedict <135045760+benegee@users.noreply.github.com> Date: Fri, 5 Jun 2026 17:02:38 +0200 Subject: [PATCH 82/83] Apply suggestions from code review Co-authored-by: Tristan Montoya --- src/equations/equations.jl | 6 ++++-- src/semidiscretization/semidiscretization_hyperbolic.jl | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/equations/equations.jl b/src/equations/equations.jl index 21987507ce1..95ee72e1259 100644 --- a/src/equations/equations.jl +++ b/src/equations/equations.jl @@ -406,8 +406,10 @@ have_constant_speed(::AbstractEquations) = False() """ have_aux_node_vars(equations) -Trait function determining whether `equations` need to access additional auxiliary -variables. +Trait function determining whether auxiliary variables should be stored at each node +alongside the solution variables and used to compute the flux for `equations`. When +`True()`, the signature of [`flux`](@ref) becomes the following: + The return value will be `True()` or `False()` to allow dispatching on the return type. """ have_aux_node_vars(::AbstractEquations) = False() diff --git a/src/semidiscretization/semidiscretization_hyperbolic.jl b/src/semidiscretization/semidiscretization_hyperbolic.jl index 659811cc6b8..a455ba8ac9c 100644 --- a/src/semidiscretization/semidiscretization_hyperbolic.jl +++ b/src/semidiscretization/semidiscretization_hyperbolic.jl @@ -53,7 +53,9 @@ single boundary condition that gets applied to all boundaries. which will be available, e.g., in flux computations. The current `equations` need to set `have_aux_node_vars to `True()` and `n_aux_node_vars` to the number of auxiliary variables per node. Upon refinement, `aux_field` will be called again to recompute the auxiliary variables. -NOTE: This is experimental! +!!! warning "Experimental implementation" + The use of auxiliary variables is an experimental feature and may change in future + releases. Currently, only 2D `TreeMesh` is supported. """ function SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver; source_terms = nothing, From ee30e6b45135b6a8973ec894628ae4a4a3e0023a Mon Sep 17 00:00:00 2001 From: Benedict Geihe Date: Fri, 5 Jun 2026 17:09:06 +0200 Subject: [PATCH 83/83] restore formatting --- src/callbacks_step/analysis_dg1d.jl | 12 ++++++------ src/callbacks_step/analysis_dg2d.jl | 3 ++- src/callbacks_step/analysis_dg3d.jl | 12 ++++++++---- src/callbacks_step/analysis_dgmulti.jl | 11 +++++------ 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/callbacks_step/analysis_dg1d.jl b/src/callbacks_step/analysis_dg1d.jl index 67714ad2985..b098b89d7e5 100644 --- a/src/callbacks_step/analysis_dg1d.jl +++ b/src/callbacks_step/analysis_dg1d.jl @@ -231,8 +231,8 @@ function integrate(func::Func, u, end function analyze(::typeof(entropy_timederivative), du, u, t, - mesh::Union{TreeMesh{1}, StructuredMesh{1}}, - equations, dg::Union{DGSEM, FDSBP}, cache) + mesh::Union{TreeMesh{1}, StructuredMesh{1}}, equations, + dg::Union{DGSEM, FDSBP}, cache) # Calculate ∫(∂S/∂u ⋅ ∂u/∂t)dΩ integrate_via_indices(u, mesh, equations, dg, cache, du) do u, i, element, equations, dg, du @@ -243,8 +243,8 @@ function analyze(::typeof(entropy_timederivative), du, u, t, end function analyze(::Val{:l2_divb}, du, u, t, - mesh::TreeMesh{1}, - equations::IdealGlmMhdEquations1D, dg::DGSEM, cache) + mesh::TreeMesh{1}, equations::IdealGlmMhdEquations1D, + dg::DGSEM, cache) integrate_via_indices(u, mesh, equations, dg, cache, dg.basis.derivative_matrix) do u, i, element, equations, dg, derivative_matrix @@ -258,8 +258,8 @@ function analyze(::Val{:l2_divb}, du, u, t, end function analyze(::Val{:linf_divb}, du, u, t, - mesh::TreeMesh{1}, - equations::IdealGlmMhdEquations1D, dg::DGSEM, cache) + mesh::TreeMesh{1}, equations::IdealGlmMhdEquations1D, + dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis # integrate over all elements to get the divergence-free condition errors diff --git a/src/callbacks_step/analysis_dg2d.jl b/src/callbacks_step/analysis_dg2d.jl index 3b9b1432df1..cf948b7f618 100644 --- a/src/callbacks_step/analysis_dg2d.jl +++ b/src/callbacks_step/analysis_dg2d.jl @@ -500,7 +500,8 @@ end end function analyze(::Val{:l2_divb}, du, u, t, - mesh::TreeMesh{2}, equations, dg::DGSEM, cache) + mesh::TreeMesh{2}, + equations, dg::DGSEM, cache) integrate_via_indices(u, mesh, equations, dg, cache, cache, dg.basis.derivative_matrix) do u, i, j, element, equations, dg, cache, derivative_matrix diff --git a/src/callbacks_step/analysis_dg3d.jl b/src/callbacks_step/analysis_dg3d.jl index 476cb875f9e..65abd91b827 100644 --- a/src/callbacks_step/analysis_dg3d.jl +++ b/src/callbacks_step/analysis_dg3d.jl @@ -516,7 +516,8 @@ function analyze(::typeof(entropy_timederivative), du, u, t, end function analyze(::Val{:l2_divb}, du, u, t, - mesh::TreeMesh{3}, equations, dg::DGSEM, cache) + mesh::TreeMesh{3}, equations, + dg::DGSEM, cache) integrate_via_indices(u, mesh, equations, dg, cache, cache, dg.basis.derivative_matrix) do u, i, j, k, element, equations, dg, cache, derivative_matrix @@ -541,7 +542,8 @@ end function analyze(::Val{:l2_divb}, du, u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - equations, dg::DGSEM, cache) + equations, + dg::DGSEM, cache) @unpack contravariant_vectors, inverse_jacobian = cache.elements integrate_via_indices(u, mesh, equations, dg, cache, cache, dg.basis.derivative_matrix) do u, i, j, k, element, equations, @@ -577,7 +579,8 @@ function analyze(::Val{:l2_divb}, du, u, t, end function analyze(::Val{:linf_divb}, du, u, t, - mesh::TreeMesh{3}, equations, dg::DGSEM, cache) + mesh::TreeMesh{3}, equations, + dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis # integrate over all elements to get the divergence-free condition errors @@ -613,7 +616,8 @@ end function analyze(::Val{:linf_divb}, du, u, t, mesh::Union{StructuredMesh{3}, P4estMesh{3}, T8codeMesh{3}}, - equations, dg::DGSEM, cache) + equations, + dg::DGSEM, cache) @unpack derivative_matrix, weights = dg.basis @unpack contravariant_vectors, inverse_jacobian = cache.elements diff --git a/src/callbacks_step/analysis_dgmulti.jl b/src/callbacks_step/analysis_dgmulti.jl index 77afcedf946..805c3c5d5bc 100644 --- a/src/callbacks_step/analysis_dgmulti.jl +++ b/src/callbacks_step/analysis_dgmulti.jl @@ -44,8 +44,7 @@ function integrate(func::Func, u, mesh::DGMultiMesh, end function analyze(::typeof(entropy_timederivative), du, u, t, - mesh::DGMultiMesh, have_aux_node_vars::False, equations, dg::DGMulti, - cache) + mesh::DGMultiMesh, equations, dg::DGMulti, cache) rd = dg.basis md = mesh.md (; u_values) = cache.solution_container @@ -92,8 +91,8 @@ get_component(u::StructArray, i::Int) = StructArrays.component(u, i) get_component(u::AbstractArray{<:SVector}, i::Int) = getindex.(u, i) function analyze(::Val{:l2_divb}, du, u, t, - mesh::DGMultiMesh, have_aux_node_vars::False, - equations::IdealGlmMhdEquations2D, dg::DGMulti, cache) + mesh::DGMultiMesh, equations::IdealGlmMhdEquations2D, + dg::DGMulti, cache) @unpack md = mesh rd = dg.basis B1 = get_component(u, 6) @@ -116,8 +115,8 @@ function analyze(::Val{:l2_divb}, du, u, t, end function analyze(::Val{:linf_divb}, du, u, t, - mesh::DGMultiMesh, have_aux_node_vars::False, - equations::IdealGlmMhdEquations2D, dg::DGMulti, cache) + mesh::DGMultiMesh, equations::IdealGlmMhdEquations2D, + dg::DGMulti, cache) B1 = get_component(u, 6) B2 = get_component(u, 7) B = (B1, B2)