1212# the filter handle (`./mfc.sh test --only Convergence`); convergence cases
1313# are skipped by default.
1414
15- # 1D Euler advection (rho = 1 + 0.2*sin(2*pi*x), u=1, p=1, T=1):
16- # WENO5/TENO5 use CFL=0.02 so RK3 temporal floor is below O(h^5) at N>=128.
17- # WENO7/TENO7 cap at N=128 and use CFL=0.005 (machine-precision floor near N=512).
18- # WENO3-JS degrades to 2nd order at smooth extrema (Henrick et al. 2005).
19- # MUSCL2 uses unlimited slope (limiters clip to 1st order at smooth extrema).
15+ # Advection convergence cases use cell-shift mode by default: T = K*h per
16+ # resolution, compare q(T) to np.roll(q(0), -K) per dim. Spatial error scales
17+ # as T*h^p = h^(p+1), so measured rate = p+1 (p = scheme order). Wins ~10-100x
18+ # vs running a full period since Nt = K*c/CFL is independent of N.
19+ # WENO7/TENO7 stay in period mode: at typical N their cell-shift error hits
20+ # machine precision (h^8 < 1e-15 at N=64) before any rate signal develops.
2021_CONS_VARS_1D = [("density" , 1 ), ("x-momentum" , 2 ), ("energy" , 3 )]
21- _RES_1D_DEFAULT = [64 , 128 , 256 , 512 , 1024 ]
22+ _CONS_VARS_2D = [("density" , 1 ), ("energy" , 4 )]
23+ _CONS_VARS_3D = [("density" , 1 ), ("energy" , 5 )]
24+
25+ # (label, extra_args, expected_order, tol, resolutions)
26+ # expected_order = scheme order p + 1 in cell-shift mode (T scales with h).
27+ # WENO3-JS reduces to 2 at smooth extrema → cell-shift expected = 3.
28+ # MUSCL2 unlimited central → effective order 2 → cell-shift expected = 3.
2229_CONVERGENCE_1D_SCHEMES = [
23- ("WENO5" , ["--order" , "5" , "--cfl" , "0.02" ], 5 , 0.2 , 128 , 512 ),
24- ("WENO3" , ["--order" , "3" , "--cfl" , "0.02" ], 2 , 0.2 , 256 , None ),
25- ("WENO1" , ["--order" , "1" , "--cfl" , "0.02" ], 1 , 0.05 , 128 , None ),
26- ("MUSCL2" , ["--muscl" , "--muscl-lim" , "0" , "--cfl" , "0.02" ], 2 , 0.1 , 128 , None ),
27- ("TENO5" , ["--order" , "5" , "--teno" , "--teno-ct" , "1e-6" , "--cfl" , "0.02" ], 5 , 0.2 , 128 , 512 ),
28- ("WENO7" , ["--order" , "7" , "--cfl" , "0.005" ], 7 , 0.5 , 64 , 128 ),
29- ("TENO7" , ["--order" , "7" , "--teno" , "--teno-ct" , "1e-9" , "--cfl" , "0.005" ], 7 , 0.5 , 64 , 128 ),
30+ ("WENO5" , ["--order" , "5" , "--cfl" , "0.02" ], 6 , 0.3 , [32 , 64 , 128 ]),
31+ ("WENO3" , ["--order" , "3" , "--cfl" , "0.02" ], 2.5 , 0.3 , [64 , 128 , 256 ]),
32+ ("WENO1" , ["--order" , "1" , "--cfl" , "0.02" ], 2 , 0.2 , [64 , 128 , 256 ]),
33+ ("MUSCL2" , ["--muscl" , "--muscl-lim" , "0" , "--cfl" , "0.02" ], 3 , 0.3 , [64 , 128 , 256 ]),
34+ ("TENO5" , ["--order" , "5" , "--teno" , "--teno-ct" , "1e-6" , "--cfl" , "0.02" ], 6 , 0.3 , [32 , 64 , 128 ]),
35+ ]
36+ # WENO7/TENO7 in 1D: period mode (full period T=1.0, see 1D case.py).
37+ _CONVERGENCE_1D_PERIOD_SCHEMES = [
38+ ("WENO7" , ["--order" , "7" , "--cfl" , "0.005" ], 7 , 0.5 , [64 , 128 ]),
39+ ("TENO7" , ["--order" , "7" , "--teno" , "--teno-ct" , "1e-9" , "--cfl" , "0.005" ], 7 , 0.5 , [64 , 128 ]),
3040]
3141
32- # 2D diagonal advection (rho = 1 + 0.2 sin(2pi(x+y)), v=(1,1), period T=0.5):
33- # linear primitives mean no covariance floor — clean asymptotic rates for all
34- # WENO/MUSCL/TENO orders. WENO3 reduces to 2nd at smooth extrema (Henrick 2005).
35- # 4 ranks (2x2 decomp): per-rank stencil constraint n+1 >= 5*weno_order/2.
36- # WENO5/TENO5 use [64, 96, 128] (33>=25 at N=64). WENO7/TENO7 use [80, 96]
37- # (41>=35 at N=80) and CFL=0.005 to push RK3 temporal error below O(h^7).
38- # (label, extra_args, expected_order, tol, resolutions)
39- _CONS_VARS_2D = [("density" , 1 ), ("energy" , 4 )]
4042_CONVERGENCE_2D_SCHEMES = [
41- ("WENO5" , ["--order" , "5" , "--cfl" , "0.02" ], 5 , 0.3 , [64 , 96 , 128 ]),
42- ("WENO3" , ["--order" , "3" , "--cfl" , "0.02" ], 2 , 0.3 , [32 , 64 , 128 ]),
43- ("WENO1" , ["--order" , "1" , "--cfl" , "0.02" ], 1 , 0.2 , [32 , 64 , 128 ]),
44- ("MUSCL2" , ["--muscl" , "--muscl-lim" , "0" , "--cfl" , "0.02" ], 2 , 0.1 , [32 , 64 , 128 ]),
45- ("TENO5" , ["--order" , "5" , "--teno" , "--teno-ct" , "1e-6" , "--cfl" , "0.02" ], 5 , 0.3 , [64 , 96 , 128 ]),
43+ ("WENO5" , ["--order" , "5" , "--cfl" , "0.02" ], 6 , 0.3 , [32 , 64 , 96 ]),
44+ ("WENO3" , ["--order" , "3" , "--cfl" , "0.02" ], 2.5 , 0.3 , [32 , 64 , 128 ]),
45+ ("WENO1" , ["--order" , "1" , "--cfl" , "0.02" ], 2 , 0.2 , [32 , 64 , 128 ]),
46+ ("MUSCL2" , ["--muscl" , "--muscl-lim" , "0" , "--cfl" , "0.02" ], 3 , 0.3 , [32 , 64 , 128 ]),
47+ ("TENO5" , ["--order" , "5" , "--teno" , "--teno-ct" , "1e-6" , "--cfl" , "0.02" ], 6 , 0.3 , [32 , 64 , 96 ]),
48+ ]
49+ _CONVERGENCE_2D_PERIOD_SCHEMES = [
4650 ("WENO7" , ["--order" , "7" , "--cfl" , "0.005" ], 7 , 0.5 , [80 , 96 ]),
4751 ("TENO7" , ["--order" , "7" , "--teno" , "--teno-ct" , "1e-9" , "--cfl" , "0.005" ], 7 , 0.5 , [80 , 96 ]),
4852]
4953
54+ # 3D diagonal advection: only cell-shift mode (period T=1/3 with N^3 cells
55+ # would dominate CI even at N=64). WENO7/TENO7 skipped — at N=64 with K=1
56+ # the spatial error signal is below machine precision.
57+ _CONVERGENCE_3D_SCHEMES = [
58+ ("WENO5" , ["--order" , "5" , "--cfl" , "0.02" ], 6 , 0.3 , [32 , 64 ]),
59+ ("WENO3" , ["--order" , "3" , "--cfl" , "0.02" ], 2.5 , 0.3 , [32 , 64 ]),
60+ ("WENO1" , ["--order" , "1" , "--cfl" , "0.02" ], 2 , 0.2 , [32 , 64 ]),
61+ ("MUSCL2" , ["--muscl" , "--muscl-lim" , "0" , "--cfl" , "0.02" ], 3 , 0.3 , [32 , 64 ]),
62+ ("TENO5" , ["--order" , "5" , "--teno" , "--teno-ct" , "1e-6" , "--cfl" , "0.02" ], 6 , 0.3 , [32 , 64 ]),
63+ ]
64+
5065# Sod L1 self-convergence: any conservative monotone scheme converges at L1
5166# rate ~1 (Godunov). SUPERBEE is over-compressive; min_N=128 skips its
5267# pre-asymptotic point.
7186 ("RK3" , ["--order" , "5" , "--time-stepper" , "3" ], 3 , 0.3 , [0.50 , 0.25 ]),
7287]
7388
74- # 2D diagonal advection (smooth density wave; no covariance floor): exercises
75- # WENO7 / TENO7 in 2D. CFL=0.005 keeps RK3 temporal error below O(h^7).
76- # With 4 ranks (2x2 decomp) the per-rank stencil constraint n+1 >= 5*weno_order=35
77- # sets min_N=70 (rounded up to 80). N capped at 96 to keep CI cost reasonable:
78- # 7th-order error scaling between N=80 and N=96 is ~3.6x, well above the
79- # machine-precision floor and clean for rate measurement.
80- _RES_2D_ADV_DEFAULT = [80 , 96 ]
81- _CONVERGENCE_2D_ADV_SCHEMES = [
82- ("WENO7" , ["--order" , "7" , "--cfl" , "0.005" ], 7 , 0.5 , 80 , 96 ),
83- ("TENO7" , ["--order" , "7" , "--teno" , "--teno-ct" , "1e-9" , "--cfl" , "0.005" ], 7 , 0.5 , 80 , 96 ),
84- ]
85-
8689
8790def add_convergence_cases (cases ):
8891 num_ranks = 4
8992
90- for label , extra_args , expected , tol , min_N , max_N in _CONVERGENCE_1D_SCHEMES :
93+ def _adv_spec (case_path , ndim , cons_vars , extra_args , expected , tol , resolutions , time_mode ):
94+ # cell_shift forces num_ranks=1 inside the runner; period mode keeps the suite default.
95+ return {
96+ "runner" : f"{ ndim } d_advection" ,
97+ "case_path" : case_path ,
98+ "extra_args" : extra_args ,
99+ "expected_order" : expected ,
100+ "tol" : tol ,
101+ "resolutions" : resolutions ,
102+ "ndim" : ndim ,
103+ "domain_len" : 1.0 ,
104+ "cons_vars" : cons_vars ,
105+ "primary_idx" : 1 ,
106+ "num_ranks" : num_ranks ,
107+ "time_mode" : time_mode ,
108+ "cell_shift" : 1 ,
109+ }
110+
111+ for label , extra_args , expected , tol , resolutions in _CONVERGENCE_1D_SCHEMES :
91112 cases .append (
92113 define_convergence_case (
93114 f"Convergence -> 1D -> { label } " ,
94- spec = {
95- "runner" : "1d_advection" ,
96- "case_path" : "examples/1D_euler_convergence/case.py" ,
97- "extra_args" : extra_args ,
98- "expected_order" : expected ,
99- "tol" : tol ,
100- "resolutions" : _RES_1D_DEFAULT ,
101- "min_N" : min_N ,
102- "max_N" : max_N ,
103- "ndim" : 1 ,
104- "domain_len" : 1.0 ,
105- "cons_vars" : _CONS_VARS_1D ,
106- "primary_idx" : 1 ,
107- "num_ranks" : num_ranks ,
108- },
115+ spec = _adv_spec ("examples/1D_euler_convergence/case.py" , 1 , _CONS_VARS_1D , extra_args , expected , tol , resolutions , "cell_shift" ),
116+ ppn = 1 ,
117+ )
118+ )
119+ for label , extra_args , expected , tol , resolutions in _CONVERGENCE_1D_PERIOD_SCHEMES :
120+ cases .append (
121+ define_convergence_case (
122+ f"Convergence -> 1D -> { label } " ,
123+ spec = _adv_spec ("examples/1D_euler_convergence/case.py" , 1 , _CONS_VARS_1D , extra_args , expected , tol , resolutions , "period" ),
109124 ppn = num_ranks ,
110125 )
111126 )
@@ -114,23 +129,28 @@ def add_convergence_cases(cases):
114129 cases .append (
115130 define_convergence_case (
116131 f"Convergence -> 2D -> { label } " ,
117- spec = {
118- "runner" : "2d_advection" ,
119- "case_path" : "examples/2D_advection_convergence/case.py" ,
120- "extra_args" : extra_args ,
121- "expected_order" : expected ,
122- "tol" : tol ,
123- "resolutions" : resolutions ,
124- "ndim" : 2 ,
125- "domain_len" : 1.0 ,
126- "cons_vars" : _CONS_VARS_2D ,
127- "primary_idx" : 1 ,
128- "num_ranks" : num_ranks ,
129- },
132+ spec = _adv_spec ("examples/2D_advection_convergence/case.py" , 2 , _CONS_VARS_2D , extra_args , expected , tol , resolutions , "cell_shift" ),
133+ ppn = 1 ,
134+ )
135+ )
136+ for label , extra_args , expected , tol , resolutions in _CONVERGENCE_2D_PERIOD_SCHEMES :
137+ cases .append (
138+ define_convergence_case (
139+ f"Convergence -> 2D -> { label } " ,
140+ spec = _adv_spec ("examples/2D_advection_convergence/case.py" , 2 , _CONS_VARS_2D , extra_args , expected , tol , resolutions , "period" ),
130141 ppn = num_ranks ,
131142 )
132143 )
133144
145+ for label , extra_args , expected , tol , resolutions in _CONVERGENCE_3D_SCHEMES :
146+ cases .append (
147+ define_convergence_case (
148+ f"Convergence -> 3D -> { label } " ,
149+ spec = _adv_spec ("examples/3D_advection_convergence/case.py" , 3 , _CONS_VARS_3D , extra_args , expected , tol , resolutions , "cell_shift" ),
150+ ppn = 1 ,
151+ )
152+ )
153+
134154 for label , extra_args , expected , tol , min_N in _CONVERGENCE_SOD_SCHEMES :
135155 cases .append (
136156 define_convergence_case (
@@ -1747,6 +1767,7 @@ def foreach_example():
17471767 "1D_advection_convergence" ,
17481768 "1D_sod_convergence" ,
17491769 "2D_advection_convergence" ,
1770+ "3D_advection_convergence" ,
17501771 "2D_zero_circ_vortex_analytical" ,
17511772 "3D_TaylorGreenVortex_analytical" ,
17521773 "3D_IGR_TaylorGreenVortex_nvidia" ,
0 commit comments