Skip to content

Commit 65f175f

Browse files
committed
test: refactor convergence module to match toolchain style
Apply the toolchain conventions (BenchCase pattern, MFCException, typing.List) to convergence.py and trim newcomer-hostile bits: - Replace dict-based spec with @dataclasses.dataclass ConvergenceSpec — fields and types are visible at the top of the module instead of scattered across .get(default) calls inside each runner. - Drop the _RUNNERS string registry; spec.runner is now a Callable, so cases.py just stores the function reference directly (run_h_sweep, run_dt_sweep, run_sod_l1). - Drop io.StringIO + redirect_stdout; runners build a list of lines and '\n'.join it. No stdlib magic. - Rename runners to verb-noun (run_h_sweep / run_dt_sweep / run_sod_l1). - Use common.MFCException for run failures (matches the rest of toolchain). - Add a module docstring that names the three flavours up front. - Rename time_mode='cell_shift' string flag → cell_shift int (0=period). - Rename temporal-spec field 'N' → 'fixed_N' for clarity. - Collapse cases.py registration into one loop driven by a small table of (schemes, dim_label, case_path, ndim, cons_vars, cell_shift, ppn) tuples. Same numerical results pre/post (verified 1D suite + Sod WENO1 + Temporal RK1).
1 parent 02df59d commit 65f175f

3 files changed

Lines changed: 294 additions & 347 deletions

File tree

toolchain/mfc/test/cases.py

Lines changed: 49 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from ..state import ARG
88
from .case import CaseGeneratorStack, Nt, TestCaseBuilder, define_case_d, define_case_f, define_convergence_case
9+
from .convergence import ConvergenceSpec, run_dt_sweep, run_h_sweep, run_sod_l1
910

1011
# Convergence test specs.
1112
# One TestCase per (problem, scheme) pair. Trace prefix "Convergence ->" is
@@ -92,81 +93,51 @@
9293
def add_convergence_cases(cases):
9394
num_ranks = 4
9495

95-
def _adv_spec(case_path, ndim, cons_vars, extra_args, expected, tol, resolutions, time_mode):
96-
# cell_shift forces num_ranks=1 inside the runner; period mode keeps the suite default.
97-
return {
98-
"runner": f"{ndim}d_advection",
99-
"case_path": case_path,
100-
"extra_args": extra_args,
101-
"expected_order": expected,
102-
"tol": tol,
103-
"resolutions": resolutions,
104-
"ndim": ndim,
105-
"domain_len": 1.0,
106-
"cons_vars": cons_vars,
107-
"primary_idx": 1,
108-
"num_ranks": num_ranks,
109-
"time_mode": time_mode,
110-
"cell_shift": 1,
111-
}
112-
113-
for label, extra_args, expected, tol, resolutions in _CONVERGENCE_1D_SCHEMES:
114-
cases.append(
115-
define_convergence_case(
116-
f"Convergence -> 1D -> {label}",
117-
spec=_adv_spec("examples/1D_euler_convergence/case.py", 1, _CONS_VARS_1D, extra_args, expected, tol, resolutions, "cell_shift"),
118-
ppn=1,
119-
)
120-
)
121-
for label, extra_args, expected, tol, resolutions in _CONVERGENCE_1D_PERIOD_SCHEMES:
122-
cases.append(
123-
define_convergence_case(
124-
f"Convergence -> 1D -> {label}",
125-
spec=_adv_spec("examples/1D_euler_convergence/case.py", 1, _CONS_VARS_1D, extra_args, expected, tol, resolutions, "period"),
126-
ppn=num_ranks,
127-
)
96+
def _h_sweep(case_path, ndim, cons_vars, extra_args, expected, tol, resolutions, cell_shift):
97+
return ConvergenceSpec(
98+
runner=run_h_sweep,
99+
case_path=case_path,
100+
extra_args=extra_args,
101+
expected_order=expected,
102+
tol=tol,
103+
cons_vars=cons_vars,
104+
resolutions=resolutions,
105+
ndim=ndim,
106+
cell_shift=cell_shift,
107+
num_ranks=num_ranks, # ignored by run_h_sweep when cell_shift > 0
128108
)
129109

130-
for label, extra_args, expected, tol, resolutions in _CONVERGENCE_2D_SCHEMES:
131-
cases.append(
132-
define_convergence_case(
133-
f"Convergence -> 2D -> {label}",
134-
spec=_adv_spec("examples/2D_advection_convergence/case.py", 2, _CONS_VARS_2D, extra_args, expected, tol, resolutions, "cell_shift"),
135-
ppn=1,
136-
)
137-
)
138-
for label, extra_args, expected, tol, resolutions in _CONVERGENCE_2D_PERIOD_SCHEMES:
139-
cases.append(
140-
define_convergence_case(
141-
f"Convergence -> 2D -> {label}",
142-
spec=_adv_spec("examples/2D_advection_convergence/case.py", 2, _CONS_VARS_2D, extra_args, expected, tol, resolutions, "period"),
143-
ppn=num_ranks,
144-
)
145-
)
146-
147-
for label, extra_args, expected, tol, resolutions in _CONVERGENCE_3D_SCHEMES:
148-
cases.append(
149-
define_convergence_case(
150-
f"Convergence -> 3D -> {label}",
151-
spec=_adv_spec("examples/3D_advection_convergence/case.py", 3, _CONS_VARS_3D, extra_args, expected, tol, resolutions, "cell_shift"),
152-
ppn=1,
110+
advection_groups = [
111+
(_CONVERGENCE_1D_SCHEMES, "1D", "examples/1D_euler_convergence/case.py", 1, _CONS_VARS_1D, 1, 1),
112+
(_CONVERGENCE_1D_PERIOD_SCHEMES, "1D", "examples/1D_euler_convergence/case.py", 1, _CONS_VARS_1D, 0, num_ranks),
113+
(_CONVERGENCE_2D_SCHEMES, "2D", "examples/2D_advection_convergence/case.py", 2, _CONS_VARS_2D, 1, 1),
114+
(_CONVERGENCE_2D_PERIOD_SCHEMES, "2D", "examples/2D_advection_convergence/case.py", 2, _CONS_VARS_2D, 0, num_ranks),
115+
(_CONVERGENCE_3D_SCHEMES, "3D", "examples/3D_advection_convergence/case.py", 3, _CONS_VARS_3D, 1, 1),
116+
]
117+
for schemes, dim_label, case_path, ndim, cons_vars, cell_shift, ppn in advection_groups:
118+
for label, extra_args, expected, tol, resolutions in schemes:
119+
cases.append(
120+
define_convergence_case(
121+
f"Convergence -> {dim_label} -> {label}",
122+
spec=_h_sweep(case_path, ndim, cons_vars, extra_args, expected, tol, resolutions, cell_shift),
123+
ppn=ppn,
124+
)
153125
)
154-
)
155126

156127
for label, extra_args, expected, tol, min_N in _CONVERGENCE_SOD_SCHEMES:
128+
resolutions = [N for N in _RES_SOD_DEFAULT if min_N is None or N >= min_N]
157129
cases.append(
158130
define_convergence_case(
159131
f"Convergence -> Sod -> {label}",
160-
spec={
161-
"runner": "sod_l1",
162-
"case_path": "examples/1D_sod_convergence/case.py",
163-
"extra_args": extra_args,
164-
"expected_order": expected,
165-
"tol": tol,
166-
"resolutions": _RES_SOD_DEFAULT,
167-
"min_N": min_N,
168-
"num_ranks": num_ranks,
169-
},
132+
spec=ConvergenceSpec(
133+
runner=run_sod_l1,
134+
case_path="examples/1D_sod_convergence/case.py",
135+
extra_args=extra_args,
136+
expected_order=expected,
137+
tol=tol,
138+
resolutions=resolutions,
139+
num_ranks=num_ranks,
140+
),
170141
ppn=num_ranks,
171142
)
172143
)
@@ -175,18 +146,17 @@ def _adv_spec(case_path, ndim, cons_vars, extra_args, expected, tol, resolutions
175146
cases.append(
176147
define_convergence_case(
177148
f"Convergence -> Temporal -> {label}",
178-
spec={
179-
"runner": "temporal",
180-
"case_path": "examples/1D_euler_convergence/case.py",
181-
"extra_args": extra_args,
182-
"expected_order": expected,
183-
"tol": tol,
184-
"cfls": cfls,
185-
"N": 512,
186-
"cons_vars": _CONS_VARS_1D,
187-
"primary_idx": 1,
188-
"num_ranks": num_ranks,
189-
},
149+
spec=ConvergenceSpec(
150+
runner=run_dt_sweep,
151+
case_path="examples/1D_euler_convergence/case.py",
152+
extra_args=extra_args,
153+
expected_order=expected,
154+
tol=tol,
155+
cons_vars=_CONS_VARS_1D,
156+
cfls=cfls,
157+
fixed_N=512,
158+
num_ranks=num_ranks,
159+
),
190160
ppn=num_ranks,
191161
)
192162
)

0 commit comments

Comments
 (0)