FFS - IMPROVEMENT - Cap the core knot density of the EL coefficient splines - #408
Open
logan-nc wants to merge 4 commits into
Open
Conversation
…plines The Euler-Lagrange coefficient splines inherited every knot of the equilibrium grid. A cubic spline's third-derivative jumps at knots scale as (node error)/dpsi^3, so the equilibrium's near-axis packing (dpsi ~ 1e-6) amplifies even tolerance-level node error into huge C2 kinks, and the adaptive integrator's step size becomes slaved to the knot spacing -- measured directly: core jump magnitudes grow ~34x per mpsi doubling while a (tol/J)^(1/4) step model reproduces the observed step-count ladder. The coefficients are near-cylindrical in the core and do not need that packing. Build their splines on a subset of the equilibrium grid with core density capped at dpsi >= 0.05*psi below psi = 0.1; node values are unchanged, only knot density. Measured on DIII-D stripped decks (route-a base, mpsi 512/1024): accepted EL steps 2768 -> 2188 and 4403 -> 3034, per-doubling growth 1.59x -> 1.39x, warm run -19% at mpsi=512, with et[1] unchanged to 3e-8 relative and the Riccati BVP Delta-prime diagonal unchanged to 4e-7 on all five surfaces. Interim fixed-cap form; a matrix-curvature knot selection is planned to replace the fixed rule, with this commit as the fallback. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…es knots On the production two-pass auto grid the cap is a no-op (its core spacing already satisfies the density rule), so the unconditional message was noise. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… protect rationals Reframes the cap as log-uniform sampling of the Frobenius region: near the axis every component is a power law in psi, and cubic interpolation of psi^p on a log-uniform grid errs by ~(p*c)^4/384, so c = 0.05 resolves even the steepest spectrum component (p = mmax/2) to ~2e-4 while the physics responds far below that. Two generalization guards, motivated by cross-equilibrium testing: the capped region now ends at the innermost rational surface when that sits inside psi = 0.1, and no knot inside a rational's RATIONAL_RES_RADIUS window is ever removed -- preserving the Delta'-stencil structure for decks (e.g. higher n) whose rationals reach the core. Both guards are no-ops on every current case, verified: DIII-D m512 and Solovev m512 reproduce the previous cap's step counts and knot sets exactly. Cross-equilibrium check of the rule itself: tj_analytic_direct m1024 (analytic, traced) 1470 -> 959 steps at et[1] 1.3e-9; LAR m1024 (inversion path, clean geometry) 951 -> 875 at et[1] identical to 8 digits; Solovev ldp m512/m1024 ~unchanged steps at ~4.5e-7 absolute et[1] shift (a +-10.4 cancellation amplifies this to 3e-5 relative). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Collaborator
Author
|
Review package (visual companion to this PR — decoupling diagram, knot-density and step-distribution before/afters, the Frobenius-scale basis for the cap, the cross-equilibrium generalization table, and the why-not-general-curvature-selection sweep): 📦 https://claude.ai/code/artifact/e1ed1ea9-1362-40bd-9f52-ccd386118e21 Self-contained page; complements rather than duplicates the description and diff. If the link does not resolve, ask @logan-nc to enable sharing on it. |
…netic matrices The expensive bounce-average kernel ran on every equilibrium knot, which both starves kinetic decks of resolution (the shipped calculated example uses mpsi=16, carrying percent-level errors on the B/C totals) and wastes kernel evaluations on fine grids. Adds certified_kinetic_grid: seed with a coarse skeleton of the ideal coefficient- spline knots (endpoints and rational windows always retained; the seed must not scale with the equilibrium grid), then batched certify-or-refine rounds -- spline the kinetic increments on the current knots, propose all uncertified midpoints, evaluate the whole batch with the existing threaded kernel, and certify or insert. The certificate is the max-element residual against tolerance * max|total| for every consumed family including the adjoint combination kw3 - kt3, so tolerance is held on the ideal+kinetic totals the solver consumes, never on increments in isolation. Spacing floors: the Frobenius cap in the core, RATIONAL_RES_SPACING outside, and RATIONAL_RES_SPACING/4 inside rational windows so narrow layers cannot hide behind the floor where they are expected. Control: kinetic_grid_tol (default 0 = off; knob-off verified bit-identical). Measured on the Solovev calculated case at tol=1e-3: m64 deck 65 -> 93 knots (certification adds knots where the coarse grid under-resolves, matching the pre-registered expectation); m256 deck 150 kernel evaluations vs 255 (-41%) with et[1] within 9.4e-5 of the full grid; tol sweep 3e-3..1e-4 is plateau-flat. The kernel now accepts an arbitrary psi list (psis kwarg), threading pattern unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Euler-Lagrange coefficient splines (
fmats/kmats/gmatsand the primitives) inherited every knot of the equilibrium grid. A cubic spline's third-derivative jumps at knots scale as (node error)/Δψ³, so the equilibrium's near-axis packing (Δψ ~ 1e-6 at high mpsi) amplifies even tolerance-level node error (~1e-9, measured) into huge C² kinks — and the adaptive integrator's step size becomes slaved to the knot spacing. Measured directly: core jump magnitudes grow ~34× per mpsi doubling, and an (tol/J)^¼ step model reproduces the observed step-count ladder.The coefficients are near-cylindrical in the core and do not need that packing. This PR builds their splines on a subset of the equilibrium grid with core density capped at Δψ ≥ 0.05·ψ below ψ = 0.1. Node values are unchanged — only interpolation density — which is why the physics moves at the 1e-7–1e-8 level.
Stacked on #398 (route (a), same investigation); diff shows only the cap once #398 lands.
Measured (DIII-D stripped decks, route-(a) base, mpsi 512/1024)
Not a tuned hack: the rule's basis and its generalization
Form: near the axis every component is a Frobenius power law in ψ; power laws are scale-free, so log-uniform sampling (Δψ ≥ c·ψ) resolves them at constant relative accuracy. Constant: cubic interpolation of ψ^p on a log-uniform grid errs by ~(p·c)⁴/384, so c = 0.05 resolves even the steepest spectrum component (p = m_max/2 = 11) to ~2e-4 — and the physics responds far below that because the steep components carry vanishing solution amplitude. Region: ends at min(0.1, innermost rational −
RATIONAL_RES_RADIUS), and no knot inside a rational's resolution window is ever removed — guards for decks (e.g. higher n) whose rationals reach the core; verified no-ops on every current case.Cross-equilibrium check (four equilibria, two construction paths, three grid families):
The LAR row is the anti-over-fit witness: clean geometry with no noise to exploit, and the cap is still harmless.
Two properties reviewers should know
diiid_n1, solovev_n1, diiid_n1_riccati, gal_resistive_diiid) reproduces EQUIL - IMPROVEMENT - Sample every flux surface at the same straight-fieldline angles #398's numbers exactly. The cap engages only on explicitly packed fine grids (largempsi), which is precisely the issue Performance: Why do large equilibrium splines slow down the code? #376 scenario.handoff/issue376/RESULTS.md§22–§23 (experiment branch).Verification
runtests_eulerlagrange,runtests_riccati,runtests_sing— all pass.handoff/issue376/RESULTS.md§22.🤖 Generated with Claude Code