Skip to content

Tearing - BUGFIX! - Reject GGJ tearing models at parse time and stop swallowing stage errors - #547

Merged
logan-nc merged 2 commits into
developfrom
bugfix/reject-ggj-tearing
Oct 22, 2026
Merged

logan-nc merged 2 commits into
developfrom
bugfix/reject-ggj-tearing

Conversation

@matt-pharr

@matt-pharr matt-pharr commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

Release note

  • Audience: users
  • Numerical impact: none (harness @ 9fadd79)
  • Migration: A deck with [SLAYER] inner_model = "ggj_ray", "ggj_shooting" or "ggj_galerkin" now fails at the start of the force-free-states stage (before any solve, and not at all on an equilibrium-only run), with a message that GGJ tearing growth rates are not currently supported; use inner_model = "slayer_fitzpatrick". This is revisable whenever @d-burg merges in his work fixing the GGJ normalizations for tearing applications. A tearing stage that fails for any other reason now stops the run instead of logging an error and finishing.

A deck that asked for a GGJ tearing model used to finish "successfully" with no Tearing/ group, because the stage caught and logged the "not implemented" error. GGJ tearing models are now rejected up front, and tearing-stage errors reach the user; every earlier stage has already written its output when the tearing stage runs.

Regression report

At the current head, after #536 merged and the base became develop: --refs 9365f0d6c,9fadd79c5 --cases diiid_slayer_n1,diiid_n1 (feynman, fresh cache). Every quantity is 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: 9365f0d6c  @ 9365f0d6c (2026-10-22)
       env: julia 1.11.7, x86_64-linux-gnu, manifest 7027ae20 (pinned), 16 threads/16 BLAS, jit build
Ref 2: 9fadd79c5  @ 9fadd79c5 (2026-10-22)
       env: julia 1.11.7, x86_64-linux-gnu, manifest 7027ae20 (pinned), 16 threads/16 BLAS, jit build
-------------------------------------------------------------------------
Quantity                            9365f0d6c  9fadd79c5  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 Q_root [2/1,3/1,4/1]         [3 elem]   [3 elem]   1.2e-05  OK    
SLAYER ω_Hz [2/1,3/1,4/1]           [3 elem]   [3 elem]   3.3e-01  OK    
SLAYER γ_Hz [2/1,3/1,4/1]           [3 elem]   [3 elem]   2.5e-02  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)                         270.5s     260.2s              --    
=========================================================================
Summary: 17 unchanged


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

Regression Report: diiid_n1
=================================================================================================
Ref 1: 9365f0d6c  @ 9365f0d6c (2026-10-22)
       env: julia 1.11.7, x86_64-linux-gnu, manifest 7027ae20 (pinned), 16 threads/16 BLAS, jit build
Ref 2: 9fadd79c5  @ 9fadd79c5 (2026-10-22)
       env: julia 1.11.7, x86_64-linux-gnu, manifest 7027ae20 (pinned), 16 threads/16 BLAS, jit build
-------------------------------------------------------------------------------------------------
Quantity                                      9365f0d6c        9fadd79c5        Diff       Status
-------------------------------------------------------------------------------------------------
total energy Re(et[1])                        8.006120e-01     8.006120e-01     0.0e+00    OK    
total energy Im(et[1])                        7.924916e-05     7.924916e-05     0.0e+00    OK    
plasma energy Re(ep[1])                       -1.372262e+00    -1.372262e+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)                             786              786              0.0e+00    OK    
ODE steps (total)                             781              781              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.842269e-01     8.842269e-01     0.0e+00    OK    
internal inductance li2                       7.080757e-01     7.080757e-01     0.0e+00    OK    
internal inductance li3                       7.304341e-01     7.304341e-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)                          39d9421352fb...  39d9421352fb...  identical  OK    
pressure profile (checksum)                   4dcd02ebd430...  4dcd02ebd430...  identical  OK    
Mercier D_I profile (checksum)                8f2e24b7a722...  8f2e24b7a722...  identical  OK    
resistive interchange D_R profile (checksum)  9cc3fb326bf3...  9cc3fb326bf3...  identical  OK    
ballooning Delta' profile (checksum)          b9e975c03644...  b9e975c03644...  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.288793e-04     5.288793e-04     0.0e+00    OK    
dominant-coupling singular values             [3 elem]         [3 elem]         0.0e+00    OK    
|forcing overlap with dominant mode|          1.411621e-04     1.411621e-04     0.0e+00    OK    
|delta_nominal| of coil set 1                 7.034987e-05     7.034987e-05     0.0e+00    OK    
||ddelta/d(shift)|| over coil sets            1.245516e-04     1.245516e-04     0.0e+00    OK    
||ddelta/d(tilt)|| over coil sets             4.176408e-07     4.176408e-07     0.0e+00    OK    
PE plasma energy                              3.320677e+00     3.320677e+00     0.0e+00    OK    
PE vacuum energy                              3.174510e+00     3.174510e+00     0.0e+00    OK    
PE surface energy                             5.509018e+00     5.509018e+00     0.0e+00    OK    
PE toroidal torque                            1.119450e-04     1.119450e-04     0.0e+00    OK    
NTV torque FGAR [N·m]                         5.483474e-01     5.483474e-01     0.0e+00    OK    
NTV kinetic energy dW FGAR [J]                8.163864e-02     8.163864e-02     0.0e+00    OK    
Runtime (s)                                   265.4s           261.3s                      --    
||forcing b~|| (root-area-weighted)           4.683330e-04     4.683330e-04     0.0e+00    OK    
resonant area-weighted field b^r              [5 elem]         [5 elem]         0.0e+00    OK    
=================================================================================================
Summary: 53 unchanged

Earlier run against the old stack base:

Compared against the stack base, --refs c8b68e4ba,b6bbb9ae9 (refactor/ggj-ray-galerkin-bvp, bugfix/reject-ggj-tearing), on diiid_slayer_n1 and diiid_n1_riccati, the two cases that run SLAYER.

================================================================
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: c8b68e4ba  @ c8b68e4ba (2026-10-20)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4676c192 (unpinned), 8 threads/8 BLAS, jit build
Ref 2: b6bbb9ae9  @ b6bbb9ae9 (2026-10-20)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4676c192 (unpinned), 8 threads/8 BLAS, jit build
-------------------------------------------------------------------------
Quantity                            c8b68e4ba  b6bbb9ae9  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 Q_root [2/1,3/1,4/1]         [3 elem]   [3 elem]   1.2e-05  OK    
SLAYER ω_Hz [2/1,3/1,4/1]           [3 elem]   [3 elem]   3.3e-01  OK    
SLAYER γ_Hz [2/1,3/1,4/1]           [3 elem]   [3 elem]   2.5e-02  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)                         295.9s     313.1s              --    
=========================================================================
Summary: 17 unchanged


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

Regression Report: diiid_n1_riccati
============================================================================
Ref 1: c8b68e4ba  @ c8b68e4ba (2026-10-20)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4676c192 (unpinned), 8 threads/8 BLAS, jit build
Ref 2: b6bbb9ae9  @ b6bbb9ae9 (2026-10-20)
       env: julia 1.12.6, x86_64-linux-gnu, manifest 4676c192 (unpinned), 8 threads/8 BLAS, jit build
----------------------------------------------------------------------------
Quantity                       c8b68e4ba      b6bbb9ae9      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)              96             96             0.0e+00  OK    
ODE steps (total)              2634           2634           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)                    283.9s         274.8s                  --    
============================================================================
Summary: 17 unchanged

REGRESS_EXIT=0

Notes for reviewers

🤖 Generated with Claude Code

@matt-pharr matt-pharr self-assigned this Oct 20, 2026
@matt-pharr
matt-pharr requested a review from d-burg October 20, 2026 11:31
@github-actions github-actions Bot added bugfix Something was wrong and now is not changed-results Results move or an interface breaks - read before upgrading labels Oct 20, 2026
@matt-pharr
matt-pharr added this pull request to stack #539 October 20, 2026 11:34
@matt-pharr
matt-pharr force-pushed the bugfix/reject-ggj-tearing branch from 7febb5d to b6bbb9a Compare October 20, 2026 12:22
@matt-pharr
matt-pharr requested a review from logan-nc October 20, 2026 13:28
Base automatically changed from refactor/ggj-ray-galerkin-bvp to develop October 22, 2026 07:19
…swallowing stage errors

A deck with inner_model = "ggj_*" passed validation, then solve(TearingProblem,
GGJModel) errored and run_slayer_stage's try/catch logged it, so the run
finished with no Tearing/ group. validate now rejects the ggj_* models, since
GGJ tearing growth rates are not implemented in v2.0.0. run_slayer_stage no
longer catches errors, so a failing tearing stage stops the run after every
earlier stage has written its output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@logan-nc
logan-nc force-pushed the bugfix/reject-ggj-tearing branch from b6bbb9a to 29a7577 Compare October 22, 2026 07:19

@logan-nc logan-nc 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.

OK. My one nit here is that putting an exact version number into the source code is a recipe for getting stale messaging. Just remove the specific version and say it is not currently supported

…ion messages

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdRsGGg4YRG6E9fgLGbpdF
@logan-nc
logan-nc merged commit 9a51446 into develop Oct 22, 2026
10 of 11 checks passed
@logan-nc
logan-nc deleted the bugfix/reject-ggj-tearing branch October 22, 2026 08:45
@d-burg

d-burg commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

@matt-pharr two post-merge notes:

  • The rejection fires in slayer_control_from_toml → validate, which the layer-overlap scan calls for every [SLAYER] section before the force-free-states stage. So a deck with enabled = false and a ggj_* inner_model, for example one that keeps [SLAYER] only for its profiles, now aborts where it used to run. Was that intended? If not, skipping the check when enabled = false fixes it.
  • The release note says such a deck "fails when the deck is read", but it actually fails at the start of the force-free-states stage, and not at all on an equilibrium-only run. Also, a bad profile_file there only warns, so the run goes on through every later stage and then fails in the tearing stage.

@matt-pharr

Copy link
Copy Markdown
Collaborator Author

Thanks @d-burg, not intended. The rejection should only apply when tearing is enabled. I'll open a follow-up that skips the inner-model check when enabled = false and makes a bad profile_file fail at parse time instead of at the tearing stage. I'll also correct the release-note wording here: it fires at the start of the force-free-states stage, not when the deck is read.

matt-pharr added a commit that referenced this pull request Oct 23, 2026
Brings in develop (#536, #547). run_slayer_stage keeps #547's unguarded body
without the stage timer, which main now owns, and run_kinetic_forces keeps the
new axis_psi_c boundary without its own banner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
matt-pharr added a commit that referenced this pull request Oct 23, 2026
…-in-main

Brings in develop (#536, #547) through the stack. The deck/API match parity
test compares on the galerkin inner model, the only one that still returns
inner profiles by default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Something was wrong and now is not changed-results Results move or an interface breaks - read before upgrading

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants