Skip to content

Commit 0acfce9

Browse files
jlchanranochaandrewwinters5000
authored
Add Winters et al matrix dissipation for 1D, 2D Euler (#2291)
* adding Winters et al matrix dissipation in 1D and 2D * exporting dissipation operator * adding tests * Apply suggestions from code review Co-authored-by: Hendrik Ranocha <[email protected]> * renaming * fix naming in tests * define avg * fix formatting * Apply suggestions from code review Co-authored-by: Andrew Winters <[email protected]> * more formatting * adding LinAlg: norm * add LinAlg: dot * formatting * adding 3D matrix dissipation operator * adding 3D matrix dissipation tests * add modified sod example and test * credit fluxo * Apply suggestions from code review Co-authored-by: Andrew Winters <[email protected]> Co-authored-by: Hendrik Ranocha <[email protected]> * remove avg(...) calls fixing 0.5f -> 0.5f0 * add specialization for orientation::Integer * adding 2D and 3D tests * format modified Sod elixir * add DOI to comment * fix tree_2d_dgsem test * Update test/test_tree_2d_euler.jl Co-authored-by: Hendrik Ranocha <[email protected]> * Apply suggestions from code review Co-authored-by: Hendrik Ranocha <[email protected]> * formatting --------- Co-authored-by: Hendrik Ranocha <[email protected]> Co-authored-by: Andrew Winters <[email protected]>
1 parent d7047ec commit 0acfce9

File tree

10 files changed

+503
-1
lines changed

10 files changed

+503
-1
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using OrdinaryDiffEqSSPRK, OrdinaryDiffEqLowStorageRK
2+
using Trixi
3+
4+
surface_flux = FluxPlusDissipation(flux_ranocha, DissipationMatrixWintersEtal())
5+
volume_flux = flux_ranocha
6+
dg = DGMulti(polydeg = 3, element_type = Line(), approximation_type = SBP(),
7+
surface_integral = SurfaceIntegralWeakForm(surface_flux),
8+
volume_integral = VolumeIntegralFluxDifferencing(volume_flux))
9+
10+
equations = CompressibleEulerEquations1D(1.4)
11+
12+
function initial_condition_modified_sod(x, t, ::CompressibleEulerEquations1D)
13+
if x[1] < 0.3
14+
return prim2cons(SVector(1, 0.75, 1), equations)
15+
else
16+
return prim2cons(SVector(0.125, 0.0, 0.1), equations)
17+
end
18+
end
19+
20+
initial_condition = initial_condition_modified_sod
21+
22+
cells_per_dimension = (50,)
23+
mesh = DGMultiMesh(dg, cells_per_dimension,
24+
coordinates_min = (0.0,), coordinates_max = (1.0,), periodicity = false)
25+
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg)
26+
27+
tspan = (0.0, 0.2)
28+
ode = semidiscretize(semi, tspan)
29+
30+
summary_callback = SummaryCallback()
31+
alive_callback = AliveCallback(alive_interval = 100)
32+
analysis_interval = 1000
33+
analysis_callback = AnalysisCallback(semi, interval = analysis_interval, uEltype = real(dg))
34+
callbacks = CallbackSet(summary_callback,
35+
analysis_callback,
36+
alive_callback)
37+
38+
###############################################################################
39+
# run the simulation
40+
41+
sol = solve(ode, SSPRK43(); adaptive = false,
42+
dt = 0.5 * estimate_dt(mesh, dg),
43+
ode_default_options()...,
44+
callback = callbacks);

src/Trixi.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ export flux, flux_central, flux_lax_friedrichs, flux_hll, flux_hllc, flux_hlle,
190190
flux_chan_etal, flux_nonconservative_chan_etal, flux_winters_etal,
191191
hydrostatic_reconstruction_audusse_etal, flux_nonconservative_audusse_etal,
192192
FluxPlusDissipation, DissipationGlobalLaxFriedrichs, DissipationLocalLaxFriedrichs,
193-
DissipationLaxFriedrichsEntropyVariables,
193+
DissipationLaxFriedrichsEntropyVariables, DissipationMatrixWintersEtal,
194194
FluxLaxFriedrichs, max_abs_speed_naive,
195195
FluxHLL, min_max_speed_naive, min_max_speed_davis, min_max_speed_einfeldt,
196196
FluxLMARS,

src/equations/compressible_euler_1d.jl

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,64 @@ end
708708
λ_max = max(v_mag_ll, v_mag_rr) + max(c_ll, c_rr)
709709
end
710710

711+
@inline function (dissipation::DissipationMatrixWintersEtal)(u_ll, u_rr,
712+
normal_direction::AbstractVector,
713+
equations::CompressibleEulerEquations1D)
714+
gamma = equations.gamma
715+
716+
norm_ = norm(normal_direction)
717+
unit_normal_direction = normal_direction / norm_
718+
719+
rho_ll, v1_ll, p_ll = cons2prim(u_ll, equations)
720+
rho_rr, v1_rr, p_rr = cons2prim(u_rr, equations)
721+
722+
b_ll = rho_ll / (2 * p_ll)
723+
b_rr = rho_rr / (2 * p_rr)
724+
725+
rho_log = ln_mean(rho_ll, rho_rr)
726+
b_log = ln_mean(b_ll, b_rr)
727+
v1_avg = 0.5f0 * (v1_ll + v1_rr)
728+
p_avg = 0.5f0 * (rho_ll + rho_rr) / (b_ll + b_rr) # 2 * b_avg = b_ll + b_rr
729+
v1_squared_bar = v1_ll * v1_rr
730+
h_bar = gamma / (2 * b_log * (gamma - 1)) + 0.5f0 * v1_squared_bar
731+
c_bar = sqrt(gamma * p_avg / rho_log)
732+
733+
v1_minus_c = v1_avg - c_bar * unit_normal_direction[1]
734+
v1_plus_c = v1_avg + c_bar * unit_normal_direction[1]
735+
v_avg_normal = v1_avg * unit_normal_direction[1]
736+
737+
entropy_vars_jump = cons2entropy(u_rr, equations) - cons2entropy(u_ll, equations)
738+
739+
lambda_1 = abs(v_avg_normal - c_bar) * rho_log / (2 * gamma)
740+
lambda_2 = abs(v_avg_normal) * rho_log * (gamma - 1) / gamma
741+
lambda_3 = abs(v_avg_normal + c_bar) * rho_log / (2 * gamma)
742+
lambda_4 = abs(v_avg_normal) * p_avg
743+
744+
entropy_var_rho_jump, entropy_var_rho_v1_jump, entropy_var_rho_e_jump = entropy_vars_jump
745+
746+
w1 = lambda_1 * (entropy_var_rho_jump + v1_minus_c * entropy_var_rho_v1_jump +
747+
(h_bar - c_bar * v_avg_normal) * entropy_var_rho_e_jump)
748+
w2 = lambda_2 * (entropy_var_rho_jump + v1_avg * entropy_var_rho_v1_jump +
749+
v1_squared_bar / 2 * entropy_var_rho_e_jump)
750+
w3 = lambda_3 * (entropy_var_rho_jump + v1_plus_c * entropy_var_rho_v1_jump +
751+
(h_bar + c_bar * v_avg_normal) * entropy_var_rho_e_jump)
752+
753+
dissipation_rho = w1 + w2 + w3
754+
755+
dissipation_rho_v1 = (w1 * v1_minus_c +
756+
w2 * v1_avg +
757+
w3 * v1_plus_c)
758+
759+
dissipation_rhoe = (w1 * (h_bar - c_bar * v_avg_normal) +
760+
w2 * 0.5f0 * v1_squared_bar +
761+
w3 * (h_bar + c_bar * v_avg_normal) +
762+
lambda_4 *
763+
(entropy_var_rho_e_jump * (v1_avg * v1_avg - v_avg_normal^2)))
764+
765+
return -0.5f0 * SVector(dissipation_rho, dissipation_rho_v1, dissipation_rhoe) *
766+
norm_
767+
end
768+
711769
# Calculate estimates for minimum and maximum wave speeds for HLL-type fluxes
712770
@inline function min_max_speed_naive(u_ll, u_rr, orientation::Integer,
713771
equations::CompressibleEulerEquations1D)

src/equations/compressible_euler_2d.jl

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,6 +1507,95 @@ end
15071507
return λ_min, λ_max
15081508
end
15091509

1510+
@inline function (dissipation::DissipationMatrixWintersEtal)(u_ll, u_rr,
1511+
normal_direction::AbstractVector,
1512+
equations::CompressibleEulerEquations2D)
1513+
(; gamma) = equations
1514+
1515+
norm_ = norm(normal_direction)
1516+
unit_normal_direction = normal_direction / norm_
1517+
1518+
rho_ll, v1_ll, v2_ll, p_ll = cons2prim(u_ll, equations)
1519+
rho_rr, v1_rr, v2_rr, p_rr = cons2prim(u_rr, equations)
1520+
1521+
b_ll = rho_ll / (2 * p_ll)
1522+
b_rr = rho_rr / (2 * p_rr)
1523+
1524+
rho_log = ln_mean(rho_ll, rho_rr)
1525+
b_log = ln_mean(b_ll, b_rr)
1526+
v1_avg = 0.5f0 * (v1_ll + v1_rr)
1527+
v2_avg = 0.5f0 * (v2_ll + v2_rr)
1528+
p_avg = 0.5f0 * (rho_ll + rho_rr) / (b_ll + b_rr) # 2 * b_avg = b_ll + b_rr
1529+
v_squared_bar = v1_ll * v1_rr + v2_ll * v2_rr
1530+
h_bar = gamma / (2 * b_log * (gamma - 1)) + 0.5f0 * v_squared_bar
1531+
c_bar = sqrt(gamma * p_avg / rho_log)
1532+
1533+
v_avg_normal = dot(SVector(v1_avg, v2_avg), unit_normal_direction)
1534+
1535+
lambda_1 = abs(v_avg_normal - c_bar) * rho_log / (2 * gamma)
1536+
lambda_2 = abs(v_avg_normal) * rho_log * (gamma - 1) / gamma
1537+
lambda_3 = abs(v_avg_normal + c_bar) * rho_log / (2 * gamma)
1538+
lambda_4 = abs(v_avg_normal) * p_avg
1539+
1540+
v1_minus_c = v1_avg - c_bar * unit_normal_direction[1]
1541+
v2_minus_c = v2_avg - c_bar * unit_normal_direction[2]
1542+
v1_plus_c = v1_avg + c_bar * unit_normal_direction[1]
1543+
v2_plus_c = v2_avg + c_bar * unit_normal_direction[2]
1544+
v1_tangential = v1_avg - v_avg_normal * unit_normal_direction[1]
1545+
v2_tangential = v2_avg - v_avg_normal * unit_normal_direction[2]
1546+
1547+
entropy_vars_jump = cons2entropy(u_rr, equations) - cons2entropy(u_ll, equations)
1548+
entropy_var_rho_jump, entropy_var_rho_v1_jump,
1549+
entropy_var_rho_v2_jump, entropy_var_rho_e_jump = entropy_vars_jump
1550+
1551+
velocity_minus_c_dot_entropy_vars_jump = v1_minus_c * entropy_var_rho_v1_jump +
1552+
v2_minus_c * entropy_var_rho_v2_jump
1553+
velocity_plus_c_dot_entropy_vars_jump = v1_plus_c * entropy_var_rho_v1_jump +
1554+
v2_plus_c * entropy_var_rho_v2_jump
1555+
velocity_avg_dot_vjump = v1_avg * entropy_var_rho_v1_jump +
1556+
v2_avg * entropy_var_rho_v2_jump
1557+
w1 = lambda_1 * (entropy_var_rho_jump + velocity_minus_c_dot_entropy_vars_jump +
1558+
(h_bar - c_bar * v_avg_normal) * entropy_var_rho_e_jump)
1559+
w2 = lambda_2 * (entropy_var_rho_jump + velocity_avg_dot_vjump +
1560+
v_squared_bar / 2 * entropy_var_rho_e_jump)
1561+
w3 = lambda_3 * (entropy_var_rho_jump + velocity_plus_c_dot_entropy_vars_jump +
1562+
(h_bar + c_bar * v_avg_normal) * entropy_var_rho_e_jump)
1563+
1564+
entropy_var_v_normal_jump = dot(SVector(entropy_var_rho_v1_jump,
1565+
entropy_var_rho_v2_jump),
1566+
unit_normal_direction)
1567+
1568+
dissipation_rho = w1 + w2 + w3
1569+
1570+
dissipation_rho_v1 = (w1 * v1_minus_c +
1571+
w2 * v1_avg +
1572+
w3 * v1_plus_c +
1573+
lambda_4 * (entropy_var_rho_v1_jump -
1574+
unit_normal_direction[1] * entropy_var_v_normal_jump +
1575+
entropy_var_rho_e_jump * v1_tangential))
1576+
1577+
dissipation_rho_v2 = (w1 * v2_minus_c +
1578+
w2 * v2_avg +
1579+
w3 * v2_plus_c +
1580+
lambda_4 * (entropy_var_rho_v2_jump -
1581+
unit_normal_direction[2] * entropy_var_v_normal_jump +
1582+
entropy_var_rho_e_jump * v2_tangential))
1583+
1584+
v_tangential_dot_entropy_vars_jump = v1_tangential * entropy_var_rho_v1_jump +
1585+
v2_tangential * entropy_var_rho_v2_jump
1586+
1587+
dissipation_rhoe = (w1 * (h_bar - c_bar * v_avg_normal) +
1588+
w2 * 0.5f0 * v_squared_bar +
1589+
w3 * (h_bar + c_bar * v_avg_normal) +
1590+
lambda_4 * (v_tangential_dot_entropy_vars_jump +
1591+
entropy_var_rho_e_jump *
1592+
(v1_avg^2 + v2_avg^2 - v_avg_normal^2)))
1593+
1594+
return -0.5f0 *
1595+
SVector(dissipation_rho, dissipation_rho_v1, dissipation_rho_v2,
1596+
dissipation_rhoe) * norm_
1597+
end
1598+
15101599
# Called inside `FluxRotated` in `numerical_fluxes.jl` so the direction
15111600
# has been normalized prior to this rotation of the state vector
15121601
@inline function rotate_to_x(u, normal_vector, equations::CompressibleEulerEquations2D)

src/equations/compressible_euler_3d.jl

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,100 @@ end
12371237
u[5])
12381238
end
12391239

1240+
@inline function (dissipation::DissipationMatrixWintersEtal)(u_ll, u_rr,
1241+
normal_direction::AbstractVector,
1242+
equations::CompressibleEulerEquations3D)
1243+
(; gamma) = equations
1244+
1245+
# Step 1:
1246+
# Rotate solution into the appropriate direction
1247+
1248+
norm_ = norm(normal_direction)
1249+
# Normalize the vector without using `normalize` since we need to multiply by the `norm_` later
1250+
normal_vector = normal_direction / norm_
1251+
1252+
# Some vector that can't be identical to normal_vector (unless normal_vector == 0)
1253+
tangent1 = SVector(normal_direction[2], normal_direction[3], -normal_direction[1])
1254+
# Orthogonal projection
1255+
tangent1 -= dot(normal_vector, tangent1) * normal_vector
1256+
tangent1 = normalize(tangent1)
1257+
1258+
# Third orthogonal vector
1259+
tangent2 = normalize(cross(normal_direction, tangent1))
1260+
1261+
u_ll_rotated = rotate_to_x(u_ll, normal_vector, tangent1, tangent2, equations)
1262+
u_rr_rotated = rotate_to_x(u_rr, normal_vector, tangent1, tangent2, equations)
1263+
1264+
# Step 2:
1265+
# Compute the averages using the rotated variables
1266+
rho_ll, v1_ll, v2_ll, v3_ll, p_ll = cons2prim(u_ll_rotated, equations)
1267+
rho_rr, v1_rr, v2_rr, v3_rr, p_rr = cons2prim(u_rr_rotated, equations)
1268+
1269+
b_ll = rho_ll / (2 * p_ll)
1270+
b_rr = rho_rr / (2 * p_rr)
1271+
1272+
rho_log = ln_mean(rho_ll, rho_rr)
1273+
b_log = ln_mean(b_ll, b_rr)
1274+
v1_avg = 0.5f0 * (v1_ll + v1_rr)
1275+
v2_avg = 0.5f0 * (v2_ll + v2_rr)
1276+
v3_avg = 0.5f0 * (v3_ll + v3_rr)
1277+
p_avg = 0.5f0 * (rho_ll + rho_rr) / (b_ll + b_rr)
1278+
v_squared_bar = v1_ll * v1_rr + v2_ll * v2_rr + v3_ll * v3_rr
1279+
h_bar = gamma / (2 * b_log * (gamma - 1)) + 0.5f0 * v_squared_bar
1280+
c_bar = sqrt(gamma * p_avg / rho_log)
1281+
1282+
# Step 3:
1283+
# Build the dissipation term as given in Appendix A of the paper
1284+
# - A. R. Winters, D. Derigs, G. Gassner, S. Walch, A uniquely defined entropy stable matrix dissipation operator
1285+
# for high Mach number ideal MHD and compressible Euler simulations (2017). Journal of Computational Physics.
1286+
# [DOI: 10.1016/j.jcp.2016.12.006](https://doi.org/10.1016/j.jcp.2016.12.006).
1287+
1288+
# Get entropy variables jump in the rotated variables
1289+
w_jump = cons2entropy(u_rr_rotated, equations) -
1290+
cons2entropy(u_ll_rotated, equations)
1291+
1292+
# Entries of the diagonal scaling matrix where D = ABS(\Lambda)T
1293+
lambda_1 = abs(v1_avg - c_bar) * rho_log / (2 * gamma)
1294+
lambda_2 = abs(v1_avg) * rho_log * (gamma - 1) / gamma
1295+
lambda_3 = abs(v1_avg) * p_avg # scaled repeated eigenvalue in the tangential direction
1296+
lambda_5 = abs(v1_avg + c_bar) * rho_log / (2 * gamma)
1297+
D = SVector(lambda_1, lambda_2, lambda_3, lambda_3, lambda_5)
1298+
1299+
# Entries of the right eigenvector matrix (others have already been precomputed)
1300+
r21 = v1_avg - c_bar
1301+
r25 = v1_avg + c_bar
1302+
r51 = h_bar - v1_avg * c_bar
1303+
r52 = 0.5f0 * v_squared_bar
1304+
r55 = h_bar + v1_avg * c_bar
1305+
1306+
# Build R and transpose of R matrices
1307+
R = @SMatrix [[1;; 1;; 0;; 0;; 1];
1308+
[r21;; v1_avg;; 0;; 0;; r25];
1309+
[v2_avg;; v2_avg;; 1;; 0;; v2_avg];
1310+
[v3_avg;; v3_avg;; 0;; 1;; v3_avg];
1311+
[r51;; r52;; v2_avg;; v3_avg;; r55]]
1312+
1313+
RT = @SMatrix [[1;; r21;; v2_avg;; v3_avg;; r51];
1314+
[1;; v1_avg;; v2_avg;; v3_avg;; r52];
1315+
[0;; 0;; 1;; 0;; v2_avg];
1316+
[0;; 0;; 0;; 1;; v3_avg];
1317+
[1;; r25;; v2_avg;; v3_avg;; r55]]
1318+
1319+
# Compute the dissipation term R * D * R^T * [[w]] from right-to-left
1320+
1321+
# First comes R^T * [[w]]
1322+
diss = RT * w_jump
1323+
# Next multiply with the eigenvalues and Barth scaling
1324+
diss = D .* diss
1325+
# Finally apply the remaining eigenvector matrix
1326+
diss = R * diss
1327+
1328+
# Step 4:
1329+
# Do not forget to backrotate and then return with proper normalization scaling
1330+
return -0.5f0 * rotate_from_x(diss, normal_vector, tangent1, tangent2, equations) *
1331+
norm_
1332+
end
1333+
12401334
# Rotate x-axis to normal vector; normal, tangent1 and tangent2 need to be orthonormal
12411335
# Called inside `FluxRotated` in `numerical_fluxes.jl` so the directions
12421336
# has been normalized prior to this back-rotation of the state vector

src/equations/numerical_fluxes.jl

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,54 @@ function Base.show(io::IO, d::DissipationLaxFriedrichsEntropyVariables)
261261
print(io, "DissipationLaxFriedrichsEntropyVariables(", d.max_abs_speed, ")")
262262
end
263263

264+
@doc raw"""
265+
DissipationMatrixWintersEtal()
266+
267+
Creates the Roe-like entropy-stable matrix dissipation operator from Winters et al. (2017). This operator
268+
must be used together with an entropy-conservative two-point flux function
269+
(e.g., [`flux_ranocha`](@ref) or [`flux_chandrashekar`](@ref)) to yield
270+
an entropy-stable surface flux. The surface flux function can be initialized as:
271+
```julia
272+
flux_es = FluxPlusDissipation(flux_ec, DissipationMatrixWintersEtal())
273+
```
274+
The 1D and 2D implementations are adapted from the [Atum.jl library](https://github.com/mwarusz/Atum.jl/blob/c7ed44f2b7972ac726ef345da7b98b0bda60e2a3/src/balancelaws/euler.jl#L198).
275+
The 3D implementation is adapted from the [FLUXO library](https://github.com/project-fluxo/fluxo)
276+
277+
For the derivation of the matrix dissipation operator, see:
278+
- A. R. Winters, D. Derigs, G. Gassner, S. Walch, A uniquely defined entropy stable matrix dissipation operator
279+
for high Mach number ideal MHD and compressible Euler simulations (2017). Journal of Computational Physics.
280+
[DOI: 10.1016/j.jcp.2016.12.006](https://doi.org/10.1016/j.jcp.2016.12.006).
281+
"""
282+
struct DissipationMatrixWintersEtal end
283+
284+
@inline function (dissipation::DissipationMatrixWintersEtal)(u_ll, u_rr,
285+
orientation::Integer,
286+
equations::AbstractEquations{1})
287+
return dissipation(u_ll, u_rr, SVector(1), equations)
288+
end
289+
290+
@inline function (dissipation::DissipationMatrixWintersEtal)(u_ll, u_rr,
291+
orientation::Integer,
292+
equations::AbstractEquations{2})
293+
if orientation == 1
294+
return dissipation(u_ll, u_rr, SVector(1, 0), equations)
295+
else # orientation == 2
296+
return dissipation(u_ll, u_rr, SVector(0, 1), equations)
297+
end
298+
end
299+
300+
@inline function (dissipation::DissipationMatrixWintersEtal)(u_ll, u_rr,
301+
orientation::Integer,
302+
equations::AbstractEquations{3})
303+
if orientation == 1
304+
return dissipation(u_ll, u_rr, SVector(1, 0, 0), equations)
305+
elseif orientation == 2
306+
return dissipation(u_ll, u_rr, SVector(0, 1, 0), equations)
307+
else # orientation == 3
308+
return dissipation(u_ll, u_rr, SVector(0, 0, 1), equations)
309+
end
310+
end
311+
264312
"""
265313
FluxHLL(min_max_speed=min_max_speed_davis)
266314

test/test_dgmulti_1d.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,26 @@ end
165165
end
166166
end
167167

168+
@trixi_testset "elixir_euler_modified_sod.jl" begin
169+
@test_trixi_include(joinpath(examples_dir(), "dgmulti_1d",
170+
"elixir_euler_modified_sod.jl"),
171+
cells_per_dimension=(16,),
172+
l2=[0.26352391505659767, 0.4528974787813885, 0.9310255091126164],
173+
linf=[
174+
0.6268146194274395,
175+
0.8214003799995101,
176+
1.8606901431409795
177+
])
178+
# Ensure that we do not have excessive memory allocations
179+
# (e.g., from type instabilities)
180+
let
181+
t = sol.t[end]
182+
u_ode = sol.u[end]
183+
du_ode = similar(u_ode)
184+
@test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000
185+
end
186+
end
187+
168188
@trixi_testset "elixir_euler_fdsbp_periodic.jl" begin
169189
@test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_fdsbp_periodic.jl"),
170190
l2=[

0 commit comments

Comments
 (0)