Skip to content

InnerLayer.SLAYER - FEATURE! - 🚨 Derive the toroidal critical-Δ geometric factor in the r_s reference - #441

Merged
d-burg merged 27 commits into
developfrom
feature/toroidal-delta-crit-geometry
Oct 29, 2026
Merged

d-burg merged 27 commits into
developfrom
feature/toroidal-delta-crit-geometry

Conversation

@d-burg

@d-burg d-burg commented Sep 3, 2026 •

Copy link
Copy Markdown
Collaborator

Release note

  • Audience: users
  • Numerical impact: none at defaults (D_c_type = "none"); with D_c_type = "toroidal" the critical-Δ offset is now computed from the equilibrium rather than from a user-supplied D_geo, and its parallel-conduction closure uses the same toroidal geometry (Δ_crit +3.7 to +5.9 % from the closure on the DIII-D-like example). The HDF5 dataset Tearing/PerSurface/D_geo carries derived values instead of zeros. (harness @ c72188c)
  • Migration: runs at the default D_c_type = "none" are unaffected. Under D_c_type = "toroidal", drop D_geo to take the derived geometric factor; D_c_type = "toroidal" no longer errors when it is absent. A prescribed D_geo now means the factor in the r_s reference, i.e. Eq. 59's own value × k_ref·v1/V_s (≈ 2 at large aspect ratio). A value that was passed as Eq. 59's own factor must be converted, or it gives about half the intended Δ_crit. Anything reading Tearing/PerSurface/D_geo must now expect derived values where it previously read zeros. :lar and :fitzpatrick are unchanged.

The toroidal critical-Δ of Connor, Ham, Hastie & Liu 2015 (PPCF 57 065001, Eq. 59) can now be used on any equilibrium: its geometric factor is derived per rational surface from the flux-surface averages GPEC already computes, expressed in the same r_s reference length as the rest of the SLAYER layer stack.

image

Left: the critical Δ at each rational surface of the DIII-D-like example under the cylindrical fitzpatrick model, under the toroidal geometric factor with a cylindrical parallel-conduction closure, and under the full toroidal model. The toroidal model is 22 to 60 % above fitzpatrick; the closure accounts for 3.7 to 5.9 % of that. Right: SLAYER growth rates with no critical Δ (the default) and under each model. The figure was made at 276288065, before develop's χ_e and resistivity changes; at fa5c2596b the toroidal 2/1 is still damped, at −230 s⁻¹ (see the regression report).

Changes since the last review

Regression report

Latest full run (2026-10-29): regress --refs f43b5bee8,c72188cc5 --force (all cases) on feynman (SLURM, 8 threads, Julia 1.11.9, manifest pinned). Every case is unchanged except D_geo in diiid_slayer_n1 and diiid_slayer_n1_chi_perp_e (zeros on develop, derived values here; all γ, Q and Δ′ rows unchanged). diiid_slayer_n1_toroidal fails on develop, which has no derived factor, so the harness exits 1; gal_resistive_pe is N/A on both refs.

Previous SDCC fanout rerun (2026-10-28): develop 057c4af0d vs a0305d167 — 22 cases; D_geo diagnostic changes; the toroidal case fails on the baseline, so the harness exits 1. Full report and limitations. This comparison also includes the existing gal_resistive_pe case with all quantities missing. Earlier reports are retained below.

Previous full run, before @matt-pharr's develop merge: regress --refs 0b4b9fbfb,fa5c2596b --force (all cases) on feynman (SLURM, 8 threads; both fresh, manifest pinned). Every case not listed here is unchanged; gal_resistive_pe is N/A on both refs, as on develop. The nine SLAYER and layer test files pass at fa5c2596b.

Regression Report: diiid_slayer_n1
==============================================================================================
Ref 1: 0b4b9fbfb  @ 0b4b9fbfb (2026-10-27)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f826ee26 (pinned), 8 threads/8 BLAS, jit build
Ref 2: fa5c2596b  @ fa5c2596b (2026-10-27)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f826ee26 (pinned), 8 threads/8 BLAS, jit build
----------------------------------------------------------------------------------------------
Quantity                                 0b4b9fbfb  fa5c2596b  Diff              Status
----------------------------------------------------------------------------------------------
SLAYER surface indices                   [6 elem]   [6 elem]   0.0e+00           OK
SLAYER poloidal m                        [6 elem]   [6 elem]   0.0e+00           OK
SLAYER toroidal n                        [6 elem]   [6 elem]   0.0e+00           OK
SLAYER minor radius rs                   [6 elem]   [6 elem]   0.0e+00           OK
SLAYER r-based shear                     [6 elem]   [6 elem]   0.0e+00           OK
SLAYER Lundquist S                       [6 elem]   [6 elem]   0.0e+00           OK
SLAYER D_norm                            [6 elem]   [6 elem]   0.0e+00           OK
SLAYER P_perp                            [6 elem]   [6 elem]   0.0e+00           OK
SLAYER tauk                              [6 elem]   [6 elem]   0.0e+00           OK
SLAYER iota_e                            [6 elem]   [6 elem]   0.0e+00           OK
SLAYER Q_e                               [6 elem]   [6 elem]   0.0e+00           OK
SLAYER Q_i                               [6 elem]   [6 elem]   0.0e+00           OK
SLAYER toroidal critical-Δ factor D_geo  [6 elem]   [6 elem]   8.151e+00 (Inf%)  ** CHANGED **
SLAYER Q_root [2/1,3/1,4/1]              [3 elem]   [3 elem]   0.0e+00           OK
SLAYER ω_Hz [2/1,3/1,4/1]                [3 elem]   [3 elem]   0.0e+00           OK
SLAYER γ_Hz [2/1,3/1,4/1]                [3 elem]   [3 elem]   0.0e+00           OK
SLAYER no_root flags [2/1,3/1,4/1]       [3 elem]   [3 elem]   0.0e+00           OK
SLAYER enabled flag                      1          1          0.0e+00           OK
Runtime (s)                              263.5s     292.8s                       --
==============================================================================================
Summary: 1 changed, 17 unchanged
  • D_geo: changes from zeros to the derived factor. This is the intended change, and the only one: every layer input and every root is unchanged. diiid_slayer_n1_chi_perp_e shows the same single change.
  • diiid_slayer_n1_toroidal: develop fails this case (D_c_type = "toroidal" without a D_geo errors there), so it has values only at this head:
surface 2/1 3/1 4/1 5/1 6/1 7/1
Δ_crit, fa5c2596b 14.37 13.37 37.52 230.70 41.31 22.12
Δ_crit, b16b95795 13.91 13.44 37.42 230.56 41.68 22.39
Δ_crit, 90c320185 17.52 16.91 47.10 289.76 52.27 28.13
γ [s⁻¹], fa5c2596b −229.7 −943.1 −3852.9
γ [s⁻¹], b16b95795 −163.9 −805.6 −3118.9
γ [s⁻¹], 90c320185 −229.9 −820.3 −3274.1

Both moves come from develop, not from this PR. Since b16b95795, Δ_crit moves by −1.2 to +3.3 % and the modes are 17–40 % more damped; the values at 36f623cf2 are identical to b16b95795's, so the change arrives with develop 0b4b9fbfb, which brings #501's split of χ⊥ into electron and ion parts and its D_perp default for P_perp. Before that, from 90c320185 to b16b95795, Δ_crit was 20 % lower on every surface (ratio 0.794–0.797). That comes from develop, not from this PR: develop doubled the example's χ_e and now takes Z_eff(ψ) from the kinetic file. Doubling χ⊥ alone lowers Δ_crit by 2^{−1/4} = 0.84 in the collisional limit and by 2^{−1/3} = 0.79 in the free-streaming limit (closed form in the closure section), and Z_eff enters only the collisional part of χ∥. The measured 0.795 sits in that range, near the free-streaming end. D_R and D_geo are unchanged by the merge. The tracked modes stay damped.

The closure commit's own effect, measured before the develop merge (regress --refs d0e8a0261,276288065):

Regression Report: diiid_slayer_n1_toroidal
==========================================================================================
Ref 1: d0e8a0261  @ d0e8a0261 (2026-09-25)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f826ee26 (pinned), 8 threads/8 BLAS
Ref 2: 276288065  @ 276288065 (2026-09-26)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f826ee26 (pinned), 8 threads/8 BLAS
------------------------------------------------------------------------------------------
Quantity                            d0e8a0261  276288065  Diff               Status       
------------------------------------------------------------------------------------------
SLAYER resistive interchange D_R    [6 elem]   [6 elem]   0.0e+00            OK           
SLAYER critical-Δ offset D_c        [6 elem]   [6 elem]   1.368e+01 (4.95%)  ** CHANGED **
SLAYER Q_root [2/1,3/1,4/1]         [3 elem]   [3 elem]   2.959e-03 (0.42%)  ** CHANGED **
SLAYER γ_Hz [2/1,3/1,4/1]           [3 elem]   [3 elem]   1.105e+02 (3.49%)  ** CHANGED **
SLAYER no_root flags [2/1,3/1,4/1]  [3 elem]   [3 elem]   0.0e+00            OK           
Runtime (s)                         257.2s     255.1s                        --           
==========================================================================================
Summary: 3 changed, 2 unchanged

The per-surface numbers are in the closure section below. D_R and every layer input are identical.

Review package

A self-contained page with the derivation, the implementation data path (where the coordinate transformation enters), the symbolic and numerical verification ladder, and all figures embedded: Toroidal Critical-Δ Review Package.

Base branch

Originally based on and targeted at bugfix/slayer-dprime-reference-length (#403), which defines the r_s reference length K = r_s·dψ_N/dr used below. #403 has since merged into develop (f36ecef86), so this branch was rebased onto #403's final head 12f64da8c and the PR now targets develop with a single commit.

Derivation

Connor's Eq. 59, in Hamada coordinates with ψ(V) the toroidal flux, χ(V) the poloidal flux, primes d/dV, ι/2π = χ'/ψ' = 1/q, Λ = ψ'² ι'/2π, α = 2πn/χ':

$$\Delta'_{crit} = \frac{\pi^{3/2}}{2}\left(\frac{\chi_\parallel}{\chi_\perp}\right)^{1/4} V_s \left(\frac{\alpha^2\Lambda^2}{\langle B^2\rangle\langle|\nabla V|^2\rangle}\right)^{1/4}(-D_R)$$

In GPEC quantities (ψ_N normalized poloidal flux, chi1 = 2π·psio = dχ/dψ_N with χ the full poloidal flux, v1 = dV/dψ_N, q1 = dq/dψ_N):

$$\iota' = 2\pi\frac{d(1/q)}{dV} = -\frac{2\pi}{q^2},\frac{q_1}{v_1},\qquad \psi_t' = \frac{d\psi_t}{d\psi_N}\frac{d\psi_N}{dV} = \frac{q,\texttt{chi1}}{v_1},\qquad \Lambda = \left(\frac{q,\texttt{chi1}}{v_1}\right)^2\left(-\frac{q_1}{q^2 v_1}\right),\qquad \alpha = \frac{2\pi n}{\texttt{chi1}/v_1}$$

$$\langle B^2\rangle = \oint B^2,\frac{\texttt{jac}}{V'},d\theta,\qquad \langle|\nabla V|^2\rangle = v_1^2\oint|\nabla\psi_N|^2,\frac{\texttt{jac}}{V'},d\theta$$

Two points where the paper's notation has to be read carefully, both verified against the paper's own large-aspect-ratio limit (Eq. 61):

  1. Connor writes ⟨A⟩ = (1/2π)∮A dθ, but with Hamada θ of period 1 this must be the normalized flux-surface average (⟨1⟩ = 1), i.e. the jac/V' weighting above. A literal 1/2π leaves a (2π)^{1/2} mismatch with Eq. 61.
  2. Eq. 59 is the jump in dΨ/dY with Y = (V−V_s)/V_s. GPEC's layer stack, the fitzpatrick critical-Δ, and the Tearing - BUGFIX! - Convert Δ' to the r_s reference length before slab-layer matching #403-converted Δ' are all referenced to x̂ = (r−r_s)/r_s. Because Eq. 59 is derived at H = 0 (Frobenius exponent μ = 1/2), the conversion is linear: multiply by r_s(dV/dr)/V_s = K·v1/V_s. V_s cancels, so no volume integral is needed. Without this conversion Eq. 59 gives exactly half of fitzpatrick at large aspect ratio (V ∝ r²).

With the conversion the geometric factor reduces at large aspect ratio to √(n s r_s/R₀) with s = (r_s/q)dq/dr, which is exactly the factor inside fitzpatrick, so the two branches coincide there and the paper's Eq. 61 is recovered after dividing by r_s.

Implementation

  • ResistGeometry (src/ForceFreeStates/Surfaces/ResistEval.jl) gains avg_dpsisq = ⟨|∇ψ_N|²⟩, an eighth column of the existing θ-loop.

  • toroidal_dgeo (src/InnerLayer/SLAYER/LayerInputs.jl, exported) evaluates

    dgeo = k_ref · v1 · (α²Λ²/(⟨B²⟩ · v1² · ⟨|∇ψ_N|²⟩))^{1/4}
    

    with α and Λ as above. k_ref · v1 is the Y → x̂ reference conversion; this is the only place the coordinate transformation enters, and k_ref is the same K that delta_prime_to_rs_reference applies to Δ'.

  • build_slayer_inputs derives dgeo_val whenever the surface carries a ResistGeometry (sing.restype, populated by resist_eval_all!), for every dc_type; only :toroidal consumes it, via _solve_dc_tmp's 0.5·(−D_R)·π^{3/2}·(χ∥/χ⊥)^{1/4}·dgeo, whose χ∥ closure now uses the same toroidal geometry (next section). It throws only if dc_type=:toroidal is requested on a surface without a ResistGeometry. An explicit D_geo in the deck (dgeo_val in the API) still overrides.

Toroidal χ∥ closure

Eq. 59 needs χ∥/χ⊥. GPEC gets χ∥ by harmonically combining a collisional (Spitzer–Härm) value with a free-streaming value. That combination is solved self-consistently with the critical width W_d.

Until 276288065, :toroidal used Eq. 59's toroidal geometry only in the final prefactor. The W_d loop and the free-streaming χ∥ inside it still used the cylindrical field-line pitch n·s/R₀ (Fitzpatrick 1995, Phys. Plasmas 2 825, Eq. 132 and Sec. VII). Both now come from the balance that produces Eq. 59.

The balance. Connor's Eq. 18 with the Eq. 20 coefficients, written in x = V − V_s, reads

$$\chi_\perp\langle|\nabla V|^2\rangle,\partial_x^2T = \chi_\parallel,\frac{\alpha^2\Lambda^2}{\langle B^2\rangle},x^2T .$$

That is χ⊥k⊥² = χ∥k∥² with k∥(x) = |αΛ|·x/√⟨B²⟩ [1/m].

  • No hidden factor in k∥. The choice α = 2πn/χ′ together with the phase exp(2πinu/χ′) fixes Hamada angles of period 1, so B·∇u = Λx exactly. The "Λx/φ" printed on Connor's p. 3 is dimensionally inconsistent. The paper's own Eq. 59 → 61 reduction confirms this.
  • Transport width: x_T = (χ⊥/χ∥)^{1/4}/D_V, with D_V = (α²Λ²/(⟨B²⟩⟨|∇V|²⟩))^{1/4}.
  • Eq. 59 in terms of it: (π^{3/2}/2)·D_R·V_s/x_T.

Critical width. Fitzpatrick's w_D (Connor Eq. 65) is 2√2 times the cylindrical x_T. In the x̂ reference, with the same conversion K·v1 = r_s·dV/dr as D_geo:

$$W_d = \frac{2\sqrt2,x_T}{K v_1} = \frac{\sqrt8,(\chi_\perp/\chi_\parallel)^{1/4}}{D_{geo}},\qquad \Delta'_{crit} = \frac{\sqrt2,\pi^{3/2}(-D_R)}{W_d},$$

The second relation is the same identity that links :lar and :fitzpatrick.

Free-streaming χ∥. The form and the 2/√π flux-limit factor are unchanged; only k∥ changes, to its value from the balance at x = W_d·K·v1:

$$\chi_{fs} = \frac{2v_{te}}{\sqrt\pi,K_\parallel W_d},\qquad K_\parallel = \frac{|\alpha\Lambda|,K,v_1}{\sqrt{\langle B^2\rangle}}.$$

K∥ is computed by the new toroidal_kpar.

In a circular cylinder, αΛ = −n s B₀/(4π²R₀²r²) and K·v1 = 4π²R₀r², so K∥ = n·s/R₀. That is exactly the previous code.

K∥ is not D_geo²/r_s. Algebraically, K∥ = (D_geo²/r_s)·g, with g = r_s√⟨|∇ψ_N|²⟩/K. The metric factor g is 1 in a cylinder, but 0.57–0.76 on the DIII-D-like surfaces. Taking K∥ from D_geo would put it 24–43 % off and make χ∥ depend on the radial label. So K∥ is computed separately.

Limits.

  • Collisional (χ_SH ≪ χ_fs): K∥ drops out, and the result is unchanged from before.
  • Free-streaming: the fixed point solves in closed form, χ∥^{3/4} = 2v_te·D_geo/(√(8π)·K∥·χ⊥^{1/4}), so Δ′_crit ∝ D_geo^{4/3}·K∥^{−1/3}. Relative to the previous closure, the factor is (D_geo·K_cyl/(D_cyl·K∥))^{1/3}.

That factor bounds the change on the DIII-D-like equilibrium (midplane label):

surface ψ_N D_geo/D_cyl K∥/K_cyl metric g free-streaming Δ_crit change
2/1 0.518 1.172 1.044 0.761 +3.9 %
3/1 0.770 1.248 1.093 0.702 +4.5 %
4/1 0.893 1.316 1.134 0.655 +5.1 %
5/1 0.968 1.391 1.180 0.610 +5.6 %
6/1 0.993 1.457 1.210 0.570 +6.4 %

Measured with the diiid_slayer_n1_toroidal harness case, which uses the same equilibrium with psihigh = 0.9995 and so also reaches the 7/1. It compares d0e8a0261 (before) with 276288065 (after):

surface Δ_crit before Δ_crit after change free-streaming bound γ before [s⁻¹] γ after [s⁻¹]
2/1 16.89 17.52 +3.7 % +3.9 % −214.2 −229.8
3/1 16.22 16.91 +4.3 % +4.5 % −796.4 −820.3
4/1 44.93 47.10 +4.8 % +5.1 % −3164 −3274
5/1 276.1 289.8 +5.0 % +5.6 %
6/1 49.80 52.27 +5.0 % +6.4 %
7/1 26.56 28.13 +5.9 %

Every surface stays inside its free-streaming bound, and close to it: at these temperatures χ∥ is mostly free-streaming. D_R, D_geo and every layer input are bit-identical. The three tracked modes were already stable and become 3.0–7.3 % more stable.

Checks. All but the last are in the unit tests:

  • Large-aspect-ratio limit (runtests_tj_analytic.jl): on TJ circular equilibria at ε = 0.1, 0.05 and 0.025, K∥/(n s/R₀) − 1 = (0.37–0.47)·ε². That is second order; the test requires |dev| ≤ ε² and a quartering from ε = 0.05 to 0.025. D_geo's first-order deviation is entirely the metric factor, g − 1 ≈ −2·(D_geo/D_cyl − 1), which checks the K∥–D_geo identity numerically.
  • Closure algebra (runtests_slayer_params.jl, Test 1e):
    • Given cylindrical (D_geo, K∥), :toroidal reproduces :lar to 1e-12 and :fitzpatrick to 1e-8.
    • Both limits match their closed forms to 1e-8 for three (D_geo, K∥) pairs.
    • dgeo_val = 0 still gives no offset.
  • Radial-label invariance (runtests_slayer_inputs.jl):
    • The toroidal Δ_crit/K is identical across :midplane, :flux and :volume to 1e-8. The previous cylindrical closure does not have this property, because its r-based shear and r_s change with the label.
    • K∥ and D_geo scale with K exactly.
    • A prescribed D_geo keeps the derived K∥, and without a ResistGeometry the closure falls back to the cylindrical K∥ with a warning.
  • Scaling: K∥·a is invariant under B₀ → B₀/2 and (a, R₀) → 2(a, R₀).
  • Independent re-derivation: a separate AI reviewer, given only the two papers and the diff, re-derived each step and confirmed it: k∥, W_d, the cylinder limit, the K∥–D_geo identity, the closed forms, label invariance, and the code. It also confirmed that v1_local, avg_bsq and avg_dpsisq are the normalized-average quantities the formulas need.

Still a modelling choice (also in the code comments and docstrings):

  • Averaging: k∥ is taken in Connor's flux-surface-averaged sense, |αΛ|/√⟨B²⟩, so its variation along a field line is not resolved.
  • Closure form: the closure itself is unchanged: Spitzer–Härm and free streaming, combined harmonically, with the 2/√π factor, and k∥ evaluated at the full W_d.
  • Trapped electrons: there is no trapped-electron reduction of the free-streaming χ∥. Connor et al. treat χ∥ as an input, so that would be new modelling.
  • Cylindrical models: :lar and :fitzpatrick keep the cylindrical geometry by definition.

Verification

  • Symbolic (SymPy), 12/12: Λ ≡ ψ'χ'' − χ'ψ'' = ψ'²(ι/2π)'; the chain-rule images of ψ_t', Λ, α equal the code expressions; the code formula equals Eq. 59 × r_s(dV/dr)/V_s with V_s cancelling; the circular limit gives ½√(n s r/R) before and √(n s r/R) after conversion for an arbitrary q(r); Eq. 61·r_s equals the fitzpatrick formula through Connor's Eq. 65; the factor is invariant under B → λB and lengths → μ·lengths, while the Fortran one-power form scales as (λ/μ)^{-1/2}. The consequences that can be checked numerically are pinned by this PR's unit tests rather than by the script: the large-aspect-ratio limit and its linear ε-scaling (runtests_tj_analytic.jl), scale invariance, which the one-power form fails by √2 (runtests_tj_analytic.jl), and the exact :toroidal/:fitzpatrick prefactor identity (runtests_slayer_inputs.jl).
  • Analytic chain Eq. 59 → Eq. 61 → Lutjens offset √2π^{3/2}(−D_R)/w_D (Eq. 65) → the fitzpatrick code formula: all consistent, pinning the prefactor.
  • Large-aspect-ratio limit on TJ circular equilibria: dgeo/√(n s r_s/R₀) = 1.001–1.012 at ε = 0.05, ≤ 1.09 at ε = 0.3 near the edge The residual is a genuine O(ε) toroidal correction: it equals (0.144–0.185)·r_s/R₀ at every ε from 0.1 to 0.0125 and halves with ε to within 1–2 %. The unit test bounds it by the local r_s/R₀ at ε = 0.05 and requires it to halve from ε = 0.05 to 0.025 within 10 %, which a wrong O(1) factor (e.g. the Y-vs-r_s factor of 2, or a first-power ψ′) cannot satisfy.
  • Scale invariance: dgeo unchanged to 6 digits under B₀ → B₀/2 and (a, R₀) → 2(a, R₀) (unit test). The Fortran STRIDE form on the slayer_growthrate branch of the Fortran GPEC, which carries one power of ψ_t' in Λ instead of two, fails this by √2 and is off by ψ_t'^{-1/2} (2.3× at ε = 0.1, 3.2× at ε = 0.05). That branch also feeds D_I rather than D_R and writes log(q) as shear; none of that is used here.
  • Independent metric: ⟨B²⟩, ⟨|∇ψ_N|²⟩ and V' recomputed from R(ψ,θ), Z(ψ,θ), F(ψ), psio alone agree with ResistGeometry to 1e-7–1e-4 on interior surfaces of the circular and DIII-D-like cases.
  • End-to-end prefactor: given cylindrical geometry, :toroidal reproduces :lar to 1e-12 and :fitzpatrick to 1e-8 (unit test). This checks the shared χ-matching prefactor. With toroidal geometry the closure checks are listed in the closure section above.
  • Sign: an interchange-stable surface (D_R < 0) gets a positive, stabilizing offset (unit test).
  • Wiring checks, not physics: the derivation reaches toroidal_dgeo with the surface's inputs, and the radial label reaches it only through k_ref.
  • Tests at 5633fc4d6 (feynman): runtests_slayer_params.jl 87/87, runtests_slayer_inputs.jl 84/84, runtests_tj_analytic.jl 28/28, runtests_slayer_runner.jl 88/88, and the other SLAYER, GGJ and layer-overlap suites all pass.

Radial-label sensitivity

The numbers below come from one-off runs, not from code in this PR, so this is how to regenerate them from the public API. On examples/DIIID-like_SLAYER_example, form the equilibrium and a fresh Riccati Δ′, then call build_slayer_inputs(equil, sings, profiles; rs_method=lab, dc_type=:toroidal) and the same with dc_type=:fitzpatrick, for lab in (:midplane, :flux, :volume). The ratio of the two dc_tmp values, and Δ′_rs/dc_tmp, give the rows. The TJ ε scan is runtests_tj_analytic.jl's _lar_equilibrium(ε) swept over ε.

DIII-D-like SLAYER example, n = 1 (Δ' diagonal reproduces #403's table: 9.097, −6.196, −16.374):

2/1 3/1 4/1
Δ_crit toroidal / fitzpatrick, :midplane (current default) 1.17 1.25 1.32
Δ_crit toroidal / fitzpatrick, :flux 0.96 0.94 0.91
Δ_crit toroidal / fitzpatrick, :volume 1.00 1.01 1.01
label spread of the margin Δ'_rs/Δ_crit, fitzpatrick 31 % 32 % 41 %
label spread of the margin Δ'_rs/Δ_crit, toroidal 7.7 % 10 % 15 %

Because dgeo ∝ K exactly and the converted Δ' ∝ K^{2μ} with μ ≈ 1/2, the toroidal threshold margin is nearly label-invariant; the cylindrical fitzpatrick formula (∝ r_s/√(da/dψ)) is not. The residual toroidal spread in this table is ~1 % from K^{2μ−1} and ~6 % from χ∥ through the W_d loop. The table predates 276288065, which makes that loop toroidal and removes the second source exactly: Δ_crit/K is now identical across labels to 1e-8 (unit test). With either branch the 2/1 sits at about half its threshold under every label, whereas with D_c_type = "none" it is unstable.

TJ circular ε scan (fresh Δ' per point, surfaces 2/1 and 3/1): the label spread of the margin and the toroidal/fitzpatrick deviation both vanish roughly linearly in ε (fitzpatrick spread 1.3–1.7 % at ε = 0.05, toroidal 0.2 %; toroidal/fitzpatrick 1.006–1.012 midplane, 0.995–0.998 flux). No residual at small ε, so no implementation artefact; finite-ε differences are label physics.

Notes for reviewers

  1. Reference-conversion exponent — decision: linear. The critical-Δ is converted from Connor's Y = (V−V_s)/V_s reference to x̂ = (r−r_s)/r_s with the linear rule (Frobenius exponent ½, exact in the paper's H = 0 ordering). The alternative would be this PR's base's K^(2α) rule with the equilibrium's Mercier exponent α = √(−D_I). Linear is the defensible choice: Δ_crit is a layer-side quantity like the slab Δ̂(Q), W_d and fitzpatrick, all defined with the slab exponents ½ ± ½; only the outer Δ' genuinely carries ½ ± α, which is why Tearing - BUGFIX! - Convert Δ' to the r_s reference length before slab-layer matching #403 converts it with K^(2α). Applying c^(2α) to the offset would put an outer-region exponent on a quantity derived without one; the consistent generalization would be a finite-D_I layer theory with thermal conduction, which changes the structure of the D_R term and does not exist. Recorded in the toroidal_dgeo docstring. Cost of the alternative, c^(2α−1) on Δ_crit (always stabilizing), and the residual label-covariance mismatch of the threshold under the linear rule, K^(2α−1), on the DIII-D-like equilibrium (midplane label):

    surface ψ_N α c c^(2α−1) K^(2α−1)
    3/2 (q = 1.5) 0.273 0.584 2.11 1.13 0.90
    2/1 0.518 0.540 2.21 1.07 0.99
    3/1 0.770 0.529 2.38 1.05 1.01
    4/1 0.893 0.558 2.60 1.12 1.04

    At the 2/1 and 3/1, where accurate γ matters most, the ambiguity is 5–7 % on Δ_crit and the label mismatch is ≤ 1 %. The 10 % mismatch at the 3/2 comes from the midplane label deep in the Shafranov-shifted core (K = 0.52), an argument for the flux label (InnerLayer.SLAYER - API - Choose one default radial label for the Fitzpatrick layer formalism #417), not for changing the exponent. The 5/1 (α = 0.83, D_R = −0.67) is outside the small-D_R ordering under either rule.

  2. Default radial label. This PR inherits :midplane from Tearing - BUGFIX! - Convert Δ' to the r_s reference length before slab-layer matching #403. The evidence in InnerLayer.SLAYER - API - Choose one default radial label for the Fitzpatrick layer formalism #417 and the tables above point to :flux (Fitzpatrick's toroidal-flux label, the one the layer formulas are derived in) as the default for shaped plasmas; :volume only coincides with fitzpatrick by accident of near-circularity. InnerLayer.SLAYER - API! - Default the layer radial label to the toroidal-flux label #599 makes that flip. The two PRs are independent: with both merged, D_geo and k_ref move by the same factor (0.811 on the test surface), Δ_crit/K stays label-invariant, and the tests here pass either way. Whichever merges second needs a new harness stamp.

  3. D_geo is written for every D_c_type once a ResistGeometry exists; it is a diagnostic and does not feed the dispersion unless D_c_type = "toroidal".


🤖 Generated with Claude Code

@d-burg d-burg self-assigned this Sep 3, 2026
Base automatically changed from bugfix/slayer-dprime-reference-length to develop September 11, 2026 18:58
@d-burg
d-burg force-pushed the feature/toroidal-delta-crit-geometry branch from d433522 to 1197cfb Compare September 14, 2026 16:49
@github-actions github-actions Bot added changed-results Results move or an interface breaks - read before upgrading feature New capability labels Sep 14, 2026
@d-burg

d-burg commented Sep 14, 2026 •

Copy link
Copy Markdown
Collaborator Author

Review package

Toroidal Critical-Δ Review Package — a single self-contained page with the derivation (including the two notation readings that had to be checked against Eq. 61), the implementation data path showing the one place the coordinate transformation enters, the symbolic (SymPy, 12/12) and numerical verification ladder, the radial-label sensitivity tables and the TJ ε scan, with all figures embedded.

Decision recorded in the PR body and the toroidal_dgeo docstring: the Y → x̂ reference conversion of the critical-Δ stays linear (exponent ½, the paper's H = 0 ordering); the K^(2α) rule remains reserved for the outer Δ′, which genuinely carries the Mercier exponent. Cost of the alternative, c^(2α−1) on Δ_crit: 7 % at the 2/1, 5 % at the 3/1, 13 % at the 3/2, all in the stabilizing direction.

🤖 Generated with Claude Code

d-burg and others added 6 commits September 23, 2026 16:25
…ic factor in the r_s reference

The Connor et al. 2015 (PPCF 57 065001) Eq. 59 geometric factor of the toroidal
critical-Δ (dc_type=:toroidal) is now derived per surface from the equilibrium
instead of requiring a user-supplied dgeo_val. `toroidal_dgeo` evaluates
V_s·(α²Λ²/(⟨B²⟩⟨|∇V|²⟩))^{1/4} with Λ = ψ_t'² ι'/2π and converts it from the paper's
Y = (V−V_s)/V_s reference to the x̂ = (r−r_s)/r_s reference shared by the slab layer,
the rfitzp critical-Δ and the reference-length-converted Δ'; the factor r_s(dV/dr)/V_s
= k_ref·v1/V_s cancels V_s. ResistGeometry gains the ⟨|∇ψ_N|²⟩ average it needs.

At large aspect ratio the factor reduces to √(n s r_s/R₀), so :toroidal coincides
with :rfitzp there; the factor is dimensionless and scales with the radial label
exactly as the converted Δ' does. The PerSurface/D_geo dataset now carries derived
values instead of zeros.

Tests: derivation wiring and label invariance (LayerInputs), large-aspect-ratio
limit and scale invariance (TJ analytic). Benchmarks regenerate the convergence,
verification, label-sensitivity and TJ ε-scan figures.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ision for the toroidal critical-Δ

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…M-processing

They are one-off physics studies, archived with their figures under
CTM-processing/julia_deltaprime_harness/figures/delta_crit_toroidal/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the dgeo_val reference, and tighten its guards

- Cite Connor, Ham, Hastie & Liu 2015 (PPCF 57 065001) everywhere the source was credited to
  "Connor-Hastie-Helander".
- A prescribed dgeo_val must be in the r_s reference (Eq. 59's value times k_ref·v1/V_s).
- toroidal_dgeo requires dV/dψ_N > 0 and a non-zero chi1; the q guard could not fire.
- Name the Mercier exponent α_M so it no longer collides with Connor's α, and drop the
  equilibrium-specific percentages from the docstring.
- The k_ref fallback warning names the critical-Δ too; ResistGeometry docs name ψ_N and the
  eight integrands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nst rfitzp and the stable-D_R sign

dc_tmp(:toroidal)/dc_tmp(:rfitzp) must equal dgeo/√(n|s|r_s/R₀) exactly (up to the W_d
iteration's convergence), which checks the shared χ-matching prefactor end to end; a stable
D_R < 0 surface must get a positive offset. The direct-evaluation and label checks are labelled
as the wiring checks they are.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… case

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@d-burg
d-burg force-pushed the feature/toroidal-delta-crit-geometry branch from dc653ed to c0dba9f Compare September 23, 2026 22:05
d-burg and others added 8 commits September 24, 2026 15:53
…-ratio residual by local ε and require it to halve

The old rtol = 1e-2 sat inside the measured spread of a genuine O(ε) toroidal correction and
passed only because the two sampled surfaces fell under it. The residual is now bounded by the
local r_s/R₀ (measured coefficient 0.15–0.18 at ε = 0.05) and must halve from ε = 0.05 to
0.025 within 10 % (measured 0.491–0.495), which a wrong O(1) factor cannot satisfy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…te GGJ 1975

The bare | in |∇ψ|² split the Markdown table cells, truncating avg_bsq_over_dpsisq and leaving avg_dpsisq undocumented. Use ‖∇ψ_N‖, state the normalized-average convention, list the eighth integrand in the file header, and replace the Fortran routine citation in the edited resist_geometry docstring with Glasser, Greene & Johnson 1975.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…te the D_geo override

An explicit dgeo_val = 0.0 only disables the offset for dc_type = :toroidal; dr_val = 0.0 disables it for every dc_type. The D_geo dataset holds the prescribed value when dgeo_val is overridden.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
D_geo is derived independently of dc_type, so the toroidal variant of the same deck tracked an identical vector twice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e toroidal critical-Δ parallel-conduction closure

dc_type = "toroidal" took Connor, Ham, Hastie & Liu 2015 (PPCF 57 065001) Eq. 59's toroidal
geometry only in its final prefactor; the self-consistent W_d loop and the free-streaming χ∥
inside it still used the cylindrical field-line pitch n·s/R₀ (Fitzpatrick 1995). Both now come
from the same Eq. 20 transport balance, χ⊥⟨|∇V|²⟩∂²_x = χ∥(α²Λ²/⟨B²⟩)x²:

  W_d = √8·(χ⊥/χ∥)^¼ / D_geo
  χ∥,fs = 2·v_te / (√π·K∥·W_d),   K∥ = |αΛ|·r_s(dV/dr)/√⟨B²⟩   (new toroidal_kpar)

K∥ is not D_geo²/r_s outside a cylinder (they differ by r_s√⟨|∇ψ_N|²⟩/k_ref, 0.57–0.76 on the
DIII-D-like deck), so it is derived separately. Both reduce to the cylindrical forms at large
aspect ratio (K∥ at O(ε²), D_geo at O(ε)), and the whole toroidal critical-Δ is now invariant
under the choice of radial label up to k_ref. :lar and :rfitzp are algebraically unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…der the toroidal critical-Δ model

With k_ref = 1 the toroidal critical Δ stayed in the ψ_N reference while Δ' was reported per r_s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tity

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@d-burg d-burg changed the title InnerLayer.SLAYER - FEATURE! - Derive the toroidal critical-Δ geometric factor in the r_s reference InnerLayer.SLAYER - FEATURE! - 🚨 Derive the toroidal critical-Δ geometric factor in the r_s reference Oct 5, 2026
d-burg and others added 3 commits October 5, 2026 15:50
…elta-crit-geometry

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nce length for every critical-Δ model

Erroring under the toroidal model only was inconsistent: with k_ref = 1 the derived toroidal critical Δ stays
consistent with Δ', and the mismatch against the layer response exists under every model. This restores the
behaviour the branch had before ff50706.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cites them

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@d-burg
d-burg marked this pull request as ready for review October 6, 2026 18:38
@d-burg
d-burg requested review from jhalpern30 and a balanced review from Copilot October 6, 2026 18:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The new toroidal closure API has inconsistent K∥ defaults and lacks validation for invalid geometry values.

Review effort: Balanced
Findings: 2 Medium severity

Open (2)
What changed in this PR

Derives toroidal critical-Δ geometry from equilibrium data and propagates it through SLAYER’s thermal-conduction closure.

Changes:

  • Adds D_geo, K∥, and ⟨|∇ψ_N|²⟩ calculations.
  • Integrates derived geometry into SLAYER and HDF5 output.
  • Adds analytic, unit, and regression coverage.

THIRD-PARTY HUMAN REVIEW IS REQUIRED BEFORE MERGE.

File Description
src/​ForceFreeStates/​Surfaces/​ResistEval.jl Adds the gradient flux-surface average.
src/​InnerLayer/​SLAYER/​LayerInputs.jl Derives toroidal geometry per surface.
src/​InnerLayer/​SLAYER/​LayerParameters.jl Applies geometry to the closure.
src/​InnerLayer/​SLAYER/​SLAYER.jl Exports geometry helpers.
src/​InnerLayer/​InnerLayer.jl Re-exports geometry helpers.
src/​Tearing/​Runner/​Control.jl Documents control semantics.
src/​Tearing/​Runner/​HDF5Output.jl Updates critical-Δ metadata.
test/​runtests_tj_analytic.jl Tests asymptotic and scale limits.
test/​runtests_slayer_params.jl Tests closure algebra.
test/​runtests_slayer_inputs.jl Tests geometry derivation and wiring.
regression-harness/​cases/​diiid_slayer_n1.toml Tracks derived D_geo.
regression-harness/​cases/​diiid_slayer_n1_toroidal.toml Adds toroidal regression coverage.
docs/​development/​references.md Adds the Connor et al. reference.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/InnerLayer/SLAYER/LayerParameters.jl Outdated
Comment on lines +152 to +156
g_w, kpar = if dc_type === :toroidal
(dgeo_val, kpar_val === nothing ? kpar_cyl : kpar_val)
else
(sqrt((rs / R0) * abs(sval_r) * n_tor), kpar_cyl)
end
@jhalpern30

Copy link
Copy Markdown
Collaborator

Review package

Toroidal Critical-Δ Review Package — a single self-contained page with the derivation (including the two notation readings that had to be checked against Eq. 61), the implementation data path showing the one place the coordinate transformation enters, the symbolic (SymPy, 12/12) and numerical verification ladder, the radial-label sensitivity tables and the TJ ε scan, with all figures embedded.

Decision recorded in the PR body and the toroidal_dgeo docstring: the Y → x̂ reference conversion of the critical-Δ stays linear (exponent ½, the paper's H = 0 ordering); the K^(2α) rule remains reserved for the outer Δ′, which genuinely carries the Mercier exponent. Cost of the alternative, c^(2α−1) on Δ_crit: 7 % at the 2/1, 5 % at the 3/1, 13 % at the 3/2, all in the stabilizing direction.

🤖 Generated with Claude Code

@d-burg I am getting a page not found error when trying to view the review package

d-burg and others added 2 commits October 22, 2026 12:20
Brings in the TOML renames, the TearingProblem API and the layer-overlap cap. The toroidal
critical-Δ docs, harness case and tests now use D_c_type, D_R and D_geo and the renamed
:fitzpatrick offset, and the TJ analytic tests the renamed config keywords; the error for a
missing dgeo_val stays removed, since this branch derives it from the surface geometry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…reject invalid critical-Δ geometric factors

A hand-built SLAYERParameters now stores the cylindrical K∥ = n·|s|/R₀ when none is given, as
slayer_parameters does, instead of zero. The critical-Δ iteration rejects a non-finite or
non-positive geometric factor or K∥ up front, rather than failing later with NaNs or a generic
non-convergence error; dgeo_val = 0 still disables the toroidal offset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@d-burg

d-burg commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

@jhalpern30 should be fixed, can you access it now?

…idal critical-Δ tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
d-burg added a commit to PrincetonUniversity/GPEC that referenced this pull request Oct 23, 2026
dc_type='toroidal' used a geometric factor (STRIDE Delta_geo) that was
not correct in the r_s reference length the layer matching now uses.
On the DIII-D-like example it came out within 1% of 'rfitzp', while
the validated derivation (Connor et al. 2015 Eq. 59 in the r_s
reference, with a toroidal parallel-conduction closure;
OpenFUSIONToolkit/GPEC#441) puts it 22-60% above.

The option now stops with a message pointing to 'rfitzp'. STRIDE no
longer computes or writes Delta_geo and keeps only the shear output
SLAYER reads. dgeo_val stays in the namelist, unused, so older inputs
still read. A port of the Julia derivation can follow once it is
merged there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@jhalpern30 jhalpern30 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems legit, but this is quite far outside of my expertise - nothing I could offer would be more than "here is what my Claude said about your code". So if you've done all those checks yourself for accuracy, then go for it

d-burg and others added 3 commits October 26, 2026 17:55
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…elta-crit-geometry

# Conflicts:
#	test/runtests_tj_analytic.jl
…elta-crit-geometry

# Conflicts:
#	src/InnerLayer/SLAYER/LayerParameters.jl
@matt-pharr

Copy link
Copy Markdown
Collaborator

@d-burg — completed the requested full SDCC fanout comparison against develop 057c4af0d, testing PR head a0305d167 on 2026-10-28.

Result: two diagnostic changes and one failed baseline run; harness exit code 1. This is not an all-pass comparison.

  • 18 cases are entirely unchanged.
  • diiid_slayer_n1 and diiid_slayer_n1_chi_perp_e: the only change in each is D_geo, from the baseline's zeros to derived values (maximum absolute difference 8.151). The other 17 quantities in each case are unchanged.
  • diiid_slayer_n1_toroidal succeeds at this PR head, but the run at baseline 057c4af0d fails, including on the report job's retry. Its five tracked quantities therefore have no valid before/after comparison. The PR-head runtime was 231.2 s. The report log ends with REGRESS_EXIT=1 even though the Slurm report job itself completed with exit code zero.
  • gal_resistive_pe: all eight quantities are missing on both refs. It supplies no numerical validation.

The release-note stamp records the tested commit, not a claim that the failed baseline case passed.

Environment: Julia 1.12.6, x86_64 Linux, CI manifest pin 4c9d54fa, partition sirius. There were 22 cases / 44 per-ref tasks. Each case used the same allocation at both refs: 2 Julia threads / 1 BLAS thread normally, and 16 / 8 for diiid_error_field. The precompiled Riccati case was compared in its precompiled build at both refs. Each PR head's own harness case definitions were used.

./regress_fanout.sh --refs 057c4af0d,a0305d167 --harness-ref a0305d167 --name pr441_a0305d167_vs_057c4af0d_20261028

SDCC report: /home/ITER/pharrm/Projects/GPEC_dev/regress-fanout/runs/pr441_a0305d167_vs_057c4af0d_20261028/report.txt; report job 1298991.

Full regression report (22 cases)
HEAD is now at 057c4af0d PerturbedEquilibrium - DOCS - Identify the surface displacement and correct Glasser citations (#540)

================================================================
Case: diiid_error_field — DIII-D-like error-field assessment, n=1: ErrorFields stage with the NTV-limited correction couplings
================================================================

Regression Report: diiid_error_field
============================================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 16 threads/8 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 16 threads/8 BLAS, jit build
--------------------------------------------------------------------------------------------
Quantity                                         057c4af0d     a0305d167     Diff     Status
--------------------------------------------------------------------------------------------
EFC overlap per kAt                              [1 elem]      [1 elem]      0.0e+00  OK    
EFC whole-field NTV torque per kAt² [N·m]        [1 elem]      [1 elem]      0.0e+00  OK    
EFC residual-field NTV torque per kAt² [N·m]     [1 elem]      [1 elem]      0.0e+00  OK    
EFC reference rotation ω_ref [rad/s]             [1 elem]      [1 elem]      0.0e+00  OK    
EFC rotation-scan shifts [rad/s]                 [9 elem]      [9 elem]      0.0e+00  OK    
EFC residual torque against rotation [N·m/kAt²]  [9 elem]      [9 elem]      0.0e+00  OK    
dominant-coupling singular values                [3 elem]      [3 elem]      0.0e+00  OK    
|delta_nominal| of coil set 1                    1.406930e-06  1.406930e-06  0.0e+00  OK    
|Σ δ_as_designed| of the error-field coils       1.358875e-18  1.358875e-18  0.0e+00  OK    
Monte Carlo mean |δ| of the error-field coils    4.701300e-05  4.701300e-05  0.0e+00  OK    
Runtime (s)                                      269.4s        258.6s                 --    
============================================================================================
Summary: 10 unchanged


================================================================
Case: diiid_multi_n — DIII-D-like equilibrium, n = 1, 2, ideal + perturbed equilibrium
================================================================

Regression Report: diiid_multi_n
=================================================================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
-----------------------------------------------------------------------------------------------------------------
Quantity                                                      057c4af0d        a0305d167        Diff       Status
-----------------------------------------------------------------------------------------------------------------
total energy Re(et[1])                                        -5.750527e-01    -5.750527e-01    0.0e+00    OK    
total energy (all)                                            [58 elem]        [58 elem]        0.0e+00    OK    
ODE steps (saved)                                             628              628              0.0e+00    OK    
mpert                                                         29               29               0.0e+00    OK    
npert                                                         2                2                0.0e+00    OK    
toroidal mode label of each mode index (checksum)             8d8d42b8832d...  8d8d42b8832d...  identical  OK    
permeability diagonal P~_ii (all n blocks)                    [58 elem]        [58 elem]        0.0e+00    OK    
forcing b~ (root-area-weighted), n = 1, 2                     [58 elem]        [58 elem]        0.0e+00    OK    
response b~ (root-area-weighted), n = 1, 2                    [58 elem]        [58 elem]        0.0e+00    OK    
PE plasma energy (sum over n)                                 2.936559e+00     2.936559e+00     0.0e+00    OK    
PE vacuum energy (sum over n)                                 3.113946e+00     3.113946e+00     0.0e+00    OK    
PE surface energy (sum over n)                                3.523427e+00     3.523427e+00     0.0e+00    OK    
PE toroidal torque sum_n -2n Im(Phi_n' Lambda_nn^-1 Phi_n)/4  1.820337e-06     1.820337e-06     0.0e+00    OK    
resonant n per row (rows sorted by psi across n)              [7 elem]         [7 elem]         0.0e+00    OK    
resonant m per row                                            [7 elem]         [7 elem]         0.0e+00    OK    
resonant area-weighted field b^r per row                      [7 elem]         [7 elem]         0.0e+00    OK    
island half-widths per row                                    [7 elem]         [7 elem]         0.0e+00    OK    
Chirikov parameter per row                                    [7 elem]         [7 elem]         0.0e+00    OK    
forcing-driven Delta' per row                                 [7 elem]         [7 elem]         0.0e+00    OK    
Runtime (s)                                                   208.8s           209.4s                      --    
=================================================================================================================
Summary: 19 unchanged


================================================================
Case: diiid_n1 — DIII-D-like equilibrium, n=1, ideal + perturbed equilibrium
================================================================

Regression Report: diiid_n1
=================================================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
-------------------------------------------------------------------------------------------------
Quantity                                      057c4af0d        a0305d167        Diff       Status
-------------------------------------------------------------------------------------------------
total energy Re(et[1])                        8.006122e-01     8.006122e-01     0.0e+00    OK    
total energy Im(et[1])                        7.924882e-05     7.924882e-05     0.0e+00    OK    
plasma energy Re(ep[1])                       -1.372261e+00    -1.372261e+00    0.0e+00    OK    
vacuum energy Re(ev[1])                       2.172874e+00     2.172874e+00     0.0e+00    OK    
vacuum matrix min eigenvalue                  1.873975e-01     1.873975e-01     0.0e+00    OK    
plasma energy (all)                           [35 elem]        [35 elem]        0.0e+00    OK    
vacuum energy (all)                           [35 elem]        [35 elem]        0.0e+00    OK    
total energy (all)                            [35 elem]        [35 elem]        0.0e+00    OK    
ODE steps (saved)                             788              788              0.0e+00    OK    
ODE steps (total)                             783              783              0.0e+00    OK    
q0                                            1.204212e+00     1.204212e+00     0.0e+00    OK    
q95                                           4.781723e+00     4.781723e+00     0.0e+00    OK    
beta_t                                        1.327024e-02     1.327024e-02     0.0e+00    OK    
beta_n                                        1.372511e+00     1.372511e+00     0.0e+00    OK    
internal inductance li1                       8.842268e-01     8.842268e-01     0.0e+00    OK    
internal inductance li2                       7.080757e-01     7.080757e-01     0.0e+00    OK    
internal inductance li3                       7.304340e-01     7.304340e-01     0.0e+00    OK    
poloidal beta betap1                          6.680739e-01     6.680739e-01     0.0e+00    OK    
poloidal beta betap2                          5.349836e-01     5.349836e-01     0.0e+00    OK    
poloidal beta betap3                          5.518764e-01     5.518764e-01     0.0e+00    OK    
# singular surfaces                           5                5                0.0e+00    OK    
singular psi locations                        [5 elem]         [5 elem]         0.0e+00    OK    
singular q values                             [5 elem]         [5 elem]         0.0e+00    OK    
current beta betaj                            4.236480e-01     4.236480e-01     0.0e+00    OK    
plasma volume                                 1.829472e+01     1.829472e+01     0.0e+00    OK    
plasma current                                1.152130e+00     1.152130e+00     0.0e+00    OK    
mpert                                         35               35               0.0e+00    OK    
npert                                         1                1                0.0e+00    OK    
toroidal field bt0                            2.006573e+00     2.006573e+00     0.0e+00    OK    
wall field bwall                              3.880145e-01     3.880145e-01     0.0e+00    OK    
aspect ratio                                  2.845746e+00     2.845746e+00     0.0e+00    OK    
elongation kappa                              1.708322e+00     1.708322e+00     0.0e+00    OK    
q profile (checksum)                          6da947d0754e...  6da947d0754e...  identical  OK    
pressure profile (checksum)                   c9c6ca4072ca...  c9c6ca4072ca...  identical  OK    
Mercier D_I profile (checksum)                26babbe22505...  26babbe22505...  identical  OK    
resistive interchange D_R profile (checksum)  c46830151a0b...  c46830151a0b...  identical  OK    
ballooning Delta' profile (checksum)          c27c6779804a...  c27c6779804a...  identical  OK    
island half-widths                            [5 elem]         [5 elem]         0.0e+00    OK    
Chirikov parameter                            [5 elem]         [5 elem]         0.0e+00    OK    
||resonant area-weighted field||              5.288412e-04     5.288412e-04     0.0e+00    OK    
dominant-coupling singular values             [3 elem]         [3 elem]         0.0e+00    OK    
|forcing overlap with dominant mode|          1.411553e-04     1.411553e-04     0.0e+00    OK    
|delta_nominal| of coil set 1                 7.034649e-05     7.034649e-05     0.0e+00    OK    
||ddelta/d(shift)|| over coil sets            1.245448e-04     1.245448e-04     0.0e+00    OK    
||ddelta/d(tilt)|| over coil sets             4.177341e-07     4.177341e-07     0.0e+00    OK    
PE plasma energy                              3.320466e+00     3.320466e+00     0.0e+00    OK    
PE vacuum energy                              3.174319e+00     3.174319e+00     0.0e+00    OK    
PE surface energy                             5.508585e+00     5.508585e+00     0.0e+00    OK    
PE toroidal torque                            1.119354e-04     1.119354e-04     0.0e+00    OK    
NTV torque FGAR [N·m]                         5.480614e-01     5.480614e-01     0.0e+00    OK    
NTV kinetic energy dW FGAR [J]                8.163291e-02     8.163291e-02     0.0e+00    OK    
Runtime (s)                                   246.7s           245.8s                      --    
||forcing b~|| (root-area-weighted)           4.683171e-04     4.683171e-04     0.0e+00    OK    
resonant area-weighted field b^r              [5 elem]         [5 elem]         0.0e+00    OK    
=================================================================================================
Summary: 53 unchanged


================================================================
Case: diiid_n1_riccati — DIII-D-like equilibrium, n=1, Riccati integrator Δ' matrix
================================================================

Regression Report: diiid_n1_riccati
============================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
----------------------------------------------------------------------------
Quantity                       057c4af0d      a0305d167      Diff     Status
----------------------------------------------------------------------------
delta prime (BVP diagonal)     [5 elem]       [5 elem]       0.0e+00  OK    
delta prime (raw side-major)   [10 elem]      [10 elem]      0.0e+00  OK    
edge coil response delta_coil  [10 elem]      [10 elem]      0.0e+00  OK    
total energy Re(et[1])         8.031971e-01   8.031971e-01   0.0e+00  OK    
plasma energy Re(ep[1])        -1.368534e+00  -1.368534e+00  0.0e+00  OK    
vacuum energy Re(ev[1])        2.171732e+00   2.171732e+00   0.0e+00  OK    
total energy (all)             [35 elem]      [35 elem]      0.0e+00  OK    
# singular surfaces            5              5              0.0e+00  OK    
singular psi locations         [5 elem]       [5 elem]       0.0e+00  OK    
singular q values              [5 elem]       [5 elem]       0.0e+00  OK    
ODE steps (saved)              93             93             0.0e+00  OK    
ODE steps (total)              2631           2631           0.0e+00  OK    
mpert                          35             35             0.0e+00  OK    
npert                          1              1              0.0e+00  OK    
q0                             1.204212e+00   1.204212e+00   0.0e+00  OK    
q95                            4.781723e+00   4.781723e+00   0.0e+00  OK    
beta_n                         1.372511e+00   1.372511e+00   0.0e+00  OK    
Runtime (s)                    203.7s         208.4s                  --    
============================================================================
Summary: 17 unchanged


================================================================
Case: diiid_n1_riccati_precompiled — DIII-D-like equilibrium, n=1, Riccati integrator Δ' matrix, precompiled build
================================================================

Regression Report: diiid_n1_riccati_precompiled
============================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, aot build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, aot build
----------------------------------------------------------------------------
Quantity                       057c4af0d      a0305d167      Diff     Status
----------------------------------------------------------------------------
delta prime (BVP diagonal)     [5 elem]       [5 elem]       0.0e+00  OK    
delta prime (raw side-major)   [10 elem]      [10 elem]      0.0e+00  OK    
edge coil response delta_coil  [10 elem]      [10 elem]      0.0e+00  OK    
total energy Re(et[1])         8.031971e-01   8.031971e-01   0.0e+00  OK    
plasma energy Re(ep[1])        -1.368534e+00  -1.368534e+00  0.0e+00  OK    
vacuum energy Re(ev[1])        2.171732e+00   2.171732e+00   0.0e+00  OK    
total energy (all)             [35 elem]      [35 elem]      0.0e+00  OK    
# singular surfaces            5              5              0.0e+00  OK    
singular psi locations         [5 elem]       [5 elem]       0.0e+00  OK    
singular q values              [5 elem]       [5 elem]       0.0e+00  OK    
ODE steps (saved)              93             93             0.0e+00  OK    
ODE steps (total)              2631           2631           0.0e+00  OK    
mpert                          35             35             0.0e+00  OK    
npert                          1              1              0.0e+00  OK    
q0                             1.204212e+00   1.204212e+00   0.0e+00  OK    
q95                            4.781723e+00   4.781723e+00   0.0e+00  OK    
beta_n                         1.372511e+00   1.372511e+00   0.0e+00  OK    
Runtime (s)                    32.8s          33.1s                   --    
============================================================================
Summary: 17 unchanged


================================================================
Case: diiid_slayer_n1 — DIII-D-like H-mode equilibrium, n=1, SLAYER tearing-mode analysis (uncoupled per-surface, AMR, validity-gated)
================================================================

Regression Report: diiid_slayer_n1
==============================================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
----------------------------------------------------------------------------------------------
Quantity                                 057c4af0d  a0305d167  Diff              Status       
----------------------------------------------------------------------------------------------
SLAYER surface indices                   [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER poloidal m                        [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER toroidal n                        [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER minor radius rs                   [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER r-based shear                     [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER Lundquist S                       [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER D_norm                            [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER P_perp                            [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER tauk                              [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER iota_e                            [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER Q_e                               [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER Q_i                               [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER toroidal critical-Δ factor D_geo  [6 elem]   [6 elem]   8.151e+00 (Inf%)  ** CHANGED **
SLAYER Q_root [2/1,3/1,4/1]              [3 elem]   [3 elem]   0.0e+00           OK           
SLAYER ω_Hz [2/1,3/1,4/1]                [3 elem]   [3 elem]   0.0e+00           OK           
SLAYER γ_Hz [2/1,3/1,4/1]                [3 elem]   [3 elem]   0.0e+00           OK           
SLAYER no_root flags [2/1,3/1,4/1]       [3 elem]   [3 elem]   0.0e+00           OK           
SLAYER enabled flag                      1          1          0.0e+00           OK           
Runtime (s)                              232.2s     231.2s                       --           
==============================================================================================
Summary: 1 changed, 17 unchanged


================================================================
Case: diiid_slayer_n1_chi_perp_e — DIII-D-like H-mode equilibrium, n=1, SLAYER tearing-mode analysis with P_perp_model = chi_perp_e
================================================================

Regression Report: diiid_slayer_n1_chi_perp_e
==============================================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
----------------------------------------------------------------------------------------------
Quantity                                 057c4af0d  a0305d167  Diff              Status       
----------------------------------------------------------------------------------------------
SLAYER surface indices                   [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER poloidal m                        [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER toroidal n                        [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER minor radius rs                   [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER r-based shear                     [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER Lundquist S                       [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER D_norm                            [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER P_perp                            [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER tauk                              [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER iota_e                            [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER Q_e                               [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER Q_i                               [6 elem]   [6 elem]   0.0e+00           OK           
SLAYER toroidal critical-Δ factor D_geo  [6 elem]   [6 elem]   8.151e+00 (Inf%)  ** CHANGED **
SLAYER Q_root [2/1,3/1,4/1]              [3 elem]   [3 elem]   0.0e+00           OK           
SLAYER ω_Hz [2/1,3/1,4/1]                [3 elem]   [3 elem]   0.0e+00           OK           
SLAYER γ_Hz [2/1,3/1,4/1]                [3 elem]   [3 elem]   0.0e+00           OK           
SLAYER no_root flags [2/1,3/1,4/1]       [3 elem]   [3 elem]   0.0e+00           OK           
SLAYER enabled flag                      1          1          0.0e+00           OK           
Runtime (s)                              235.8s     238.1s                       --           
==============================================================================================
Summary: 1 changed, 17 unchanged


================================================================
Case: diiid_slayer_n1_coupled — DIII-D-like H-mode equilibrium, n=1, SLAYER coupled multi-surface determinant with kinetic-file E×B rotation (reuses the n=1 deck via overrides)
================================================================

Regression Report: diiid_slayer_n1_coupled
==================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
------------------------------------------------------------------
Quantity                     057c4af0d  a0305d167  Diff     Status
------------------------------------------------------------------
SLAYER tauk                  [6 elem]   [6 elem]   0.0e+00  OK    
SLAYER q_shift               [6 elem]   [6 elem]   0.0e+00  OK    
SLAYER coupled Q_root        [1 elem]   [1 elem]   0.0e+00  OK    
SLAYER coupled ω             [1 elem]   [1 elem]   0.0e+00  OK    
SLAYER coupled γ             [1 elem]   [1 elem]   0.0e+00  OK    
SLAYER coupled no_root flag  [1 elem]   [1 elem]   0.0e+00  OK    
SLAYER enabled flag          1          1          0.0e+00  OK    
Runtime (s)                  240.2s     236.6s              --    
==================================================================
Summary: 7 unchanged


================================================================
Case: diiid_slayer_n1_toroidal — DIII-D-like H-mode, n=1, SLAYER with the toroidal critical-Δ offset (D_c_type = toroidal)
================================================================

Regression Report: diiid_slayer_n1_toroidal
======================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28) (FAILED)
       env: environment unknown (cached before fingerprinting)
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
  Ref 1 error: in expression starting at /tmp/jl_MPqtWdCzwT.jl:5
----------------------------------------------------------------------
Quantity                            057c4af0d  a0305d167  Diff  Status
----------------------------------------------------------------------
SLAYER resistive interchange D_R    FAILED     [6 elem]         FAILED
SLAYER critical-Δ offset D_c        FAILED     [6 elem]         FAILED
SLAYER Q_root [2/1,3/1,4/1]         FAILED     [3 elem]         FAILED
SLAYER γ_Hz [2/1,3/1,4/1]           FAILED     [3 elem]         FAILED
SLAYER no_root flags [2/1,3/1,4/1]  FAILED     [3 elem]         FAILED
Runtime (s)                         FAILED     231.2s           --    
======================================================================
Summary: 5 missing/N/A


================================================================
Case: diiid_truncation_n1 — DIII-D-like, n=1, psihigh=0.9999 with the resistive-layer overlap cap binding (truncation only)
================================================================

Regression Report: diiid_truncation_n1
====================================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
------------------------------------------------------------------------------------
Quantity                               057c4af0d      a0305d167      Diff     Status
------------------------------------------------------------------------------------
layer-overlap cap applied              1              1              0.0e+00  OK    
layer-overlap psilim                   9.985081e-01   9.985081e-01   0.0e+00  OK    
first overlapping surface index        7              7              0.0e+00  OK    
diffusive-resistive layer widths (Δψ)  [7 elem]       [7 elem]       0.0e+00  OK    
qlim                                   6.200000e+00   6.200000e+00   0.0e+00  OK    
psilim                                 9.949767e-01   9.949767e-01   0.0e+00  OK    
mpert                                  37             37             0.0e+00  OK    
# singular surfaces                    5              5              0.0e+00  OK    
singular q values                      [5 elem]       [5 elem]       0.0e+00  OK    
singular psi locations                 [5 elem]       [5 elem]       0.0e+00  OK    
plasma energy Re(ep[1])                -1.372379e+00  -1.372379e+00  0.0e+00  OK    
total energy Re(et[1])                 8.005437e-01   8.005437e-01   0.0e+00  OK    
Runtime (s)                            196.9s         192.0s                  --    
====================================================================================
Summary: 12 unchanged


================================================================
Case: efit_fixedbdy_separatrix — Fixed-boundary EFIT (box hugs LCFS), Newton separatrix-find regression
================================================================

Regression Report: efit_fixedbdy_separatrix
=======================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
-----------------------------------------------------------------------
Quantity                    057c4af0d     a0305d167     Diff     Status
-----------------------------------------------------------------------
psio (total poloidal flux)  3.344390e-01  3.344390e-01  0.0e+00  OK    
q0                          1.155202e+00  1.155202e+00  0.0e+00  OK    
q95                         5.741022e+00  5.741022e+00  0.0e+00  OK    
beta_t                      3.945172e-05  3.945172e-05  0.0e+00  OK    
beta_n                      1.009505e-01  1.009505e-01  0.0e+00  OK    
Runtime (s)                 47.9s         48.3s                  --    
=======================================================================
Summary: 5 unchanged


================================================================
Case: gal_resistive_diiid — DIII-D-like, n=1, RDCON outer-region Galerkin Δ′ with rpec coil columns (delta_coil)
================================================================

Regression Report: gal_resistive_diiid
====================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
--------------------------------------------------------------------
Quantity                 057c4af0d     a0305d167     Diff     Status
--------------------------------------------------------------------
gal # singular surfaces  4             4             0.0e+00  OK    
gal singular q values    [4 elem]      [4 elem]      0.0e+00  OK    
gal PEST3 Δ diagonal     [4 elem]      [4 elem]      0.0e+00  OK    
||gal Δ′ matrix||        2.302048e+03  2.302048e+03  0.0e+00  OK    
||gal Δ_coil block||     1.581714e+01  1.581714e+01  0.0e+00  OK    
gal D_I per surface      [4 elem]      [4 elem]      0.0e+00  OK    
gal α per surface        [4 elem]      [4 elem]      0.0e+00  OK    
||gal inner-layer Δ||    1.474577e+06  1.474577e+06  0.0e+00  OK    
||gal match cout||       3.048397e-02  3.048397e-02  0.0e+00  OK    
||gal match bpen||       1.206218e+00  1.206218e+00  0.0e+00  OK    
gal match residual       1.709610e-16  1.709610e-16  0.0e+00  OK    
Runtime (s)              187.3s        189.5s                 --    
====================================================================
Summary: 11 unchanged


================================================================
Case: gal_resistive_diiid_galinner — DIII-D-like, n=1, Galerkin Δ′ matched with the Galerkin inner-layer backend
================================================================

Regression Report: gal_resistive_diiid_galinner
====================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
--------------------------------------------------------------------
Quantity                 057c4af0d     a0305d167     Diff     Status
--------------------------------------------------------------------
gal # singular surfaces  4             4             0.0e+00  OK    
gal singular q values    [4 elem]      [4 elem]      0.0e+00  OK    
gal PEST3 Δ diagonal     [4 elem]      [4 elem]      0.0e+00  OK    
||gal Δ′ matrix||        2.302048e+03  2.302048e+03  0.0e+00  OK    
||gal Δ_coil block||     1.581714e+01  1.581714e+01  0.0e+00  OK    
gal D_I per surface      [4 elem]      [4 elem]      0.0e+00  OK    
gal α per surface        [4 elem]      [4 elem]      0.0e+00  OK    
||gal inner-layer Δ||    1.474566e+06  1.474566e+06  0.0e+00  OK    
||gal match cout||       3.048397e-02  3.048397e-02  0.0e+00  OK    
||gal match bpen||       1.206218e+00  1.206218e+00  0.0e+00  OK    
gal match residual       1.872671e-16  1.872671e-16  0.0e+00  OK    
Runtime (s)              184.5s        183.9s                 --    
====================================================================
Summary: 11 unchanged


================================================================
Case: gal_resistive_pe — DIII-D-like, n=1, DRIVEN/RPEC: gal-matched resistive ξ → PerturbedEquilibrium (coil-driven singular coupling)
================================================================

Regression Report: gal_resistive_pe
==========================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
----------------------------------------------------------
Quantity                057c4af0d  a0305d167  Diff  Status
----------------------------------------------------------
rational q values       N/A        N/A        N/A   N/A   
island half-widths      N/A        N/A        N/A   N/A   
Chirikov parameter      N/A        N/A        N/A   N/A   
||resonant b field||    N/A        N/A        N/A   N/A   
resonant b field (all)  N/A        N/A        N/A   N/A   
penetrated b field      N/A        N/A        N/A   N/A   
PE Δ' per surface       N/A        N/A        N/A   N/A   
||C resonant b field||  N/A        N/A        N/A   N/A   
Runtime (s)             187.4s     187.6s           --    
==========================================================
Summary: 8 missing/N/A


================================================================
Case: ggj_ray_q500i — GGJ inner-layer :ray backend, q=4 surface, Q = 500i (beyond :galerkin)
================================================================

Regression Report: ggj_ray_q500i
===============================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
---------------------------------------------------------------
Quantity            057c4af0d     a0305d167     Diff     Status
---------------------------------------------------------------
Re(Δ₊ interchange)  2.472007e+00  2.472007e+00  0.0e+00  OK    
Im(Δ₊ interchange)  1.335402e+01  1.335402e+01  0.0e+00  OK    
Re(Δ₋ tearing)      1.374966e-01  1.374966e-01  0.0e+00  OK    
Im(Δ₋ tearing)      7.427542e-01  7.427542e-01  0.0e+00  OK    
Runtime (s)         21.9s         21.7s                  --    
===============================================================
Summary: 4 unchanged


================================================================
Case: ggj_reference — GGJ inner-layer Galerkin solver, Glasser & Wang 2020 Eq. 55 with physical τ_A, τ_R, 1 kHz rotation (Q ≈ 0.22i)
================================================================

Regression Report: ggj_reference
=================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
-----------------------------------------------------------------
Quantity            057c4af0d      a0305d167      Diff     Status
-----------------------------------------------------------------
Re(Δ₊ interchange)  1.225728e+03   1.225728e+03   0.0e+00  OK    
Im(Δ₊ interchange)  2.064823e+04   2.064823e+04   0.0e+00  OK    
Re(Δ₋ tearing)      -5.345663e+00  -5.345663e+00  0.0e+00  OK    
Im(Δ₋ tearing)      2.592091e+01   2.592091e+01   0.0e+00  OK    
Runtime (s)         10.4s          10.4s                   --    
=================================================================
Summary: 4 unchanged


================================================================
Case: solovev_kinetic_calculated — Solovev, n=1, kinetic_source=calculated, kinetic_factor=1.0, 50/50 D-T multi-ion kinetic matrices, mode-converged band (delta_m=8, mpert=32); pressure-consistent kinetic.dat (n·T tied to the Solovev P₀≈4.27e4 Pa).
================================================================

Regression Report: solovev_kinetic_calculated
================================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
--------------------------------------------------------------------------------
Quantity                           057c4af0d      a0305d167      Diff     Status
--------------------------------------------------------------------------------
vacuum energy Re(ev[1])            1.054739e+01   1.054739e+01   0.0e+00  OK    
q0                                 1.900003e+00   1.900003e+00   0.0e+00  OK    
NTV fgar quadrature torque [N·m]   2.267351e-03   2.267351e-03   0.0e+00  OK    
||xi_clebsch_alpha||               6.041963e-01   6.041963e-01   0.0e+00  OK    
total energy Re(et[1])             1.828278e+00   1.828278e+00   0.0e+00  OK    
total energy Im(et[1])             -1.326607e+00  -1.326607e+00  0.0e+00  OK    
plasma energy Re(ep[1])            -8.719112e+00  -8.719112e+00  0.0e+00  OK    
ODE steps (saved)                  608            608            0.0e+00  OK    
# singular surfaces                2              2              0.0e+00  OK    
boundary-response torque [N·m]     2.285518e-03   2.285518e-03   0.0e+00  OK    
singular psi locations             [2 elem]       [2 elem]       0.0e+00  OK    
total energy (all)                 [32 elem]      [32 elem]      0.0e+00  OK    
ODE steps (total)                  607            607            0.0e+00  OK    
mpert                              32             32             0.0e+00  OK    
q95                                3.147422e+00   3.147422e+00   0.0e+00  OK    
||Jb_theta_reg||                   3.945600e-03   3.945600e-03   0.0e+00  OK    
Runtime (s)                        223.9s         222.9s                  --    
T_xe applied-forcing torque [N·m]  2.285518e-03   2.285518e-03   0.0e+00  OK    
||dxi_clebsch_psi/dpsi||           3.791914e+00   3.791914e+00   0.0e+00  OK    
singular q values                  [2 elem]       [2 elem]       0.0e+00  OK    
npert                              1              1              0.0e+00  OK    
================================================================================
Summary: 20 unchanged


================================================================
Case: solovev_kinetic_multiion — Solovev n=1, ideal + PE + multi-ion NTV (D + T + electron summed)
================================================================

Regression Report: solovev_kinetic_multiion
==========================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
--------------------------------------------------------------------------
Quantity                     057c4af0d      a0305d167      Diff     Status
--------------------------------------------------------------------------
NTV total (D+T+imp+e) [N·m]  3.141767e+01   3.141767e+01   0.0e+00  OK    
NTV Deuterium [N·m]          1.973730e+01   1.973730e+01   0.0e+00  OK    
NTV Tritium [N·m]            2.046293e+01   2.046293e+01   0.0e+00  OK    
NTV electron [N·m]           -8.782557e+00  -8.782557e+00  0.0e+00  OK    
total energy Re(et[1])       1.090560e-02   1.090560e-02   0.0e+00  OK    
# singular surfaces          2              2              0.0e+00  OK    
Runtime (s)                  214.5s         213.4s                  --    
==========================================================================
Summary: 6 unchanged


================================================================
Case: solovev_kinetic_ntv — Solovev analytical equilibrium, n=1, ideal + PE + NTV torque quadrature
================================================================

Regression Report: solovev_kinetic_ntv
======================================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
--------------------------------------------------------------------------------------
Quantity                                   057c4af0d     a0305d167     Diff     Status
--------------------------------------------------------------------------------------
NTV torque fgar [Re, Im]                   [1 elem]      [1 elem]      0.0e+00  OK    
NTV ψ quadrature evaluations               45            45            0.0e+00  OK    
fluid CGL energy fcgl [J]                  1.552303e+01  1.552303e+01  0.0e+00  OK    
root-area-weighted total energy Re(et[1])  1.090560e-02  1.090560e-02  0.0e+00  OK    
# singular surfaces                        2             2             0.0e+00  OK    
singular psi locations                     [2 elem]      [2 elem]      0.0e+00  OK    
q0                                         1.900006e+00  1.900006e+00  0.0e+00  OK    
Runtime (s)                                215.3s        234.6s                 --    
======================================================================================
Summary: 7 unchanged


================================================================
Case: solovev_kinetic_nuzero — Solovev, n=1, kinetic_source=calculated, nutype=zero (collisionless energy integral), 50/50 D-T multi-ion kinetic matrices, mode-converged band (delta_m=8, mpert=32). Reuses the calculated example deck via override; pressure-consistent kinetic.dat.
================================================================

Regression Report: solovev_kinetic_nuzero
======================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
----------------------------------------------------------------------
Quantity                 057c4af0d      a0305d167      Diff     Status
----------------------------------------------------------------------
vacuum energy Re(ev[1])  1.058613e+01   1.058613e+01   0.0e+00  OK    
q0                       1.900003e+00   1.900003e+00   0.0e+00  OK    
total energy Re(et[1])   2.290965e+00   2.290965e+00   0.0e+00  OK    
total energy Im(et[1])   -1.564546e+00  -1.564546e+00  0.0e+00  OK    
plasma energy Re(ep[1])  -8.295163e+00  -8.295163e+00  0.0e+00  OK    
ODE steps (saved)        608            608            0.0e+00  OK    
# singular surfaces      2              2              0.0e+00  OK    
singular psi locations   [2 elem]       [2 elem]       0.0e+00  OK    
total energy (all)       [32 elem]      [32 elem]      0.0e+00  OK    
ODE steps (total)        607            607            0.0e+00  OK    
mpert                    32             32             0.0e+00  OK    
q95                      3.147422e+00   3.147422e+00   0.0e+00  OK    
Runtime (s)              242.7s         242.9s                  --    
singular q values        [2 elem]       [2 elem]       0.0e+00  OK    
npert                    1              1              0.0e+00  OK    
======================================================================
Summary: 14 unchanged


================================================================
Case: solovev_multi_n — Solovev analytical equilibrium, multi-n, ideal stability
================================================================

Regression Report: solovev_multi_n
=================================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
---------------------------------------------------------------------------------
Quantity                      057c4af0d        a0305d167        Diff       Status
---------------------------------------------------------------------------------
total energy Re(et[1])        -2.134718e+00    -2.134718e+00    0.0e+00    OK    
total energy Im(et[1])        1.968592e-10     1.968592e-10     0.0e+00    OK    
vacuum matrix min eigenvalue  1.730832e+00     1.730832e+00     0.0e+00    OK    
plasma energy (all)           [70 elem]        [70 elem]        0.0e+00    OK    
vacuum energy (all)           [70 elem]        [70 elem]        0.0e+00    OK    
total energy (all)            [70 elem]        [70 elem]        0.0e+00    OK    
ODE steps (saved)             56               56               0.0e+00    OK    
ODE steps (total)             1044             1044             0.0e+00    OK    
q0                            1.900006e+00     1.900006e+00     0.0e+00    OK    
q95                           3.147422e+00     3.147422e+00     0.0e+00    OK    
# singular surfaces           3                3                0.0e+00    OK    
singular psi locations        [3 elem]         [3 elem]         0.0e+00    OK    
mpert                         35               35               0.0e+00    OK    
npert                         2                2                0.0e+00    OK    
q profile (checksum)          2340b888d410...  2340b888d410...  identical  OK    
Runtime (s)                   208.5s           209.2s                      --    
=================================================================================
Summary: 15 unchanged


================================================================
Case: solovev_n1 — Solovev analytical equilibrium, n=1, ideal stability
================================================================

Regression Report: solovev_n1
=================================================================================
Ref 1: 057c4af0d  @ 057c4af0d (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
Ref 2: a0305d167  @ a0305d167 (2026-10-28)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4c9d54fa (pinned), 2 threads/1 BLAS, jit build
---------------------------------------------------------------------------------
Quantity                      057c4af0d        a0305d167        Diff       Status
---------------------------------------------------------------------------------
total energy Re(et[1])        1.090560e-02     1.090560e-02     0.0e+00    OK    
total energy Im(et[1])        1.350301e-10     1.350301e-10     0.0e+00    OK    
plasma energy Re(ep[1])       -1.041640e+01    -1.041640e+01    0.0e+00    OK    
vacuum energy Re(ev[1])       1.042730e+01     1.042730e+01     0.0e+00    OK    
vacuum matrix min eigenvalue  2.170703e+00     2.170703e+00     0.0e+00    OK    
plasma energy (all)           [32 elem]        [32 elem]        0.0e+00    OK    
vacuum energy (all)           [32 elem]        [32 elem]        0.0e+00    OK    
total energy (all)            [32 elem]        [32 elem]        0.0e+00    OK    
ODE steps (saved)             287              287              0.0e+00    OK    
ODE steps (total)             285              285              0.0e+00    OK    
q0                            1.900006e+00     1.900006e+00     0.0e+00    OK    
q95                           3.147422e+00     3.147422e+00     0.0e+00    OK    
beta_t                        4.621027e-02     4.621027e-02     0.0e+00    OK    
beta_n                        3.217775e+00     3.217775e+00     0.0e+00    OK    
# singular surfaces           2                2                0.0e+00    OK    
singular psi locations        [2 elem]         [2 elem]         0.0e+00    OK    
singular q values             [2 elem]         [2 elem]         0.0e+00    OK    
mpert                         32               32               0.0e+00    OK    
npert                         1                1                0.0e+00    OK    
q profile (checksum)          2340b888d410...  2340b888d410...  identical  OK    
pressure profile (checksum)   108b947087e6...  108b947087e6...  identical  OK    
ca_left (checksum)            b7a5bbc5f549...  b7a5bbc5f549...  identical  OK    
Runtime (s)                   212.6s           213.2s                      --    
=================================================================================
Summary: 22 unchanged

Third-party human review and approval are required before merge.

@d-burg d-burg added this to the GPEC v2.0.0 milestone Oct 29, 2026
…elta-crit-geometry

# Conflicts:
#	src/InnerLayer/SLAYER/LayerParameters.jl
@d-burg
d-burg added this pull request to the merge queue Oct 29, 2026
Merged via the queue into develop with commit b6a2889 Oct 29, 2026
9 of 10 checks passed
@d-burg
d-burg deleted the feature/toroidal-delta-crit-geometry branch October 29, 2026 18:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changed-results Results move or an interface breaks - read before upgrading feature New capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants