Skip to content

[spectre-05] Add symplectic field-line Poincare app for SPECTRE equilibria #437

Description

@krystophny

Stage: SIMPLE / field-line diagnostics (milestone M1)
Source language: Fortran 2008
Manuals to read first: itpplasma/SPOIC spoic.f90:106-141 (trace — the working symplectic field-line scheme against SPEC data: Newton on the implicit radial update, A_theta as canonical momentum, zeta as time); SPECTRE fortran_src/poincare_mod.F90 and spectre/field_tracer.py (the reference tracers to match); DOC/coordinates-and-fields.md.
Depends on: itpplasma/libneo#371

Goal

SIMPLE ships a standalone app spectre_poincare.x producing Poincare sections and rotational-transform profiles for a SPECTRE equilibrium by symplectic field-line integration, per volume. Field lines never cross MRxMHD interfaces (B.n = 0 on both sides), so no crossing logic is involved; this milestone validates the whole libneo evaluation stack against SPECTRE's own tracer before any guiding-center work.

Files to edit

  • app/spectre_poincare.f90: NEW. Namelist input: SPECTRE file, volume list, seeds per volume, turns, section plane zeta0; output one poincare_volN.dat per volume (columns: turn index, s, theta, R, Z).
  • test/tests/test_spectre_poincare.py: NEW. Runs the app on the libneo fixture and compares against committed SPECTRE-tracer reference sections.
  • DOC/coordinates-and-fields.md: document the SPECTRE field input and its coordinate conventions (mandatory per repo policy).
  • src/CMakeLists.txt / CMakeLists.txt: link LIBNEO::spectre, add app target.

Behavior to implement

Field-line flow as canonical system with zeta as time, conjugate pair (A_theta, theta), radial coordinate solved implicitly (semi-implicit symplectic Euler as in SPOIC, second-order midpoint optional):

! Newton solve for r at fixed theta: A_theta(r_new) - A_theta_old = h * dH/dtheta
fun = f%dAth(1)*(f%Ath - Athold) + h*(f%dAzt(2)*f%dAth(1) - f%dAzt(1)*f%dAth(2))
r = r - fun/dfun
theta = theta + h*f%dAzt(1)/f%dAth(1); zeta = zeta + h

Seeds placed on zeta = zeta0, radially spread inside each volume, off-axis offset in volume 1.

Acceptance scenarios (BDD)

  • Given the fixture equilibrium, when tracing 16 seeds per volume for 500 toroidal turns, then no field line leaves its volume (|s| <= 1 throughout) — direct numerical witness of B.n = 0.
  • Given the same seeds traced by SPECTRE's Poincare tracer (reference data committed), then section point clouds agree: for regular surfaces, radial spread of matched surfaces within 1e-6; island chains reproduced with matching O-point positions and widths within 5%.
  • Given a seed on a regular surface, then the fitted rotational transform matches SPECTRE's write_transform output for that surface to 1e-6.
  • Given step-halving, then section points converge at the order of the chosen scheme (no first-order pollution from the Newton tolerance).

Success criteria

make && make test TEST=spectre_poincare

Non-goals

  • No guiding-center orbits, no interface crossing, no losses.
  • No chaos classification beyond visual/reference comparison (SIMPLE classifiers arrive with guiding-center milestones).

Verification

make test TEST=spectre_poincare

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions