diff --git a/examples/structured_2d_dgsem/elixir_euler_source_terms_nonperiodic_fvO2.jl b/examples/structured_2d_dgsem/elixir_euler_source_terms_nonperiodic_fvO2.jl new file mode 100644 index 00000000000..872557d219e --- /dev/null +++ b/examples/structured_2d_dgsem/elixir_euler_source_terms_nonperiodic_fvO2.jl @@ -0,0 +1,61 @@ +using OrdinaryDiffEqLowStorageRK +using Trixi + +############################################################################### +# semidiscretization of the compressible Euler equations + +equations = CompressibleEulerEquations2D(1.4) + +initial_condition = initial_condition_convergence_test +source_terms = source_terms_convergence_test + +boundary_condition = BoundaryConditionDirichlet(initial_condition) +boundary_conditions = (x_neg = boundary_condition, + x_pos = boundary_condition, + y_neg = boundary_condition, + y_pos = boundary_condition) + +polydeg = 3 +basis = LobattoLegendreBasis(polydeg) +surface_flux = flux_hll + +volume_integral = VolumeIntegralPureLGLFiniteVolumeO2(basis, + volume_flux_fv = surface_flux, + reconstruction_mode = reconstruction_O2_full, + slope_limiter = vanLeer) + +solver = DGSEM(polydeg = polydeg, surface_flux = surface_flux, volume_integral = volume_integral) + +coordinates_min = (0.0, 0.0) +coordinates_max = (2.0, 2.0) +cells_per_dimension = (8, 8) +mesh = StructuredMesh(cells_per_dimension, coordinates_min, coordinates_max, periodicity = false) + +semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, + source_terms = source_terms, + boundary_conditions = boundary_conditions) + +############################################################################### +# ODE solvers, callbacks etc. + +tspan = (0.0, 2.0) +ode = semidiscretize(semi, tspan) + +summary_callback = SummaryCallback() + +analysis_interval = 100 +analysis_callback = AnalysisCallback(semi, interval = analysis_interval) + +alive_callback = AliveCallback(analysis_interval = analysis_interval) + +stepsize_callback = StepsizeCallback(cfl = 1.0) + +callbacks = CallbackSet(summary_callback, + analysis_callback, alive_callback, + stepsize_callback) +############################################################################### +# run the simulation + +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_euler_convergence_pure_fvO2.jl b/examples/tree_2d_dgsem/elixir_euler_convergence_pure_fvO2.jl new file mode 100644 index 00000000000..3c7fb0c0ca5 --- /dev/null +++ b/examples/tree_2d_dgsem/elixir_euler_convergence_pure_fvO2.jl @@ -0,0 +1,58 @@ + +using OrdinaryDiffEqLowStorageRK +using Trixi + +############################################################################### +# semidiscretization of the compressible Euler equations + +equations = CompressibleEulerEquations2D(1.4) + +initial_condition = initial_condition_convergence_test + +polydeg = 3 # Governs in this case only the number of subcells +basis = LobattoLegendreBasis(polydeg) +surface_flux = flux_hllc +volume_integral = VolumeIntegralPureLGLFiniteVolumeO2(basis, + volume_flux_fv = surface_flux, + reconstruction_mode = reconstruction_O2_full, + slope_limiter = monotonized_central) +solver = DGSEM(polydeg = polydeg, surface_flux = surface_flux, + volume_integral = volume_integral) + +coordinates_min = (0.0, 0.0) +coordinates_max = (2.0, 2.0) +mesh = TreeMesh(coordinates_min, coordinates_max, + initial_refinement_level = 3, + n_cells_max = 10_000) + +semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, + source_terms = source_terms_convergence_test) + +############################################################################### +# ODE solvers, callbacks etc. + +tspan = (0.0, 2.0) +ode = semidiscretize(semi, tspan) + +summary_callback = SummaryCallback() + +analysis_interval = 100 +analysis_callback = AnalysisCallback(semi, interval = analysis_interval, + extra_analysis_errors = (:l2_error_primitive, + :linf_error_primitive, + :conservation_error)) + +alive_callback = AliveCallback(analysis_interval = analysis_interval) + +stepsize_callback = StepsizeCallback(cfl = 1.1) + +callbacks = CallbackSet(summary_callback, + analysis_callback, alive_callback, + stepsize_callback) + +############################################################################### +# run the simulation + +sol = solve(ode, ORK256(), + dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback + save_everystep = false, callback = callbacks); diff --git a/src/solvers/dgsem_structured/dg_2d.jl b/src/solvers/dgsem_structured/dg_2d.jl index 151cce0528a..1354e253047 100644 --- a/src/solvers/dgsem_structured/dg_2d.jl +++ b/src/solvers/dgsem_structured/dg_2d.jl @@ -356,6 +356,116 @@ end return nothing end +@inline function calcflux_fvO2!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, u, + mesh::Union{StructuredMesh{2}, StructuredMeshView{2}, + UnstructuredMesh2D, + P4estMesh{2}, T8codeMesh{2}}, + have_nonconservative_terms::False, equations, + volume_flux_fv, dg::DGSEM, element, cache, + x_interfaces, reconstruction_mode, slope_limiter) + @unpack contravariant_vectors = cache.elements + @unpack weights, derivative_matrix = dg.basis + + 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) + # We compute FV02 fluxes at the (nnodes(dg) - 1) subcell boundaries + # See `calcflux_fvO2!` in solvers/dgsem_tree/dg_1d.jl for a schematic + + # The left subcell node values are labelled `_ll` (left-left) and `_lr` (left-right), while + # the right subcell node values are labelled `_rl` (right-left) and `_rr` (right-right). + + normal_direction = get_contravariant_vector(1, contravariant_vectors, + 1, j, element) + + for i in 2:nnodes(dg) + ## Obtain unlimited values in primitive variables ## + + # Note: If i - 2 = 0 we do not go to neighbor element, as one would do in a finite volume scheme. + # Here, we keep it purely cell-local, thus overshoots between elements are not strictly ruled out, + # **unless** `reconstruction_mode` is set to `reconstruction_O2_inner` + u_ll = cons2prim(get_node_vars(u, equations, dg, max(1, i - 2), j, element), + equations) + u_lr = cons2prim(get_node_vars(u, equations, dg, i - 1, j, element), + equations) + u_rl = cons2prim(get_node_vars(u, equations, dg, i, j, element), + equations) + # Note: If i + 1 > nnodes(dg) we do not go to neighbor element, as one would do in a finite volume scheme. + # Here, we keep it purely cell-local, thus overshoots between elements are not strictly ruled out, + # **unless** `reconstruction_mode` is set to `reconstruction_O2_inner` + u_rr = cons2prim(get_node_vars(u, equations, dg, min(nnodes(dg), i + 1), j, + element), equations) + + ## Reconstruct values at interfaces with limiting ## + u_l, u_r = reconstruction_mode(u_ll, u_lr, u_rl, u_rr, + x_interfaces, i, + slope_limiter, dg) + + # Compute freestream-preserving normal vector for the finite volume flux. + for m in eachnode(dg) + normal_direction += weights[i - 1] * derivative_matrix[i - 1, m] * + get_contravariant_vector(1, contravariant_vectors, + m, j, element) + end + + # Compute the contravariant flux by taking the scalar product of the + # normal vector and the flux vector. + ## Convert primitive variables back to conservative variables ## + contravariant_flux = volume_flux_fv(prim2cons(u_l, equations), prim2cons(u_r, equations), + normal_direction, equations) + + set_node_vars!(fstar1_L, contravariant_flux, equations, dg, i, j) + set_node_vars!(fstar1_R, contravariant_flux, equations, dg, i, j) + end + 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 i in eachnode(dg) + normal_direction = get_contravariant_vector(2, contravariant_vectors, + i, 1, element) + + for j in 2:nnodes(dg) + u_ll = cons2prim(get_node_vars(u, equations, dg, i, max(1, j - 2), element), + equations) + u_lr = cons2prim(get_node_vars(u, equations, dg, i, j - 1, element), + equations) + u_rl = cons2prim(get_node_vars(u, equations, dg, i, j, element), + equations) + u_rr = cons2prim(get_node_vars(u, equations, dg, i, min(nnodes(dg), j + 1), + element), equations) + + ## Reconstruct values at interfaces with limiting ## + u_l, u_r = reconstruction_mode(u_ll, u_lr, u_rl, u_rr, + x_interfaces, j, + slope_limiter, dg) + + for m in eachnode(dg) + normal_direction += weights[j - 1] * derivative_matrix[j - 1, m] * + get_contravariant_vector(2, contravariant_vectors, + i, m, element) + end + + # Compute the contravariant flux by taking the scalar product of the + # normal vector and the flux vector. + ## Convert primitive variables back to conservative variables ## + contravariant_flux = volume_flux_fv(prim2cons(u_l, equations), prim2cons(u_r, equations), + normal_direction, equations) + + set_node_vars!(fstar2_L, contravariant_flux, equations, dg, i, j) + set_node_vars!(fstar2_R, contravariant_flux, equations, dg, i, j) + end + end + + return nothing +end + @inline function calcflux_fv!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, u, mesh::Union{StructuredMesh{2}, StructuredMesh{2}, UnstructuredMesh2D, diff --git a/src/solvers/dgsem_tree/dg_1d.jl b/src/solvers/dgsem_tree/dg_1d.jl index 8753eb0967e..3453a9f33bd 100644 --- a/src/solvers/dgsem_tree/dg_1d.jl +++ b/src/solvers/dgsem_tree/dg_1d.jl @@ -385,15 +385,17 @@ end ## Obtain unlimited values in primitive variables ## # Note: If i - 2 = 0 we do not go to neighbor element, as one would do in a finite volume scheme. - # Here, we keep it purely cell-local, thus overshoots between elements are not ruled out. - u_ll = cons2prim(get_node_vars(u, equations, dg, max(1, i - 2), element), + # Here, we keep it purely cell-local, thus overshoots between elements are not strictly ruled out, + # **unless** `reconstruction_mode` is set to `reconstruction_O2_inner` + u_ll = cons2prim(get_node_vars(u, equations, dg, max(1, i - 2), element), equations) u_lr = cons2prim(get_node_vars(u, equations, dg, i - 1, element), equations) u_rl = cons2prim(get_node_vars(u, equations, dg, i, element), equations) # Note: If i + 1 > nnodes(dg) we do not go to neighbor element, as one would do in a finite volume scheme. - # Here, we keep it purely cell-local, thus overshoots between elements are not ruled out. + # Here, we keep it purely cell-local, thus overshoots between elements are not strictly ruled out, + # **unless** `reconstruction_mode` is set to `reconstruction_O2_inner` u_rr = cons2prim(get_node_vars(u, equations, dg, min(nnodes(dg), i + 1), element), equations) diff --git a/src/solvers/dgsem_tree/dg_2d.jl b/src/solvers/dgsem_tree/dg_2d.jl index 7edc830a601..6b03ed90e50 100644 --- a/src/solvers/dgsem_tree/dg_2d.jl +++ b/src/solvers/dgsem_tree/dg_2d.jl @@ -62,7 +62,7 @@ end function create_cache(mesh::Union{TreeMesh{2}, StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, T8codeMesh{2}}, equations, - volume_integral::VolumeIntegralPureLGLFiniteVolume, dg::DG, + volume_integral::AbstractVolumeIntegralPureLGLFiniteVolume, dg::DG, uEltype) A3d = Array{uEltype, 3} @@ -291,6 +291,137 @@ end end end +@inline function fvO2_kernel!(du, u, + mesh::Union{TreeMesh{2}, StructuredMesh{2}, + UnstructuredMesh2D, P4estMesh{2}, + T8codeMesh{2}}, + have_nonconservative_terms, equations, + volume_flux_fv, dg::DGSEM, cache, element, + x_interfaces, reconstruction_mode, slope_limiter, + 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 + + # Calculate FV two-point fluxes + fstar1_L = fstar1_L_threaded[Threads.threadid()] + fstar2_L = fstar2_L_threaded[Threads.threadid()] + fstar1_R = fstar1_R_threaded[Threads.threadid()] + fstar2_R = fstar2_R_threaded[Threads.threadid()] + calcflux_fvO2!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, u, mesh, + have_nonconservative_terms, equations, + volume_flux_fv, dg, element, cache, + x_interfaces, reconstruction_mode, slope_limiter) + + # Calculate FV volume integral contribution + for j in eachnode(dg), i in eachnode(dg) + for v in eachvariable(equations) + du[v, i, j, element] += (alpha * + (inverse_weights[i] * + (fstar1_L[v, i + 1, j] - fstar1_R[v, i, j]) + + inverse_weights[j] * + (fstar2_L[v, i, j + 1] - fstar2_R[v, i, j]))) + end + end + + return nothing +end + +function calc_volume_integral!(du, u, mesh::Union{TreeMesh{2}, StructuredMesh{2}, P4estMesh{2}, UnstructuredMesh2D, T8codeMesh{2}}, + have_nonconservative_terms, equations, + volume_integral::VolumeIntegralPureLGLFiniteVolumeO2, + dg::DGSEM, cache) + @unpack x_interfaces, volume_flux_fv, reconstruction_mode, slope_limiter = volume_integral + + # Calculate LGL second-order FV volume integral + @threaded for element in eachelement(dg, cache) + fvO2_kernel!(du, u, mesh, + have_nonconservative_terms, equations, + volume_flux_fv, dg, cache, element, + x_interfaces, reconstruction_mode, slope_limiter, true) + end + + return nothing +end + +@inline function calcflux_fvO2!(fstar1_L, fstar1_R, fstar2_L, fstar2_R, + u::AbstractArray{<:Any, 4}, + mesh::TreeMesh{2}, + 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)) + 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) + # We compute FV02 fluxes at the (nnodes(dg) - 1) subcell boundaries + # See `calcflux_fvO2!` in dg_1d.jl for a schematic of how it works + + # The left subcell node values are labelled `_ll` (left-left) and `_lr` (left-right), while + # the right subcell node values are labelled `_rl` (right-left) and `_rr` (right-right). + + ## Obtain unlimited values in primitive variables ## + + # Note: If i - 2 = 0 we do not go to neighbor element, as one would do in a finite volume scheme. + # Here, we keep it purely cell-local, thus overshoots between elements are not strictly ruled out, + # **unless** `reconstruction_mode` is set to `reconstruction_O2_inner` + u_ll = cons2prim(get_node_vars(u, equations, dg, max(1, i - 2), j, element), + equations) + u_lr = cons2prim(get_node_vars(u, equations, dg, i - 1, j, element), + equations) + u_rl = cons2prim(get_node_vars(u, equations, dg, i, j, element), + equations) + # Note: If i + 1 > nnodes(dg) we do not go to neighbor element, as one would do in a finite volume scheme. + # Here, we keep it purely cell-local, thus overshoots between elements are not strictly ruled out, + # **unless** `reconstruction_mode` is set to `reconstruction_O2_inner` + u_rr = cons2prim(get_node_vars(u, equations, dg, min(nnodes(dg), i + 1), j, + element), equations) + + ## Reconstruct values at interfaces with limiting ## + u_l, u_r = reconstruction_mode(u_ll, u_lr, u_rl, u_rr, + x_interfaces, i, + slope_limiter, dg) + + ## Convert primitive variables back to conservative variables ## + flux = volume_flux_fv(prim2cons(u_l, equations), prim2cons(u_r, equations), + 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 = cons2prim(get_node_vars(u, equations, dg, i, max(1, j - 2), element), + equations) + u_lr = cons2prim(get_node_vars(u, equations, dg, i, j - 1, element), + equations) + u_rl = cons2prim(get_node_vars(u, equations, dg, i, j, element), + equations) + u_rr = cons2prim(get_node_vars(u, equations, dg, i, min(nnodes(dg), j + 1), + element), equations) + + ## Reconstruct values at interfaces with limiting ## + u_l, u_r = reconstruction_mode(u_ll, u_lr, u_rl, u_rr, + x_interfaces, j, + slope_limiter, dg) + + ## Convert primitive variables back to conservative variables ## + flux = volume_flux_fv(prim2cons(u_l, equations), prim2cons(u_r, equations), + 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 + @inline function fv_kernel!(du, u, mesh::Union{TreeMesh{2}, StructuredMesh{2}, UnstructuredMesh2D, P4estMesh{2}, diff --git a/test/test_p4est_2d.jl b/test/test_p4est_2d.jl index 212276f0ddd..67739200118 100644 --- a/test/test_p4est_2d.jl +++ b/test/test_p4est_2d.jl @@ -199,6 +199,27 @@ end @test_allocations(Trixi.rhs!, semi, sol, 1000) end +@trixi_testset "elixir_euler_free_stream.jl (O2 full reconstruction)" begin + @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_free_stream.jl"), + solver=DGSEM(polydeg = 3, surface_flux = flux_hllc, + volume_integral=VolumeIntegralPureLGLFiniteVolumeO2(LobattoLegendreBasis(3), + volume_flux_fv=flux_hllc, + reconstruction_mode = reconstruction_O2_full, + slope_limiter = vanLeer)), + l2=[ + 2.063350241405049e-15, + 1.8571016296925367e-14, + 3.1769447886391905e-14, + 1.4104095258528071e-14 + ], + linf=[1.9539925233402755e-14, 2e-12, 1.3e-12, 9.3e-13], + atol=2.0e-12,) + # Ensure that we do not have excessive memory allocations + # (e.g., from type instabilities) + @test_allocations(Trixi.rhs!, semi, sol, 1000) +end + + @trixi_testset "elixir_euler_free_stream_hybrid_mesh.jl" begin @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_free_stream_hybrid_mesh.jl"), diff --git a/test/test_structured_2d.jl b/test/test_structured_2d.jl index b8f861f84b7..5fa0bf5f794 100644 --- a/test/test_structured_2d.jl +++ b/test/test_structured_2d.jl @@ -540,6 +540,26 @@ end @test_allocations(Trixi.rhs!, semi, sol, 1000) end +@trixi_testset "elixir_euler_source_terms_nonperiodic_fvO2.jl" begin + @test_trixi_include(joinpath(EXAMPLES_DIR, + "elixir_euler_source_terms_nonperiodic_fvO2.jl"), + l2=[ + 0.0027535201954222072, + 0.0017808463145373606, + 0.0017808463145373874, + 0.005589356782700206 + ], + linf=[ + 0.010801198634897702, + 0.00787469718577416, + 0.007874697185775936, + 0.02417877751394304 + ]) + # Ensure that we do not have excessive memory allocations + # (e.g., from type instabilities) + @test_allocations(Trixi.rhs!, semi, sol, 1000) +end + @trixi_testset "elixir_euler_vortex_perk4.jl" begin @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_vortex_perk4.jl"), l2=[ diff --git a/test/test_t8code_2d.jl b/test/test_t8code_2d.jl index 61bbd71f508..b6f7593fdf8 100644 --- a/test/test_t8code_2d.jl +++ b/test/test_t8code_2d.jl @@ -165,6 +165,32 @@ end @test_allocations(Trixi.rhs!, semi, sol, 1000) end +@trixi_testset "elixir_euler_source_terms_nonconforming_unstructured_flag.jl (O2 inner reconstruction)" begin + @test_trixi_include(joinpath(EXAMPLES_DIR, + "elixir_euler_source_terms_nonconforming_unstructured_flag.jl"), + solver=DGSEM(polydeg = 3, surface_flux = flux_hll, + volume_integral=VolumeIntegralPureLGLFiniteVolumeO2(LobattoLegendreBasis(3), + volume_flux_fv=flux_hll, + reconstruction_mode = reconstruction_O2_inner, + slope_limiter = vanLeer)), + + l2=[ + 0.01872951597687948, + 0.01146844899089883, + 0.014258199256512774, + 0.031637508582254815 + ], + linf=[ + 0.057283852256227785, + 0.03992615300124713, + 0.04871972163845162, + 0.11212570929707955 + ]) + # Ensure that we do not have excessive memory allocations + # (e.g., from type instabilities) + @test_allocations(Trixi.rhs!, semi, sol, 1000) +end + @trixi_testset "elixir_euler_free_stream.jl" begin # This test is identical to the one in `test_p4est_2d.jl`. @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_free_stream.jl"), diff --git a/test/test_tree_2d_euler.jl b/test/test_tree_2d_euler.jl index da5305f0217..366557160d6 100644 --- a/test/test_tree_2d_euler.jl +++ b/test/test_tree_2d_euler.jl @@ -48,6 +48,48 @@ end @test_allocations(Trixi.rhs!, semi, sol, 1000) end +@trixi_testset "elixir_euler_convergence_pure_fv.jl (O2, constant reconstruction)" begin + @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_convergence_pure_fv.jl"), + volume_integral=VolumeIntegralPureLGLFiniteVolumeO2(LobattoLegendreBasis(3), + volume_flux_fv=flux_hllc, + reconstruction_mode = reconstruction_constant, + slope_limiter = central_slope), + l2=[ + 0.026440292358506527, + 0.013245905852168414, + 0.013245905852168479, + 0.03912520302609374 + ], + linf=[ + 0.042130817806361964, + 0.022685499230187034, + 0.022685499230187922, + 0.06999771202145322 + ]) + # Ensure that we do not have excessive memory allocations + # (e.g., from type instabilities) + @test_allocations(Trixi.rhs!, semi, sol, 1000) +end + +@trixi_testset "elixir_euler_convergence_pure_fvO2.jl" begin + @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_convergence_pure_fvO2.jl"), + l2=[ + 0.0025035946669334152, + 0.0016446683868937965, + 0.001644668386893891, + 0.005333979740615437 + ], + linf=[ + 0.0057968192449908695, + 0.004564113130849812, + 0.00456411313084959, + 0.01494308497387209 + ]) + # Ensure that we do not have excessive memory allocations + # (e.g., from type instabilities) + @test_allocations(Trixi.rhs!, semi, sol, 1000) +end + @trixi_testset "elixir_euler_density_wave.jl" begin @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_density_wave.jl"), l2=[ diff --git a/test/test_unstructured_2d.jl b/test/test_unstructured_2d.jl index 7f06ee3e75e..5e7da6033d4 100644 --- a/test/test_unstructured_2d.jl +++ b/test/test_unstructured_2d.jl @@ -30,6 +30,26 @@ isdir(outdir) && rm(outdir, recursive = true) @test_allocations(Trixi.rhs!, semi, sol, 1000) end +@trixi_testset "elixir_euler_periodic.jl (O2 inner reconstruction)" begin + @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_periodic.jl"), + solver=DGSEM(polydeg = 6, surface_flux = FluxRotated(flux_hll), + volume_integral=VolumeIntegralPureLGLFiniteVolumeO2(LobattoLegendreBasis(6), + volume_flux_fv=FluxRotated(flux_hll), + reconstruction_mode = reconstruction_O2_inner, + slope_limiter = vanLeer)), + l2=[ + 0.005880232650481141, 0.004052961929767396, + 0.004052961929767276, 0.010484942040224163 + ], + linf=[ + 0.015735983423449618, 0.011413826186377207, + 0.01141382618637854, 0.028639280744277684 + ]) + # Ensure that we do not have excessive memory allocations + # (e.g., from type instabilities) + @test_allocations(Trixi.rhs!, semi, sol, 1000) +end + @trixi_testset "elixir_euler_free_stream.jl" begin @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_free_stream.jl"), l2=[