Skip to content

Bound SPECTRE canonical construction#484

Merged
krystophny merged 3 commits into
mainfrom
perf/spectre-construction-memory
Jul 13, 2026
Merged

Bound SPECTRE canonical construction#484
krystophny merged 3 commits into
mainfrom
perf/spectre-construction-memory

Conversation

@krystophny

@krystophny krystophny commented Jul 13, 2026

Copy link
Copy Markdown
Member

Risk tier

  • T0: docs, comments, small build metadata
  • T1: pure refactor, no behavior change intended
  • T2: local numerical logic
  • T3: physics, output behavior, coordinate convention
  • T4: higher-risk build or runtime logic

Correctness contract

Intended behavior change

Make SPECTRE's per-volume Meiss construction bounded and diagnosable. The ODE now returns a catchable status through libneo, reports the failing radial, poloidal, and toroidal indices, and accepts explicit spline-order, step-limit, and relative-tolerance controls. Construction-only transformation arrays and five redundant field-component arrays no longer overlap the retained batch-spline allocation. Explicit startmode = 2 SPECTRE runs now initialize the magnetic-field bounds used only for trapped/passing diagnostics, eliminating non-finite diagnostic output without changing starting points or orbit dynamics.

The SPECTRE construction ODE tolerance defaults to 1e-2; tighter settings failed to construct the seven-volume Meiss equilibrium even after one million accepted/rejected steps. The established 48 x 48 x 32, quintic non-axisymmetric grid remains the default. Smaller grids and cubic splines are opt-in only.

Behavior that must not change

The canonical coordinates remain (r, theta, zeta) with stacked SPECTRE volume radius and dimensionless angles in radians. Vector-potential, covariant-field, and magnetic-field units are unchanged. The batch spline still stores (A_theta, A_zeta, h_theta, h_zeta, |B|) and uses the same periodicity and per-volume interface boundaries.

Default grid dimensions and spline order are unchanged because the lower-grid candidates did not preserve the existing interface-crossing convergence tests. Successful construction remains deterministic and thread-safe; repeated construction produces bit-identical field values and 64 concurrent evaluations reproduce the same finite value.

Numerical invariants

The completed chart retains the existing guiding-center energy, canonical toroidal momentum, crossing landing, step-halving, and particle-accounting checks. The ODE status path returns the last accepted state only on failure and never exposes a partial SPECTRE chart. A failed construction is cleaned up and a later construction can succeed.

Dependency

Requires merged libneo PR #391 (e451e0a42f5228d85b0479de40aa35db8b48239d), which adds the catchable ODE step-limit status without changing successful integrations.

Measured construction envelope

On the seven-volume Meiss equilibrium with 14 fixed markers and identical tracing settings:

  • default 48 x 48 x 32, quintic: 5,306.5 MiB peak RSS, 81.33 s, all 14 markers confined, maximum relative energy drift 4.39e-8
  • opt-in 24 x 24 x 16, quintic: 779.4 MiB, 27.22 s, maximum Poincare errors ds=1.79e-4, dtheta=7.58e-5
  • opt-in 24 x 24 x 16, cubic: 255.7 MiB, 20.95 s, maximum Poincare errors ds=3.77e-4, dtheta=2.73e-4
  • 16 x 16 x 16, cubic: rejected (ds=1.77e-2, dtheta=8.11e-3)

Despite their smooth-orbit accuracy, both 24-point candidates are kept opt-in because the existing SPECTRE crossing golden tests reject them as global defaults.

Tests added or changed

  • catchable one-step ODE failure followed by successful recovery
  • repeated construction equality and 64-thread evaluation equality
  • exposed order, step-limit, and tolerance controls
  • cubic-vs-quintic memory and confined-energy checks
  • transformation diagnostics now read the retained spline after raw construction arrays are released
  • three resource-heavy SPECTRE integration tests run serially to avoid CTest oversubscription; their numerical assertions and thresholds are unchanged
  • explicit SPECTRE starts remain bit-identical and produce finite trapped/passing diagnostics during a real trace

Verification

Failing before, against main:

RuntimeError: spectre_construction_grid line missing from stdout
times_lost.dat: trap_par = NaN for SPECTRE startmode = 2

The initial lower-default experiment also failed the existing physics gates:

test_spectre_sympl_crossing: 35 landings; loss fractions 0.531 and 0.156; step-halving ratio 1.15
test_spectre_validation: 6 crossing events

Those defaults were rejected and restored to 48 x 48, quintic. Passing after:

test_spectre_freeboundary        Passed
spectre_construction_grid        Passed
spectre_sympl_crossing           Passed
spectre_validation               Passed
Static: OK (174 modules, 174 changed, 174 affected)
Build: OK
Tests: OK
Lint: OK
Fmt: WARN (touched Fortran files only)
All stages passed

@krystophny krystophny enabled auto-merge (squash) July 13, 2026 11:45
@krystophny krystophny force-pushed the perf/spectre-construction-memory branch from fad64c6 to 59f88a4 Compare July 13, 2026 14:48
@krystophny krystophny merged commit 1a29fad into main Jul 13, 2026
7 checks passed
@krystophny krystophny deleted the perf/spectre-construction-memory branch July 13, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant