Skip to content

Transport volume fractions in the LF solver - #2050

Open
aliencaocao wants to merge 3 commits into
MFlowCode:masterfrom
aliencaocao:fix/lf-interface-velocity
Open

aliencaocao wants to merge 3 commits into
MFlowCode:masterfrom
aliencaocao:fix/lf-interface-velocity

Conversation

@aliencaocao

@aliencaocao aliencaocao commented Oct 13, 2026 •

Copy link
Copy Markdown

Fixes #1818.

Change

src/simulation/m_riemann_solver_lf.fpp hands the right-hand side what adv_src_mode_vel_iface (the mode m_global_parameters.fpp assigns to riemann_solver = 5) expects:

  • the volume fraction flux is the Lax-Friedrichs flux of αₖu, including the advective part that the original code omits;
  • the first source slot holds the Lax-Friedrichs interface velocity instead of an averaged α;
  • in axisymmetric runs, the radial geometric source of the volume fractions is zero. Every other Method 2 solver does the same.
flux(αₖ) = (s_M αₖ,R u_R − s_P αₖ,L u_L + s_M s_P (αₖ,L − αₖ,R)) / (s_M − s_P)
flux_src(adv%beg) = (s_M u_R − s_P u_L) / (s_M − s_P)

With the Lax-Friedrichs speeds s_M = −s_P, these are exactly the Method 2 formulas of MFC's HLL_HLLC_non_conservative_terms_derivations.md, Section 3. This is the same code path that HLL already uses with hll_u_interface = T (m_riemann_solver_hll.fpp lines 586 to 608). That path includes the zero radial source for α (lines 683 to 690).

Why this is correct

The five-equation model advects each volume fraction, ∂αₖ/∂t + u·∇αₖ = 0 (Coralic and Colonius 2014, Eq. 5). MFC discretises this as ∂αₖ/∂t + ∇·(αₖu) = αₖ∇·u, with one shared interface velocity (Coralic and Colonius 2014, Section 3.1). Both terms are built from the same velocity u*. A sum over the fluids then gives

∂(Σₖ αₖ)/∂t = −Δ(Σₖ αₖ u*)/Δx + (Σₖ αₖ) Δu*/Δx = 0        when Σₖ αₖ = 1

The fractions therefore still sum to one, and a uniform α stays uniform. This is the requirement that uniform pressure and velocity stay uniform across an interface (Saurel and Abgrall 1999, Section 3). In cylindrical coordinates, the (1/r)∂(r αu_r)/∂r and α(1/r)∂(r u_r)/∂r terms share the same αu_r/r part. The radial geometric source of α therefore cancels exactly. Before this PR, neither term carried u·∇α. A bubble's volume fraction did not move, while its mass did.

Before and after

The figures below show interface advection from the issue: a light gas bubble in air, in a periodic box. The flow has uniform pressure and velocity (1, 0). The time is t = 0.4. The exact answer moves the bubble from x = 0.3 to x = 0.7.

pr pr
  • Before: the bubble gas sits at x = 0.68 and is torn. The volume fraction stays at x = 0.27 and grows to 172.7. Cell filling ranges from 8% to 17,368%.
  • After: the volume fraction and the bubble gas both sit at x = 0.70. Both stay round. |α_air + α_bubble − 1| ≤ 1.1 × 10⁻¹³ everywhere.

Tests and goldens

The existing Lax-Friedrichs cases with two fluids were generated with the defect and change. The suite had no axisymmetric Lax-Friedrichs case. One is added next to the existing axisymmetric HLL cases (2D -> Axisymmetric -> LF): the stratified two-fluid problem with radial waves. That problem exercises the radial geometric source that this PR changes. It fails on the original code against the new golden. The goldens were regenerated on CPU with GCC 16.2 in double precision without case optimization:

  • 27B24CD9 1D -> 2 Fluid(s) -> Viscous -> riemann_solver=5
  • 4AADC848 3D -> 2 Fluid(s) -> riemann_solver=5 -> mixture_err
  • 4C812637 2D -> 2 Fluid(s) -> Viscous -> riemann_solver=5
  • 96AF00B3 1D -> 2 Fluid(s) -> riemann_solver=5 -> mixture_err
  • 9730B2DF 2D -> 2 Fluid(s) -> riemann_solver=5 -> mixture_err
  • AD1A50B7 3D -> 2 Fluid(s) -> Viscous -> riemann_solver=5
  • B44AF4A1 2D -> Axisymmetric -> LF (new)

Every other test in the suite passes unchanged against its existing golden (from a full suite run with the same compiler and flags).

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:

  • A clear understanding of the codebase
  • Alignment with product direction
  • Thoughtful reasoning behind changes
  • Evidence of real-world usage or hands-on experience with the problem

If these expectations are not met, we would prefer to implement the changes ourselves rather than spend time reviewing low-effort submissions.


Acknowledgement

  • I confirm this PR meets the above expectations and reflects my own understanding and real-world context.

PR template credit: junegunn

The Lax-Friedrichs advection flux carries the transport term like the
mass flux beside it, and its source exports the shared face-normal
interface velocity, which is what the adv_src_mode_vel_iface contract
assigns to this solver. The cylindrical geometric source of the volume
fractions is zero, as it already is for HLL.

Adds an axisymmetric LF suite case; the six existing LF cases with two
fluids change.

Fixes MFlowCode#1818.
Copilot AI balanced review requested due to automatic review settings October 13, 2026 20:03

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.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Claude Code Review

Head SHA: 6f33861

Files changed:

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

Findings:
No issues found. Checked in step 4: src/simulation/m_riemann_solver_lf.fpp (the new advection flux and source use the same Lax-Friedrichs form as the mass flux, with s_M = -s_P; the geometric source for the void fraction is now zero, as its comment says). The cases.py change is a one-line addition and has no context file.

@codecov

codecov Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.92%. Comparing base (47568a0) to head (f0ed089).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2050      +/-   ##
==========================================
+ Coverage   61.90%   61.92%   +0.02%     
==========================================
  Files          86       86              
  Lines       22885    22885              
  Branches     3369     3369              
==========================================
+ Hits        14166    14171       +5     
+ Misses       6220     6215       -5     
  Partials     2499     2499              

☔ 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.

@sbryngelson sbryngelson reopened this Oct 14, 2026
@sbryngelson
sbryngelson requested review from a team, ChrisZYJ and danieljvickers October 14, 2026 15:08
@github-actions

Copy link
Copy Markdown

Lines of Code

File Lines Diff
src/simulation/m_riemann_solver_lf.fpp 510 +1
Directory Lines Diff
simulation 28527 +1
total 47586 +1

@wilfonba

Copy link
Copy Markdown
Collaborator

@sbryngelson, I ran the reproducer for this myself and confirmed the implemented equations reduce to the correct flux. I am confident this change is correct and improves the code. It is ready to merge once the runners finish. It's a ~6-line source-code change + regenerated golden files for affected numerics. It failed a documentation runner for some reason, but I just restarted it. Hopefully that fixes the issue.

@wilfonba

Copy link
Copy Markdown
Collaborator

@aliencaocao I believed the failed runners just need to be restarted, but I don't think I get that option till the rest of the suite finishes.

This branch has not been deployed

No deployments
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: Lax-Friedrichs solver does not transport volume fractions

4 participants