Commit 76f8f51
authored
Combustion: condensed-phase reactive burn (5-/6-equation, Arrhenius kinetics) + IBM burning surfaces (#1670)
* simulation: fix IBM+chemistry hang by setting consistent species/energy at immersed-boundary points
* examples: enable IBM+chemistry in flame-holder now that the hang is fixed
* examples: add hybrid-rocket fuel slab and 1D propellant flame (solid-fuel analogs)
* simulation: add burning-grain surface fuel injection to IBM (v_blow + inj_species)
* simulation: pressure-coupled IBM burn rate (Vieille's law) for internal-ballistics feedback
* examples: make flameholder a proper reacting bluff-body (fuel-injecting cylinder, wake flame)
* examples: add --tend knob to burning-grain case
* simulation: add condensed-phase reactive burn (multi-fluid programmed detonation)
* simulation: harden reactive_burn preconditions and IBM burn-rate against negative pressure
* test: add reactive_burn regression test (condensed programmed burn)
* examples: fix hybrid slab run time and viscosity (flame now anchors)
* examples: add 3D spherical burning grain with octant symmetry
* example: reactive shock-flame RM roll-up via hardcoded IC 273
* test: golden files for combustion example and reactive-burn tests (generated on master base)
* checker: require rburn_pref > 0 and forbid chemistry + Euler bubbles
Addresses PR review (Copilot):
- reactive_burn divides the pressure drive by rburn_pref; prohibit rburn_pref <= 0
- s_interpolate_image_point selects the bubbles/QBMM branch before chemistry, so the
Ys_IP species state is not carried when both are on; forbid chemistry + bubbles_euler/qbmm
(Fortran m_checker + Python case_validator) rather than touch the hot IBM path
* checker: constrain reactive_burn to model_eqns=2 and burn_rate_exp >= 0
Addresses independent review findings on #1670:
- reactive_burn's exact volume-fraction swap and single-pressure read assume the
5-equation pressure-equilibrium model, but num_fluids=2 alone also admits model_eqns=3;
prohibit model_eqns /= 2 (m_checker + case_validator.check_reactive_burn + PHYSICS_DOCS)
- Vieille's-law v_blow ~ p^n diverges for a negative exponent as surface pressure -> 0;
prohibit patch_ib%burn_rate_exp < 0 (case_validator.check_ibm)
* feat(reactive-burn): 6-equation model support + Arrhenius temperature kinetics
Extends the condensed-phase reactive burn beyond the 5-equation model to the 6-equation (Saurel/Pelanti) multi-fluid model, and adds an optional temperature-driven ignition term.
6-equation support: the reactant->product qv release is carried through the phasic-pressure relaxation. m_pressure_relaxation.fpp threaded the formation energy (alpha_rho_k*qv_k) through s_equilibrate_pressure and s_correct_internal_energies so the phasic pressures and the recovered mixture pressure are qv-consistent with s_compute_pressure -- otherwise a nonzero qv inflated the phasic pressure by rho_k*qv_k/gamma_k. The existing 5-eq burn source then works unchanged on model_eqns=3. For qv=0 the new terms are exactly zero, so all 13 existing 6-eq relaxation goldens are bit-identical (verified CPU/OMP/ACC).
Arrhenius kinetics: new rburn_ta (activation temperature [K]); default 0 keeps the pure pressure-driven rate bit-identical. When rburn_ta>0 the rate gains a exp(-rburn_ta/T_r) factor, with T_r=(p+pi_inf)/((gamma-1)*cv*rho) the reactant phasic temperature. Guarded (checker + case_validator) so rburn_ta>0 with cv=0 is rejected instead of silently disabling the factor.
Test: adds a model_eqns=3 reactive-burn regression golden (nested off the 5-eq test), and hardens both reactive goldens by giving the uniform case a small advection velocity so the momentum output is well-resolved rather than near-zero roundoff (the old golden compared ~0 momentum at 1e-12 and failed across recompiles/backends). Validated on CPU, OpenMP-offload, and OpenACC.
* test(reactive-burn): add Arrhenius (rburn_ta>0) regression golden
Nested off the reactive-burn detonation test with rburn_ta=500 and cv=1500, chosen so the exp(-rburn_ta/T_r) factor is O(0.4) at the IC temperature -- exercising the temperature branch (all other reactive goldens use rburn_ta=0). Verified on CPU, OpenMP-offload, and OpenACC.
* refactor(reactive-burn): group rburn params into a derived type; address review panel + CI
Post-review hardening from a 5-reviewer panel, plus the CI-surfaced flame-example fragility.
rburn derived type: the five rburn_* scalars (k, pign, pref, n, ta) become a rburn type instance, matching the sibling chem_params pattern (type in m_derived_types, TYPED_DECLS registration, member _r/_nv, descriptions regex, auto GPU_DECLARE + GPU_UPDATE(device=[rburn]) in m_global_parameters and m_start_up so the type is device-resident). Numerically inert (~1 ULP recompile roundoff); reactive goldens regenerated for the namelist-key change. Verified CPU/OMP/ACC.
Completeness guards (review): rburn%k (>0), rburn%pign (set), rburn%pref (>0), rburn%n (>=0) are now validated in both m_checker and case_validator. Each defaults to the dflt_real sentinel, so an unset value silently produced spurious ignition (pign), NaN via drive**n (n), or a backward reaction (k).
IB inj_species bound (review): m_checker now requires patch_ib%inj_species <= num_species when chemistry + ib; it indexes Ys_IP(1:num_species) at image points, so an out-of-range value was an out-of-bounds write.
Docs (review): reactive_burn requires num_fluids = 2 (checker aborts otherwise), corrected from >= 2 in case.md and the module docstring.
CI: skip the 1D_propellant_flame example (golden removed). Its finite-rate flame front drifts past the 1e-3 Example tolerance across compilers (nvhpc 25.11 golden vs 24.3/GNU/Intel/CCE/AMD) -- same non-portability class as the flame examples already skipped. The reactive_burn detonation goldens remain portable (they passed every CI lane).
* fix(reactive-burn): broadcast the rburn derived type to non-root ranks
The rburn refactor moved the five rburn_* scalars (auto-broadcast) into a derived type, but derived-type members are not auto-broadcast -- they are hand-emitted per type in fortran_gen.py (as for chem_params/lag_params). rburn had no emitter, so on a multi-rank reactive_burn run every non-root rank kept rburn at the dflt_real sentinel: a silent wrong-physics bug the single-rank golden tests cannot catch. Adds _emit_rburn (all members REAL -> mpi_p, under the reactive_burn guard, sim target), mirroring _emit_chem_params. Verified in the regenerated generated_bcast.fpp.
* test(reactive-burn): add a 2-rank MPI regression test for the rburn broadcast
All other reactive goldens run single-rank, so a broken rburn broadcast is invisible to them. This ppn=2 variant of the detonation case burns rank 1's half of the domain with the broadcast rburn; verified to FAIL when the rburn broadcast emitter is removed and PASS with it, so it locks the fix in CI.
* test(ibm): add a golden for the Vieille's-law pressure-coupled burn rate
The ibm_burning_grain/ibm_flameholder Example goldens already cover surface injection (v_blow + the inj_species composition swap), but both leave burn_rate_exp at 0, so the pressure-coupled scaling v_blow*(p/burn_rate_pref)^n shipped with no regression coverage. Registers the same example with --burn_exp 0.5 at the Example suite's 25x25/50-step size, so it differs from the existing golden only by the coupling: turning it on moves the solution by ~5e-3 relative (1.3 absolute in energy), well above the 1e-3 tolerance, so a broken multiplier fails the test. Tolerance pinned to 1e-3 to match the sibling Example golden -- compute_tolerance would otherwise pick 1e-10 via the ib branch, which a 50-step IBM + finite-rate-chemistry run cannot hold across compilers.
* test: skip the 2D_hybrid_slab example golden (not portable across compilers)
The diffusion flame over the fuel slab is positioned by accumulated stiff-kinetics roundoff, so by step 50 the transverse momentum drifts past the 1e-3 Example tolerance: nvhpc lanes pass, Intel and Frontier CCE disagree with the golden by ~2e-3 absolute (up to 44% relative on a small component). Same non-portability class as 1D_propellant_flame and the other flame examples already skipped there, so no single golden passes every lane. The case remains a runnable example; the reactive_burn, shock_flame, ibm_burning_grain and ibm_flameholder goldens are unaffected and pass on all lanes.
* fix(ibm): initialize the burning-surface fields on particle-cloud IB patches
particle_cloud_ibs is allocated without default initialization, and s_add_cloud_particle set only the geometry/motion members. s_reduce_ib_patch_array then copies the whole struct into patch_ib, overwriting the zeroed defaults from s_assign_default_values_to_user_inputs -- so v_blow, inj_species and burn_rate_exp/pref reached the solver as uninitialized memory.
That was latent until this branch added the first read of those members in m_ibm: a garbage v_blow > 0 superimposes a garbage wall-normal velocity on the ghost points, which NaNs the field. It reproduced only where the allocation is not already zero-filled -- Frontier AMD failed 2D_mibm_particle_cloud with 'ICFL is NaN' at step 2 while every NVHPC lane (and local CPU/OMP/ACC) passed. Sets the four fields for the inert particle surfaces; audited that these are exactly the patch_ib members m_ibm reads (airfoil_id/model_id/length_x remain unset but are never read for circle/sphere particles).
* docs: record the derived-type broadcast and patch_ib init traps in common-pitfalls
Both bit this branch, both fail silently, and neither is visible to local testing: a derived-type param regrouping dropped its MPI broadcast (non-root ranks kept the sentinel, invisible to single-rank goldens), and an uninitialized patch_ib member reached the solver through the whole-struct copy from particle_cloud_ibs (garbage v_blow -> ICFL NaN, reproducing only on Frontier AMD where the allocation is not zero-filled). Documents the required steps and the platform-only-NaN signature.1 parent 86165fc commit 76f8f51
47 files changed
Lines changed: 3381 additions & 23 deletions
File tree
- .claude/rules
- docs
- documentation
- examples
- 1D_propellant_flame
- 1D_reactive_burn
- 2D_hybrid_slab
- 2D_ibm_burning_grain
- 2D_ibm_flameholder
- 2D_shock_flame
- src
- common
- include
- pre_process
- simulation
- tests
- 135ED2EF
- 5F3BB2E0
- 64F05A05
- B317404C
- CB0DC420
- CF4FE4C9
- E5B66084
- F08B0D0E
- F200F862
- toolchain/mfc
- params
- generators
- test
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
62 | 79 | | |
63 | 80 | | |
64 | 81 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1129 | 1129 | | |
1130 | 1130 | | |
1131 | 1131 | | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
| 1137 | + | |
1132 | 1138 | | |
1133 | 1139 | | |
1134 | 1140 | | |
| 1141 | + | |
| 1142 | + | |
1135 | 1143 | | |
1136 | 1144 | | |
1137 | 1145 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
25 | 26 | | |
26 | 27 | | |
27 | 28 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
0 commit comments