Skip to content

IBM: restore the IB force and torque with the dual-pass hypoelastic HLLD - #2206

Merged
sbryngelson merged 4 commits into
MFlowCode:masterfrom
sbryngelson:fix/ib-force-igr-hypo
Nov 14, 2026
Merged

sbryngelson merged 4 commits into
MFlowCode:masterfrom
sbryngelson:fix/ib-force-igr-hypo

Conversation

@sbryngelson

Copy link
Copy Markdown
Member

What

#2162 took the IB force from the momentum fluxes across the body's faces and added a validator rule rejecting force output and moving bodies with igr or with the hypoelastic dual-pass HLLD (hypoelasticity = T, riemann_solver = 4), whose RHS it said is "not one set of face fluxes". That removed a working feature for the dual-pass solver. This PR restores it.

  • Dual-pass hypoelastic HLLD: the RHS is assembled twice, from the hat-L and hat-R anchored flux sets. A fluid cell takes the hat-L flux at its right face and the hat-R flux at its left face, so a body face now reads the set that actually updates its fluid cell (new f_ib_face_flux), and the accumulation runs once per direction after both sets exist. s_accumulate_ib_face_fluxes returns early when no force or exchange is wanted, so the RHS calls it unconditionally. A one-element placeholder for the unused hat-R array keeps amdflang from aborting on unallocated arrays named in untaken branches.
  • IGR is not touched. The igr clause of the IBM: take the IB force from the momentum fluxes across the body's faces #2162 rule was unreachable: check_igr_simulation already rejects ib = T with igr = T ("IGR does not support the immersed boundary method"). With that rule lifted as a diagnostic, even a static circle fails on every platform (q_prim_vf is never allocated under IGR: a bounds error on CPU debug, an illegal address on an A100, a memory fault on an MI300A), so IGR with immersed boundaries never worked and nothing was removed there. Supporting it is a separate feature and is not attempted here.
  • The IBM: take the IB force from the momentum fluxes across the body's faces #2162 validator rule is removed (redundant), two validator tests now expect the existing IGR message, and one new test checks that hypoelastic HLLD with forces and a moving body is accepted. case.md loses the two "not supported with igr or hypoelastic HLLD" clauses and gains a note on which flux sets form the force.
  • Three new tests with ib_force_wrt: 2D fixed circle (AA36F5D2), 2D two-way circle (BA59123E), 3D sphere (8DDB767E).

Verification

Exactness (temporary instrumentation, not committed; NVIDIA A100, 2D and 3D, fixed and moving bodies): at body faces the accumulated force equals the force reconstructed from the RHS arrays the solver actually used (rhs_hatL and rhs_hatR of the fluid cells next to the body) to a relative difference of at most 2.5e-15 over more than 1000 comparisons, for all directions, G = 0, 0.5 and 5, and a two-way body.

G = 0 limit: with G = 0 for both fluids the dual-pass HLLD force history matches the WENO5 + HLLC force (no hypoelasticity) to the printed 9 digits, in 2D and 3D, and the momentum balance of the non-body fluid cells against the body force closes to about 1e-15. With G /= 0 the same balance leaves 2e-5 to 3e-5 (1.7e-4 with a moving body): the dual-pass hat-L and hat-R fluxes differ at interior faces, so fluid momentum is not exactly conserved by the scheme itself; it is not an error in the accumulation. The AMD force history matches NVIDIA's to the printed precision.

Test sets, labels run with --no-chemistry --no-examples:

Platform New tests IBM Hypoelasticity
A100 80GB, NVHPC 25.11, OpenACC (this head) 3/3 87/87 65/65
MI300A, AFAR amdflang, OpenMP offload (before the last merge of master) 3/3 85/85 65/65
CPU, gfortran, no MPI (before the last merge of master) 3/3 85/85 64/64

Limitations

  • The two 2D tests carry override_tol = 1e-5: on the first A100 run 11 of 225,280 stress values near the body differed from the CPU-generated golden by up to 1.5e-6. With that tolerance these two tests alone would not catch a wrong-flux-set error of order 1e-5; the exactness check above is the real evidence.
  • The torque reuses the unchanged lever-arm code and was not checked separately.
  • ib_heat_wrt and thermal_bc = 3 need chemistry, which hypoelastic HLLD forbids, so the flux selection wired through the energy and mass fluxes is not exercised.
  • Axisymmetric hypoelastic HLLD: the geometric source flux is not part of the face sums, as before. Not tested.
  • Not run on Cray CCE here (CI has Frontier).

This PR was made with Claude Code (AI).

MFlowCode#2162 took the IB force from the momentum fluxes across the body's faces and
made the validator reject it with hypoelastic HLLD, whose RHS uses two flux
sets. That RHS updates a fluid cell with the hat-L flux at its right face and
the hat-R flux at its left, so each body face now reads the set that updates
its fluid cell (f_ib_face_flux), and the accumulation runs once per direction
after both sets exist. s_accumulate_ib_face_fluxes now returns early when no
force or exchange is wanted, so the RHS calls it unconditionally.

Adds 2D fixed, 2D two-way and 3D sphere tests with ib_force_wrt. The igr
clause of the MFlowCode#2162 rule was unreachable (check_igr_simulation rejects ib
with igr) and goes with it; the validator tests expect that message.
@github-actions

github-actions Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Claude Code Review

Head SHA: 49a75b0

Files changed:

  • 7
  • docs/documentation/case.md
  • src/simulation/m_ibm.fpp
  • src/simulation/m_rhs.fpp
  • src/simulation/m_riemann_solvers.fpp
  • toolchain/mfc/case_validator.py
  • toolchain/mfc/test/cases.py
  • toolchain/mfc/test_case_validator.py

Findings:
No issues found. Checked m_ibm.fpp (side/hatR mapping: side=-1 means the fluid cell's left face, so hat_R is right; side=+1 means its right face, so hat_L), m_rhs.fpp, m_riemann_solvers.fpp (placeholder alloc/dealloc pairing), case_validator.py (the igr rejection still comes from the existing "IGR does not support the immersed boundary method" check) and test_case_validator.py.

@sbryngelson
sbryngelson marked this pull request as ready for review November 12, 2026 14:12
@sbryngelson
sbryngelson requested a review from a team as a code owner November 12, 2026 14:12
@sbryngelson
sbryngelson requested review from danieljvickers and removed request for a team November 12, 2026 14:12
@codecov

codecov Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 64.28571% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.91%. Comparing base (9649d50) to head (19cdf55).
⚠️ Report is 7 commits behind head on master.

Files with missing lines Patch % Lines
src/simulation/m_ibm.fpp 81.81% 0 Missing and 2 partials ⚠️
src/simulation/m_rhs.fpp 0.00% 0 Missing and 2 partials ⚠️
src/simulation/m_riemann_solvers.fpp 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2206      +/-   ##
==========================================
+ Coverage   63.71%   64.91%   +1.20%     
==========================================
  Files          90      110      +20     
  Lines       24569    29488    +4919     
  Branches     3584     4469     +885     
==========================================
+ Hits        15653    19143    +3490     
- Misses       6135     6803     +668     
- Partials     2781     3542     +761     

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

@github-actions

Copy link
Copy Markdown

Lines of Code

File Lines Diff
src/simulation/m_ibm.fpp 2874 +13
src/simulation/m_rhs.fpp 2083 -2
src/simulation/m_riemann_solvers.fpp 143 +2
Directory Lines Diff
simulation 39242 +13
total 59189 +13

@sbryngelson
sbryngelson merged commit 9bf41e8 into MFlowCode:master Nov 14, 2026
50 of 54 checks passed
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.

1 participant