Skip to content

Equilibrium - FEATURE! - Store the analytic config on PlasmaEquilibrium and re-form every source from it - #548

Merged
matt-pharr merged 7 commits into
developfrom
refactor/equilibrium-source
Oct 26, 2026
Merged

matt-pharr merged 7 commits into
developfrom
refactor/equilibrium-source

Conversation

@matt-pharr

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

Copy link
Copy Markdown
Collaborator

Release note

  • Audience: users
  • Numerical impact: none for deck runs (harness @ 6a94cca). Scripted analytic runs with mpsi=0 now get the same refined two-pass ψ grid as the deck instead of the single-pass grid, so their results move.
  • Migration: setup_equilibrium(config, source) is removed; call PlasmaEquilibrium(config, source), or the one-call PlasmaEquilibrium(file; eq_type), PlasmaEquilibrium(analytic_config) or PlasmaEquilibrium(dd). The equil.toml / [EQUIL_CONTROL] loader (setup_equilibrium(path), EquilibriumConfig(path)) is removed; configure the equilibrium from the [Equilibrium] section of gpec.toml. A script that builds an analytic equilibrium with mpsi=0 and wants the old single-pass grid must now set mpsi explicitly. A source that does not match eq_type (an analytic config with eq_type="efit", or a dd without eq_type="imas") now raises an error instead of being silently ignored.

A PlasmaEquilibrium now remembers the source it was formed from, so a script gets the same two-pass auto grid as a deck. Analytic and IMAS equilibria can be built in one call: PlasmaEquilibrium(SolovevConfig(...); mpsi=0) and PlasmaEquilibrium(dd; imas_cocos=11).

Regression report

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

Regression Report: solovev_n1
=============================================================================================
Ref 1: 231e7766a  @ 231e7766a (2026-10-23)
       env: julia 1.12.6, x86_64-linux-gnu, manifest aa94b997 (pinned), 2 threads/1 BLAS, jit build
Ref 2: refactor/equilibrium-source  @ 6a94cca8d (2026-10-23)
       env: julia 1.12.6, x86_64-linux-gnu, manifest aa94b997 (pinned), 2 threads/1 BLAS, jit build
---------------------------------------------------------------------------------------------
Quantity                      231e7766a        refactor/equilibrium-source  Diff       Status
---------------------------------------------------------------------------------------------
total energy Re(et[1])        1.090560e-02     1.090560e-02                 0.0e+00    OK
total energy Im(et[1])        2.141340e-10     2.141340e-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)          af93c6269245...  af93c6269245...              identical  OK
pressure profile (checksum)   e252b3b40ede...  e252b3b40ede...              identical  OK
ca_left (checksum)            06afdeb86cdc...  06afdeb86cdc...              identical  OK
Runtime (s)                   190.9s           220.6s                                  --
=============================================================================================
Summary: 22 unchanged


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

Regression Report: solovev_multi_n
=============================================================================================
Ref 1: 231e7766a  @ 231e7766a (2026-10-23)
       env: julia 1.12.6, x86_64-linux-gnu, manifest aa94b997 (pinned), 2 threads/1 BLAS, jit build
Ref 2: refactor/equilibrium-source  @ 6a94cca8d (2026-10-23)
       env: julia 1.12.6, x86_64-linux-gnu, manifest aa94b997 (pinned), 2 threads/1 BLAS, jit build
---------------------------------------------------------------------------------------------
Quantity                      231e7766a        refactor/equilibrium-source  Diff       Status
---------------------------------------------------------------------------------------------
total energy Re(et[1])        -2.134718e+00    -2.134718e+00                0.0e+00    OK
total energy Im(et[1])        4.510275e-10     4.510275e-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)             1043             1043                         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)          af93c6269245...  af93c6269245...              identical  OK
Runtime (s)                   216.3s           234.0s                                  --
=============================================================================================
Summary: 15 unchanged


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

Regression Report: diiid_n1
=============================================================================================================
Ref 1: 231e7766a  @ 231e7766a (2026-10-23)
       env: julia 1.12.6, x86_64-linux-gnu, manifest aa94b997 (pinned), 2 threads/1 BLAS, jit build
Ref 2: refactor/equilibrium-source  @ 6a94cca8d (2026-10-23)
       env: julia 1.12.6, x86_64-linux-gnu, manifest aa94b997 (pinned), 2 threads/1 BLAS, jit build
-------------------------------------------------------------------------------------------------------------
Quantity                                      231e7766a        refactor/equilibrium-source  Diff       Status
-------------------------------------------------------------------------------------------------------------
total energy Re(et[1])                        8.006123e-01     8.006123e-01                 0.0e+00    OK
total energy Im(et[1])                        7.924925e-05     7.924925e-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)                             800              800                          0.0e+00    OK
ODE steps (total)                             795              795                          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.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)                          ea980cf7e8cf...  ea980cf7e8cf...              identical  OK
pressure profile (checksum)                   75be5949b7c1...  75be5949b7c1...              identical  OK
Mercier D_I profile (checksum)                cafa40526b39...  cafa40526b39...              identical  OK
resistive interchange D_R profile (checksum)  c70e46071c9d...  c70e46071c9d...              identical  OK
ballooning Delta' profile (checksum)          029149d57e8c...  029149d57e8c...              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.288864e-04     5.288864e-04                 0.0e+00    OK
dominant-coupling singular values             [3 elem]         [3 elem]                     0.0e+00    OK
|forcing overlap with dominant mode|          1.411634e-04     1.411634e-04                 0.0e+00    OK
|delta_nominal| of coil set 1                 7.035049e-05     7.035049e-05                 0.0e+00    OK
||ddelta/d(shift)|| over coil sets            1.245519e-04     1.245519e-04                 0.0e+00    OK
||ddelta/d(tilt)|| over coil sets             4.176407e-07     4.176407e-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.509017e+00     5.509017e+00                 0.0e+00    OK
PE toroidal torque                            1.119454e-04     1.119454e-04                 0.0e+00    OK
NTV torque FGAR [N·m]                         5.483495e-01     5.483495e-01                 0.0e+00    OK
NTV kinetic energy dW FGAR [J]                8.163740e-02     8.163740e-02                 0.0e+00    OK
Runtime (s)                                   314.1s           267.9s                                  --
||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

Notes for reviewers

  • Source stored on the equilibrium. PlasmaEquilibrium gains an analytic field, a defensive copy of the analytic config, because the configs are still mutable. The new abstract type AnalyticEquilibriumConfig is the supertype of SolovevConfig, LargeAspectRatioConfig and TJAnalyticConfig.
  • The IMAS dd is not stored. read_imas already captures a DirectIngest, and rebuilding from it is the same arithmetic as re-reading the dd. A new test in runtests_imas.jl checks that the two match exactly on the refined nodes.
  • Equilibrium.reform(equil, psi_nodes) rebuilds from the stored config, else the ingest, else by re-reading the file. The driver still builds the node list (rational surfaces plus kinetic-resonance pins), so Equilibrium does not depend on ForceFreeStates.
  • Driver changes. additional_input is gone from the re-form path. The skip in solve(::EulerLagrangeProblem) is deleted, along with its warning, which wrongly said IMAS equilibria carry no ingest.
  • Dispatch on the source type. setup_equilibrium's isa chain is replaced by run_input(config, source) methods for Nothing (file), AnalyticEquilibriumConfig, IMASdd.dd, DirectRunInput and InverseRunInput. PlasmaEquilibrium(config, source; override_psi_nodes) is now the single entry point; setup_equilibrium and the equil.toml loader are deleted (no alias), with every caller in test/, examples/, benchmarks/, docs/ and the harness's computed-separatrix template moved to PlasmaEquilibrium.
  • Equilibrium - FEATURE - 🌱 Add the Cerfon-Freidberg diverted analytic equilibrium #495 (Cerfon-Freidberg): CerfonConfig needs <: AnalyticEquilibriumConfig. Its registry row then works with the new constructor and reform unchanged.
  • Equilibrium - FEATURE - Read inverse i-files such as TokaMaker save_ifile output #511 (i-files): merged; its i-file reader and the psihigh resolve on rebuilt inverse inputs are ported into the run_input methods.
  • Follow-up: a stacked pure-move PR will split Equilibrium.jl into construction and post-processing files, with no logic changes.

🤖 Generated with Claude Code

@matt-pharr matt-pharr self-assigned this Oct 20, 2026
@matt-pharr
matt-pharr requested a review from jhalpern30 October 20, 2026 11:33
@github-actions github-actions Bot added changed-results Results move or an interface breaks - read before upgrading feature New capability labels Oct 20, 2026
matt-pharr and others added 4 commits October 20, 2026 17:09
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e driver and solve

Scripted analytic runs with mpsi=0 now get the deck's refined two-pass grid instead of the
single-pass grid, so their results move. Deck runs are unchanged.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@matt-pharr
matt-pharr added this pull request to stack #566 October 23, 2026 10:22
@matt-pharr matt-pharr added this to the GPEC v2.0.0 milestone Oct 26, 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.

I like this one - I think it converts a Fortran-y approach to a very Julian one. Good use of multiple dispatch, moves a lot of equilibrium specific code into the equilibrium module, cleans up main a bit etc.

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.

2 participants