Skip to content

Fix lost particles after virtual surface crossings in complex regions - #4139

Open
yrrepy wants to merge 7 commits into
openmc-dev:developfrom
yrrepy:fix-complex-region-distance-position
Open

yrrepy wants to merge 7 commits into
openmc-dev:developfrom
yrrepy:fix-complex-region-distance-position

Conversation

@yrrepy

@yrrepy yrrepy commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Description

This fixes a lost-particle failure that can occur at complex CSG boundaries. The issue was exposed by weight-window surface checkpoints.

I have a large model, in it, when weight window surface checkpoints are on, I would get the following failures:
WARNING: Could not find the cell containing particle 2488140
WARNING: Could not find the cell containing particle 2771912

This was previously working in 0.15.4, but these errors appear with 0.16.1-dev.
I narrowed it down to PR #3934
Issue #4140 documents the problem and provides a MWE to reproduce it.

per Codex:
During a complex-region distance search, the candidate position was previously advanced incrementally across virtual surface crossings. The particle was later transported by applying the returned total distance to its original position. Roundoff could therefore make the position used to identify the boundary differ from the particle's actual transported position. In affected cases, the returned surface was inconsistent with the final position and the subsequent cell search failed.

per Codex

- Recomputes each candidate position from the initial position and accumulated distance, matching `GeometryState::move_distance`.
  - Uses `std::nextafter` when a roundoff-scale step does not increase the accumulated distance, ensuring progress across coincident surfaces.
  - Adds unit tests covering:
    - Position consistency after multiple virtual crossings.
    - Leaving a union through coincident surfaces.
    - Entering an intersection through coincident surfaces.
  - Updates the `filter_mesh` reference result. The position change affects a spherical-mesh crossing at `theta = pi/2` through roundoff.

Checklist

  • I have performed a self-review of my own code
  • I have run clang-format (version 18) on any C++ source files (if applicable)
  • I have followed the style guidelines for Python source files (if applicable)
  • I have made corresponding changes to the documentation (if applicable)
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I used Codex

The position in Region::distance_complex is recomputed from the accumulated
distance. When a candidate step is smaller than the resolution of that
distance, the position does not move. Two coincident surfaces in one region
then make the search alternate between them forever. This occurs after about
100 m of flight inside one cell, when leaving a union and when entering an
intersection.

Take the smallest representable step when the accumulated distance does not
change. Add a unit test with two coincident planes that covers both cases.
The position change in Region::distance_complex moves track end points by
roundoff. Only the spherical mesh tallies of this test change, because
SphericalMesh::find_theta_crossing detects the crossing of the theta = pi/2
grid surface depending on roundoff. All other regression results are
unchanged. Generated with GCC and OPENMC_ENABLE_STRICT_FP=on.
Assert the returned distance, state that the test coordinates are
deliberate, and scope the comment in Region::distance_complex to the
position at the true boundary.
@yrrepy
yrrepy marked this pull request as ready for review September 17, 2026 22:44
@GuySten GuySten added the Bugs label Sep 17, 2026

@GuySten GuySten 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.

Except from one small suggestion,
LGTM.

Comment thread src/cell.cpp Outdated
Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com>
@yrrepy
yrrepy force-pushed the fix-complex-region-distance-position branch from 51ef78e to f240a12 Compare September 18, 2026 07:54
@GuySten GuySten added the Merging Soon PR will be merged in < 24 hrs if no further comments are made. label Sep 18, 2026

@paulromano paulromano 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.

I'm planning on reviewing this

@GuySten GuySten removed the Merging Soon PR will be merged in < 24 hrs if no further comments are made. label Sep 18, 2026

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants