Skip to content

Commit bbe4872

Browse files
benegeeamrueda
andauthored
Add an MPI capable test case (#94)
* run the warm bubble test using a P4estMesh and compare to Trixi's TreeMesh version * switch to TrixiAtmo elixir * need to use Trixi initial condition * tolerances * add MPI test * !fixup * tolerances again * switch to recommended mpiexec syntax * add some safety measures from Trixi.jl * tolerance * fixed expected errors * remove surface_integral * remove dry bubble for serial tests * Revert "remove dry bubble for serial tests" This reverts commit fba9b73. * re-add test, but without polydeg override * check tighter tolerances * revert tolerance --------- Co-authored-by: Andrés Rueda-Ramírez <[email protected]>
1 parent a284e56 commit bbe4872

File tree

6 files changed

+115
-51
lines changed

6 files changed

+115
-51
lines changed

examples/elixir_moist_euler_dry_bubble.jl

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using OrdinaryDiffEq
1+
using OrdinaryDiffEqLowStorageRK
22
using Trixi
33
using TrixiAtmo
44
using TrixiAtmo: source_terms_geopotential, cons2drypot
@@ -48,10 +48,8 @@ end
4848

4949
initial_condition = initial_condition_warm_bubble
5050

51-
boundary_condition = (x_neg = boundary_condition_periodic,
52-
x_pos = boundary_condition_periodic,
53-
y_neg = boundary_condition_slip_wall,
54-
y_pos = boundary_condition_slip_wall)
51+
boundary_conditions = Dict(:y_neg => boundary_condition_slip_wall,
52+
:y_pos => boundary_condition_slip_wall)
5553

5654
# Gravity source since Q_ph=0
5755
source_term = source_terms_geopotential
@@ -70,18 +68,18 @@ volume_integral = VolumeIntegralFluxDifferencing(volume_flux)
7068
# and the EC flux (chandrashekar) as volume flux
7169
solver = DGSEM(basis, surface_flux, volume_integral)
7270

73-
coordinates_min = (0.0, 0.0)
74-
coordinates_max = (20000.0, 10000.0)
71+
coordinates_min = (0.0, -5000.0)
72+
coordinates_max = (20000.0, 15000.0)
7573

76-
cells_per_dimension = (64, 32)
77-
78-
# Create curved mesh with 64 x 32 elements
79-
mesh = StructuredMesh(cells_per_dimension, coordinates_min, coordinates_max,
80-
periodicity = (true, false))
74+
trees_per_dimension = (2, 2)
75+
mesh = P4estMesh(trees_per_dimension, polydeg = 1,
76+
coordinates_min = coordinates_min, coordinates_max = coordinates_max,
77+
initial_refinement_level = 5,
78+
periodicity = (true, false))
8179

8280
# A semidiscretization collects data structures and functions for the spatial discretization
8381
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,
84-
boundary_conditions = boundary_condition,
82+
boundary_conditions = boundary_conditions,
8583
source_terms = source_term)
8684

8785
###############################################################################

test/Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[deps]
2+
MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195"
23
NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56"
34
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
45
OrdinaryDiffEqLowStorageRK = "b0944070-b475-4768-8dec-fb6eb410534d"
@@ -8,6 +9,7 @@ Trixi = "a7f1ee26-1774-49b1-8366-f1abc58fbfcb"
89
TrixiTest = "0a316866-cbd0-4425-8bcb-08103b2c1f26"
910

1011
[compat]
12+
MPI = "0.20.6"
1113
NLsolve = "4.5.1"
1214
OrdinaryDiffEq = "6.91"
1315
OrdinaryDiffEqLowStorageRK = "1.2"

test/runtests.jl

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Test
2+
using MPI: mpiexec
23

34
# Trixi.jl runs tests in parallel with CI jobs setting the `TRIXI_TEST` environment
45
# variable to determine the subset of tests to execute.
@@ -9,6 +10,26 @@ const TRIXI_MPI_NPROCS = clamp(Sys.CPU_THREADS, 2, 3)
910
const TRIXI_NTHREADS = clamp(Sys.CPU_THREADS, 2, 3)
1011

1112
@time @testset verbose=true showtiming=true "TrixiAtmo.jl tests" begin
13+
# This is placed first since tests error out otherwise if `TRIXI_TEST == "all"`,
14+
# at least on some systems.
15+
@time if TRIXI_TEST == "all" || TRIXI_TEST == "mpi"
16+
# Do a dummy `@test true`:
17+
# If the process errors out the testset would error out as well,
18+
# cf. https://github.com/JuliaParallel/MPI.jl/pull/391
19+
@test true
20+
21+
run(`$(mpiexec()) -n $TRIXI_MPI_NPROCS $(Base.julia_cmd()) --threads=1 --check-bounds=yes $(abspath("test_mpi.jl"))`)
22+
end
23+
24+
@time if TRIXI_TEST == "all" || TRIXI_TEST == "threaded"
25+
# Do a dummy `@test true`:
26+
# If the process errors out the testset would error out as well,
27+
# cf. https://github.com/JuliaParallel/MPI.jl/pull/391
28+
@test true
29+
30+
run(`$(Base.julia_cmd()) --threads=$TRIXI_NTHREADS --check-bounds=yes --code-coverage=none $(abspath("test_threaded.jl"))`)
31+
end
32+
1233
@time if TRIXI_TEST == "all" || TRIXI_TEST == "trixi_consistency"
1334
include("test_trixi_consistency.jl")
1435
end
@@ -29,15 +50,6 @@ const TRIXI_NTHREADS = clamp(Sys.CPU_THREADS, 2, 3)
2950
include("test_2d_shallow_water_covariant.jl")
3051
end
3152

32-
@time if TRIXI_TEST == "all" || TRIXI_TEST == "threaded"
33-
# Do a dummy `@test true`:
34-
# If the process errors out the testset would error out as well,
35-
# cf. https://github.com/JuliaParallel/MPI.jl/pull/391
36-
@test true
37-
38-
run(`$(Base.julia_cmd()) --threads=$TRIXI_NTHREADS --check-bounds=yes --code-coverage=none $(abspath("test_threaded.jl"))`)
39-
end
40-
4153
@time if TRIXI_TEST == "upstream"
4254
include("test_trixi_consistency.jl")
4355
end

test/test_2d_moist_euler.jl

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,21 @@ EXAMPLES_DIR = TrixiAtmo.examples_dir()
1111
@test_trixi_include(joinpath(EXAMPLES_DIR,
1212
"elixir_moist_euler_dry_bubble.jl"),
1313
l2=[
14-
1.300428671901329e-6,
15-
2.601090012108739e-5,
16-
0.0006660124630171347,
17-
0.008969786054960861,
14+
9.103834949215729e-7,
15+
1.8209333828866736e-5,
16+
0.0004709417153612775,
17+
0.006342004383628925,
1818
0.0,
1919
0.0
2020
],
2121
linf=[
22-
1.0312042909910168e-5,
23-
0.00020625488871672815,
24-
0.006392107590872236,
25-
0.07612038028310053,
22+
1.0258282803210506e-5,
23+
0.0002051932980897675,
24+
0.006394867661494521,
25+
0.076401537633501,
2626
0.0,
2727
0.0
2828
],
29-
polydeg=3,
3029
tspan=(0.0, 0.1))
3130
# Ensure that we do not have excessive memory allocations
3231
# (e.g., from type instabilities)

test/test_mpi.jl

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
module TestMPI
2+
3+
using Test
4+
using TrixiAtmo
5+
6+
include("test_trixiatmo.jl")
7+
8+
# Start with a clean environment: remove Trixi.jl output directory if it exists
9+
outdir = "out"
10+
Trixi.mpi_isroot() && isdir(outdir) && rm(outdir, recursive = true)
11+
Trixi.MPI.Barrier(Trixi.mpi_comm())
12+
13+
# CI with MPI and some tests fails often on Windows. Thus, we check whether this
14+
# is the case here. We use GitHub Actions, so we can check whether we run CI
15+
# in the cloud with Windows as follows, see also
16+
# https://docs.github.com/en/actions/learn-github-actions/environment-variables
17+
CI_ON_WINDOWS = (get(ENV, "GITHUB_ACTIONS", false) == "true") && Sys.iswindows()
18+
19+
EXAMPLES_DIR = pkgdir(TrixiAtmo, "examples")
20+
21+
@testset "MPI tests" begin
22+
#! format: noindent
23+
24+
@trixiatmo_testset "elixir_moist_euler_moist_bubble" begin
25+
@test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_moist_euler_dry_bubble.jl"),
26+
l2=[
27+
9.103834949215729e-7,
28+
1.8209333828866736e-5,
29+
0.0004709417153612775,
30+
0.006342004383628925,
31+
0.0,
32+
0.0
33+
],
34+
linf=[
35+
1.0258282803210506e-5,
36+
0.0002051932980897675,
37+
0.006394867661494521,
38+
0.076401537633501,
39+
0.0,
40+
0.0
41+
],
42+
tspan=(0.0, 0.1))
43+
# Ensure that we do not have excessive memory allocations
44+
# (e.g., from type instabilities)
45+
let
46+
t = sol.t[end]
47+
u_ode = sol.u[end]
48+
du_ode = similar(u_ode)
49+
@test (@allocated TrixiAtmo.Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000
50+
end
51+
end
52+
end
53+
54+
# Clean up afterwards: delete Trixi.jl output directory
55+
Trixi.mpi_isroot() && @test_nowarn rm(outdir, recursive = true)
56+
Trixi.MPI.Barrier(Trixi.mpi_comm())
57+
58+
end # module

test/test_trixi_consistency.jl

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ isdir(outdir) && rm(outdir, recursive = true)
1111
@trixiatmo_testset "Dry air consistency check" begin
1212
# Dry air warm bubble test case in Trixi.jl
1313
maxiters = 100
14-
trixi_elixir = joinpath(Trixi.examples_dir(), "structured_2d_dgsem",
14+
trixi_elixir = joinpath(Trixi.examples_dir(), "tree_2d_dgsem",
1515
"elixir_euler_warm_bubble.jl")
1616

17-
# Override maxiter and fluxes
17+
# Override fluxes, polydeg, cfl, maxiters
1818
trixi_include(trixi_elixir;
1919
volume_flux = Trixi.flux_chandrashekar,
2020
surface_flux = Trixi.FluxLMARS(360.0),
21+
polydeg = 4,
22+
stepsize_callback = Trixi.StepsizeCallback(cfl = 0.2),
2123
maxiters = maxiters)
2224

2325
# Save errors
@@ -27,37 +29,30 @@ isdir(outdir) && rm(outdir, recursive = true)
2729
equations_trixi = Trixi.CompressibleEulerEquations2D(Main.warm_bubble_setup.gamma)
2830
add_zeros = SVector(zero(eltype(Main.sol)), zero(eltype(Main.sol)))
2931

30-
# Now use moist equations instead
31-
equations_moist = CompressibleMoistEulerEquations2D()
32-
33-
# Redefine source terms for CompressibleMoistEulerEquations2D
34-
@inline function (setup::Main.WarmBubbleSetup)(u, x, t,
35-
equations_moist::CompressibleMoistEulerEquations2D)
36-
ret_trixi = setup(u, x, t, equations_trixi)
37-
return vcat(ret_trixi, add_zeros)
38-
end
39-
40-
# Redefine initial condition for CompressibleMoistEulerEquations2D
32+
# Redefine initial condition in Trixi.jl for CompressibleMoistEulerEquations2D
33+
# Different formulae were used!
4134
@inline function (setup::Main.WarmBubbleSetup)(x, t,
42-
equations_moist::CompressibleMoistEulerEquations2D)
35+
::CompressibleMoistEulerEquations2D)
4336
ret_trixi = setup(x, t, equations_trixi)
4437
return vcat(ret_trixi, add_zeros)
4538
end
4639

47-
# Run again with overrides
48-
trixi_include(trixi_elixir,
49-
equations = equations_moist,
50-
volume_flux = flux_chandrashekar,
51-
surface_flux = FluxLMARS(360.0),
40+
# Now use the elixir in TrixiAtmo
41+
elixir_atmo = joinpath(TrixiAtmo.examples_dir(), "elixir_moist_euler_dry_bubble.jl")
42+
43+
# Override initial condition, maxiters
44+
trixi_include(elixir_atmo,
45+
initial_condition = Main.warm_bubble_setup,
5246
maxiters = maxiters)
5347

48+
# Save errors
5449
errors_atmo = Main.analysis_callback(Main.sol)
5550

5651
for (error_trixi, error_atmo) in zip(errors_trixi.l2, errors_atmo.l2)
5752
@test isapprox(error_trixi, error_atmo, rtol = 1e-12)
5853
end
5954
for (error_trixi, error_atmo) in zip(errors_trixi.linf, errors_atmo.linf)
60-
@test isapprox(error_trixi, error_atmo, rtol = 3e-12)
55+
@test isapprox(error_trixi, error_atmo, rtol = 1.1e-10)
6156
end
6257
end
6358
end

0 commit comments

Comments
 (0)