JWL equation of state and detonation modeling for the five-equation model#1586
JWL equation of state and detonation modeling for the five-equation model#1586fahnab666 wants to merge 4 commits into
Conversation
c7db505 to
87a0281
Compare
Maintainer review — full issue listThanks for this. The physics is genuinely thoughtful — four mixture closures, exact inverses for the linear ones, fail-fast parameter validation in init, and an honest validation tracker that separates what's verified from what isn't. That part I'm not asking you to change. The engineering, however, isn't yet at MFC standards. Below is the complete list of what needs to be addressed before this can merge, grouped by severity, with the reason each one matters. Numbering is for ease of reference in replies. Blocking — correctness & maintainability1. Six near-identical copies of the JWL energy-reconstruction block. 2. HLLC and HLL/LF feed the sound-speed routine different inputs for the same physics. 3. alpha_rho_j = q_prim_vf(max(1, jwl_idx))%sf(j, k, l)Why it matters: when no JWL fluid is present ( 4. Runtime branch added to the hottest kernel in every build. 5. Per-face 60-iteration bisection with transcendentals, on GPU. 6. Silent NaN/floor squashing masks divergence. if (pres /= pres) pres = sgm_eps
if (pres < sgm_eps) pres = sgm_epsand if (c2 /= c2) c2 = jwl_omegas(jwl_idx)*max(pres, 1._wp)/max(rho, sgm_eps)
c2 = max(c2, jwl_omegas(jwl_idx)*max(pres, 1._wp)/max(rho, sgm_eps))Why it matters: a diverged bisection or a NaN pressure gets converted to a 1e-16 floor and the solver keeps running with garbage instead of aborting — a classic silent-failure mode that makes bugs nearly impossible to localize. Additionally Blocking — validation & test integration7. The unit test exercises a Python re-implementation, not the compiled Fortran. 8. Golden cases not wired into the test registry, generated on a dirty tree. 9. Promote validation tiers only with reports. The tracker lists Kamm/Tarver/PBX as exploratory and TNT-air as stress-only. Non-blocking — quality & style10. Hardcoded air defaults as non-sentinel values, triple-duplicated. fluid_pp(i)%jwl_air_e0 = 2.5575e5_wp
fluid_pp(i)%jwl_air_rho0 = 1._wp
fluid_pp(i)%jwl_air_gamma = 0.4_wpWhy it matters: every neighboring field defaults to 11. Dead/over-broad public API. 12. rj = max(Y_s*rho_s/a_lo, sgm_eps); ra = max((1._wp - Y_s)*rho_s/(1._wp - a_lo), sgm_eps); V = rho0/rjWhy it matters: MFC is one-statement-per-line throughout; this hurts readability and makes 13. Unnamed magic thresholds. 14. Possibly-negative denominator flooring in the Kuhl closure. 15. Energy floor ignores the cold-curve offset. 16. LLM-style verbosity vs MFC norms. 17. Leftover dev cruft in SummaryThe closures are the strong part — leave them. The asks, in priority order: de-dup the six energy blocks (1), unify the sound-speed input path (2, 3), gate the JWL branch at compile time (4), justify-or-host-gate the bisection (5), replace silent floors with assertions (6), and fix the test/golden story (7, 8). The rest are cleanup. Happy to discuss any of these. |
|
I unsure why you created the file Also, for your tests added, you add 3 1D cases and a 2D case. It is not inherently bad to add them, but a feature like this really requires a 3D example to be added with comparison to some sort of example. I know that I have seen comparisons of your code to published examples, and those comparisons should make it into the readme if you are going to provide a readme. The only concern I have about the fortran code outside of the minor comments that I left are with the size of the jwl module. I need to actually take a look at it in an IDE where I have access to |
Automated re-review (run on behalf of @sbryngelson)
Nice work on the revision — most of the prior review is genuinely addressed in the code, not just the commit log. The energy-reconstruction macro de-duplicates correctly, the sound-speed inputs are unified, the indexing hack and Python re-implementation test are gone, the defaults are sentinel-ized through a shared helper, the public API is tight, and The following items are still open and should each be resolved before merge. ResolvedFor the record, these are confirmed fixed in the current diff: de-duplicated Still openA. Golden-case provenance and registration. B. Hot-path JWL branch is a runtime test, not compile-time gated. C. D. Residual silent mask with a misleading comment. E. Unconditionally-passed if (jwl_idx > 0) then
Y_jwl = min(max(q_prim_vf(jwl_idx)%sf(j, k, l)/max(rho, sgm_eps), 0._wp), 1._wp)
end if
call s_compute_speed_of_sound(..., jwl_Y=Y_jwl)When F. Kuhl G. Remaining H. 3D example with published comparison. Once A–H are addressed, this looks ready for a final human pass. The physics and the structural refactor are in good shape.
|
Automated re-review — additional code-quality items (run on behalf of @sbryngelson)
I. Closure test coverage. J. Single-precision ( ! m_jwl.fpp:331
if (abs(f_m) <= 1.e-12_wp*max(abs(pres), sgm_eps)) exit
! m_jwl.fpp:400
if (abs(g_m) <= 1.e-12_wp*p_s) exitIn a single-precision build these can never be satisfied, so both K. EOS selectors are bare magic numbers. L. Validation lives outside the checker convention. M. Missing artifacts for a feature of this scope.
N. Incomplete/inconsistent Doxygen. O. Cold-curve duplication across closures. P. For completeness, these were checked and are fine:
|
|
I am still working on this PR in more detail. I am currently changing the implementation format to make the JWL mixture-closure logic cleaner, more modular, and easier to review. The goal is to move toward a better closure-model structure where each approach is more clearly separated, documented, and easier to validate. So far, I have been focusing on the mixture EOS closure workflow, including the connection between the 5-equation model, the explosive-products mass fraction, the caloric EOS, and the thermal EOS. I am also comparing different closure directions, including p–T equilibrium, Kuhl/Khasainov-style interpolation, linear/quadratic fitting approaches, and possible reduced-fit models for mixture pressure, temperature, and sound speed. I will keep refining the implementation and keep up here in the comment. The code is far for ready. |
e02341c to
1f19647
Compare
Composition-weighted JWL mixture closure for the five-equation model (fluid_pp%eos = 2): pressure, the energy inverse, and an analytic sound speed are recovered from (rho, e, Y) with no iterative solve. Adds three optional reaction sources (program burn, afterburn, and JWL++ reactive) plus the jwl_delta_e reactant offset for resolved ZND structure, wired through the HLL/HLLC/LF Riemann solvers, the checkers, parameter definitions, and the pre and post pressure diagnostics. Includes worked examples, validation benchmarks, and golden regression tests.
Ghost-cell energy and the reaction progress scalars are rebuilt through the JWL closure in s_ibm_correct_state, moving bodies repopulate fresh solid-to-fluid cells by neighbour extrapolation, and Euler-Lagrange bubble seed pressure and Keller-Miksis liquid sound speed go through the same closure. Adds immersed-boundary and bubble demonstration cases.
5e7e2f2 to
67cd9b7
Compare
jwl_delta_es was assigned straight from fluid_pp%jwl_delta_e without checking f_is_default, so any case that leaves jwl_delta_e unset (the documented default 0 = off) picked up dflt_real = -1e6 instead. Every JWL closure test except the base case hits this, since none of them set jwl_delta_e explicitly.
README-JWL-EOS.md duplicated the m_jwl.fpp module docstring; README-JWL-IMPLEMENTATION.md was an internal audit doc referencing already-removed features (jwl_mix_type). Neither belongs in the shipped diff, so both are dropped and the two remaining pointers to README-JWL-EOS.md are redirected to the in-file derivation. 2D_jwl_prog_burn duplicated the program-burn kinematics already exercised by 2D_jwl_detonation; 2D_jwl_ibm_freeflight_cylinder duplicated the moving-IB coupling already exercised by 2D_jwl_progburn_ibm_freeflight (which explicitly supersedes it, per its own comment).
Summary
Closes #1638.
This PR adds a Jones-Wilkins-Lee (JWL) equation of state and a detonation modeling
capability to the five-equation Allaire model (
model_eqns = 2). A JWL fluid is selectedper material with
fluid_pp(i)%eos = 2and coexists with an ideal-gas or stiffened-gasambient. On top of the EOS, the PR adds three optional reaction sources (program burn,
afterburn, and self-propagating reactive detonation) and couples the whole capability with
immersed boundaries and Euler-Lagrange bubbles.
Mixture closure
For a pure products cell the JWL pressure law is
Products and the surrounding gas are mixed with a composition (heat-capacity) weighted$Y$ the JWL mass fraction, the products' heat-capacity share is
closure. With
and the mixture coefficients are
where$\hat{\pi}$ is a cold offset that is active only for a stiffened ambient$\pi_\infty > 0$ ). Every coefficient depends on $Y$ alone, never on $\rho$ or $e$ , which is
(
what makes the closure cheap and exact at the endpoints:
so no handover smoothing is needed.
An initialization-time scan verifies the$e \to p \to e$ round-trip over the reachable state
envelope and aborts on any non-physical state.
Reaction sources
All three sources default off, and each carries a$(1-x)/\Delta t$ rate clamp so the SSP-RK$Y,q$ energy budget.
stages cannot overshoot the
prog_burnpb_widthjwl_afterburnjwl_reactiveprog_burnThe JWL++ reaction progress evolves as
For$\le 0$ , default $0$ = off)
jwl_reactive, the optionalfluid_pp(i)%jwl_delta_e(applies the Garno et al. (2020) reactant energy offset: the thermal term uses
putting unreacted explosive on a stiffer Hugoniot so a resolved detonation shows genuine ZND$Y$ factor confines the offset to the explosive, and the inverse and sound
structure (a von Neumann spike decaying to the Chapman-Jouguet state) instead of a monotonic
energy source. The
speed stay closed-form. The two progress variables ride the HLLC contact flux like the color
function.
Capabilities added
model_eqns = 2pb_*parameters)ibbodies rebuild ghost energy and progress scalars through the closurebubbles_lagrangeseed pressure and Keller-Miksis sound speed go through the closurepre_processandsimulationreach the same closure leaf routine for theProhibited with
eos_jwl(their pressure paths bypass the closure):wave_speeds = 2,CBC boundaries,
alt_soundspeed, elasticity,igr,bubbles_euler,mhd, andchemistry.Constraints are enforced both at startup (
m_checker*) and in./mfc.sh validate(
case_validator.py).Validation
(
examples/1D_jwl_znd_detonation).examples/2D_sedov_taylor_blast) and far-field TNToverpressure against Kinney-Graham
(
benchmarks/3D_jwl_spherical_tnt_free_air_validation).program burn, afterburn, reactive burn, and the immersed-boundary and bubble couplings.
Tasks
jwl_delta_ereactant offset for resolved ZND structurem_checker*andcase_validator.pydocs/documentation/case.mdparameters and capabilities overview updated./mfc.sh format,precheck(7/7), and a full three-target build passAI review
@copilot review) before human reviewNotes for reviewers
The GPU device paths use the$N$ -constituent
GPU_*Fypp macros only, and the new sources and progress-variableadvection are feature-gated and GPU-wrapped. The Mie-Grüneisen
pressure-equilibrium closure (for products, water, and air together) is the sanctioned next
step and is described in
README-JWL-IMPLEMENTATION.md; it is not part of this PR.