Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions regression-harness/cases/diiid_n1_riccati.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,33 @@ name = "diiid_n1_riccati"
description = "DIII-D-like equilibrium, n=1, Riccati integrator Δ' matrix"
example_dir = "examples/DIIID-like_riccati_deltaprime_example"

# Which formalism produced the Δ′ below. The Δ′ matrix is written to one canonical
# SingularSurfaces/ path whichever integrator computed it, so the numbers alone cannot say
# whether a gold pinned from the BVP is being compared against a Galerkin run. Pinning the
# deck's declared choice makes a formalism swap a loud failure instead of a silent re-gold.
[quantities.integrator]
h5path = "Input/gpec_toml_raw"
type = "token"
extract = "toml_key:ForceFreeStates.integrator"
label = "integrator (Δ′ provenance)"
noise_threshold = 0
order = 1

# Tearing stability Δ' — the msing×msing BVP matrix diagonal, and the raw side-major
# outer-region matrix it is projected from.
[quantities.delta_prime]
h5path = "SingularSurfaces/Delta_prime_matrix"
type = "complex_matrix"
extract = "diagonal_complex"
label = "delta prime (BVP diagonal)"
label = "Δ′ STRIDE-like BVP (PEST3) diagonal"
noise_threshold = 1e-8
order = 10

[quantities.delta_prime_raw]
h5path = "SingularSurfaces/Delta_prime_raw"
type = "complex_matrix"
extract = "all_complex"
label = "delta prime (raw side-major)"
label = "Δ′ STRIDE-like BVP (PEST3) raw side-major"
noise_threshold = 1e-8
order = 11

Expand Down
57 changes: 57 additions & 0 deletions regression-harness/cases/diiid_slayer_n1.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ description = "DIII-D-like H-mode equilibrium, n=1, SLAYER tearing-mode analysis
example_dir = "examples/DIIID-like_SLAYER_example"

# Per-surface SLAYER layer parameters (geometry + dimensionless)
# Which formalism produced the Δ′ this case's layer physics consumes. The Δ′ matrix lands on
# one canonical SingularSurfaces/ path whichever integrator computed it, so pinning the deck's
# declared choice is what keeps a BVP-derived gold from being compared against a Galerkin run.
[quantities.integrator]
h5path = "Input/gpec_toml_raw"
type = "token"
extract = "toml_key:ForceFreeStates.integrator"
label = "integrator (Δ′ provenance)"
noise_threshold = 0
order = 1

[quantities.slayer_ising]
h5path = "Tearing/PerSurface/rational_index"
type = "real_vector"
Expand Down Expand Up @@ -132,6 +143,52 @@ label = "SLAYER no_root flags [2/1,3/1,4/1]"
noise_threshold = 0
order = 34

# Outer-region Δ' consumed by the SLAYER matching — the same STRIDE-like BVP (PEST3) matrix
# the riccati case pins at source; tracked here too so a change in what SLAYER actually
# ingests is caught even if the source case is not run.
[quantities.slayer_delta_prime_diag]
h5path = "Tearing/PerSurface/Delta_prime_matrix"
type = "complex_matrix"
extract = "diagonal_complex"
label = "Δ′ STRIDE-like BVP (PEST3) diagonal, as ingested by SLAYER"
noise_threshold = 1e-8
order = 40

# Inner-layer solve outputs per surface (the resistive-layer Riccati solution itself, not the
# outer matching). The adaptive-scan Δ(Q) sample arrays are deliberately NOT pinned: AMR sample
# locations move under any refinement change, so they have no stable identity to pin.
[quantities.slayer_delta_s]
h5path = "Tearing/LayerWidths/delta_s"
type = "complex_vector"
extract = "all_complex"
label = "SLAYER inner-layer thickness δ_s (complex, Riccati)"
noise_threshold = 1e-10
order = 41

[quantities.slayer_delta_s_over_d_beta]
h5path = "Tearing/LayerWidths/delta_s_over_d_beta"
type = "complex_vector"
extract = "all_complex"
label = "SLAYER inner-layer δ_s/d_β (complex, dimensionless)"
noise_threshold = 1e-10
order = 42

[quantities.slayer_delta_s_abs]
h5path = "Tearing/LayerWidths/delta_s_abs"
type = "real_vector"
extract = "all_real"
label = "SLAYER inner-layer physical thickness |δ_s| [m]"
noise_threshold = 1e-12
order = 43

[quantities.slayer_d_beta]
h5path = "Tearing/LayerWidths/d_beta"
type = "real_vector"
extract = "all_real"
label = "SLAYER β-weighted ion drift scale d_β [m]"
noise_threshold = 1e-12
order = 44

# Settings (catches accidental config drift)
[quantities.slayer_enabled]
h5path = "Tearing/enabled"
Expand Down
16 changes: 14 additions & 2 deletions regression-harness/cases/gal_resistive_diiid.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@ name = "gal_resistive_diiid"
description = "DIII-D-like, n=1, RDCON outer-region Galerkin Δ′ with rpec coil columns (delta_coil)"
example_dir = "examples/DIIID-like_gal_resistive_example"

# Which formalism produced the Galerkin Δ′ below. The Δ′ matrix is written to one canonical
# SingularSurfaces/ path whichever integrator computed it, so the numbers alone cannot say whether
# a gold pinned from the Galerkin solve is being compared against a BVP run. Pinning the deck's
# declared choice makes a formalism swap a loud failure instead of a silent re-gold.
[quantities.integrator]
h5path = "Input/gpec_toml_raw"
type = "token"
extract = "toml_key:ForceFreeStates.integrator"
label = "integrator (Δ′ provenance)"
noise_threshold = 0
order = 1

# Number of resonant surfaces in the gal domain
[quantities.gal_msing]
h5path = "ForceFreeStates/Solutions/GalerkinIntegration/rational_count"
Expand All @@ -31,7 +43,7 @@ order = 11
h5path = "SingularSurfaces/Delta_prime_matrix"
type = "complex_matrix"
extract = "diagonal_complex"
label = "gal PEST3 Δ diagonal"
label = "Δ′ Galerkin RDCON (PEST3) diagonal"
noise_threshold = 1e-6
order = 20

Expand All @@ -40,7 +52,7 @@ order = 20
h5path = "SingularSurfaces/Delta_prime_raw"
type = "complex_matrix"
extract = "norm"
label = "||gal Δ′ matrix||"
label = "||Δ′ Galerkin RDCON (PEST3) matrix||"
noise_threshold = 1e-6
order = 21

Expand Down
18 changes: 16 additions & 2 deletions regression-harness/cases/gal_resistive_pe.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ example_dir = "examples/DIIID-like_gal_resistive_pe_example"
# FINITE, per-rational-surface singular-coupling scalars (the physics-meaningful driven quantities) — not
# any whole-profile ξ/ξ′ norm (those diverge at the rationals and are ill-posed as benchmarks).

# Which formalism produced the Galerkin Δ′ below. The Δ′ matrix is written to one canonical
# SingularSurfaces/ path whichever integrator computed it, so the numbers alone cannot say whether
# a gold pinned from the Galerkin solve is being compared against a BVP run. Pinning the deck's
# declared choice makes a formalism swap a loud failure instead of a silent re-gold.
[quantities.integrator]
h5path = "Input/gpec_toml_raw"
type = "token"
extract = "toml_key:ForceFreeStates.integrator"
label = "integrator (Δ′ provenance)"
noise_threshold = 0
order = 1

# Surface locations / count (sanity)
[quantities.pe_rational_q]
h5path = "PerturbedEquilibrium/SingularCoupling/rational_q"
Expand Down Expand Up @@ -66,12 +78,14 @@ label = "penetrated b field"
noise_threshold = 1e-8
order = 32

# Per-surface Δ' from the PE singular-coupling analysis
# Per-surface driven-response Δ' from the PE singular-coupling jump (∂b^ψ/∂ψ across the
# rational surface over 2π·χ₁, forced by the applied flux). This is a driven-response
# diagnostic, NOT the tearing-stability Δ' of the STRIDE-like BVP or Galerkin RDCON solvers.
[quantities.pe_delta_prime]
h5path = "PerturbedEquilibrium/SingularCoupling/Delta_prime"
type = "complex_vector"
extract = "all_complex"
label = "PE Δ' per surface"
label = "PE driven-response Δ′ (SingularCoupling jump)"
noise_threshold = 1e-8
order = 33

Expand Down
68 changes: 68 additions & 0 deletions regression-harness/cases/slayer_dels_fitzpatrick.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Regression case: GPEC's del_s Riccati layer-width solver against Fitzpatrick, "Tearing Mode
# Dynamics in Tokamak Plasmas" (IOP 2023), figures 6.2 and 6.3 (p. 6-10).
#
# This is the suite's only case pinned to an EXTERNAL published reference rather than to GPEC's own
# previous output: a failure means we no longer reproduce the textbook. Verified at eight points
# against the published contour bands, e.g. (Q,P) = (4.0, 0.5) -> Re 2.008 against the 1.9-2.1
# contours, (0.5, 4.0) -> Re 1.537 against the 1.5 contour. The magnitudes also match the book's
# table 6.2 reactor estimates (|delta_s| 2.95-4.69 mm) at DIII-D-like parameters.
#
# Pure ODE: no equilibrium, no geqdsk, no kinetic file. Sub-second, so it is fast-tier eligible, and
# it carries no equilibrium dependence -- its golden values survive equilibrium-side re-baselining.
# Complements slayer_delta_probe, which pins the dispersion solve Delta(Q); this pins the width
# solve delta_s/d_beta over (Q_hat, P_hat).
[case]
name = "slayer_dels_fitzpatrick"
description = "del_s Riccati layer width vs Fitzpatrick 2023 figs 6.2/6.3 over (Q_hat, P_hat)"
kind = "computed"

# The scan axes, pinned so a silently reshaped grid is a failure rather than a re-gold.
[quantities.q_hat]
h5path = "fitzpatrick/Q_hat"
type = "real_vector"
extract = "all_real"
label = "grid Q_hat (= Q_*/D^4)"
noise_threshold = 0
order = 10

[quantities.p_hat]
h5path = "fitzpatrick/P_hat"
type = "real_vector"
extract = "all_real"
label = "grid P_hat (= P/D^6)"
noise_threshold = 0
order = 11

# tau is not stated in the book's figure captions; tau = 1 (table 5.1, low-field reactor) is the
# assumption this reproduction rests on, so it is pinned rather than left implicit.
[quantities.tau]
h5path = "fitzpatrick/tau"
type = "real_scalar"
extract = "value"
label = "tau (assumed; not given in the figure captions)"
noise_threshold = 0
order = 12

[quantities.dels_db_re]
h5path = "fitzpatrick/dels_db_re"
type = "real_vector"
extract = "all_real"
label = "Re(delta_s/d_beta) — Fitzpatrick fig 6.2"
noise_threshold = 1e-10
order = 20

[quantities.dels_db_im]
h5path = "fitzpatrick/dels_db_im"
type = "real_vector"
extract = "all_real"
label = "Im(delta_s/d_beta) — Fitzpatrick fig 6.3"
noise_threshold = 1e-10
order = 21

[quantities.runtime]
h5path = ""
type = "runtime"
extract = "value"
label = "Runtime (s)"
noise_threshold = 0.0
order = 999
50 changes: 50 additions & 0 deletions regression-harness/cases/slayer_delta_probe.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Regression case: fixed-Q probe of the SLAYER inner-layer dispersion Δ(Q).
# Evaluates Δ(Q) on a fixed 4×4 grid over Re(Q), Im(Q) ∈ [-10, 10] using the DIII-D-like
# SLAYER deck's own 2/1-surface layer parameters, quoted verbatim in the runner's computed
# script. Fixed Q values are refinement-stable, unlike the AMR scan samples in gpec.h5, so
# this pins the dispersion curve itself; the parameter chain producing those layer inputs
# is pinned separately by diiid_slayer_n1. Seconds to run — fast-tier eligible.
[case]
name = "slayer_delta_probe"
description = "SLAYER inner-layer Δ(Q) on a fixed 4×4 Q grid, DIII-D-like 2/1 layer parameters"
kind = "computed"

[quantities.q_re]
h5path = "slayer_probe/Q_re"
type = "real_vector"
extract = "all_real"
label = "probe grid Re(Q)"
noise_threshold = 0
order = 10

[quantities.q_im]
h5path = "slayer_probe/Q_im"
type = "real_vector"
extract = "all_real"
label = "probe grid Im(Q)"
noise_threshold = 0
order = 11

[quantities.delta_re]
h5path = "slayer_probe/Delta_re"
type = "real_vector"
extract = "all_real"
label = "SLAYER inner-layer Re Δ(Q) on the fixed grid"
noise_threshold = 1e-10
order = 20

[quantities.delta_im]
h5path = "slayer_probe/Delta_im"
type = "real_vector"
extract = "all_real"
label = "SLAYER inner-layer Im Δ(Q) on the fixed grid"
noise_threshold = 1e-10
order = 21

[quantities.runtime]
h5path = ""
type = "runtime"
extract = "value"
label = "Runtime (s)"
noise_threshold = 0.0
order = 999
59 changes: 59 additions & 0 deletions regression-harness/golden/slayer_dels_fitzpatrick.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
[meta]
blas_threads = 2
case = "slayer_dels_fitzpatrick"
commit = "af3e4492"
generated_at = "2026-08-18"
golden_version = 1
julia_version = "1.11.6"
manifest_sha = "7e5c34ad1722fa6addf94f7387b972fa8ac17ff86166793819b158496d495132"
nthreads = 2
os_arch = "arm64-apple-darwin24.0.0"
reason = "Initial pin: validated against Fitzpatrick 2023 figs 6.2/6.3 at eight contour points"

[values.dels_db_im]
atol = 0.0
class = "physics_converged"
rtol = 1.0e-6
tolerance_basis = "class-default (provisional)"
value_text = "[-0.03903669609227284,-0.7097932061530505,-1.0865009301031268,-1.5690999603536648,-2.2242340056733148,-0.011118192607611124,-0.35424388489008746,-0.776484631542084,-1.416939644030615,-2.2250603072320665,-0.008402000357094586,-0.23928032159546678,-0.5666784684880879,-1.241924594739638,-2.1750391797697133,-0.006297613829213364,-0.1657149360631757,-0.3716832232708168,-0.9092532037784165,-1.9732264855758332,-0.004682490543220957,-0.11916296976842101,-0.2502562086693129,-0.578522722631012,-1.4658508790642786]"
value_type = "json_array"

[values.dels_db_re]
atol = 0.0
class = "physics_converged"
rtol = 1.0e-6
tolerance_basis = "class-default (provisional)"
value_text = "[0.46252746222290736,0.7691732891864712,1.0821020639186198,1.5537655127977916,2.2130417549691974,0.9838377906344368,0.9426353501706125,1.017567466663986,1.35072260354625,2.0080394342246684,1.1484429925403958,1.1069495858506195,1.0754748077370269,1.2328881423647,1.8273926389542299,1.336215433387759,1.3118923623802783,1.259193827055807,1.2120466712964955,1.540405108811276,1.5494641775774003,1.5373751336175125,1.5040680534472435,1.4084024975856595,1.350103015944749]"
value_type = "json_array"

[values.p_hat]
atol = 0.0
class = "physics_converged"
rtol = 1.0e-6
tolerance_basis = "class-default (provisional)"
value_text = "[0.02,0.02,0.02,0.02,0.02,0.5,0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0,1.0,2.0,2.0,2.0,2.0,2.0,4.0,4.0,4.0,4.0,4.0]"
value_type = "json_array"

[values.q_hat]
atol = 0.0
class = "physics_converged"
rtol = 1.0e-6
tolerance_basis = "class-default (provisional)"
value_text = "[0.02,0.5,1.0,2.0,4.0,0.02,0.5,1.0,2.0,4.0,0.02,0.5,1.0,2.0,4.0,0.02,0.5,1.0,2.0,4.0,0.02,0.5,1.0,2.0,4.0]"
value_type = "json_array"

[values.runtime]
atol = +inf
class = "diagnostic"
rtol = +inf
tolerance_basis = "class-default (provisional)"
value = 1.2057960033416748
value_type = "real"

[values.tau]
atol = 0.0
class = "physics_converged"
rtol = 1.0e-6
tolerance_basis = "class-default (provisional)"
value = 1.0
value_type = "real"
Loading
Loading