Skip to content

Commit f5317ff

Browse files
Fahad NabidFahad Nabid
authored andcommitted
jwl: harden Rocflu closure and correct pre_process t=0 pressure diagnostic
- m_jwl: derive Gamma_air from the ideal-gas fluid, smoothstep omega(rho) and the Y blend, use ej_rho_ref, mass-weighted cv, and a c^2 floor; scan (rho,e,Y) at init. - HLLC/HLL: use the closure-consistent averaged-state pressure. - pre_process serial writer: pass the cell's own jwl_Y into the t=0 primitive-pressure recovery so pure-air cells use Gamma_air instead of the products omega (was writing 0.75x for air; conserved energy was always correct). - Add 1D JWL/air interface-advection mechanical-equilibrium guard (quiescent, max|dp|/p0 ~ 1e-16) and a JWL/air mixture test; regenerate the affected golden files.
1 parent cf49473 commit f5317ff

24 files changed

Lines changed: 1060 additions & 158 deletions

File tree

README-JWL-EOS.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ The cold-curve pressure is evaluated through a shared helper so pressure recover
1616

1717
## Mixture Closures
1818

19-
The JWL mixture closure applies to five-equation JWL/ideal-gas mixtures with one JWL products fluid and one non-JWL ideal-gas fluid. Whenever a JWL fluid is present, MFC applies the Rocflu single-fluid closure from `modflu/RFLU_ModJWL.F90`. It interpolates the JWL `A` and `B` coefficients with specific internal energy and interpolates `omega` and heat capacity with mixture density. The closure uses adapted mixture coefficients through products mass fraction `Y <= 0.99` and pure-products JWL coefficients for `Y > 0.99`.
19+
The JWL mixture closure applies to five-equation JWL/ideal-gas mixtures with one JWL products fluid and one non-JWL ideal-gas fluid. Whenever a JWL fluid is present, MFC applies the Rocflu single-fluid closure from `modflu/RFLU_ModJWL.F90`. It ramps the JWL `A` and `B` coefficients linearly in specific internal energy between the ambient-gas energy `jwl_air_e0` and the products reference energy `e_j = jwl_E0/jwl_ej_rho_ref`, ramps `omega` with mixture density via a smoothstep between `jwl_air_rho0` and `jwl_rho0`, and blends the heat capacity as the mass-weighted `cv = Y*cv_products + (1 - Y)*cv_air`. The transition from these mixture coefficients to pure-products JWL coefficients is a smoothstep in products mass fraction `Y` over `[0.95, 0.999]`, replacing the earlier hard cutoff at `Y = 0.99`; because the smoothstep weight depends only on `Y`, the analytic pressure-to-energy inverse remains exact under the blend.
2020

21-
This closure is not TNT-specific. MFC reads `jwl_A`, `jwl_B`, `jwl_R1`, `jwl_R2`, `jwl_omega`, `jwl_rho0`, `cv`, and either `jwl_Q` or `jwl_E0` from the JWL fluid, so any explosive products model with a valid JWL parameter set can be used. `jwl_Q` is the specific detonation energy in J/kg; internally MFC derives `jwl_E0 = jwl_rho0*jwl_Q`. If both are provided, they must be consistent. Unlike Rocflupicl's case-specific implementation, MFC does not hard-code TNT density, TNT energy scaling, ambient density, ambient energy, or air heat capacity inside the EOS. The reference parameters must satisfy `jwl_rho0 > jwl_air_rho0` and `jwl_E0/jwl_rho0 > jwl_air_e0`.
21+
This closure is not TNT-specific. MFC reads `jwl_A`, `jwl_B`, `jwl_R1`, `jwl_R2`, `jwl_omega`, `jwl_rho0`, `cv`, and either `jwl_Q` or `jwl_E0` from the JWL fluid, plus `jwl_air_rho0` and either `jwl_air_e0` or `jwl_air_p0` for the co-existing gas, so any explosive products model with a valid JWL parameter set can be used. `jwl_Q` is the specific detonation energy in J/kg; internally MFC derives `jwl_E0 = jwl_rho0*jwl_Q`. If both are provided, they must be consistent. The ambient-gas Grüneisen coefficient is taken from the ideal-gas fluid's own `gamma` (`Gamma_air = 1/gamma`; with a single JWL fluid the JWL fluid's own `gamma` is used), and the optional `jwl_ej_rho_ref` sets the products-energy reference density (default `jwl_rho0`). Unlike Rocflupicl's case-specific implementation, MFC does not hard-code TNT density, TNT energy scaling, ambient density, ambient energy, or air heat capacity inside the EOS. The reference parameters must satisfy `jwl_rho0 > jwl_air_rho0` and `jwl_E0/jwl_ej_rho_ref > jwl_air_e0`.
2222

23-
Finite pressure, temperature, energy, and sound-speed floors are applied only after explicit finite checks. NaNs are intentionally preserved so bad states are visible during debugging instead of being converted into plausible-looking floor values.
23+
Finite pressure, temperature, and energy floors are applied only after explicit finite checks. The state routine returns the raw squared sound speed; the public wrappers bound it below by the ideal-gas value `Gamma_air*p/rho`. NaNs are otherwise intentionally preserved so bad states are visible during debugging instead of being converted into plausible-looking floor values.
2424

2525
## Validation Scope
2626

2727
The production closure is covered by a registered golden test. The regression includes a homogeneous 50/50 products-air slab so the Rocflu density and energy interpolation is exercised in addition to its endpoint branches.
2828

29+
At initialization MFC scans the closure over the configured material's `(rho, e, Y)` envelope and aborts if any state yields a non-positive or non-finite squared sound speed, or if the pressure-to-energy round-trip fails to recover the input energy. An inconsistent parameter set therefore fails fast at startup rather than producing silently wrong states during the run.
30+
2931
The closure follows Rocflu's pressure, temperature, inverse-energy, and sound-speed formulas, but replaces its case-specific hard-coded air values and explosive energy divisor with the corresponding MFC material inputs. Its inverse energy selects the exact low-, blended-, or high-energy branch of that pressure law; this removes the legacy fallback's pressure/energy round-trip mismatch.
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
# 3D JWL Spherical TNT Free-Air Benchmark
2+
3+
This benchmark is a 3D JWL/TNT free-air blast candidate for MFC. A spherical
4+
region of TNT detonation products expands into ambient air, and native point
5+
probes record pressure-time histories for arrival time, peak incident
6+
overpressure, and positive-phase impulse extraction.
7+
8+
Reference values are intentionally not fabricated. The MFC probe extraction is
9+
implemented and the case runs, but the published reference values still need to
10+
be filled from the paper/CONWEP table before this should be described as
11+
completed validation.
12+
13+
## Citation
14+
15+
Giam, Toh, and Tan, "Numerical Review of Jones-Wilkins-Lee Parameters for
16+
Trinitrotoluene Explosive in Free-Air Blast," Journal of Applied Mechanics,
17+
2020. DOI: `10.1115/1.4046243`.
18+
19+
The case is motivated by that free-air TNT/JWL review, but this repository does
20+
not currently include an accessible table of the paper's exact benchmark
21+
values. Until those values, Kingery-Bulmash/CONWEP values, or another trusted
22+
numeric free-air TNT reference are added, this is a benchmark candidate rather
23+
than completed validation.
24+
25+
## Physics Scope
26+
27+
This benchmark initializes TNT detonation products directly and validates 3D JWL product-air blast expansion. It does not model detonation initiation, reaction-zone structure, afterburn, or structural coupling.
28+
29+
The benchmark exercises:
30+
31+
- 3D JWL product-air expansion.
32+
- Radial free-air blast propagation in a Cartesian grid.
33+
- Native MFC pressure probes and post-processing.
34+
- A comparison framework for published or standard free-air blast quantities.
35+
36+
The benchmark does not validate detonation initiation, reaction-zone physics,
37+
afterburn, structural coupling, confined blast, tunnel blast, or ground
38+
reflection.
39+
40+
## Why This Is Genuinely 3D
41+
42+
The default case resolves an octant of a spherical products region in a 3D
43+
Cartesian domain. The shock expands in x, y, and z, with active transverse
44+
reconstruction and Riemann fluxes. This is not a 1D shock tube extruded through
45+
the 3D solver path.
46+
47+
Symmetry planes at `x = 0`, `y = 0`, and `z = 0` recover the full spherical
48+
solution while reducing the cell count by a factor of about eight. The probes
49+
lie near the positive x radial direction, at the nearest cell centers to the
50+
target radii. Keeping probes on cell centers avoids boundary and
51+
MPI-decomposition interpolation artifacts on the coarse default grid.
52+
53+
## Geometry
54+
55+
| Quantity | Value |
56+
|---|---:|
57+
| Charge center | `(0, 0, 0) m` in the octant representation |
58+
| Charge radius | `0.05 m` |
59+
| TNT/product reference density | `1630 kg/m^3` |
60+
| Full-sphere TNT mass | `0.853466 kg` |
61+
| Domain | `x, y, z in [0, 0.5] m` |
62+
| Final time | `2.0e-4 s` |
63+
64+
The simulated octant contains one eighth of the full sphere. The symmetry
65+
boundaries make the resolved field equivalent to the full charge, so scaled
66+
distance uses the full TNT mass:
67+
68+
```text
69+
W = (4/3) pi (0.05 m)^3 (1630 kg/m^3) = 0.853466 kg
70+
Z = r / W^(1/3)
71+
```
72+
73+
## Grid
74+
75+
Default local grid:
76+
77+
| Quantity | Value |
78+
|---|---:|
79+
| `m = n = p` | `63` |
80+
| Cells in octant | `64^3` |
81+
| Cell size | `0.0078125 m` |
82+
| Reconstruction | mapped WENO3 |
83+
| Riemann solver | HLLC |
84+
| Time stepper | RK3 |
85+
| CFL target | `0.3` |
86+
87+
Lower-resolution smoke run:
88+
89+
```bash
90+
./mfc.sh run benchmarks/3D_jwl_spherical_tnt_free_air_validation/case.py -n 4 -- --grid 31
91+
python3 benchmarks/3D_jwl_spherical_tnt_free_air_validation/gauges.py --grid 31
92+
```
93+
94+
The `64^3` octant default gives a visibly cleaner spherical shock than the
95+
older `32^3` smoke grid, but it takes several minutes and writes larger output
96+
files.
97+
98+
## Boundary Conditions
99+
100+
| Boundary | MFC value | Meaning |
101+
|---|---:|---|
102+
| `bc_x%beg`, `bc_y%beg`, `bc_z%beg` | `-2` | symmetry planes |
103+
| `bc_x%end`, `bc_y%end`, `bc_z%end` | `-3` | non-reflecting/open boundaries |
104+
105+
## EOS And Initial Conditions
106+
107+
Ambient air fills the full octant before the products sphere is overlaid:
108+
109+
| Parameter | Value |
110+
|---|---:|
111+
| Air EOS | ideal gas/stiffened gas, `eos = 1` |
112+
| Air pressure | `101325 Pa` |
113+
| Air density | `1.225 kg/m^3` |
114+
| Air physical gamma | `1.4` |
115+
| MFC air `fluid_pp(2)%gamma` | `2.5` |
116+
| Air sound speed | `340.3 m/s` |
117+
| Air `cv` | `717.5 J/(kg K)` |
118+
119+
TNT products use the JWL constants already present in the MFC JWL examples and
120+
benchmarks. They are documented here as the repo-local parameter source, not as
121+
a claim that these are the exact Giam et al. tabulated values:
122+
123+
| Parameter | Value |
124+
|---|---:|
125+
| Products EOS | JWL, `eos = 2` |
126+
| Products density/reference density `rho0` | `1630 kg/m^3` |
127+
| Products volume-fraction floor | `1.0e-6` |
128+
| JWL `A` | `3.712e11 Pa` |
129+
| JWL `B` | `3.231e9 Pa` |
130+
| JWL `R1` | `4.15` |
131+
| JWL `R2` | `0.95` |
132+
| JWL `omega` | `0.30` |
133+
| Initial specific energy equivalent | `E0/rho0 = 6.1908e6 J/kg` |
134+
| Initial internal energy density `E0` | `1.0089e10 J/m^3` |
135+
| JWL cold pressure at `rho = rho0` | `6.2837e9 Pa` |
136+
| Initial products pressure | `9.3104e9 Pa` |
137+
| Products `cv` | `613.5 J/(kg K)` |
138+
| `jwl_air_e0` | `2.5575e5 J/kg` |
139+
| `jwl_air_rho0` | `1.225 kg/m^3` |
140+
| air Grüneisen (derived from `fluid_pp(2)%gamma`) | `1/2.5 = 0.4` |
141+
142+
The initialized products pressure is computed in `case.py` from:
143+
144+
```text
145+
p = A (1 - omega/(R1 V)) exp(-R1 V)
146+
+ B (1 - omega/(R2 V)) exp(-R2 V)
147+
+ omega E0,
148+
V = rho0 / rho = 1.
149+
```
150+
151+
## Probe Locations
152+
153+
The default `--grid 63` run uses the nearest cell centers to target x positions
154+
`0.15, 0.25, 0.35, 0.45 m`:
155+
156+
| Gauge | x (m) | y (m) | z (m) | r (m) | Z (m/kg^(1/3)) |
157+
|---:|---:|---:|---:|---:|---:|
158+
| 1 | 0.152344 | 0.003906 | 0.003906 | 0.152444 | 0.160712 |
159+
| 2 | 0.253906 | 0.003906 | 0.003906 | 0.253966 | 0.267741 |
160+
| 3 | 0.347656 | 0.003906 | 0.003906 | 0.347700 | 0.366558 |
161+
| 4 | 0.449219 | 0.003906 | 0.003906 | 0.449253 | 0.473618 |
162+
163+
MFC's native probe interpolation can write a local initial pressure that differs
164+
from the analytic ambient state on this coarse octant grid. The reducer therefore
165+
uses each probe's first sample as its local baseline and reports pressure rise
166+
relative to that baseline.
167+
168+
Arrival time is the first time the pressure rise exceeds 5 percent of ambient:
169+
170+
```text
171+
p(t) - p(t=0) > 0.05 p_ambient
172+
```
173+
174+
Peak incident overpressure is estimated from the same baseline-corrected trace:
175+
176+
```text
177+
dp_peak = max(p(t) - p(t=0))
178+
```
179+
180+
Positive-phase impulse is integrated over the baseline-corrected history:
181+
182+
```text
183+
I = integral max(p(t) - p(t=0), 0) dt
184+
```
185+
186+
## Run Commands
187+
188+
From the repository root:
189+
190+
```bash
191+
./mfc.sh run benchmarks/3D_jwl_spherical_tnt_free_air_validation/case.py -n 4
192+
python3 benchmarks/3D_jwl_spherical_tnt_free_air_validation/gauges.py
193+
./mfc.sh precheck
194+
```
195+
196+
The probe reducer reads:
197+
198+
```text
199+
benchmarks/3D_jwl_spherical_tnt_free_air_validation/D/probe<i>_prim.dat
200+
```
201+
202+
and writes:
203+
204+
```text
205+
benchmarks/3D_jwl_spherical_tnt_free_air_validation/gauge_results.csv
206+
```
207+
208+
## Comparison Table
209+
210+
| Gauge | r (m) | Z (m/kg^(1/3)) | MFC arrival (s) | Ref arrival (s) | MFC peak dp (Pa) | Ref peak dp (Pa) | MFC impulse (Pa s) | Ref impulse (Pa s) | Error |
211+
|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|
212+
| 1 | 0.152444 | 0.160712 | 8.000000e-06 | pending reference | 9.189414e+06 | pending reference | 1.142617e+03 | pending reference | pending |
213+
| 2 | 0.253966 | 0.267741 | 3.700000e-05 | pending reference | 7.494431e+06 | pending reference | 3.127588e+02 | pending reference | pending |
214+
| 3 | 0.347700 | 0.366558 | 7.200000e-05 | pending reference | 5.750937e+06 | pending reference | 2.453974e+02 | pending reference | pending |
215+
| 4 | 0.449253 | 0.473618 | 1.150000e-04 | pending reference | 4.023872e+06 | pending reference | 3.029903e+02 | pending reference | pending |
216+
217+
Reference values may be filled from Giam et al. if numeric values are available,
218+
from Kingery-Bulmash/CONWEP free-air TNT data if used for comparison, or from
219+
another clearly cited spherical free-air TNT reference. If values are digitized
220+
from a figure, label them as digitized estimates.
221+
222+
## Pass/Fail Expectations
223+
224+
This candidate benchmark passes its local sanity checks when:
225+
226+
- The case completes without NaNs.
227+
- Density, pressure, and internal energy remain positive.
228+
- Shock arrival time increases monotonically with radius.
229+
- Peak incident overpressure decreases monotonically with radius.
230+
- The pressure histories show a radially reasonable outward blast.
231+
232+
Quantitative error should be reported only after trusted reference arrival,
233+
peak incident overpressure, and impulse values are added.
234+
235+
## Limitations And Remaining Work
236+
237+
- This is not completed validation until the reference columns are populated.
238+
- A `32^3` octant run is available as a faster smoke test, but the default is now `64^3`.
239+
- The products sphere initialization does not model a detonation wave or
240+
reaction zone.
241+
- No afterburn, structural coupling, confinement, or ground reflection is
242+
represented.
243+
- A higher-resolution run should be used before drawing quantitative
244+
conclusions.

0 commit comments

Comments
 (0)