Stage: SIMPLE / interface-crossing infrastructure (milestone M2)
Source language: Fortran 2008
Manuals to read first: VENUS-LEVIS + SPEC crossing paper (https://doi.org/10.1016/j.cpc.2021.108191) — the event-location precedent; the boundary-stop event code added by [spectre-06]; DOC/coordinates-and-fields.md.
Depends on: #438
Goal
Multi-volume RK45 guiding-center orbits run end to end with the energy-exact "Level-0" crossing map. This child establishes all crossing infrastructure — event refinement, volume handover, reflection branch, crossing log — behind a single apply_crossing entry point that [spectre-09] later upgrades to the full symplectic refraction map without touching the callers. Level 0 keeps position and mu, rescales v_par from exact energy conservation; it is exact when the field is smooth across the interface and energy-exact always (it omits the tangential sheet-drift kick, which is Level 1).
Files to edit
src/interface_crossing.f90: NEW. apply_crossing(field, y_iface, mu, y_out, info) — Level-0 map + reflection branch; pure function of the interface state; info carries event type and bookkeeping for the log.
- RK45 orbit driver /
src/simple_main.f90: replace the boundary-stop of [spectre-06] with locate → apply_crossing → continue in the neighbor volume; outermost interface remains the loss surface.
test/tests/test_spectre_crossing_l0.py: NEW.
DOC/coordinates-and-fields.md: document the crossing pipeline and the Level-0 map.
Behavior to implement
- Event refinement to
|rho_g - integer| < 1e-10 (dense output or bisection on the accepted step).
- Map:
(theta, zeta, mu) unchanged; volume lvol -> lvol +- 1, local s flips -+1; v_par'^2 = v_par^2 - 2*mu*(Bmod_new - Bmod_old) with both Bmod values evaluated at the same interface point from the respective volumes; sign of v_par (relative to the local field direction) carried over.
- Reflection branch: radicand negative → particle stays in its volume with unchanged state (energy exactly conserved); event logged as reflection.
- Crossing log per event: time, interface index,
(theta, zeta), v_par before/after, mu, type (crossing/reflection).
- Grazing guard: if the event refinement stalls (near-tangent approach), reduce the step and retry; never loop unbounded.
Acceptance scenarios (BDD)
- Given a two-volume SPECTRE tokamak file with a pressure step, when a passing guiding center crosses, then
H = v_par^2/2 + mu*Bmod (each side evaluated in its own volume) is conserved to 1e-14 per crossing and mu is unchanged.
- Given an interface with zero jump in
Bmod, then the state passes through unchanged (pure chart switch) and a trajectory in a smooth reference field represented piecewise is reproduced within integrator tolerance — the exactness case.
- Given a deeply trapped particle with
2*mu*[[Bmod]] > v_par^2 at the crossing point, then the reflection branch triggers, the particle remains in its volume, energy is exactly conserved, and the event is logged as reflection.
- Given a multi-volume ensemble run to
trace_time, then every particle is accounted (confined, lost at the outermost interface, or alive) and the crossing log is consistent (entry/exit volumes pair up), reproducible with fixed seed.
Success criteria
make && make test TEST=spectre_crossing_l0
Non-goals
- No tangential sheet-drift kick, no drift-order
v_par term, no derivation note — that is the Level-1 upgrade ([spectre-09]).
- No symplectic-integrator wiring ([spectre-10]).
- No mu-scattering model (full-orbit quantification is [spectre-11]).
Verification
make test TEST=spectre_crossing_l0
Stage: SIMPLE / interface-crossing infrastructure (milestone M2)
Source language: Fortran 2008
Manuals to read first: VENUS-LEVIS + SPEC crossing paper (https://doi.org/10.1016/j.cpc.2021.108191) — the event-location precedent; the boundary-stop event code added by [spectre-06];
DOC/coordinates-and-fields.md.Depends on: #438
Goal
Multi-volume RK45 guiding-center orbits run end to end with the energy-exact "Level-0" crossing map. This child establishes all crossing infrastructure — event refinement, volume handover, reflection branch, crossing log — behind a single
apply_crossingentry point that [spectre-09] later upgrades to the full symplectic refraction map without touching the callers. Level 0 keeps position and mu, rescalesv_parfrom exact energy conservation; it is exact when the field is smooth across the interface and energy-exact always (it omits the tangential sheet-drift kick, which is Level 1).Files to edit
src/interface_crossing.f90: NEW.apply_crossing(field, y_iface, mu, y_out, info)— Level-0 map + reflection branch; pure function of the interface state;infocarries event type and bookkeeping for the log.src/simple_main.f90: replace the boundary-stop of [spectre-06] with locate →apply_crossing→ continue in the neighbor volume; outermost interface remains the loss surface.test/tests/test_spectre_crossing_l0.py: NEW.DOC/coordinates-and-fields.md: document the crossing pipeline and the Level-0 map.Behavior to implement
|rho_g - integer| < 1e-10(dense output or bisection on the accepted step).(theta, zeta, mu)unchanged; volumelvol -> lvol +- 1, localsflips-+1;v_par'^2 = v_par^2 - 2*mu*(Bmod_new - Bmod_old)with bothBmodvalues evaluated at the same interface point from the respective volumes; sign ofv_par(relative to the local field direction) carried over.(theta, zeta),v_parbefore/after,mu, type (crossing/reflection).Acceptance scenarios (BDD)
H = v_par^2/2 + mu*Bmod(each side evaluated in its own volume) is conserved to 1e-14 per crossing andmuis unchanged.Bmod, then the state passes through unchanged (pure chart switch) and a trajectory in a smooth reference field represented piecewise is reproduced within integrator tolerance — the exactness case.2*mu*[[Bmod]] > v_par^2at the crossing point, then the reflection branch triggers, the particle remains in its volume, energy is exactly conserved, and the event is logged as reflection.trace_time, then every particle is accounted (confined, lost at the outermost interface, or alive) and the crossing log is consistent (entry/exit volumes pair up), reproducible with fixed seed.Success criteria
Non-goals
v_parterm, no derivation note — that is the Level-1 upgrade ([spectre-09]).Verification
make test TEST=spectre_crossing_l0