Skip to content

Keep on-boundary 3D points inside the domain (fix corner/edge/face NaN masking) - #5704

Closed
aabills wants to merge 2 commits into
mainfrom
claude/contains-points-boundary
Closed

Keep on-boundary 3D points inside the domain (fix corner/edge/face NaN masking)#5704
aabills wants to merge 2 commits into
mainfrom
claude/contains-points-boundary

Conversation

@aabills

@aabills aabills commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Description

UnstructuredSubMesh.contains_points_3d decides whether 3D query points lie inside the mesh domain, using the generalized winding number (sum of signed solid angles over the boundary triangles), and returns winding > 2 * np.pi.

A point sitting exactly on the boundary surface gets a partial solid angle that lands at or below the halfway threshold, so it is misclassified as outside:

point location winding > 2π?
interior ✅ inside
flat face ❌ (not strictly >) → outside
edge π ❌ → outside
corner π/2 ❌ → outside
exterior 0 ❌ outside

contains_points_3d is called (via ProcessedVariable._get_boundary_mask_interpolate_spatial, and via get_3d_slices) to blank out-of-domain points to NaN when interpolating or plotting a 3D unstructured field. So any query point that lands exactly on a domain face/edge/corner — which happens routinely when a regular plotting/sampling grid touches the domain boundary — is masked to NaN. The solution itself is unaffected; this is post-processing/plotting only.

Verified empirically on a unit cube: winding is exactly π/2 at a corner, π on an edge, 2π on a face, 4π in the interior, and 0 outside — matching the geometry.

Fix

Lower the threshold below the smallest on-surface value (π/2 at a corner), so interior and on-boundary points count as inside while true exterior (winding ≈ 0) stays outside:

return winding > 0.1

Testing

  • New test test_contains_points_3d_boundary_points_are_inside asserts a corner, edge midpoint, face centre, and interior point are all inside, and an exterior point is not. It fails before the change (corner/edge/face classified outside) and passes after — verified by reverting the source line alone.
  • uv run --group dev pytest packages/pybamm/tests/unit/test_meshes — 163 passed.
  • uv run pre-commit run --all-files clean.

🤖 Generated with Claude Code

UnstructuredSubMesh.contains_points_3d classified query points lying
exactly on a face, edge, or corner of the domain as outside, because
their winding number is a partial value (2*pi on a face, pi on an edge,
pi/2 at a corner) that fails the strict > 2*pi interior test. Points
sampled on the domain boundary when interpolating or plotting a 3D
unstructured field were therefore masked to NaN. Use a small positive
threshold so on-boundary points count as inside while true exterior
(winding ~ 0) stays outside.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@aabills
aabills requested a review from a team as a code owner August 7, 2026 00:01
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.11%. Comparing base (f82976f) to head (ccd225c).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #5704   +/-   ##
=======================================
  Coverage   98.11%   98.11%           
=======================================
  Files         340      340           
  Lines       32744    32744           
=======================================
  Hits        32128    32128           
  Misses        616      616           

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

@aabills

aabills commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Closing: out of scope for #5688. Pre-existing item in already-merged #5687 mesh code, not part of the spatial-method PR.

@aabills aabills closed this Aug 7, 2026
@aabills
aabills deleted the claude/contains-points-boundary branch August 7, 2026 00:26
Sign up for free to 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.

1 participant