Skip to content

IB: abort if an immersed boundary marks no cell anywhere - #1914

Open
sbryngelson wants to merge 1 commit into
MFlowCode:masterfrom
sbryngelson:feat/ib-patch-must-be-claimed
Open

sbryngelson wants to merge 1 commit into
MFlowCode:masterfrom
sbryngelson:feat/ib-patch-must-be-claimed

Conversation

@sbryngelson

Copy link
Copy Markdown
Member

The failure

A rank is given an IB patch when the patch centroid falls in its share of the domain. For an STL the centroid and the geometry are independent: the body is placed by model_translate, and a case may legitimately leave patch_ib%*_centroid at the origin. Ownership is then decided at a point the body does not occupy, and the owning rank marks only whatever of the geometry its own subdomain happens to reach.

That reach shrinks as the decomposition is refined. A body erodes, and can vanish outright — no markers, no ghost points, and a force of exactly 0.0 written to the force file every step, with nothing reported.

Marker generation is a pure function of geometry and grid, so a result that depends on the rank count is always wrong.

Reproducer

Two-body case, identical input deck, only the rank count changed, with a patch at the origin as a built-in control:

ranks control (at origin) patch 8 chords away
64 30191 cells, span 2.50 19115 cells, span 2.51
128 30191 cells, span 2.50 12667 cells, span 0.84
512 30191 cells, span 2.50 absent, force identically 0.0

The control is bit-identical at every decomposition; only the off-origin patch degrades.

What this changes

It does not change the ownership rule — using the centroid as the placement point is a legitimate design choice. It adds the invariant that choice implies: every global patch marks at least one cell somewhere. One integer reduction per patch at setup, nothing at run time, and a specific error message pointing at the centroid/geometry mismatch.

Limitation, stated plainly

This catches total loss, not the partial erosion visible at 128 ranks above. Detecting partial erosion needs the marked volume, which is not available at that point in setup. A user-side check on lustre_ib.dat can compare marked volumes across rank counts if that matters; volume is the right invariant there, not cell count, since a patch in a coarser region of a stretched grid is correctly marked by fewer cells (in our case 37% fewer cells for 1.1% more volume).

Verification

  • All three targets (pre_process, simulation, post_process) build on master + this patch.
  • ./mfc.sh format clean; all seven precheck gates pass.

🤖 Generated with Claude Code

A rank is given an IB patch when the patch centroid falls in its share of
the domain. For an STL the centroid and the geometry are independent: the
body is placed by model_translate, and a case may legitimately leave the
centroid at the origin. Ownership is then decided at a point the body does
not occupy, and the owning rank marks only whatever of the geometry its own
subdomain happens to reach.

That reach shrinks as the decomposition is refined, so a body erodes and can
vanish outright -- no markers, no ghost points, and a force of exactly zero
written every step, with nothing reported. Marker generation is a pure
function of geometry and grid, so a result that depends on the rank count is
always wrong.

Measured on a two-body case, identical deck, only the rank count changed,
with a patch at the origin as a control:

    ranks    control (at origin)      patch 8 chords away
      64     30191 cells, span 2.50   19115 cells, span 2.51
     128     30191 cells, span 2.50   12667 cells, span 0.84
     512     30191 cells, span 2.50   absent, force identically 0.0

This does not change the ownership rule -- using the centroid as the
placement point is a legitimate choice. It adds the invariant that choice
implies: every patch marks at least one cell somewhere. One reduction per
patch at setup, nothing at run time.

It catches total loss, not partial erosion; that needs the marked volume,
which is not available at this point.
Copilot AI lite review requested due to automatic review settings September 20, 2026 23:22
@github-actions

Copy link
Copy Markdown

Lines of Code

File Lines Diff
src/simulation/m_ibm.fpp 1356 +21
Directory Lines Diff
simulation 27869 +21
total 46701 +21

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 review overview

🟡 Changes recommended

The critical setup-time scaling and collective overhead must be addressed before approval.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

Adds setup-time validation to abort when an immersed-boundary patch marks no cells globally.

Changes:

  • Validates marker presence after IB generation.
  • Counts markers per global patch using MPI reduction.
  • Reports centroid/geometry mismatch guidance.
File Summary Review
src/​simulation/​m_ibm.fpp Adds global IB marker validation during setup. Critical: scanning all local cells once per global patch and repeating collectives creates excessive setup cost; use a single count pass and reduction, or restrict scans to local IDs.

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

Comment thread src/simulation/m_ibm.fpp
Comment on lines +1703 to +1707
do gid = 1, num_gbl_ibs
cnt_loc = 0_8
do k = 0, p
do j = 0, n
do i = 0, m

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.

2 participants