Skip to content

Refactor: establish the thermodynamics interface - #1698

Draft
fahnab666 wants to merge 2 commits into
MFlowCode:masterfrom
fahnab666:pr1-thermo-interface
Draft

Refactor: establish the thermodynamics interface#1698
fahnab666 wants to merge 2 commits into
MFlowCode:masterfrom
fahnab666:pr1-thermo-interface

Conversation

@fahnab666

@fahnab666 fahnab666 commented Jul 29, 2026

Copy link
Copy Markdown

Both sound-speed floor sites open-code the same mixture_err guard: s_compute_speed_of_sound in m_variables_conversion.fpp and the post-process derivation in m_derived_variables.fpp. This PR factors the test into one shared predicate, f_validate_state, a [seq] device routine with cray_inline=True, and rewires both sites to it. Each site keeps its own floor (100*sgm_eps simulation, 1.e-16_wp post-process).

The predicate is the old condition inverted, so no arithmetic changes. Diff: two source files, +21/-6. A second commit documents the interface contract in equations.md section 3.3.

This is the first step toward a multi-EOS thermodynamics interface (#1638): name the operations once, so a later EOS family adds a branch instead of editing call sites. No new physics, no new parameters, no runtime dispatch.

Correctness. Bit-identical by construction and by measurement, against a pristine clone of this repo at the branch point (782a1fd). On GPU (LLNL Tuolumne, MI300A gfx942, CCE 19.0.0, OpenMP offload): restart files byte-identical in 16/16 comparisons across 10k/40k/160k cells (2D_shockdroplet, mixture_err on, HLLC, WENO5) plus a case-optimized build, and 32/32 scaling restarts at 1/2/4/8 APUs. 170/170 1D goldens pass. Zero NaN in every scanned restart.

Performance. ./mfc.sh bench on Tuolumne, both trees run concurrently (one node each, 4 ranks x 1 APU), two passes. Grind delta, this branch vs upstream:

case Test 1 Test 2
5eq_rk3_weno3_hll +0.0% -2.0%
5eq_rk3_weno3_hllc +0.3% +0.2%
5eq_rk3_weno3_lf -1.0% +1.0%
hypo_hll +0.9% +0.7%
ibm +0.9% +1.4%
igr -1.6% -2.0%
viscous_weno5_sgb_acoustic -0.9% +0.7%

Signs flip between passes, so there is no systematic trend; hllc, where the sound-speed path is hottest, sits at +0.3/+0.2%. The binary carries no separate device symbol for the predicate, so CCE inlines it on the offload path.

Scaling. Strong: 2.56M cells fixed on 1/2/4/8 APUs. Weak: 1.28M cells per APU. Grind (ns/gp/eq/RHS), lower is better: test in ns per grid point per equation per RHS, global-cell normalized:

APUs strong upstream strong PR weak upstream weak PR
1 0.9358 0.9334 1.2778 1.2856
2 0.6302 0.6371 0.6367 0.6257
4 0.4866 0.4863 0.3201 0.3190
8 0.4134 0.4188 0.1648 0.1657

Agreement within 1.7% at every point; weak efficiency at 8 APUs is 96.9% upstream, 97.0% PR. The strong-scaling solution is byte-identical across 1/2/4/8 ranks under a single hash, so the predicate introduces no rank dependence.

Chemistry. The chemistry adapter ran end to end on the machine: the build generated m_thermochem.f90 with Pyrometheus 1.1.1 from a checksum-pinned Cantera 3.2.0 h2o2.yaml, byte-identical between the two trees. The reactive shocktube (400 cells, 18,681 steps) completed NaN-free on 1 and 8 APUs with output trees matching byte for byte between trees. Golden 5DCF300C passes on GPU in both.

macOS CPU reference. M4 Pro, gfortran, Open MPI 5.0.9, double precision. Restart files byte-identical to the baseline at all three grids. 625/627 goldens; the 2 failures are known load flakes that pass in isolation with and without the change. Debug build runs the shockdroplet case with bounds checks and asserts enabled, no trip. Single-rank simulation wall time, best of two:

grid branch baseline delta
200x50 2.082 s 2.120 s -1.8%
400x100 4.520 s 4.625 s -2.3%
800x200 14.273 s 14.210 s +0.4%

Strong scaling on 14 cores: 91/71/53% efficiency at 2/4/8 ranks; weak: 98/99/76%. The rolloff is single-socket bandwidth saturation, identical with and without the change.

Builds checked in both trees: double, single, chemistry, case-optimized, all clean with warning profiles identical line for line. --mixed fails identically in both trees inside untouched m_derived_types.fpp (CCE 19.0.0 rejects real(kind=2)); pre-existing, unrelated to this change.

…dicate

Both the simulation and post-process sound-speed paths open-coded the same
mixture_err/negative-argument guard before taking sqrt, each with its own floor.
Factor the predicate into f_validate_state, a [seq] device function, and rewire
both sites to it. Each site keeps its existing floor (100*sgm_eps in simulation,
1.e-16 in post-process), so the change is bit-identical: f_validate_state(c) is
.not. (mixture_err .and. c < 0), which reproduces the original NaN-when-mixture_err
-off behavior exactly. First shared operation of the thermodynamics interface.
Add section 3.3 describing the operations every solver path uses to obtain
thermodynamic quantities and the two compile-time-selected adapters that supply
them: stiffened gas (section 3.1) and the Pyrometheus-generated ideal-gas mixture
(section 3.2). Selection is a compile-time branch on the chemistry parameter, so
the device routines carry no indirection and adding an EOS family means adding a
branch to these operations rather than editing every call site.
Copilot AI review requested due to automatic review settings July 29, 2026 06:37
@fahnab666
fahnab666 requested a review from sbryngelson as a code owner July 29, 2026 06:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@fahnab666 fahnab666 changed the title Refactor: route sound-speed admissibility through a shared f_validate_state predicate Refactor: establish the thermodynamics interface Jul 29, 2026
@fahnab666
fahnab666 marked this pull request as draft July 29, 2026 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants