Skip to content

[spectre-08] Implement Level-0 interface crossing with event location #443

Description

@krystophny

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions