Stage: SIMPLE / symplectic multi-volume integration (milestone M2/M3 boundary)
Source language: Fortran 2008
Manuals to read first: src/orbit_symplectic.f90 (orbit_timestep_sympl, per-scheme step routines — where the substep must land exactly on the interface); DOC/spectre-interface-crossing.md (from #440); src/field/field_can_spectre.f90 (from [spectre-07]).
Depends on: #439, #440
Goal
Multi-volume symplectic guiding-center integration: when an implicit symplectic step would cross an interface, SIMPLE shortens it to land exactly on the surface (same scheme, Newton on the substep length), applies the Level-1 map from #440 in physical variables, re-canonicalizes the momenta in the neighbor volume's gauge (per-volume gauges differ; re-initialization sidesteps gauge matching entirely — same code path as orbit start), and continues. Composition {symplectic flow} ∘ {symplectic jump} ∘ {symplectic flow} preserves long-time invariants.
Files to edit
src/orbit_symplectic.f90 (or a NEW thin wrapper module if cleaner): crossing detection on accepted steps, substep solve, restart; no change to in-volume step math.
src/simple.f90 / src/simple_main.f90: multi-volume orbit loop for integmode >= 1.
test/tests/test_spectre_sympl_crossing.py: NEW.
Behavior to implement
- Detection: accepted step ends with
rho_g past an integer, or Newton fails to converge near a boundary → event mode.
- Substep: solve
rho_g(h*) = boundary with the same implicit scheme (map for shorter h* is symplectic); Newton iterates may evaluate the polynomial extension past the boundary — allowed, never clamped.
- Handover: physical state
(theta, zeta, v_par, mu) + kicked components from the crossing map → re-initialize the integrator state (pth, internal caches) from the neighbor volume's Ath, Aph, hth, hph exactly like a fresh orbit start.
- One-step methods only — no history to migrate; assert this where the integrator is selected.
Acceptance scenarios (BDD)
- Given an axisymmetric two-volume equilibrium with a pressure step, when a passing orbit crosses interfaces thousands of times over a long trace, then energy AND
p_phi show no secular drift (linear-fit slope consistent with zero; bounded oscillation) — the symplecticity witness for the composed map.
- Given the same physical setup, then symplectic and RK45+crossing loss/CROSS statistics agree within Monte-Carlo error for a 1000-particle ensemble.
- Given a Poincare section of a crossing orbit (guiding-center footprint at fixed
zeta), then the footprint is continuous across the interface up to the documented tangential kick — no numerical gap or overlap artifacts.
- Given step-size halving across a crossing-rich trace, then post-crossing states converge at the scheme's order (the event location does not degrade order).
- Given a reflection event during symplectic integration, then the orbit continues in-volume with exactly conserved energy and the event appears in the crossing log.
Success criteria
make && make test TEST=spectre_sympl_crossing
Non-goals
Verification
make test TEST=spectre_sympl_crossing
Stage: SIMPLE / symplectic multi-volume integration (milestone M2/M3 boundary)
Source language: Fortran 2008
Manuals to read first:
src/orbit_symplectic.f90(orbit_timestep_sympl, per-scheme step routines — where the substep must land exactly on the interface);DOC/spectre-interface-crossing.md(from #440);src/field/field_can_spectre.f90(from [spectre-07]).Depends on: #439, #440
Goal
Multi-volume symplectic guiding-center integration: when an implicit symplectic step would cross an interface, SIMPLE shortens it to land exactly on the surface (same scheme, Newton on the substep length), applies the Level-1 map from #440 in physical variables, re-canonicalizes the momenta in the neighbor volume's gauge (per-volume gauges differ; re-initialization sidesteps gauge matching entirely — same code path as orbit start), and continues. Composition {symplectic flow} ∘ {symplectic jump} ∘ {symplectic flow} preserves long-time invariants.
Files to edit
src/orbit_symplectic.f90(or a NEW thin wrapper module if cleaner): crossing detection on accepted steps, substep solve, restart; no change to in-volume step math.src/simple.f90/src/simple_main.f90: multi-volume orbit loop forintegmode >= 1.test/tests/test_spectre_sympl_crossing.py: NEW.Behavior to implement
rho_gpast an integer, or Newton fails to converge near a boundary → event mode.rho_g(h*) = boundarywith the same implicit scheme (map for shorterh*is symplectic); Newton iterates may evaluate the polynomial extension past the boundary — allowed, never clamped.(theta, zeta, v_par, mu)+ kicked components from the crossing map → re-initialize the integrator state (pth, internal caches) from the neighbor volume'sAth, Aph, hth, hphexactly like a fresh orbit start.Acceptance scenarios (BDD)
p_phishow no secular drift (linear-fit slope consistent with zero; bounded oscillation) — the symplecticity witness for the composed map.zeta), then the footprint is continuous across the interface up to the documented tangential kick — no numerical gap or overlap artifacts.Success criteria
Non-goals
Verification
make test TEST=spectre_sympl_crossing