Repository navigation
Restore pT equilibrium when pTg relaxation uses up a phase - #2052
aliencaocao wants to merge 3 commits into
Conversation
When the pTg relaxation depletes one of the reacting phases, the Gibbs equality no longer constrains the state, so the pT solver runs again on the final masses. The seven Phase Change model 6 goldens and the phasechange_bubble example change. Fixes MFlowCode#1820.
|
Claude Code Review Head SHA: bc23e06 Files changed:
Findings: |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #2052 +/- ##
==========================================
- Coverage 61.90% 61.89% -0.01%
==========================================
Files 86 86
Lines 22885 22887 +2
Branches 3369 3370 +1
==========================================
+ Hits 14166 14167 +1
Misses 6220 6220
- Partials 2499 2500 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Lines of Code
|
|
@aliencaocao I changed the triggering condition from floating-point comparisons to |
|
@wilfonba I have ran the reproducer using your fix and can confirm it fixes the issue in the same way. |
| real(wp), intent(in) :: rhoe | ||
| type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf | ||
| real(wp), intent(inout) :: TS | ||
| logical, intent(out) :: ptg_conv |
| call s_infinite_ptg_relaxation_k(j, k, l, pS, rhoe, q_cons_vf, TS, ptg_conv) | ||
|
|
||
| ! Unconverged pTg; solve pT equilibrium again for the final masses | ||
| if (.not. ptg_conv) call s_infinite_pt_relaxation_k(j, k, l, 2, pS, p_infpT, q_cons_vf, rhoe, TS) |
There was a problem hiding this comment.
prove this gives the right results, what are the costs if it does? tradeoffs?
|
your PR shows that the solution changes and via an energy argument is better, but i don't see validation that this is the correct solution it's converging to? what about transient processes as well? is it robust under those? surely there's some cost to this as well? |
|
I think it would help to set the context if I go through what the bug is first so you can see how I am arriving at the fix, before we get to why it is correct and its costs. Every time step, each cell runs two solves in a row. First, a pT solve, given these masses and this much internal energy, find the one pressure and temperature where the fluids exactly fill the cell and the energies add up. Then, if both reacting phases are present, a pTg solve, move mass between liquid and vapor until both would rather coexist. (that's the saturation condition). Sometimes the right answer to the second solve is to convert all of it. The liquid fully evaporates. But the equation the pTg solver is trying to satisfy (liquid and vapor in equilibrium) is meaningless once one of them is gone. So the Newton just runs out of iterations MFC/src/common/m_phase_change.fpp Lines 369 to 372 in 47568a0 My fix is to ignore the leftover (p, T) and redo the first pT solve with the final masses. That problem always has an answer, and it just reuses an existing solver (relax_model = 5). Why that is correct: To validate the solution independently of MFC's solvers, I took the output files and checked whether they indeed satisfy the equations of the pT problem. On D21F4F38 step 50, the two depleted cells are pure single phase, so the equilibrium has a closed form, p = (n−1)(ρe − m·q) − n·B. It matches the pressure in MFC's output to floating-point accuracy, with α = 1 exactly. Cost: On transients: D21F4F38's depletion happens during the run, not just at the initial condition, and in the bubble reproducer 552 cells deplete between step 0 and step 20 and still close to 4.6e-11 / 5.7e-12. The re-solve only recomputes (p, T) so it adds no new feedback path into the time stepping. Thus it remains stable mid-run. If anything, the transients were the problem that the PR is trying to fix. For the trade off we have 3 cases:
|
|
seems convincing |
Fixes #1820.
Change
In
s_infinite_relaxation_k(src/common/m_phase_change.fpp), right after the pTg solve, the code checks whether either reacting mass is exactly zero. If it is, the existing pT solver is called again for the final masses. The call happens before the volume fractions and phasic energies are rebuilt:The test is exact because the pTg solver projects the liquid mass with
min(max(ml, 0), mT). A depleted phase is therefore exactly 0. The vapor massmT − mlis exactly 0 when the liquid mass reaches mT. States where both phases are present take the same path as in the original code.Why this is correct
The pTg system solves Gibbs equality g_l(p, T) = g_v(p, T) together with the energy constraint for the liquid mass and pressure. The formulation follows Wilfong et al. (2025), Section 4.1.3 and MFC equations.md, Section 8.2. Gibbs equality is the condition for coexisting phases. When the projection removes one phase entirely, it cannot hold. The (p, T) where the Newton iteration stops is then not an equilibrium of the fluids that remain. Their equilibrium is the pT problem (Pelanti and Shyue 2014, Section 4, Step 3a; Wilfong et al. 2025, Section 4.1.3):
That is exactly what
s_infinite_pt_relaxation_ksolves (Section 8.1), with the masses that the pTg step leaves and the unchanged ρe. The rebuild of αₖ = mₖ/ρₖ and αₖρₖeₖ from that (p, T) therefore satisfies Σαₖ = 1 and Σαₖρₖeₖ = ρe by construction.Before and after
The figure shows the air and vapor bubble from the issue, from the initial state that
pre_processwrites to 20 steps (1.8 ns):Tests and goldens
The
Phase Change model 6cases and thephasechange_bubbleexample pass through depleted cells. Their goldens therefore change (for the example already at step 0, becausepre_processrelaxes the initial condition with the same routine). The goldens were regenerated on CPU with GCC 16.2 in double precision without case optimization:02BD9B5E2D -> Phase Change model 6 -> 3 Fluid(s) -> model equation -> 376C663B71D -> Phase Change model 6 -> 2 Fluid(s) -> model equation -> 28D6E051E1D -> Phase Change model 6 -> 3 Fluid(s) -> model equation -> 3AAE5C27B2D -> Phase Change model 6 -> 3 Fluid(s) -> model equation -> 2B97D49662D -> Example -> phasechange_bubbleD21F4F381D -> Phase Change model 6 -> 2 Fluid(s) -> model equation -> 3D81363921D -> Phase Change model 6 -> 3 Fluid(s) -> model equation -> 2Related: #1927 concerns when pTg relaxation is activated. This PR concerns what happens after it has run.
Contribution Policy
We do not accept pull requests generated primarily by AI without genuine understanding or real-world usage context.
All contributions are expected to demonstrate:
If these expectations are not met, we would prefer to implement the changes ourselves rather than spend time reviewing low-effort submissions.
Acknowledgement
PR template credit: junegunn