Fix wall_hit_cart/xend_cart inconsistency when from_cart fails#321
Conversation
Visual EvidenceThe histogram compares position differences between Key improvements:
Test configuration: SQUID stellarator, 1ms simulation, 1024 particles starting at s=0.6, using CGAL-embedded STL chartmap. |
ⓘ Your approaching your monthly quota for Qodo. Upgrade your plan PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
||||||||||||||||||||||||
|
Update: The visual evidence histogram is available locally at The fix significantly improves consistency between the CGAL-reported wall intersection ( |
ⓘ Your approaching your monthly quota for Qodo. Upgrade your plan PR Code Suggestions ✨Explore these optional code suggestions:
|
||||||||||||
c85adf0 to
26182df
Compare
26182df to
00db71a
Compare
00db71a to
a7e8614
Compare
a7e8614 to
b0f92bc
Compare
b0f92bc to
c2a6649
Compare
c2a6649 to
7b58a67
Compare
5e930cb to
6252687
Compare
6252687 to
550f1f3
Compare
When CGAL detects a wall intersection, wall_hit_cart correctly stores the intersection point in Cartesian coordinates. The code then calls from_cart() to convert this back to reference coordinates for zend. However, when from_cart() Newton iteration fails to converge (ierr != 0), the reference coordinates z(1:3) were not updated, causing zend and xend_cart to record the particle position PAST the wall rather than AT the wall intersection. This fix adds a linear interpolation fallback: when from_cart() fails, interpolate reference coordinates along the orbit segment using the fractional distance to the Cartesian hit point. Also update CGAL from 5.6.1 to 6.0.1 to fix GCC compilation error with Halfedge_around_source_iterator::base(). Test results show significant improvement: - Before: 32.1% of wall hits had >100cm discrepancy - After: 3.6% of wall hits have >100cm discrepancy
For STL wall hits, xend_cart should equal wall_hit_cart (the true CGAL intersection point). Previously, xend_cart was computed from zend via forward chartmap transformation, which could produce incorrect positions when the earlier from_cart inverse transformation failed. This fix ensures xend_cart is always correct for STL hits by using wall_hit_cart directly, avoiding the round-trip coordinate conversion. Also set xend_cart to zero (not xstart_cart) for untraced particles. Test results: - PRE-FIX: 2/50 exact matches, max error 1595 cm - POST-FIX: 50/50 exact matches, zero error
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
550f1f3 to
4724600
Compare

Risk tier
Correctness contract
Intended behavior change
For STL wall intersections,
xend_cartis written from the authoritative CGALwall_hit_cartpoint. Iffrom_cart()fails in an ill-conditioned chartmap region,zendfalls back to linearly interpolated reference coordinates for angle-space diagnostics.Untraced particles now write zero
xend_cartinstead of reusingxstart_cart.Behavior that must not change
Non-STL end positions still come from
zendthrough the reference-coordinate Cartesian transform.zstart,zend,times_lost, class output, and wall-hit flags keep their existing shapes and meanings.Coordinate / unit conventions
xend_cartandwall_hit_cartare Cartesian coordinates in the NetCDFxyzframe and units.zendremains phase-space output in reference coordinates.Numerical invariants
For STL hits,
xend_cart == wall_hit_cartat the recorded hit. For untraced particles,zend(1:3) == 0impliesxend_cart == 0.Tests added
test_netcdf_results.pymake test TEST=test_netcdf_results VERBOSE=1Golden-record impact
Failure modes considered
from_cart()may fail near ill-conditioned chartmap regions.xend_cartfrom badzendcan move the displayed wall hit away from the true STL intersection.Manual validation
The NetCDF focused test passed after updating the untraced-particle expectation and adding the wall-hit semantic assertion.
Verification