KineticForces - PERFORMANCE - Panel NTV psi quadrature at rational and kinetic-resonance surfaces with rtol-primary tolerances#313
Open
logan-nc wants to merge 20 commits into
Conversation
…rfaces, rtol-primary tolerances with maxevals guard Co-Authored-By: Claude Fable 5 <[email protected]>
…rium solver paths Adds an override_psi_nodes keyword to setup_equilibrium and threads it through the direct, arclength, inverse, and by-inversion solvers, bypassing the config-driven grid with a validated externally supplied node vector. This is the injection point for the two-pass auto-grid refinement. Co-Authored-By: Claude Fable 5 <[email protected]>
…on, and mandatory-node merge GridRefinement.jl derives the pass-2 knot density from the formed pass-1 equilibrium using the cubic h^4 error model on nodal fourth divided differences (1D profiles, rzphi geometry channels at sampled theta lines, and kinetic profiles when present), with a-priori edge/core geometric floors, then equidistributes and pins mandatory knots with a delta_min snap guard. The log_asymptotic auto path now forms a coarse fixed-128 pass-1 layout; the one-pass a-priori heuristics (make_optimal_mpsi, probe log-slope, 300-point mid-spacing sampling) are removed. All regions now scale as psi_accuracy^(-1/4), so tightening the tolerance refines edge and mid proportionally. Co-Authored-By: Claude Fable 5 <[email protected]>
… add rational_psi_nodes The qextrema-interval Brent walk moves from sing_find! into _find_rational_surfaces, which returns (m, n, psifac) tuples; sing_find! rebuilds its SingType multiplicity bookkeeping on top. rational_psi_nodes exposes the unique surface locations for the two-pass grid refinement. Co-Authored-By: Claude Fable 5 <[email protected]>
…ession case covering the psi torque quadrature Co-Authored-By: Claude Fable 5 <[email protected]>
…onal-surface packing Validation on the DIIID-like example drove four corrections to the knot density model: - h^3 derivative error model (err(f') ~ h^3|f''''|/24) replaces the h^4 value model: the stability physics consumes spline derivatives (q' at rational surfaces, p' and V' in the EL and ballooning coefficients), and the value model under-resolved delta-prime by 2x at q=2. - Curvature is measured against rho = sqrt(psi), where the equilibrium is regular at the axis; the psi-space geometry channels diverge as psi^(k/2-4) there and made the implied knot count grow without bound under refinement. - Local packing around mandatory (rational) surfaces: spacing 0.06*tau^(1/3) at the surface with geometric growth, within radius 0.05 — converges the delta-prime BVP, which samples the psi-splined coefficient matrices around each singular surface. - The core below psi=0.03 uses the a-priori geometric density exclusively: nodal data on the smallest flux surfaces is dominated by integration and axis-extrapolation error. Near-duplicate mandatory nodes (same surface via different m,n) collapse onto one knot. Noise floor scales as eps/h^4 on tightly packed sample grids. Adds test/runtests_grid_refinement.jl covering the merge invariants, equidistribution, quartic-exact divided differences, layer concentration, tau^(-1/3) scaling, and a Solovev two-pass round-trip. Co-Authored-By: Claude Fable 5 <[email protected]>
…ts in main driver When grid_type=log_asymptotic with mpsi=0, the driver forms a coarse pass-1 equilibrium, pins knots on all rational surfaces in the requested n range, derives the refined grid from the measured curvature (including kinetic profiles when loaded), and re-forms from the in-memory input. The nn range validation and the kinetic-profile load are hoisted above equilibrium formation to feed the refinement; a consistency check warns when the refined equilibrium implies substantially more knots than used. Co-Authored-By: Claude Fable 5 <[email protected]>
…ha-boundary scan drivers The alpha-boundary drivers now scan only psi_N in [0.1, min(0.99, psi_edge)], reusing the existing NaN sentinel for skipped surfaces. Ballooning boundaries are physically relevant in the mid-radius and pedestal; the packed axis and far-edge surfaces dominated the scan cost. The locstab path (compute_ballooning_stability!) is unchanged. Co-Authored-By: Claude Fable 5 <[email protected]>
Quantifies knots-vs-accuracy for cubic splines of q versus iota = 1/q on the DIII-D-like example: iota gives a modest constant-factor improvement (~1.2-2x at coarse N) but the same convergence order, confirming that wholesale iota replacement is not warranted for grids ending inside the separatrix. Co-Authored-By: Claude Fable 5 <[email protected]>
…md, example annotations) Co-Authored-By: Claude Fable 5 <[email protected]>
…psi=256 grid These testsets target the bidirectional FM integration and STRIDE BVP machinery, so they now pin the radial grid instead of inheriting the example default (mpsi=0), which previously baked the defective one-pass auto grid into the pinned values and would otherwise move whenever the auto grid evolves. Re-pins et_par and the delta-prime diagonals to the ldp-256 values: q=2,3,4 real parts are grid-converged and pinned tightly; the near-separatrix q=5,6 entries are not grid-converged (value and sign vary O(1) between grids) and are now asserted finite and non-zero only. Co-Authored-By: Claude Fable 5 <[email protected]>
… equidistribution, IMAS rerun note Co-Authored-By: Claude Fable 5 <[email protected]>
The two-pass grid is a measured spline-derivative-error density with geometric floors, not a log-asymptotics model — q stays finite everywhere on the grid — so the old name misdescribed it. grid_type="auto" is the new default; "log_asymptotic" remains a working alias (two-pass when mpsi=0, the three-region log layout when mpsi>0), so no existing TOML breaks. Co-Authored-By: Claude Fable 5 <[email protected]>
…roduction auto grid Per review: the auto grid is the production default, so the machinery testsets now build it exactly as the main driver does (rational_psi_nodes + refined_psi_grid + ingest re-form) and pin its values. The auto-vs-ldp512 convergence evidence is recorded on the PR; tightening psi_accuracy converges the pinned delta-prime entries toward the dense-reference values. Co-Authored-By: Claude Fable 5 <[email protected]>
…) and generator script Co-Authored-By: Claude Fable 5 <[email protected]>
…performance/ntv-psi-quadrature-paneling
…-crossing quadrature panels, shared sign-change root scan, psilims floor above axis Co-Authored-By: Claude Fable 5 <[email protected]>
…scription and future settings docs Co-Authored-By: Claude Fable 5 <[email protected]>
…nances for quadrature panels, revert psilims floor, persist panel data to HDF5 Co-Authored-By: Claude Fable 5 <[email protected]>
…ance surfaces, annotate epsilon clamp Co-Authored-By: Claude Fable 5 <[email protected]>
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.
Closes #303. Built on #312 (
feature/two-pass-psi-gridis merged into this branch, so its commits appear in this diff until #312 lands — merge #312 first, after which this PR reduces to the KineticForces changes).Problem
The outer ψ-integration of the NTV torque
tpsi(ψ)used a single whole-domain adaptive quadrature with no interior breakpoints, nomaxevalsbound, and a discarded error estimate. The resonant torque-density peaks — at the rational surfaces and at the kinetic resonances (dominantly the ExB/superbanana-plateau resonance near ω_E ≈ 0) — forced deep adaptive bisection (1375+ evaluations, ~30 min reported in #303 on the DIII-D-like case). Separately, theatol_psi = 1e-2N·m default was an amplitude-sensitive trap: NTV ∝ δB², so a 10× weaker applied field gives a 100× smaller torque and a fixed absolute tolerance can silently dominate termination with O(1) relative error.Changes
ψ-quadrature paneling at resonant surfaces
sing+kinsing) are threaded intoKineticForcesInternal.sing_psisand passed as quadrature panel boundaries — Gauss–Kronrod handles peaks at interval endpoints natively instead of hunting them by bisection.kinetic_resonance_psi_nodes(kinetic_profiles, equil; n, nl, ...)scans for zeros of the trapped-branch resonance denominator at thermal energy, Ω_ℓ(x=1; ψ) = ℓ·ω_b(ψ) + n·(ω_E(ψ) + ω_d(ψ)) for every ℓ ∈ −nl:nl, using the pitch-averaged RLAR closed-form frequencies already intpsi!(single spline evaluations, no bounce averaging). The ℓ=0 node is the ω_d-shifted ExB resonance; ℓ≠0 nodes capture the bounce resonances. On the DIII-D case this finds 8 in-range surfaces that line up with the observed pedestal dT/dψ structure (see figure) — including the previously unexplained bump at ψ_N ≈ 0.955.kinetic_forces/<method>/panel_psi,resonance_psi) for diagnostics/plotting; the per-method log line reports torque, error estimate, evaluation count, and panel composition.fortran-physics-revieweraudit of the locator passed all checks: frequency conventions matchtpsi!/torque.F90exactly (thewdhat = q·T/(2εR₀²ZeB₀)closed form verified algebraically identical), the denominator correctly uses ω_E alone (diamagnetic terms are numerator-only), and leff = ℓ matches the trapped branch. Passing-branch (ℓ+nq transit) resonances are a documented non-goal (broad/Landau-like; quadrature resolves them without dedicated panels).Unified helpers (one source of truth per concept, no drift)
src/KineticForces/Utils.jl:find_sign_change_roots(f, grid)(grid sign-scan + Brent) — also replaces the two pre-existing inline copies of the same idiom inTorque.jl(dB/dθ extrema).kinetic_resonance_psi_nodesis the single kinetic-resonance locator, shared-signature-ready for the Kinetic-aware equilibrium grid packing: place knots on rational and kinetic-resonance surfaces #309 grid-knot packing (refined_psi_nodes=rational_psi_nodes∪ this). Rational-surface identification stays unified under_find_rational_surfaces(shared bysing_find!and EQUIL + GPEC - Two-pass measured-curvature auto psi grid with rational-surface knots #312'srational_psi_nodes).psi_panel_pointsowns sort/dedupe/bound-filtering of the merged panel list.Tolerance redesign (rtol-primary)
atol_psi: 1e-2 → 0.0. Convergence is controlled byrtol_psi = 1e-2(~2 significant figures — the limit of the NTV model's validity; tighter tolerances buy digits the physics can't back).maxevals_psi = 2000runaway guard; the error estimate is checked and a clear warning fires when the quadrature terminates without meeting tolerance, or when a user-set nonzeroatol_psidominates termination (the weak-field silent-garbage scenario).psilimsstays[0.0, 1.0]. (An interim commit floored it at 0.1 to dodge a near-axis dT/dψ spike; measurement showed that was over-optimization — at rtol=1e-2 only 7 of 345 develop evaluations land below ψ=0.1 and the core carries a real 0.3% of the torque — so the floor was reverted. The near-axis feature itself turns out to be two located ℓ≠0 resonance surfaces, now paneled like the rest.)Coverage
examples/Solovev_kinetic_NTV_example(ideal FFS → PE → NTV torque) — previously no shipped config exercised this code path — plus asolovev_kinetic_ntvregression case pinning the fgar torque and ψ evaluation count.atol_psi/rtol_psikeys from the a10 example (it stops after kinetic stability and never reaches the torque quadrature).Benchmarks (DIII-D-like case from #295, n=1, C-coil 1 kA, nl=6, 5 rationals)
The defaults run agrees with the tightly-converged answer to 0.024% in Re(T) at 1.6× fewer evaluations than develop at equal tolerance — and 210 = 14 panels × 15 nodes exactly: the initial pass alone converges, i.e. the panels sit precisely where the quadrature work is. Whole n=1 pipeline: ~3 minutes. Regularization note: the PE default
reg_spot = 0.05must stay on for this post-PE diagnostic — with raw (unregularized) ξ the "torque" becomes the grid-capped ideal-MHD 1/(m−nq)² divergence (~66,000× larger on a Solovev test) rather than a physical answer.Torque density with the identified resonance locations (rationals dashed gray; located kinetic resonances Ω_ℓ(x=1)=0 dash-dot violet — note the match to the pedestal structure and the small near-axis feature):
Quadrature evaluation clustering — develop (no panels) goes near-vertical at the edge resonances; the paneled defaults run spreads effort almost uniformly:
Cumulative torque integral — all runs overlay; ~95% of the torque accumulates in the pedestal, with the sharp rise starting at the ℓ=0 kinetic resonance:
Regression
solovev_n1: 21/21 unchanged;diiid_n1: 46/46 unchanged vsfeature/two-pass-psi-grid(this PR's changes are isolated to[KineticForces]-configured runs).solovev_kinetic_ntv: NTV torque and evaluation count move intentionally with the quadrature improvements (final baseline pinned at this head).Notes for reviewers
solovev_kinetic_calculated/solovev_kinetic_nuzeroregression cases are broken on develop and this branch alike ([SOL_INPUT]in a separatesol.tomlthatbuild_inputs_from_tomldoesn't resolve) — separate fix needed; not touched here.atol_psi/rtol_psi = 1e-2lines can simply be dropped after this merges — the new defaults are equivalent or better.docs/src/assets/(same pattern as EQUIL + GPEC - Two-pass measured-curvature auto psi grid with rational-surface knots #312's grid figure) and can back a future docs page on NTV tolerance settings.🤖 Generated with Claude Code