Skip to content

ForceFreeStates - BUGFIX! - ⚠️ Remove the resonant solution at ideal crossings regardless of reduction timing - #489

Open
d-burg wants to merge 10 commits into
developfrom
bugfix/ffs-crossing-resonant-elimination
Open

d-burg wants to merge 10 commits into
developfrom
bugfix/ffs-crossing-resonant-elimination

Conversation

@d-burg

@d-burg d-burg commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Release note

  • Audience: users
  • Numerical impact: runs in which a Gaussian reduction fires a step or two before an ideal rational-surface crossing are now correct; on the coarse Solovev n = 1 test deck at renorm_threshold = 5, et[1] went from 13.74 to 16.4037, its value at the default renorm_threshold (Apple Silicon, develop 6fc89d021). The shipped decks move little: Solovev n = 1 et[1] by 1.6e-8 (1.4e-6 relative), DIII-D-like energies by ≤ 2.3e-8 relative, ODE step counts by ≤ 0.35 %, NTV torques by ≤ 0.01 %. (harness @ 2f436c8)
  • Migration: no deck changes. Runs in which a Gaussian reduction fired just before an ideal rational-surface crossing gave wrong free-boundary energies and should be rerun.

In the standard ForceFreeStates (FFS) integration, an ideal rational-surface crossing could remove the wrong solution when a Gaussian reduction had just fired. It did so silently, and the free-boundary energies came out arbitrarily wrong. The crossing now always removes the resonant solution.

Regression report

regress --refs 9a51446df,2f436c897 --force (all cases) on feynman (SLURM, 8 threads; current develop vs this head with develop merged, both fresh, manifest pinned). The tests in runtests_eulerlagrange.jl and runtests_fullruns.jl pass at this head (126, 26 and 25).

  • Unchanged: solovev_multi_n, diiid_slayer_n1, diiid_n1_riccati, diiid_n1_riccati_precompiled, ggj_reference, ggj_ray_q500i, gal_resistive_diiid, gal_resistive_diiid_galinner, solovev_kinetic_calculated, solovev_kinetic_nuzero and efit_fixedbdy_separatrix.
  • gal_resistive_pe: extracts nothing on either ref. That is pre-existing on develop and unrelated to this PR.
  • Seven cases move because of this PR:
    • Solovev n = 1 et[1]: 0.01090570 → 0.01090571, 1.6e-8 absolute, with one ODE step fewer. The two kinetic Solovev cases that report the same energy show the same move. Develop's Solovev deck now sits much closer to marginal (et[1] was 0.675 in the previous report), so the relative move, 1.4e-6, looks larger than the absolute one; the absolute move is smaller than the earlier 2.5e-6.
    • DIII-D-like cases: energies by ≤ 2.3e-8 relative, island half-widths and b^r by ≤ 0.01 %, forcing-driven Δ′ by 0.02 %, ODE steps by ≤ 0.13 %. diiid_truncation_n1 moves by ≤ 8.8e-9 relative.
    • NTV torques: ≤ 0.01 %.
  • Against earlier develops: the same comparison at 278057d96/3ef6d15c6, bfc60610e/d50a5e5b6 and 6fc89d021/50130bafb gave moves of the same size.
  • The review changes move nothing. regress --cases solovev_n1,solovev_multi_n,diiid_n1,diiid_multi_n --refs 1bede6836,d309eebf7 and --refs d309eebf7,50130bafb (same job setup, before the Equilibrium - BUGFIX! - 🚨 Tie the equilibrium ODE absolute tolerance to etol #491 merge) compare the merge alone, the merge with the small review edits, and the head with the single-loop pivot selection: every tracked quantity is bit-identical in both comparisons, including both multi-n cases. So all the moves above come from the original fix.
solovev_n1
Regression Report: solovev_n1
================================================================================================
Ref 1: 9a51446df  @ 9a51446df (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
Ref 2: 2f436c897  @ 2f436c897 (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
------------------------------------------------------------------------------------------------
Quantity                      9a51446df        2f436c897        Diff               Status
------------------------------------------------------------------------------------------------
total energy Re(et[1])        1.090570e-02     1.090571e-02     1.567e-08 (0.00%)  ** CHANGED **
total energy Im(et[1])        -3.885688e-10    -4.169173e-10    2.8e-11            OK
plasma energy Re(ep[1])       -1.041640e+01    -1.041640e+01    1.464e-08 (0.00%)  ** CHANGED **
vacuum energy Re(ev[1])       1.042730e+01     1.042730e+01     1.033e-09 (0.00%)  ** CHANGED **
vacuum matrix min eigenvalue  2.170703e+00     2.170703e+00     0.0e+00            OK
plasma energy (all)           [32 elem]        [32 elem]        1.978e-05 (0.00%)  ** CHANGED **
vacuum energy (all)           [32 elem]        [32 elem]        3.723e-06 (0.00%)  ** CHANGED **
total energy (all)            [32 elem]        [32 elem]        1.828e-05 (0.00%)  ** CHANGED **
ODE steps (saved)             287              286              1.000e+00 (0.35%)  ** CHANGED **
ODE steps (total)             285              284              1.000e+00 (0.35%)  ** CHANGED **
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)          049799b65749...  049799b65749...  identical          OK
pressure profile (checksum)   8339185e550b...  8339185e550b...  identical          OK
ca_left (checksum)            9dd69997cd2f...  3be8eafb5c3e...  0.000e+00 (0.00%)  ** CHANGED **
Runtime (s)                   208.0s           224.0s                              --
================================================================================================
Summary: 9 changed, 13 unchanged
diiid_n1
Regression Report: diiid_n1
================================================================================================================
Ref 1: 9a51446df  @ 9a51446df (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
Ref 2: 2f436c897  @ 2f436c897 (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
----------------------------------------------------------------------------------------------------------------
Quantity                                      9a51446df        2f436c897        Diff               Status
----------------------------------------------------------------------------------------------------------------
total energy Re(et[1])                        8.006120e-01     8.006121e-01     1.536e-08 (0.00%)  ** CHANGED **
total energy Im(et[1])                        7.924916e-05     7.924916e-05     9.5e-13            OK
plasma energy Re(ep[1])                       -1.372262e+00    -1.372262e+00    3.140e-08 (0.00%)  ** CHANGED **
vacuum energy Re(ev[1])                       2.172874e+00     2.172874e+00     1.604e-08 (0.00%)  ** CHANGED **
vacuum matrix min eigenvalue                  1.873975e-01     1.873975e-01     0.0e+00            OK
plasma energy (all)                           [35 elem]        [35 elem]        2.850e-06 (0.00%)  ** CHANGED **
vacuum energy (all)                           [35 elem]        [35 elem]        3.477e-07 (0.00%)  ** CHANGED **
total energy (all)                            [35 elem]        [35 elem]        2.521e-06 (0.00%)  ** CHANGED **
ODE steps (saved)                             786              785              1.000e+00 (0.13%)  ** CHANGED **
ODE steps (total)                             781              780              1.000e+00 (0.13%)  ** CHANGED **
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]         1.352e-06 (0.00%)  ** CHANGED **
Chirikov parameter                            [5 elem]         [5 elem]         1.081e-04 (0.01%)  ** CHANGED **
||resonant area-weighted field||              5.288793e-04     5.288861e-04     6.8e-09            OK
dominant-coupling singular values             [3 elem]         [3 elem]         3.306e-05 (0.00%)  ** CHANGED **
|forcing overlap with dominant mode|          1.411621e-04     1.411623e-04     1.9e-10            OK
|delta_nominal| of coil set 1                 7.034987e-05     7.034996e-05     9.4e-11            OK
||ddelta/d(shift)|| over coil sets            1.245516e-04     1.245517e-04     1.175e-10 (0.00%)  ** CHANGED **
||ddelta/d(tilt)|| over coil sets             4.176408e-07     4.176408e-07     4.6e-15            OK
PE plasma energy                              3.320677e+00     3.320677e+00     7.024e-09 (0.00%)  ** CHANGED **
PE vacuum energy                              3.174510e+00     3.174510e+00     0.0e+00            OK
PE surface energy                             5.509018e+00     5.509018e+00     8.936e-08 (0.00%)  ** CHANGED **
PE toroidal torque                            1.119450e-04     1.119450e-04     4.310e-12 (0.00%)  ** CHANGED **
NTV torque FGAR [N·m]                         5.483474e-01     5.483506e-01     3.2e-06            OK
NTV kinetic energy dW FGAR [J]                8.163864e-02     8.163976e-02     1.1e-06            OK
Runtime (s)                                   280.8s           289.1s                              --
||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]         2.120e-08 (0.01%)  ** CHANGED **
================================================================================================================
Summary: 16 changed, 37 unchanged
diiid_multi_n
Regression Report: diiid_multi_n
================================================================================================================================
Ref 1: 9a51446df  @ 9a51446df (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
Ref 2: 2f436c897  @ 2f436c897 (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
--------------------------------------------------------------------------------------------------------------------------------
Quantity                                                      9a51446df        2f436c897        Diff               Status
--------------------------------------------------------------------------------------------------------------------------------
total energy Re(et[1])                                        -5.750527e-01    -5.750527e-01    6.028e-10 (0.00%)  ** CHANGED **
total energy (all)                                            [58 elem]        [58 elem]        7.480e-07 (0.00%)  ** CHANGED **
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]        4.259e-08 (0.00%)  ** CHANGED **
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]        7.7e-13            OK
PE plasma energy (sum over n)                                 2.936745e+00     2.936745e+00     5.2e-11            OK
PE vacuum energy (sum over n)                                 3.114147e+00     3.114147e+00     0.0e+00            OK
PE surface energy (sum over n)                                3.523659e+00     3.523659e+00     3.086e-10 (0.00%)  ** CHANGED **
PE toroidal torque sum_n -2n Im(Phi_n' Lambda_nn^-1 Phi_n)/4  1.820468e-06     1.820469e-06     1.072e-12 (0.00%)  ** CHANGED **
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]         9.2e-09            OK
island half-widths per row                                    [7 elem]         [7 elem]         4.904e-07 (0.00%)  ** CHANGED **
Chirikov parameter per row                                    [7 elem]         [7 elem]         9.500e-06 (0.00%)  ** CHANGED **
forcing-driven Delta' per row                                 [7 elem]         [7 elem]         7.982e-07 (0.02%)  ** CHANGED **
Runtime (s)                                                   214.3s           218.2s                              --
================================================================================================================================
Summary: 8 changed, 11 unchanged
solovev_kinetic_ntv
Regression Report: solovev_kinetic_ntv
=======================================================================================================
Ref 1: 9a51446df  @ 9a51446df (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
Ref 2: 2f436c897  @ 2f436c897 (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
[ Info: Running: gal_resistive_diiid_galinner @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 194.1s — 12 quantities extracted
[ Info: Running: ggj_ray_q500i @ 9a51446df (2026-10-22T17:45:04+09:00) [computed]
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 21.341s — 5 quantities extracted
[ Info: Running: solovev_kinetic_nuzero @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 247.7s — 15 quantities extracted
[ Info: Running: diiid_error_field @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 744.2s — 11 quantities extracted
[ Info: Running: diiid_slayer_n1 @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 254.2s — 18 quantities extracted
[ Info: Running: diiid_truncation_n1 @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 194.3s — 13 quantities extracted
[ Info: Running: gal_resistive_pe @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 206.5s — 9 quantities extracted
[ Info: Running: solovev_kinetic_calculated @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 252.9s — 18 quantities extracted
[ Info: Running: gal_resistive_diiid @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 189.7s — 12 quantities extracted
[ Info: Running: solovev_n1 @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 208.0s — 23 quantities extracted
[ Info: Running: ggj_reference @ 9a51446df (2026-10-22T17:45:04+09:00) [computed]
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 8.658s — 5 quantities extracted
[ Info: Running: solovev_multi_n @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 209.8s — 16 quantities extracted
[ Info: Running: diiid_n1 @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 280.8s — 54 quantities extracted
[ Info: Running: solovev_kinetic_ntv @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 253.2s — 7 quantities extracted
[ Info: Running: diiid_n1_riccati @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 215.1s — 18 quantities extracted
[ Info: Running: solovev_kinetic_multiion @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 238.3s — 7 quantities extracted
[ Info: Running: diiid_multi_n @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 214.3s — 20 quantities extracted
[ Info: Running: efit_fixedbdy_separatrix @ 9a51446df (2026-10-22T17:45:04+09:00) [computed]
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 52.585s — 6 quantities extracted
[ Info: Running: diiid_n1_riccati_precompiled @ 9a51446df (2026-10-22T17:45:04+09:00)
[ Info:   Tearing - BUGFIX! - Reject GGJ tearing models at parse ti...
[ Info:   Completed in 51.8s — 18 quantities extracted
[ Info: Running: gal_resistive_diiid_galinner @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 193.6s — 12 quantities extracted
[ Info: Running: ggj_ray_q500i @ 2f436c897 (2026-10-22T12:18:23-04:00) [computed]
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 21.114s — 5 quantities extracted
[ Info: Running: solovev_kinetic_nuzero @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 248.7s — 15 quantities extracted
[ Info: Running: diiid_error_field @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 744.1s — 11 quantities extracted
[ Info: Running: diiid_slayer_n1 @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 255.6s — 18 quantities extracted
[ Info: Running: diiid_truncation_n1 @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 192.7s — 13 quantities extracted
[ Info: Running: gal_resistive_pe @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 210.7s — 9 quantities extracted
[ Info: Running: solovev_kinetic_calculated @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 262.0s — 18 quantities extracted
[ Info: Running: gal_resistive_diiid @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 218.2s — 12 quantities extracted
[ Info: Running: solovev_n1 @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 224.0s — 23 quantities extracted
[ Info: Running: ggj_reference @ 2f436c897 (2026-10-22T12:18:23-04:00) [computed]
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 9.043s — 5 quantities extracted
[ Info: Running: solovev_multi_n @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 221.6s — 16 quantities extracted
[ Info: Running: diiid_n1 @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 289.1s — 54 quantities extracted
[ Info: Running: solovev_kinetic_ntv @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 246.3s — 7 quantities extracted
[ Info: Running: diiid_n1_riccati @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 242.8s — 18 quantities extracted
[ Info: Running: solovev_kinetic_multiion @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 247.3s — 7 quantities extracted
[ Info: Running: diiid_multi_n @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 218.2s — 20 quantities extracted
[ Info: Running: efit_fixedbdy_separatrix @ 2f436c897 (2026-10-22T12:18:23-04:00) [computed]
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 53.25s — 6 quantities extracted
[ Info: Running: diiid_n1_riccati_precompiled @ 2f436c897 (2026-10-22T12:18:23-04:00)
[ Info:   Merge develop into bugfix/ffs-crossing-resonant-elimination
[ Info:   Completed in 48.7s — 18 quantities extracted
-------------------------------------------------------------------------------------------------------
Quantity                                   9a51446df     2f436c897     Diff               Status
-------------------------------------------------------------------------------------------------------
NTV torque fgar [Re, Im]                   [1 elem]      [1 elem]      1.326e-05 (0.00%)  ** CHANGED **
NTV ψ quadrature evaluations               45            45            0.0e+00            OK
root-area-weighted total energy Re(et[1])  1.090570e-02  1.090571e-02  1.567e-08 (0.00%)  ** CHANGED **
# 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)                                253.2s        246.3s                           --
=======================================================================================================
Summary: 2 changed, 4 unchanged
solovev_kinetic_multiion
Regression Report: solovev_kinetic_multiion
===========================================================================================
Ref 1: 9a51446df  @ 9a51446df (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
Ref 2: 2f436c897  @ 2f436c897 (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
-------------------------------------------------------------------------------------------
Quantity                     9a51446df      2f436c897      Diff               Status
-------------------------------------------------------------------------------------------
NTV total (D+T+imp+e) [N·m]  2.978404e-01   2.978522e-01   1.174e-05 (0.00%)  ** CHANGED **
NTV Deuterium [N·m]          1.874428e-01   1.874494e-01   6.631e-06 (0.00%)  ** CHANGED **
NTV Tritium [N·m]            1.943137e-01   1.943206e-01   6.828e-06 (0.00%)  ** CHANGED **
NTV electron [N·m]           -8.391612e-02  -8.391784e-02  1.714e-06 (0.00%)  ** CHANGED **
total energy Re(et[1])       1.090570e-02   1.090571e-02   1.567e-08 (0.00%)  ** CHANGED **
# singular surfaces          2              2              0.0e+00            OK
Runtime (s)                  238.3s         247.3s                            --
===========================================================================================
Summary: 5 changed, 1 unchanged
diiid_error_field
Regression Report: diiid_error_field
=============================================================================================================
Ref 1: 9a51446df  @ 9a51446df (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
Ref 2: 2f436c897  @ 2f436c897 (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
-------------------------------------------------------------------------------------------------------------
Quantity                                         9a51446df     2f436c897     Diff               Status
-------------------------------------------------------------------------------------------------------------
EFC overlap per kAt                              [1 elem]      [1 elem]      2.3e-11            OK
EFC whole-field NTV torque per kAt² [N·m]        [1 elem]      [1 elem]      2.007e-07 (0.00%)  ** CHANGED **
EFC residual-field NTV torque per kAt² [N·m]     [1 elem]      [1 elem]      2.828e-08 (0.00%)  ** CHANGED **
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]      7.097e-08 (0.00%)  ** CHANGED **
dominant-coupling singular values                [3 elem]      [3 elem]      3.306e-05 (0.00%)  ** CHANGED **
|delta_nominal| of coil set 1                    1.406997e-06  1.406999e-06  1.9e-12            OK
|Σ δ_as_designed| of the error-field coils       1.207207e-18  1.207159e-18  4.7e-23            OK
Monte Carlo mean |δ| of the error-field coils    4.701439e-05  4.701441e-05  1.6e-11            OK
Runtime (s)                                      744.2s        744.1s                           --
=============================================================================================================
Summary: 4 changed, 6 unchanged
diiid_truncation_n1
Regression Report: diiid_truncation_n1
=====================================================================================================
Ref 1: 9a51446df  @ 9a51446df (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
Ref 2: 2f436c897  @ 2f436c897 (2026-10-22)
       env: julia 1.11.9, x86_64-linux-gnu, manifest f1e0eb38 (pinned), 8 threads/8 BLAS, jit build
-----------------------------------------------------------------------------------------------------
Quantity                               9a51446df      2f436c897      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.372382e+00  -1.372382e+00  1.208e-08 (0.00%)  ** CHANGED **
total energy Re(et[1])                 8.005422e-01   8.005422e-01   4.852e-09 (0.00%)  ** CHANGED **
Runtime (s)                            194.3s         192.7s                            --
=====================================================================================================
Summary: 2 changed, 10 unchanged

What was wrong

At a crossing, cross_ideal_singular_surf! reduces the solution columns and then zeroes the one it takes to be the large resonant solution. The reduction orders columns by their growth since the previous reduction (unorm ./ unorm0) and zeroes the first.

That order carries no information when a renorm_threshold reduction fired only a few steps earlier: every column has grown by about 1. The lead column's pivot then lands on an arbitrary harmonic, and the crossing removes a non-resonant solution. A crossing on the very step after a reduction was worse: compute_solution_norms! skipped the crossing's reduction altogether, and the crossing zeroed a column chosen by the previous reduction's ordering.

On develop as of 97bd878d3 (before #480), Solovev n = 1 with renorm_threshold = 2–5 hits this for most tolerances. Examples (reference et[1] = 0.6773399618, from Vern9 at reltol 1e-12, abstol 1e-14):

renorm_threshold tolerance develop et[1] column zeroed at q = 2 / q = 3 this PR
2 1e-10 −30.75 m = −8 / m = 0 0.6773399618
2 1.2e-10 3.363 m = −10 / m = 2 0.6773399622
3 1e-9 1.013 m = 2 / m = −6 0.6773399623
5 1e-8 −0.657 m = 2 / m = −12 0.6773399701
5 1.4e-10 −1.310 m = −12 / m = 1 0.6773399619

Every correct run zeroes m = 2 at q = 2 and m = 3 at q = 3. Across all 18 develop-failing configurations (renorm_threshold ∈ {2, 3, 5} at six tolerances from 1e-7 to 1.4e-10), this PR gives et[1] within 1.8e-7 of the reference at tolerance 1e-7, and within 7.5e-10 at 1e-9 and tighter. At the deck values of renorm_threshold (1e3 and 1e4) reductions are rare enough that this was seldom hit, but nothing prevented it.

The fix

  • cross_ideal_singular_surf!: computes the resonant rows before its reduction, and passes them in as resonant_rows.
  • compute_solution_norms!: with resonant_rows, always reduces, including right after a renorm_threshold reduction.
  • apply_gaussian_reduction!:
    • takes the resonant rows as its first pivots, each on the free column with the largest component on that row, so that column alone keeps the resonant harmonic;
    • the remaining columns keep the growth order.
  • Zeroing: the crossing zeroes exactly those lead columns, and zeroed_idx records their positions (1:nres) for transform_u! as before. The kinetic_factor == 0 guards in the ideal crossing are removed: that function is only reached on the ideal branch.
  • Multi-n: each lead column lies in the n-block of its resonance, so the block structure the old findfirst preserved is kept.
  • Unchanged: kinetic crossings and renorm_threshold reductions are unchanged. The Riccati path has its own crossing, which zeroes by ipert_res directly; its harness case is bit-identical.

Tests

  • test/runtests_eulerlagrange.jl, new testset "ideal-crossing reduction isolates the resonant harmonic": a 3 × 3 case in which the resonant component is not in the largest column. It checks three things:

    • that the reduction leads with and pivots on the resonant column, leaving the resonant row zero in every other column;
    • that it still does so right after a reduction;
    • that the growth-ordered reduction is unchanged without resonant rows.

    The file passes 126/126 and 26/26.

  • test/runtests_fullruns.jl, new testset "et[1] is independent of the reduction frequency": the coarse Solovev test deck at renorm_threshold = 2, 3, 5 and 10 must give the same et[1] as at its default renorm_threshold = 1e3, to rtol = 1e-6.

    • On this branch the four agree to ≤ 1.4e-9 relative.
    • On develop 6fc89d021 (Apple Silicon) two of the four fail: 13.74 at renorm_threshold = 5 and 16.397 at renorm_threshold = 10, against 16.4037. Which values fail on develop depends on where the steps land, so it can differ by platform.
    • This replaces the solovev_n1_frequent_reduction harness case from the first version of this PR.

Changes since the first review

Notes for reviewers


🤖 Generated with Claude Code

d-burg and others added 2 commits September 28, 2026 11:21
…sings regardless of reduction timing

At an ideal rational-surface crossing the Gaussian reduction ordered columns by growth since
the previous reduction and the crossing zeroed the first one. When a ucrit reduction had fired
a few steps earlier every column had grown alike, the order was arbitrary, the lead column's
pivot fell on a non-resonant harmonic, and the crossing removed the wrong solution. A crossing
that landed on the step right after a reduction skipped its own reduction and zeroed a column
chosen from the previous one.

The ideal crossing now always reduces, leads with the column carrying the most of each
resonant harmonic, and pivots it on the resonant row, so that column alone holds the resonant
component and is the one zeroed. Kinetic crossings and ucrit reductions are unchanged.

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

ucrit = 2 at eulerlagrange_tolerance 1e-10 makes a ucrit reduction fire two steps before the
q = 2 crossing, which on develop leaves the crossing removing a non-resonant solution.

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

Copy link
Copy Markdown
Collaborator

@d-burg I actually remember what I think is this exact same bug come up in the process of identifying #480. During that, it seemed that this issue had disappeared when using the column wise absolute tolerance. Can you confirm if these results are with that change included, and if not, can you quote the combination of the two fixes and if they are both necessary?

@d-burg

d-burg commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator Author

@jhalpern30 my claude answers: the main table in the body is on develop, without the column tolerance. I also ran your #480 head (3d6acd813) and #480 with this branch merged in. Same deck (Solovev n = 1), same reference; a run counts as wrong when et[1] is off by more than 1e-5:

runs with a wrong et[1] develop #480 this PR #480 + this PR
ucrit = 2, 3, 5 (18 runs) 12 8 0 0
ucrit = 10 (9 runs) 0 6 not run 0
ucrit = 1e2 (9 runs) 0 0 not run 0

So the column tolerance does not remove it. Every wrong run on #480 still zeroes a non-resonant column at a crossing (m = −10, 12, −6, 17, …). At ucrit = 10, #480 fails where develop does not, most likely because it takes about half the steps, so a reduction lands a step or two before a crossing more often. That may be why it looked fixed: it depends on where the steps land, so it comes and goes with tolerance and step count.

The two fixes do different jobs. #480 controls the error of the small columns; this PR makes the crossing remove the resonant solution whatever the reduction timing. Both are needed, and this branch merges onto #480 without conflicts.

To reproduce on your branch: the new solovev_n1_frequent_reduction harness case (ucrit = 2, tolerance 1e-10) gives et[1] = 1.013 on #480, against 0.67734.

@jhalpern30

Copy link
Copy Markdown
Collaborator

Cool thanks, I'll give this a review at some point in the near future

…tity

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@d-burg d-burg changed the title ForceFreeStates - BUGFIX - Remove the resonant solution at ideal crossings regardless of reduction timing ForceFreeStates - BUGFIX - ⚠️ Remove the resonant solution at ideal crossings regardless of reduction timing Oct 5, 2026

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

Take what you like, most of my recommendations are for clarity in a section that I think is already confusing and this adds even more logic too.

I'll note that I've found even more bugs in our singular crossing logic and will be documenting them in #481 for further input.

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.

I am not a fan of our overpopulation of regression harnesses. Is this not a bugfix that can get a targeted unit test for expected behavior? Its a rather niche thing to get an entire regression case, and no one is realistically running with urit = 2 anyway. Is there something covered here that isn't touched by the unit tests below?

Comment thread src/ForceFreeStates/EulerLagrange.jl Outdated

# Fixup solution at singular surface; the ideal jump reduces on the resonant rows so the
# solution it removes below is the resonant one
compute_solution_norms!(odet.u, odet, ctrl, intr, true; resonant_rows=(ctrl.kinetic_factor == 0 ? ipert_res : Int[]))

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.

This is an ideal crossing - I don't think kinetic factor can ever be nonzero here

Comment thread src/ForceFreeStates/EulerLagrange.jl Outdated
# The reduction above placed the column pivoted on ipert_res[i] at index position i, which also
# keeps each zeroed column in the same n-block as the resonant mode introduced below; zeroed_idx
# records the positions for transforming u back to the full solution after integration.
if ctrl.kinetic_factor == 0

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.

This wasn't changed in this function (and maybe is why the above expression has it too), but I think the same logic applies - this crossing is only called when kinetic factor is > 0.

Comment thread src/ForceFreeStates/EulerLagrange.jl Outdated

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.

Same here- I think remove unless you can see a reason to keep

compute_solution_norms!(odet.u, odet, ctrl, intr, true)
singp = intr.sing[ising]
ipert_res = 1 .+ singp.m .- intr.mlow .+ (singp.n .- intr.nlow) .* intr.mpert

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.

For clarity/concistency, maybe define

nres = length(ipert_res)

here, and then use for loop bounds below?

Comment thread src/ForceFreeStates/EulerLagrange.jl Outdated

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.

Claude says with your changes, this could be reduced to

odet.u[:, odet.index[i, odet.ifix], :] .= ua[:, ipert_res[i]+intr.numpert_total, :]

with the loop for i in 1:nres

Comment thread src/ForceFreeStates/EulerLagrange.jl Outdated

- u: Current solution vector array, updated in-place if fixfac is called
- sing_flag: Indicates if normalization is occuring at a singular surface or not
- resonant_rows: Rows of the resonant harmonics at an ideal crossing. When given, the reduction

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.

"resonant_rows: Resonant rows at an ideal crossing; when given, the reduction always runs and pivots on them." is shorter and gets the same point across

Comment thread src/ForceFreeStates/EulerLagrange.jl Outdated

# Normalize unorm and perform Gaussian reduction if required
if odet.new
if odet.new && isempty(resonant_rows)

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.

Completely up to you on this, but I had to read it a few times to understand the control flow here. An option I think is a bit more clear:

# The first call after a reduction records the reference norms; an ideal crossing reduces regardless
at_ideal_crossing = !isempty(resonant_rows)
if odet.new && !at_ideal_crossing
    odet.new = false
    odet.unorm0 .= odet.unorm
    return
end

# Growth since the last reduction (raw norms if a crossing comes right after one), then reduce if required
if !odet.new
    odet.unorm ./= odet.unorm0
end
uratio = maximum(odet.unorm) / minimum(odet.unorm)

# Perform Gaussian reduction if ucrit ratio is reached or at singular surface
if uratio > ctrl.ucrit || sing_flag
    # …
    apply_gaussian_reduction!(u, odet, intr, sing_flag; resonant_rows)
    odet.new = true
end

Comment thread src/ForceFreeStates/EulerLagrange.jl Outdated
description of `compute_solution_norms!` for more details on the benefits of in-place `u`
updates.

Columns are triangularized in order of their growth since the last reduction. At an ideal

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.

Shorter option: "At an ideal crossing, the first pivots are the resonant_rows, each on the remaining column largest there. Growth order cannot pick the resonant solution if a ucrit reduction fired just before the crossing, since every column has then grown alike."

Comment thread src/ForceFreeStates/EulerLagrange.jl Outdated
end
# Sort unorm in descending order (since we triangularize from largest to smallest)
odet.index[:, ifix] = sortperm(odet.unorm; rev=true)
# Resonant columns first, then the rest in descending unorm (we triangularize from largest to smallest)

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.

Claude's suggested cleanup for this section that I actually kinda like:

# Triangularize primary solutions, resonant rows first, then columns from largest to smallest growth
growth_order = sortperm(odet.unorm; rev=true)
row_free = trues(intr.numpert_total)
col_free = trues(intr.numpert_total)
for isol in 1:intr.numpert_total
    if isol <= length(resonant_rows)
        kpert = resonant_rows[isol]
        ksol = argmax(j -> col_free[j] ? abs(u[kpert, j, 1]) : -Inf, 1:intr.numpert_total)
    else
        ksol = growth_order[findfirst(j -> col_free[j], growth_order)]
        @views kpert = argmax(abs.(u[:, ksol, 1]) .* row_free)
    end
    odet.index[isol, ifix] = ksol
    col_free[ksol] = false
    row_free[kpert] = false
    # Eliminate other solution vectors below the pivot
    for jsol in 1:intr.numpert_total
        if col_free[jsol]
            # … elimination body unchanged …

Note that some of it (i.e. renaming mask to row_free/col_free is outside the scope of your PR but can be done here if you agree with it). This fix put the resonant logic in the same loops and removes some of this complicated lead/filter logic

d-burg and others added 4 commits October 9, 2026 12:58
…deal crossings and flatten the reduction control flow

The ideal crossing is only reached with kinetic_factor = 0, so its guards never
took the other branch. Review suggestions; no change in behavior intended.

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

One loop picks each resonant row's column from the columns still free at that
step, then continues in growth order. Identical for a single resonant row; with
several, later resonant columns are chosen after the earlier eliminations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tion frequency in the full-run tests

Runs the coarse Solovev deck at ucrit = 2, 3, 5 and 10 against its default and
replaces the solovev_n1_frequent_reduction harness case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@d-burg
d-burg marked this pull request as ready for review October 9, 2026 22:16
@d-burg

d-burg commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

@jhalpern30 thanks, all taken. Pushed as d309eeb, c9cb55d and 50130ba on a merge of current develop, and the body has the new regression report.

From claude: "Harness case: dropped. The end-to-end check is now in runtests_fullruns.jl: the coarse Solovev deck at ucrit = 2, 3, 5, 10 must give the same et[1] as its default (rtol 1e-6). On develop two of the four fail on my machine (13.74 and 16.397 against 16.4037); on this branch all agree to about 1e-9.
kinetic_factor guards: removed. You’re right, that function is only reached from the ideal branch.
nres, zeroed_idx, the OdeState docstring, both shorter docstrings, and the control flow in compute_solution_norms!: taken as suggested.
Single-loop pivot selection: taken, with row_free / col_free. With several resonant rows it picks the later resonant columns after the earlier eliminations, so I checked it separately: bit-identical to the previous version on solovev_n1, solovev_multi_n, diiid_n1 and diiid_multi_n.

One thing to look at in the new report: against current develop, solovev_n1 et[1] moves 3.8e-6 relative, where it moved 3.5e-9 against the September develop. The review edits contribute nothing to that, so it is the original fix on post-#480 develop, and it is the size of the scatter in #490."

@d-burg d-burg changed the title ForceFreeStates - BUGFIX - ⚠️ Remove the resonant solution at ideal crossings regardless of reduction timing ForceFreeStates - BUGFIX! - ⚠️ Remove the resonant solution at ideal crossings regardless of reduction timing Oct 9, 2026
@github-actions github-actions Bot added the changed-results Results move or an interface breaks - read before upgrading label Oct 9, 2026
@jhalpern30

Copy link
Copy Markdown
Collaborator

From claude: "Harness case: dropped. The end-to-end check is now in runtests_fullruns.jl: the coarse Solovev deck at ucrit = 2, 3, 5, 10 must give the same et[1] as its default (rtol 1e-6). On develop two of the four fail on my machine (13.74 and 16.397 against 16.4037); on this branch all agree to about 1e-9.

I mean I guess, but this still feels like not a good fix. We really need 4 full runthroughs of the code in the unit tests suite to test a relatively niche behavior? Up to you if you think its worth it to change it but I'm not a fan

@d-burg

d-burg commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author

@jhalpern30 The testset costs about 6 s in CI (five coarse Solovev runs, 23:34:15 → 23:34:21 on the last 1.11 job), and it is the only check that fails on develop for this bug; #520 keeps it with its own ucrit ladder, so it will carry over. I'd keep it, but I can cut it to two values if you prefer.

Before this merges I'll bring in current develop (#503 moves the vacuum results, so the report needs rerunning). Once that's pushed, could you re-approve the head? Your approval is on d3de61ca5, from before the review fixes.

@matt-pharr
matt-pharr added this pull request to stack #545 October 20, 2026 08:53
Carries the TOML rename of ucrit to renorm_threshold into the crossing-reduction logic and
its tests.

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

Copy link
Copy Markdown
Collaborator

@d-burg @jhalpern30 — can we wrap this up by next week? It's an approved ! correctness fix, so it's cheap to land before v2.0 (due 11-02).

What's left:

  • @d-burg: merge current develop (it conflicts now) and redo the regression report, as you planned on 10-16. That should also clear the failing "Title and release note" check.
  • @jhalpern30: take a quick look after the update to confirm your approval still holds, and say whether any of your optional suggestions should go in first.

This should land before #520, since #520 keeps this PR's ucrit test.

@d-burg
d-burg requested a review from jhalpern30 October 23, 2026 18:00
@d-burg

d-burg commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator Author

Merged develop (2f436c897) and redid the report; the description is updated. @jhalpern30 could you confirm your approval still holds?

@jhalpern30

Copy link
Copy Markdown
Collaborator

Sure, go ahead and merge

This branch has not been deployed

No deployments
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