Skip to content

Commit 2e10911

Browse files
sbryngelsonclaude
andcommitted
Validate all example cases in CI and clean up non-standard case files
- Expand CI "Validate example cases" step from 2 hardcoded examples to all 134 examples/*/case.py files - Rename scaling/case.py to scaling/benchmark.py since it requires mandatory CLI args (--scaling, --memory) and is not a standard example - Remove 2D_phasechange_bubble/casefile.py (unreferenced duplicate of 3D_phasechange_bubble/case.py) - Fix 2D_bubbly_steady_shock/case.py missing nb in output dictionary - Add physics_constraints.md documentation - Update doc references to scaling/benchmark.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f7febe8 commit 2e10911

7 files changed

Lines changed: 363 additions & 308 deletions

File tree

.github/workflows/lint-toolchain.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,18 @@ jobs:
4242

4343
- name: Validate example cases
4444
run: |
45-
./mfc.sh validate examples/1D_sodshocktube/case.py
46-
./mfc.sh validate examples/2D_shockbubble/case.py
45+
failed=0
46+
passed=0
47+
for case in examples/*/case.py; do
48+
if ./mfc.sh validate "$case" > /dev/null 2>&1; then
49+
passed=$((passed + 1))
50+
else
51+
echo "FAIL: $case"
52+
failed=$((failed + 1))
53+
fi
54+
done
55+
echo ""
56+
echo "Results: $passed passed, $failed failed"
57+
if [ "$failed" -ne 0 ]; then
58+
exit 1
59+
fi

docs/documentation/case.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ To run such a case, use the following format:
6565
For example, to run the `scaling` case in "weak-scaling" mode:
6666

6767
```shell
68-
./mfc.sh run examples/scaling/case.py -t pre_process -j 8 -- --scaling weak
68+
./mfc.sh run examples/scaling/benchmark.py -t pre_process -j 8 -- --scaling weak
6969
```
7070

7171
## Parameters
Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
@page physics_constraints Physics Constraints
2+
3+
# Physics Constraints Reference
4+
5+
This document catalogs the physics constraints enforced by MFC's case parameter validator.
6+
Constraints are organized by physical category with mathematical justifications.
7+
For parameter syntax and allowed values, see @ref case "Case Files" and the @ref parameters "Case Parameters" reference.
8+
9+
The validator lives in `toolchain/mfc/case_validator.py` and runs automatically before each MFC stage.
10+
Hard constraint violations produce **errors** that abort the run.
11+
Soft constraint violations produce **warnings** that flag likely mistakes without stopping execution.
12+
13+
---
14+
15+
## 1. Thermodynamic Constraints
16+
17+
### 1.1 Positive Pressure
18+
19+
\f[p > 0\f]
20+
21+
All initial patch pressures (`patch_icpp(i)%pres`) must be strictly positive.
22+
Negative or zero pressure is unphysical for the stiffened gas and other equation-of-state models used by MFC.
23+
24+
**Stage:** pre_process | **Severity:** error
25+
26+
### 1.2 Non-negative Density
27+
28+
\f[\alpha_i \rho_i \geq 0\f]
29+
30+
Partial densities (`patch_icpp(i)%alpha_rho(j)`) must be non-negative.
31+
Zero partial density is allowed for vacuum regions.
32+
33+
**Stage:** pre_process | **Severity:** error
34+
35+
### 1.3 EOS Parameter Sanity (Transformed Gamma)
36+
37+
MFC uses the **transformed** stiffened gas parameter:
38+
39+
\f[\Gamma = \frac{1}{\gamma - 1}\f]
40+
41+
where \f$\gamma\f$ is the physical specific heat ratio.
42+
A common mistake is entering the physical \f$\gamma\f$ directly (e.g., 1.4 for air) instead of the transformed value \f$1/(1.4-1) = 2.5\f$.
43+
44+
The validator warns when:
45+
- `fluid_pp(i)%gamma < 0.1` (implies physical \f$\gamma > 11\f$, unusually high)
46+
- `fluid_pp(i)%gamma > 1000` (implies physical \f$\gamma \approx 1.001\f$, unusually close to 1)
47+
48+
Similarly, `pi_inf` is stored as \f$\gamma \pi_\infty / (\gamma - 1)\f$.
49+
50+
**Stage:** common (all stages) | **Severity:** warning
51+
52+
### 1.4 Stiffened EOS Positivity
53+
54+
\f[\Gamma > 0, \quad \Pi_\infty \geq 0, \quad c_v \geq 0\f]
55+
56+
The equation-of-state parameters `fluid_pp(i)%gamma`, `fluid_pp(i)%pi_inf`, and `fluid_pp(i)%cv` must satisfy basic positivity requirements for thermodynamic stability.
57+
58+
**Stage:** common | **Severity:** error
59+
60+
---
61+
62+
## 2. Mixture Constraints
63+
64+
### 2.1 Volume Fraction Sum
65+
66+
For multi-component models (`model_eqns` \f$\in \{2, 3, 4\}\f$), the volume fractions must satisfy the mixture constraint:
67+
68+
\f[\sum_{i=1}^{N_f} \alpha_i = 1\f]
69+
70+
The validator checks this per patch and warns if the deviation exceeds \f$10^{-6}\f$.
71+
72+
**Exceptions** (constraint does not apply):
73+
- Single-fluid Euler-Euler bubble models (`bubbles_euler = T`, `num_fluids = 1`): \f$\alpha\f$ represents void fraction
74+
- Lagrangian bubble models (`bubbles_lagrange = T`): Lagrangian phase is not tracked on the Euler grid
75+
- IBM cases (`num_ibs > 0`): \f$\alpha\f$ acts as a level-set indicator
76+
- Alter patches and hard-coded IC (hcid) patches: values are computed at runtime
77+
- Analytical expressions (strings): cannot be validated statically
78+
79+
**Stage:** pre_process | **Severity:** warning
80+
81+
### 2.2 Alpha-Rho Consistency
82+
83+
The validator warns about physically inconsistent combinations:
84+
85+
- \f$\alpha_j = 0\f$ but \f$\alpha_j \rho_j \neq 0\f$: density assigned to an absent phase
86+
- \f$\alpha_j > 10^{-10}\f$ but \f$\alpha_j \rho_j = 0\f$: present phase has zero density
87+
88+
These are not strictly errors (the solver can handle them) but usually indicate a configuration mistake.
89+
90+
**Stage:** pre_process | **Severity:** warning
91+
92+
### 2.3 Volume Fraction Bounds
93+
94+
\f[0 \leq \alpha_i \leq 1\f]
95+
96+
Individual volume fractions must be non-negative and (in non-IBM cases) at most 1.
97+
98+
**Stage:** pre_process | **Severity:** error
99+
100+
---
101+
102+
## 3. Domain and Geometry Constraints
103+
104+
### 3.1 Domain Bounds
105+
106+
For each active spatial dimension:
107+
108+
\f[x_{\mathrm{end}} > x_{\mathrm{beg}}, \quad y_{\mathrm{end}} > y_{\mathrm{beg}}, \quad z_{\mathrm{end}} > z_{\mathrm{beg}}\f]
109+
110+
The domain must have positive extent. A reversed or zero-width domain is always a configuration error.
111+
112+
**Stage:** common | **Severity:** error
113+
114+
### 3.2 Positive Patch Dimensions
115+
116+
Patch geometry parameters (`length_x`, `length_y`, `length_z`, `radius`) must be positive.
117+
Exception: in cylindrical coordinates, `length_y` and `length_z` may use sentinel values.
118+
119+
**Stage:** pre_process | **Severity:** error
120+
121+
### 3.3 Patch Within Domain
122+
123+
For patches with centroid + length geometry (line segments, rectangles, cuboids), the validator checks that the patch bounding box is not entirely outside the computational domain.
124+
125+
Skipped when grid stretching is active (physical coordinates are transformed).
126+
127+
**Stage:** pre_process | **Severity:** error
128+
129+
### 3.4 Dimensionality
130+
131+
- \f$m > 0\f$ is required (x-direction must have cells)
132+
- \f$n \geq 0\f$, \f$p \geq 0\f$
133+
- If \f$n = 0\f$ then \f$p = 0\f$ (cannot have z without y)
134+
- Cylindrical coordinates (\f$p > 0\f$): \f$p\f$ must be odd
135+
136+
**Stage:** common | **Severity:** error
137+
138+
---
139+
140+
## 4. Velocity and Dimensional Consistency
141+
142+
### 4.1 Velocity Components in Inactive Dimensions
143+
144+
\f[n = 0 \implies v_{2} = 0, \quad p = 0 \implies v_{3} = 0\f]
145+
146+
Setting velocity components in dimensions that do not exist is almost certainly a mistake.
147+
148+
**Exception:** MHD simulations legitimately use transverse velocity components in 1D because they carry transverse momentum coupled to the magnetic field.
149+
150+
**Stage:** pre_process | **Severity:** error
151+
152+
### 4.2 Momentum and Velocity Output Constraints
153+
154+
Post-process outputs `mom_wrt(2)`, `vel_wrt(2)` require \f$n > 0\f$; `mom_wrt(3)`, `vel_wrt(3)` require \f$p > 0\f$.
155+
156+
**Stage:** post_process | **Severity:** error
157+
158+
---
159+
160+
## 5. Model Equation Compatibility
161+
162+
### 5.1 Model Selection
163+
164+
| `model_eqns` | Name | \f$N_f\f$ | Key requirement |
165+
|:---:|------|:---:|-------|
166+
| 1 | \f$\gamma\f$-law (single-fluid) | not set | No `num_fluids`, no bubbles, no `fluid_pp` |
167+
| 2 | Five-equation (\cite Allaire02) | \f$\geq 1\f$ | Primary workhorse model |
168+
| 3 | Six-equation (\cite Saurel09) | \f$\geq 1\f$ | `riemann_solver = 2`, `avg_state = 2`, `wave_speeds = 1` |
169+
| 4 | Four-equation | \f$= 1\f$ | Single-component with bubbles |
170+
171+
### 5.2 Key Incompatibilities
172+
173+
- `model_eqns = 1`: no `mpp_lim`, no viscosity Re parameters, no volume fraction output
174+
- `model_eqns = 3`: no cylindrical 3D, no bubble models, requires HLLC solver
175+
- `model_eqns = 4`: requires `num_fluids = 1`, bubble-specific
176+
177+
**Stage:** common | **Severity:** error
178+
179+
---
180+
181+
## 6. Boundary Conditions
182+
183+
### 6.1 Periodicity Matching
184+
185+
If one end of a dimension is periodic (`bc = -1`), the other end must also be periodic.
186+
187+
### 6.2 Boundary Condition Range
188+
189+
Valid BC values range from \f$-1\f$ to \f$-17\f$:
190+
191+
| Value | Boundary Type |
192+
|:---:|------|
193+
| -1 | Periodic |
194+
| -2 | Reflective (slip wall) |
195+
| -3 | Extrapolation (ghost cell) |
196+
| -4 | Thompson (non-reflecting, sim only) |
197+
| -5 to -12 | Characteristic BCs |
198+
| -14 | Axis (cylindrical only) |
199+
| -15 to -17 | Additional wall types |
200+
201+
### 6.3 Cylindrical Coordinate BCs
202+
203+
- 2D cylindrical (\f$p = 0\f$): `bc_y%beg = -2` (reflective at axis)
204+
- 3D cylindrical (\f$p > 0\f$): `bc_y%beg = -14` (axis BC)
205+
- 3D cylindrical z-direction: only periodic (-1) or reflective (-2)
206+
207+
**Stage:** common | **Severity:** error
208+
209+
---
210+
211+
## 7. Bubble Physics Constraints
212+
213+
### 7.1 Euler-Euler Bubbles (`bubbles_euler`)
214+
215+
- `nb >= 1` (number of bubble bins)
216+
- Polydisperse requires odd `nb > 1` and `poly_sigma > 0`
217+
- Not tested with `model_eqns` 1 or 3
218+
- Reference quantities (`rhoref`, `pref`, `bub_pp%R0ref`, etc.) must be positive when set
219+
- QBMM requires `nnode = 4`
220+
221+
### 7.2 Simulation-Specific Bubble Constraints
222+
223+
- Requires HLLC Riemann solver (`riemann_solver = 2`)
224+
- Requires arithmetic average (`avg_state = 2`)
225+
- Five-equation model does not support Gilmore (`bubble_model = 1`)
226+
- Cannot use both `bubbles_euler` and `bubbles_lagrange` simultaneously
227+
228+
### 7.3 Euler-Lagrange Bubbles (`bubbles_lagrange`)
229+
230+
- 2D/3D only (`n > 0`)
231+
- `file_per_process = F`
232+
- Not compatible with `model_eqns = 3`
233+
- Requires `polytropic = F` and `thermal = 3`
234+
235+
**Stage:** common + simulation | **Severity:** error
236+
237+
---
238+
239+
## 8. Feature Compatibility Matrix
240+
241+
Several physics models have mutual exclusion constraints. The key incompatibilities:
242+
243+
| Feature | Model | Riemann Solver | Other |
244+
|---------|-------|---------------|-------|
245+
| **MHD** | `= 2`, `num_fluids = 1` | HLL (1) or HLLD (4) | No relativity+HLLD |
246+
| **Surface tension** | `= 2` or `= 3`, `num_fluids = 2` |||
247+
| **Hypoelasticity** | `= 2` | HLL (1) ||
248+
| **Hyperelasticity** | `= 2` or `= 3` |||
249+
| **Phase change** | `= 2` (relax 5,6) or `= 3` (relax 1,4,5,6) |||
250+
| **Alt sound speed** | `= 2`, `num_fluids` 2–3 | HLLC (2) | No bubbles |
251+
| **IGR** | `= 2` | No characteristic BCs | No bubbles, MHD, elastic, etc. |
252+
253+
**Stage:** common + simulation | **Severity:** error
254+
255+
---
256+
257+
## 9. Numerical Scheme Constraints
258+
259+
### 9.1 WENO Reconstruction (`recon_type = 1`)
260+
261+
- `weno_order` \f$\in \{1, 3, 5, 7\}\f$
262+
- Grid must have enough cells: \f$m + 1 \geq\f$ `num_stcls_min * weno_order`
263+
- Schemes are mutually exclusive: only one of `mapped_weno`, `wenoz`, `teno`
264+
- `teno` requires order 5 or 7; `mp_weno` requires order 5
265+
266+
### 9.2 MUSCL Reconstruction (`recon_type = 2`)
267+
268+
- `muscl_order` \f$\in \{1, 2\}\f$
269+
- Second order requires `muscl_lim` \f$\in \{1, 2, 3, 4, 5\}\f$
270+
- THINC interface compression (`int_comp`) requires MUSCL
271+
272+
### 9.3 Time Stepping
273+
274+
- `time_stepper` \f$\in \{1, 2, 3\}\f$
275+
- `dt > 0` required for fixed time stepping
276+
- CFL-based modes: `cfl_target` \f$\in (0, 1]\f$, `t_save \leq\f$ `t_stop`
277+
- Adaptive dt (`adap_dt`): requires RK3, `polytropic = T` or `bubbles_lagrange = T`
278+
279+
### 9.4 Viscosity
280+
281+
- Reynolds numbers `Re(1)`, `Re(2)` must be positive
282+
- Requires `viscous = T`
283+
- Not supported with `model_eqns = 1`
284+
- `weno_order = 1` without `weno_avg` does not support viscosity (unless IGR)
285+
286+
**Stage:** simulation | **Severity:** error
287+
288+
---
289+
290+
## 10. Acoustic Source Constraints
291+
292+
Acoustic sources have dimension-specific support types:
293+
294+
| Dimension | Allowed `support` values |
295+
|:---------:|:----------------------:|
296+
| 1D | 1 |
297+
| 2D | 2, 5, 6, 9, 10 |
298+
| 2D (cyl) | 2, 6, 10 |
299+
| 3D | 3, 7, 11 |
300+
301+
Additional constraints:
302+
- `pulse` \f$\in \{1, 2, 3, 4\}\f$
303+
- Sinusoidal/square (1, 3): exactly one of `frequency` or `wavelength`
304+
- Gaussian (2): exactly one of `gauss_sigma_time` or `gauss_sigma_dist`, plus `delay`
305+
- Broadband (4): requires `bb_num_freq`, `bb_bandwidth`, `bb_lowest_freq`
306+
- Non-planar sources (`support >= 5`): require `foc_length` and `aperture`
307+
308+
**Stage:** simulation | **Severity:** error
309+
310+
---
311+
312+
## 11. Post-Processing Constraints
313+
314+
### 11.1 Vorticity and Schlieren
315+
316+
- `omega_wrt` and `schlieren_wrt` require at least 2D (\f$n > 0\f$)
317+
- 3D vorticity components (`omega_wrt(1)`, `omega_wrt(2)`) require \f$p > 0\f$
318+
- Both require `fd_order` to be set
319+
320+
### 11.2 FFT Output
321+
322+
- Requires 3D (\f$n > 0\f$, \f$p > 0\f$)
323+
- All boundaries must be periodic
324+
- Global dimensions must be even
325+
- Incompatible with cylindrical coordinates
326+
327+
### 11.3 Output Selection
328+
329+
At least one flow variable must be selected for post-processing output.
330+
331+
**Stage:** post_process | **Severity:** error
332+
333+
---
334+
335+
## References
336+
337+
The physics models and their constraints are described in detail in:
338+
339+
- \cite Wilfong26 — MFC 5.0: comprehensive description of all models
340+
- \cite Bryngelson21 — MFC: An open-source high-order multi-component, multi-phase, and multi-scale compressible flow solver
341+
- \cite Allaire02 — Five-equation model for compressible two-phase flow
342+
- \cite Saurel09 — Six-equation model with relaxation
343+
- \cite Kapila01 — Two-phase modeling with interface mechanics
344+
345+
For the auto-generated constraint reference with compatibility tables and working examples, see @ref case_constraints "Case Creator Guide".

examples/2D_bubbly_steady_shock/case.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@
155155
"fluid_pp(1)%pi_inf": gam_l * (pi_inf_l) / (gam_l - 1.0),
156156
# Bubbles
157157
"bubbles_euler": "T",
158+
"nb": nb,
158159
"bubble_model": 2,
159160
"polytropic": "T",
160161
"polydisperse": "F",

0 commit comments

Comments
 (0)