Evaluate Mie-Gruneisen coefficients per cell along the 5-equation path - #1809
Evaluate Mie-Gruneisen coefficients per cell along the 5-equation path#1809sbryngelson wants to merge 6 commits into
Conversation
Any Mie-Gruneisen EOS p = p_ref + rho Gamma_G (e - e_ref) is MFC's rho e = Gamma p + Pi with Gamma = 1/Gamma_G and Pi = rho e_ref - p_ref/Gamma_G, so the existing operators need only the coefficients and dPi/drho. s_eos_coefficients is the single dispatch: the Mie-Gruneisen case supplies a linear-Hugoniot reference curve (u_s = c0 + s u_p, linear release) and one shared conversion produces Gamma, Pi and dPi/drho; a second family is one more case. Stiffened and ideal gas return the constants resolved at init, and no caller invokes the routine yet, so every existing answer is bit-identical - 27-case gate. Parameters mg_rho0, mg_c0, mg_s, mg_G0 follow the flat per-fluid style; the validator requires all four under mie_gruneisen, forbids them otherwise, and forbids qv there because e_ref carries the formation energy. Thirty pytest checks pin the maths against finite differences and a numerically integrated isentrope.
A Mie-Gruneisen fluid has neither gamma, pi_inf nor qv, and an ideal gas has no pi_inf: the validator now refuses them, and the suite's base fluid and every example drop the dead values. The ideal-gas half duplicates MFlowCode#1808 and drops out once it merges.
The mixture loop calls s_eos_coefficients per phase when any fluid's EOS is state dependent; the stiffened-gas arithmetic is untouched (27/27 bit-identical on the gate). The sound speed takes the partial densities as an optional argument and mixes frozen per-phase moduli, with the derivative term applied at that one site. Callers that cannot supply them are refused by the validator: 5-equation, HLL/HLLC/LF only, no bubbles, hypoelasticity, IBM, IGR, relativity, MHD, chemistry, acoustic source, probes, post-process c, characteristic BCs or Wood's law. Validation: symmetric-impact shock speed and plateau density match the Hugoniot to 1.4e-3, and a small pulse travels at the analytic sound speed to 1.9e-4 (the missing derivative term would give 24%).
gamma = gammas(1) and friends were assigned and never read; lit_gamma was assigned in both output routines and read in neither.
…eck passes from worktrees (cherry picked from commit 5ad5c85)
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
This PR extends the 5-equation path to support state-dependent EOS coefficients (Mie–Grüneisen) by evaluating EOS coefficients per phase at each cell’s phasic density, updating sound-speed mixing accordingly, and tightening parameter ownership/validation (e.g., ideal gas no longer “accepts” pi_inf).
Changes:
- Add Mie–Grüneisen EOS selector/parameters and implement per-phase, per-cell EOS coefficient evaluation plus frozen-modulus mixture sound speed with the derivative term.
- Update case validation and tests (new unit/manufactured tests + convergence tests + new MG examples) and introduce a golden kernel covering mixed MG/ideal-gas paths.
- Remove redundant/forbidden ideal-gas
pi_infsettings across examples and test configs; harden coverage tooling’s git invocations.
Reviewed changes
Copilot reviewed 148 out of 148 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| toolchain/mfc/test_eos_mie_gruneisen.py | Adds manufactured/unit checks for MG reference curve mapping and sound-speed identity. |
| toolchain/mfc/test_case_validator.py | Adds validator tests specifically for MG selection/constraints and ideal-gas pi_inf behavior. |
| toolchain/mfc/test/test_coverage_unit.py | Uses shared git-env scrubber from coverage module for hermetic git tests. |
| toolchain/mfc/test/coverage.py | Scrubs GIT_* env for all git subprocess calls to avoid hook-induced repo contamination. |
| toolchain/mfc/test/convergence.py | Adds convergence-style runners for MG acoustic speed and MG Hugoniot impact checks. |
| toolchain/mfc/test/cases.py | Registers new MG convergence tests; adds MG selector coverage case; removes ideal-gas pi_inf from test cases. |
| toolchain/mfc/test/case.py | Removes ideal-gas pi_inf from post-process base test config. |
| toolchain/mfc/params_tests/test_eos_selector.py | Updates EOS selector tests to require pi_inf unset for ideal gas. |
| toolchain/mfc/params/definitions.py | Registers mie_gruneisen EOS and MG parameters in toolchain parameter definitions. |
| toolchain/mfc/eos.py | Implements MG reference curve + EOS coefficients + sound speed + Hugoniot helpers for tests/harness. |
| toolchain/mfc/case_validator.py | Enforces EOS parameter ownership; adds MG constraints, warnings, and scope fences. |
| tests/5AC2F65D/golden.txt | Adds new golden output for mixed MG/ideal-gas kernel coverage. |
| tests/5AC2F65D/golden-metadata.txt | Adds metadata describing environment/settings used to generate the new golden. |
| src/simulation/m_time_steppers.fpp | Threads alpha_rho into cell-state and sound-speed computations for MG path. |
| src/simulation/m_sim_helpers.fpp | Extends s_compute_cell_state signature to return alpha_rho. |
| src/simulation/m_riemann_solver_lf.fpp | Passes partial densities into s_compute_speed_of_sound. |
| src/simulation/m_riemann_solver_hllc.fpp | Passes partial densities into s_compute_speed_of_sound/_avg. |
| src/simulation/m_riemann_solver_hll.fpp | Passes partial densities into s_compute_speed_of_sound/_avg. |
| src/simulation/m_global_parameters.fpp | Initializes MG parameters in fluid_pp defaults. |
| src/simulation/m_data_output.fpp | Uses alpha_rho in stability criteria and removes dead gamma block. |
| src/pre_process/m_global_parameters.fpp | Initializes MG parameters in fluid_pp defaults. |
| src/pre_process/m_data_output.fpp | Removes unused lit_gamma handling in output. |
| src/post_process/m_global_parameters.fpp | Initializes MG parameters in fluid_pp defaults. |
| src/post_process/m_data_output.fpp | Threads alpha_rho into sound-speed call for MG-capable post processing. |
| src/common/m_variables_conversion.fpp | Implements s_eos_coefficients; supports per-phase EOS coefficients and MG sound-speed mixing. |
| src/common/m_global_parameters_common.fpp | Adds global arrays for EOS selectors and MG curve parameters plus any_state_dependent_eos. |
| src/common/m_derived_types.fpp | Adds MG parameters to fluid_parameters derived type. |
| src/common/m_constants.fpp | Adds eos_mie_gruneisen constant. |
| .github/scripts/check_coverage_map_health.py | Uses shared _git wrapper instead of raw subprocess for consistent env handling. |
| examples/3D_turb_mixing/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_sphbubcollapse/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_rotating_sphere/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_recovering_sphere/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_rayleigh_taylor_muscl/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_rayleigh_taylor/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_performance_test/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_patch_spherical_harmonic/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_moving_lag_particles/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_mibm_sphere_head_on_collision/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_mibm_periodic_collision/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_lagrange_shbubcollapse/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_lagrange_bubblescreen/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_icpp_stl_cube/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_ibm_stl_test/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_ibm_stl_pyramid/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_ibm_stl_ellipsoid/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_ibm_bowshock/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_brio_wu/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_advection_convergence/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_TaylorGreenVortex_analytical/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_TaylorGreenVortex/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_IGR_jet_1fluid/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_IGR_jet/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_IGR_TaylorGreenVortex_nvidia/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_IGR_TaylorGreenVortex/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/3D_IGR_33jet/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_zero_circ_vortex_analytical/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_zero_circ_vortex/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_viscous_shock_tube/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_tumbling_rectangle/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_triple_point/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_synthetic_turbulence/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_shockdroplet_muscl/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_shockdroplet/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_shockbubble/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_shock_cloud_rmhd/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_riemann_test_muscl/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_riemann_test/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_richtmyer_meshkov/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_rayleigh_taylor/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_poiseuille_thickening_nn/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_poiseuille_nn/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_patch_modal_shape_exp/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_patch_modal_shape/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_orszag_tang_hyper_cleaning/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_orszag_tang/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_moving_lag_bubs/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_mibm_shock_cylinder/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_mibm_particle_cloud/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_mibm_cylinder_in_cross_flow/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_mhd_rotor/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_mhd_magnetic_vortex/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_lid_driven_cavity_nn/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_lid_driven_cavity/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_laplace_pressure_jump/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_lagrange_rising_bubble/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_lagrange_in_crossflow/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_lagrange_bubblescreen/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_kelvin_helmholtz/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_jet/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_isentropicvortex_analytical/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_isentropicvortex/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_icpp_stl_circle/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_ibm_viscous_drag_over_cylinder/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_ibm_stl_wedge/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_ibm_stl_test/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_ibm_stl_MFCCharacter/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_ibm_poiseuille_nn/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_ibm_multiphase/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_ibm_ellipse/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_ibm_cfl_dt/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_ibm_airfoil/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_ibm/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_hypo_shear_contact/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_herschel_bulkley_poiseuille_nn/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_hardcoded_ic/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_forward_facing_step/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_bingham_poiseuille_nn/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_backward_facing_step/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_axisym_shockbubble/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_advection_muscl/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_advection_convergence/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_advection/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_acoustic_pulse_analytical/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_acoustic_pulse/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_acoustic_broadband/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_TaylorGreenVortex/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_IGR_triple_point/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_IGR_2fluid/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/2D_GreshoVortex/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_vacuum_restart/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_vacuum/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_titarevtorro_analytical/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_titarevtorro/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_sodshocktube_muscl/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_sodshocktube/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_sod_convergence/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_shuosher_wenoz5/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_shuosher_wenom5/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_shuosher_wenojs5/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_shuosher_teno7/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_shuosher_teno5/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_shuosher_old/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_shuosher_analytical/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_mhd_smooth_alfven_wave/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_mg_impact/case.py | Adds MG symmetric-impact example used by Hugoniot convergence harness. |
| examples/1D_mg_acoustic/case.py | Adds MG acoustic-pulse example used by wave-speed convergence harness. |
| examples/1D_laxshocktube/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_kapilashocktube/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_hypo_2materials/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_euler_convergence/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_dai_woodward_hlld/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_dai_woodward/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_convergence/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_brio_wu_rmhd/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_brio_wu_hlld/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_brio_wu/case.py | Removes ideal-gas pi_inf per new ownership rule. |
| examples/1D_advection_convergence/case.py | Removes ideal-gas pi_inf per new ownership rule. |
Suppressed comments (4)
toolchain/mfc/eos.py:1
- Using
x ** 0.5can silently produce a complex value if roundoff makes the argument slightly negative (Python will return acomplexinstead of raising). Prefermath.sqrt(...)(and optionally clamp/validate the argument) so failures are explicit and type-stable for the convergence harness.
toolchain/mfc/test/convergence.py:1 - Parsing the base pressure via
split('+')[0]is brittle (format/whitespace changes, negative terms, or a different expression shape will break the harness). A more robust approach is to have the example emit a dedicated numeric parameter (e.g.,p0) in the JSON, or storepatch_icpp(1)%presas a plain float and encode the perturbation elsewhere.
src/common/m_variables_conversion.fpp:1 s_eos_coefficientsis newly exposed on the module's public interface here. If it’s intended to be an internal helper (especially given it depends on global arrays likeeoss,mg_*s), consider keeping it private to avoid creating a supported external API surface (or add a clear module-level contract/docstring if it must be public).
tests/5AC2F65D/golden-metadata.txt:1- The committed golden metadata indicates it was generated from a dirty working tree. To improve reproducibility/auditability of goldens, regenerate from a clean state (or omit the dirty marker/branch annotation if the metadata is used programmatically).
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Lines of Code
|
Stacked on #1805 (the backend) and overlapping #1808 (the ideal-gas cleanup); review the last three commits. Third step of #1638.
What changes. When any fluid's equation of state is state dependent, the mixture loop in
s_compute_mixture_coefficientsevaluatess_eos_coefficientsper phase at that phase's own density; the stiffened-gas arithmetic is untouched, and the existing 27-case gate is bit-identical.s_compute_speed_of_soundtakes the partial densities as an optional trailing argument and, under the same flag, mixes frozen per-phase moduli with the derivative term-rho_i Pi_i'/Gamma_iapplied at that one site, sof_bulk_modulusand its twenty other callers do not change. The Riemann kernels, the cell-state helper and the post-process energy integral pass the densities through; everything that cannot is refused by the validator (5-equation model, HLL/HLLC/LF, no bubbles, hypoelasticity, IBM, IGR, relativity, MHD, chemistry, acoustic source, probes, post-processc, characteristic BCs or Wood's law). Those fences come out one by one in follow-ups; the 6-equation model needs the phasic isentrope generalized first and is its own PR.Parameter ownership. A Mie-Gruneisen fluid has neither
gamma,pi_infnorqvand an ideal gas has nopi_inf; the validator refuses them, the suite's base fluid and every example drop the dead values, and all 744 test definitions validate. The reference-curve maths moves intotoolchain/mfc/eos.py, one definition shared by the unit tests and the validation runners.Validation (both registered as convergence-kind tests):
1D_mg_impact: symmetric impact of two slabs; shock speed and plateau density match the Hugoniotu_s = c0 + s u_pto 1.4e-3 across four closing speeds (bound 5e-3).1D_mg_acoustic: a small simple-wave pulse travels at the analyticcto 1.9e-4 (bound 1e-3). This is the one observable that isolates the derivative term: without it the speed is 24% off.5AC2F65D: a Mie-Gruneisen fluid beside an ideal gas, so one kernel carries both paths.Also deletes the
gamma = gammas(1)block in both output routines, which was assigned and never read.