Skip to content

Compute bounding boxes for general planes and tori in C++ - #4087

Open
dylanpulver wants to merge 1 commit into
openmc-dev:developfrom
dylanpulver:fix-cxx-python-bounding-box-parity
Open

Compute bounding boxes for general planes and tori in C++#4087
dylanpulver wants to merge 1 commit into
openmc-dev:developfrom
dylanpulver:fix-cxx-python-bounding-box-parity

Conversation

@dylanpulver

Copy link
Copy Markdown

Description

SurfacePlane and the three torus classes have no bounding_box override, so they fall through to Surface::bounding_box and return an infinite box, while the Python API computes a real one for all four. That is the inconsistency in #2632: s64 there is a y-plane written with cos(pi/2) in the x and z slots, which PlaneMixin recognizes as axis-aligned and C++ does not.

This adds the four overrides, following @paulromano's suggestion on the issue to give SurfacePlane the logic PlaneMixin.bounding_box already has. The tori are included because they have the same gap, and there C++ was returning an infinite box for a region that is actually compact.

One thing I did not expect, and the only judgement call here. PlaneMixin.bounding_box decided alignment from the normalized normal but picked intercepts from the raw coefficients. Those disagree when an off-axis coefficient is above _atol while the normal is still within it — roughly 1e-12 to 1e-6, moving with the scale of the coefficients since the raw test is not scale-invariant. In that band the box excluded points inside its own half-space: Plane(1, 1e-11, 0, 5) gave ll = [5, 5e11, -inf]. Mirroring that into C++ would have shipped a box that makes volume calculations miss volume, so the tolerance is now applied consistently on both sides. Happy to split that into its own PR if you would rather look at it separately.

Verification. Differential harness, 224 surfaces x both senses, Python vs C++ through openmc.lib's own DBL_MAXinf convention: 116 divergences before, 0 after, with every already-implemented surface type agreeing on both sides as a built-in control. An independent oracle that reads neither implementation — check that any point satisfying the half-space inequality lies inside the reported box — went from 35,213 violations to 0 over 160,000 in-half-space points.

New tests/cpp_unit_tests/test_surface.cpp, 66 assertions, including the cell from the issue asserted against the values reported there. Mutants: reverting the source kills 27 assertions, a literal port of the Python logic kills 7, dropping the alignment gate kills 12. 38 of 66 discriminate; the other 28 guard directions that must stay unbounded.

Scope. macOS/arm64, no MPI/DAGMC/libMesh. C++ unit tests 12/13, test_mcpl_stat_sum failing identically before and after because MCPL is not installed here. Python test_surface, test_bounding_box, test_surface_composite and test_geometry: 89 passed / 1 failed identically on both sides, that failure pre-existing and wanting an openmc executable on PATH. test_region::test_plot and test_universe abort the interpreter here, also identically on both sides. The regression suites need cross-section data this machine does not have and were not run. clang-format 18 clean.

Fixes#2632

Disclosure: the code, the tests and this description were drafted by Claude Opus 5 working as a coding agent in this repository.

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)

The C++ Surface::bounding_box overrides cover the axis-aligned planes,
the axis-aligned cylinders and the sphere, but not SurfacePlane or the
three torus classes, while the Python API computes a box for all four.
A cell bounded by a general plane that is axis-aligned to within
roundoff therefore reports a different bounding box through
openmc.lib.Cell.bounding_box than through openmc.Cell.bounding_box.
Add the four missing overrides, mirroring the Python implementations.
PlaneMixin.bounding_box tested for axis alignment using the normalized
normal but chose per-axis intercepts using the raw coefficients. Those
criteria disagree for off-axis coefficients between the tolerance and
roughly 1e-6, where the resulting box excluded points that lie inside
the half-space. Apply the alignment tolerance consistently so both
implementations agree and neither produces such a box.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BoundingBox inconsistency between C++ and Python

1 participant

@dylanpulver