Skip to content

Commit 3a17004

Browse files
d-burgclaude
andcommitted
REGRESSION - NEW FEATURE - Fixed-Q probe of the SLAYER inner-layer Δ(Q)
The AMR scan's Δ(Q) samples in gpec.h5 cannot carry golden values: adaptive sample locations move under any refinement change, so they have no stable identity to pin. This computed case pins the dispersion curve itself instead — Δ(Q) on a fixed 4×4 grid over Re(Q), Im(Q) ∈ [-10, 10], sixteen refinement-stable complex values. The layer parameters are the DIII-D-like SLAYER deck's own 2/1-surface values (extracted from Tearing/PerSurface of a deck run and quoted verbatim), so the case is self-contained and probes the solver alone; the parameter chain that produces those inputs is pinned separately by diiid_slayer_n1. Runs in ~1 s — fast-tier eligible alongside the GGJ references. All sixteen Δ values are finite across the grid, |Δ| spanning 0.21 to 1.52. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 19b6017 commit 3a17004

2 files changed

Lines changed: 86 additions & 0 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Regression case: fixed-Q probe of the SLAYER inner-layer dispersion Δ(Q).
2+
# Evaluates Δ(Q) on a fixed 4×4 grid over Re(Q), Im(Q) ∈ [-10, 10] using the DIII-D-like
3+
# SLAYER deck's own 2/1-surface layer parameters, quoted verbatim in the runner's computed
4+
# script. Fixed Q values are refinement-stable, unlike the AMR scan samples in gpec.h5, so
5+
# this pins the dispersion curve itself; the parameter chain producing those layer inputs
6+
# is pinned separately by diiid_slayer_n1. Seconds to run — fast-tier eligible.
7+
[case]
8+
name = "slayer_delta_probe"
9+
description = "SLAYER inner-layer Δ(Q) on a fixed 4×4 Q grid, DIII-D-like 2/1 layer parameters"
10+
kind = "computed"
11+
12+
[quantities.q_re]
13+
h5path = "slayer_probe/Q_re"
14+
type = "real_vector"
15+
extract = "all_real"
16+
label = "probe grid Re(Q)"
17+
noise_threshold = 0
18+
order = 10
19+
20+
[quantities.q_im]
21+
h5path = "slayer_probe/Q_im"
22+
type = "real_vector"
23+
extract = "all_real"
24+
label = "probe grid Im(Q)"
25+
noise_threshold = 0
26+
order = 11
27+
28+
[quantities.delta_re]
29+
h5path = "slayer_probe/Delta_re"
30+
type = "real_vector"
31+
extract = "all_real"
32+
label = "SLAYER inner-layer Re Δ(Q) on the fixed grid"
33+
noise_threshold = 1e-10
34+
order = 20
35+
36+
[quantities.delta_im]
37+
h5path = "slayer_probe/Delta_im"
38+
type = "real_vector"
39+
extract = "all_real"
40+
label = "SLAYER inner-layer Im Δ(Q) on the fixed grid"
41+
noise_threshold = 1e-10
42+
order = 21
43+
44+
[quantities.runtime]
45+
h5path = ""
46+
type = "runtime"
47+
extract = "value"
48+
label = "Runtime (s)"
49+
noise_threshold = 0.0
50+
order = 999

regression-harness/src/runner.jl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,40 @@ end
121121
%RUNINFO%
122122
"""
123123

124+
125+
# Fixed-Q probe of the SLAYER inner-layer dispersion Δ(Q) on the DIII-D-like 2/1 surface.
126+
# The adaptive AMR scan samples in gpec.h5 cannot be pinned (sample locations move under any
127+
# refinement change), so this evaluates Δ(Q) on a fixed 4×4 grid over Re(Q), Im(Q) ∈ [-10, 10]
128+
# instead — a refinement-stable pin of the dispersion curve itself. The layer parameters are the
129+
# DIII-D-like SLAYER deck's own 2/1 surface values (Tearing/PerSurface, develop @ 1f193a6c),
130+
# quoted verbatim so the case is self-contained and probes the SOLVER alone: the parameter
131+
# chain that produces these numbers is pinned separately by the diiid_slayer_n1 case.
132+
const COMPUTED_SLAYER_DELTA_PROBE_SCRIPT_TEMPLATE = """
133+
using Pkg
134+
%INSTANTIATE%
135+
using GeneralizedPerturbedEquilibrium
136+
using GeneralizedPerturbedEquilibrium.InnerLayer
137+
using HDF5
138+
p = SLAYERParameters(;
139+
tau=1.1975430647804235, lu=6.086905739791344e6, c_beta=0.22094021004591707,
140+
D_norm=4.191469284125091, P_perp=50.2972642329308, P_tor=34.74437891503841,
141+
Q_e=1.0915286815773122, Q_i=-1.6558720999124832, iota_e=0.39729503206497013,
142+
tauk=0.00010358784131467763, tau_r=3.453343933553279, delta_n=504.745127277822,
143+
rs=0.3617373814196757, R0=1.7433359412007365, bt=1.0, sval_r=1.260093929519795,
144+
eta=4.761642777337999e-8, d_beta=0.011249087118484661)
145+
axis = range(-10.0, 10.0; length=4)
146+
Q = ComplexF64[re + im_ * 1im for im_ in axis for re in axis]
147+
t_start = time()
148+
Δ = ComplexF64[solve_inner(SLAYERModel(), p, q).tearing for q in Q]
149+
elapsed = time() - t_start
150+
h5open(ARGS[1], "w") do fid
151+
fid["slayer_probe/Q_re"] = real.(Q)
152+
fid["slayer_probe/Q_im"] = imag.(Q)
153+
fid["slayer_probe/Delta_re"] = real.(Δ)
154+
fid["slayer_probe/Delta_im"] = imag.(Δ)
155+
end
156+
%RUNINFO%
157+
"""
124158
# Self-contained separatrix-finder regression (PR #296). Loads a fixed-boundary EFIT whose
125159
# computational box hugs the LCFS (eps=0.05 TokaMaker aspect-scan g-file): outside the prescribed
126160
# LCFS the coil-vacuum flux turns back above the boundary value before the grid edge, so the old
@@ -253,6 +287,8 @@ function _computed_script_template(case_spec::CaseSpec)
253287
return COMPUTED_GGJ_SCRIPT_TEMPLATE
254288
elseif case_spec.name == "ggj_ray_q500i"
255289
return COMPUTED_GGJ_RAY_SCRIPT_TEMPLATE
290+
elseif case_spec.name == "slayer_delta_probe"
291+
return COMPUTED_SLAYER_DELTA_PROBE_SCRIPT_TEMPLATE
256292
elseif case_spec.name == "efit_fixedbdy_separatrix"
257293
return COMPUTED_SEPARATRIX_SCRIPT_TEMPLATE
258294
end

0 commit comments

Comments
 (0)