Skip to content

Fix missing qv term in the Lagrange bubble initial pressure - #1709

Open
sbryngelson wants to merge 2 commits into
masterfrom
fix/lagrange-bubble-qv
Open

Fix missing qv term in the Lagrange bubble initial pressure#1709
sbryngelson wants to merge 2 commits into
masterfrom
fix/lagrange-bubble-qv

Conversation

@sbryngelson

@sbryngelson sbryngelson commented Aug 8, 2026

Copy link
Copy Markdown
Member

Fixes #1706.

The defect

src/simulation/m_bubbles_EL.fpp open-codes the stiffened-gas pressure inversion and drops the qv (heat of formation) term:

call s_convert_to_mixture_variables(q_cons_vf, cell(1), cell(2), cell(3), rhol, gamma, pi_inf, qv, Re)
...
pliq = (q_cons_vf(eqn_idx%E)%sf(cell(1), cell(2), cell(3)) - dynP - pi_inf)/gamma

The canonical inversion, s_compute_pressure in m_variables_conversion.fpp:71, is

pres = (energy - dyn_p - pi_inf - qv)/gamma

The omission looks accidental rather than a deliberately different quantity: qv is an output argument of the s_convert_to_mixture_variables call on the line above, and it is never read anywhere else in that scope. It is computed and discarded.

Impact

pliq is too large by qv/gamma, and it seeds the initial bubble gas pressure:

gas_p(bub_id, 1) = pliq + 2._wp*(1._wp/Web)/bub_R0(bub_id)

So every Lagrangian bubble starts from the wrong internal pressure. This is physics, not diagnostic output.

Dormant when qv = 0, which is the default. It triggers for any case setting fluid_pp(i)%qv — the phase-change and reactive-burn configurations.

Why it survived

No test exercised the combination. Exactly one golden case sets bubbles_lagrange, and it leaves qv at zero; the cases that set qv are phase-change and reactive-burn, none of which use Lagrangian bubbles. The suite could not have caught this.

Test

Adds a 2D one-way-coupled Lagrange bubble case with fluid_pp(1)%qv = 0.01, restricted to a single configuration so it contributes one golden (F428FDC0).

The golden captures beta, the Lagrangian void fraction, alongside the conservative variables. beta follows the bubble radius, which is driven by the initial gas pressure, so the error is observable even under one-way coupling.

Verification

new case, fix reverted:   1 failed  (tolerance mismatch)
new case, fix applied:    1 passed
all bubble tests:        64 passed, 0 failed

Built with GNU 15.2.0, MPI, on macOS. The negative result is the one that matters — without it, a green suite would prove nothing here, since the pre-existing cases are all qv = 0.

No existing golden moved: the change is confined to a path only reachable with bubbles_lagrange, and no existing lag case has nonzero qv.

Behaviour change worth flagging

The correction shifts pliq by -qv/gamma, and gamma > 0 always, so the direction follows the sign of qv. For qv > 0 the initial bubble pressure drops, which brings two existing guards in the same routine within reach:

if (gas_mg(bub_id) <= 0._wp) call s_mpi_abort("The initial mass of gas inside the bubble is negative. ...")
if (pv*(massflag) > gas_p(bub_id, 1)) call s_mpi_abort("Lagrange bubble initially located in a region with pressure below the vapor pressure.")

A case with qv > 0 and Lagrangian bubbles that previously ran can now abort at startup. That is the correct outcome — it was running on an inflated bubble pressure that masked a setup the model rejects — but it converts a silently wrong answer into a hard stop, so it is a user-visible change rather than a pure numerical shift. For qv < 0 (as in the phase-change examples, which use qv = -1.167e6 for fluid 1) the pressure rises and the guards become less reachable.

gas_p also feeds the initial gas mass and the bubble natural frequency in the same routine, so both are corrected by the same change.

Adjacent issue found while reviewing

s_add_bubbles also assigns the module-level global pref from the last-added bubble's gas_p (line 383). pref is a documented user-settable case parameter that the four-equation EOS branch reads. This PR changes the value it gets overwritten with, but the overwrite itself is pre-existing and looks wrong independently. Filed as #1710 rather than addressed here.

Context

First of three PRs against #1708. The root cause is that the EOS algebra has several independent definitions, and s_compute_pressure is awkward enough to call — it demands a num_species array and an intent(inout) temperature — that call sites open-code the expression instead. This PR fixes only the bug; deduplication follows separately so that any behavior change lands in a PR whose purpose is to change behavior.

Copilot AI lite review requested due to automatic review settings August 8, 2026 21:11

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.

Pull request overview

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.

Fixes incorrect initial Lagrangian bubble pressure when a nonzero heat-of-formation term (qv) is configured, and adds a targeted regression test/golden to prevent recurrence.

Changes:

  • Include the missing qv term in the stiffened-gas pressure inversion used to seed Lagrangian bubble pressure.
  • Add a new lag-bubble test configuration with fluid_pp(1)%qv = 0.01 to exercise the previously untested path.
  • Add a new golden (43EA05B4) to validate the behavior.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/simulation/m_bubbles_EL.fpp Fixes pressure inversion by subtracting qv in the bubble initialization path.
toolchain/mfc/test/cases.py Adds a constrained regression case that sets qv nonzero for lag bubbles.
tests/43EA05B4/golden-metadata.txt Adds metadata for the new golden tied to the new regression case.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread toolchain/mfc/test/cases.py Outdated
Comment thread tests/43EA05B4/golden-metadata.txt Outdated
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

Claude Code Review

Head SHA: b3431b4

Files changed:

  • 2
  • src/simulation/m_bubbles_EL.fpp
  • toolchain/mfc/test/cases.py

Findings:

  • src/simulation/m_bubbles_EL.fpp:373: The new qv term is subtracted directly from q_cons_vf(eqn_idx%E)%sf(...), dynP, and pi_inf, all of which are energy-density quantities (energy/volume), then the whole thing is divided by gamma to get a pressure. qv (heat of formation) is a specific energy (energy/mass), so it is dimensionally inconsistent to subtract it directly — the standard stiffened-gas-with-formation-energy inversion requires the density-weighted term rhol*qv, not bare qv (i.e. pliq = (E - dynP - pi_inf - rhol*qv)/gamma). As written, this only happens to be correct if rhol is exactly 1, and will be numerically wrong for any real liquid density — silently producing an incorrect pliq for phase-change fluids with qv /= 0, which is precisely the regime the accompanying qv!=0 regression test (toolchain/mfc/test/cases.py) is meant to exercise.

s_add_bubbles open-coded the stiffened-gas pressure inversion and omitted the
qv (heat of formation) term:

    pliq = (E - dynP - pi_inf)/gamma

The canonical inversion in s_compute_pressure (m_variables_conversion.fpp:71)
is (energy - dyn_p - pi_inf - qv)/gamma. The omission is clearly accidental:
qv is an output argument of the s_convert_to_mixture_variables call one line
above and is never read anywhere else in that scope.

pliq seeds gas_p(bub_id, 1), so every Lagrangian bubble started from a wrong
internal pressure. This is physics, not diagnostics. It also propagates to the
initial gas mass and the bubble natural frequency, which are both derived from
gas_p in the same routine.

Consistency with the running solver settles which quantity pliq should be:
s_get_pinf, the Maeda and Colonius (2018) subgrid closure that supplies the
bubble driving pressure at every later step, interpolates q_prim_vf(eqn_idx%E),
and that field is filled by s_compute_pressure with qv included. Initializing
from an inversion that omits qv left each bubble out of equilibrium with its
own driving pressure by qv/gamma.

Only s_add_bubbles needs the change; the restart path reads gas_p straight from
the restart file rather than recomputing it.

Dormant when qv = 0, the default, and every existing lag-bubble test leaves it
there, which is why this survived.

Adds a 2D one-way-coupled case with qv /= 0. The golden lands in a follow-up
commit so that it is generated from a clean tree.

Fixes #1706
Generated from a clean checkout of the preceding commit so the recorded
provenance corresponds exactly to committed sources.

The golden captures beta, the Lagrangian void fraction, alongside the
conservative variables. beta follows the bubble radius, which is driven by the
initial gas pressure, so the defect is observable even under one-way coupling
where the bubbles do not feed back into the Eulerian field.
@sbryngelson

Copy link
Copy Markdown
Member Author

Both Copilot points were valid and are addressed in the force-push (b3431b49191c9a). Details, since I checked them rather than just applying them.

Label qv!=0. Correct, and worse than cosmetic. The case UUID is crc32(sha1(str(trace))) (toolchain/mfc/test/case.py:149), so the label is not merely display text — it determines the golden directory name. Separately, ! is history expansion in interactive bash, so ./mfc.sh test --only "...qv!=0..." misbehaves when pasted into a shell. Checking the conventions: = in labels has ample precedent (riemann_solver=1, weno_order=5, adap_dt=T), but qv!=0 was the only label in the entire file containing !. Renamed to qv_nonzero, which changed the UUID 43EA05B4F428FDC0; the old golden directory is removed and the new one added.

Dirty working tree. Also correct, and the recorded SHA 0c9a1d43 was not even the commit that ended up in the PR. Restructured into two commits so the provenance is real: the source fix and test case land first, then the golden is generated against that clean checkout, then committed. The metadata now reads

Git:  174775fb74510109ef017ea97c98fc9cee1eb5ca on fix/lagrange-bubble-qv (clean)

which is the parent commit in this PR.

One thing the restructure caught. After committing the fix, my original verification method silently stopped working — git stash push -- src/simulation/m_bubbles_EL.fpp had nothing to stash, so the "fix reverted" run was actually testing the fixed binary and reported a pass. Redone with git checkout master -- <file>, which reverts the source properly:

F428FDC0, fix reverted:   1 failed  (tolerance mismatch)
F428FDC0, fix applied:    1 passed
all bubble tests:        64 passed, 0 failed

Worth stating explicitly because a regression test that cannot fail is worse than no test, and the false pass looked identical to a real one.

Also updated the description with two things I had missed on the first pass: the fix can newly trigger the vapour-pressure and negative-gas-mass aborts for qv > 0 cases that previously ran, and s_add_bubbles overwrites the user-supplied global pref from the last bubble's pressure — pre-existing, now filed as #1710.

@codecov

codecov Bot commented Aug 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 60.77%. Comparing base (8dfe8c7) to head (9191c9a).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1709   +/-   ##
=======================================
  Coverage   60.77%   60.77%           
=======================================
  Files          83       83           
  Lines       20872    20872           
  Branches     3101     3101           
=======================================
  Hits        12685    12685           
  Misses       6121     6121           
  Partials     2066     2066           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

bug: Lagrange bubble initial gas pressure omits the qv term from the stiffened-gas inversion

2 participants