Repository navigation
ForceFreeStates - BUGFIX! - Use the fixed start for integrations that begin away from the axis - #460
Conversation
… begin away from the axis The Frobenius axis initialization [Glasser 2016 Eq. 51] is a power series about the magnetic axis, but initialize_el_at_axis! applied it wherever the integration happened to start. An interior start (psilow raised to skip a q < 1 core, or qlow above q0) therefore began from a solution set that is neither the axis-regular one nor Fortran DCON's U1 = 0, U2 = I, and the free-boundary energies and resonant coupling drifted from DCON's with the starting surface: on a DIII-D case the innermost coupling row differs by 1 % at psi_N = 0.01, 4 % at 0.03, 24 % at 0.1 and a factor of 2 at 0.3, where the total energies are 7 % apart. A single control frobenius_psi_max (default 0.01) bounds where the Frobenius start is used; above it the fixed start is used with a warning, and 0 selects the fixed start everywhere. It replaces the undocumented fixed_axis flag. Every axis-started example is unchanged. A Solovev test checks the switch, the warning, the threshold and the zero setting. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BzKDmtKYDotJWrcxWf1oJu
8070a04 to
e93df8f
Compare
|
Amended per review direction: |
Stack summary — OMFIT → Julia error-field tolerance migration (updated 2026-09-17)Nothing in this set merges without a third-party human review, the three small bugfix PRs included. Full page with the diagram, per-PR table, review order and links to every review package (a private claude.ai artifact until the author shares it; DIII-D-like and synthetic data only): https://claude.ai/code/artifact/408ddd36-e52c-42d8-8f5c-52f680f41da9
Benchmark, qualitatively. The original OMFIT project's case, rebuilt from that project's own run inputs, is reproduced once #458, #457 and #460 are in: dominant-mode singular values agree to 1e-4, singular-coupling rows match Fortran GPEC at 1.0000 correlation and within 0.5 % in norm, and every coil set's dominant-mode overlap agrees within 1 % once both codes use the same converged toroidal coil grid. The DIII-D-like example agrees with Fortran to 1e-4 throughout. Any comparison shown on these PRs uses the DIII-D-like examples only. Design issue for what comes after the stack: #461 (momentum-balance module fed by tabulated torque surfaces; stationary solvers only). |
|
Independent check while triaging #440 (which this supersedes — I'm closing it): the #440's fixture is a synthetic diverted DIII-D-like ramp-up (q0 = 3.41, n = 1, no wall,
Fortran DCON on the same deck (same mlow/mhigh/psilim/dmlim): stiff W_p +1.6092e4, no negative eigenvalue. So your fixed start is right and reproduces DCON; the default reports a spurious −1e5 instability. I understand why the boundary is Not asking you to widen this PR. Three ways to close it, your call:
If it is the third, say so in the Filed #464 for the underlying Two caveats on my numbers: the fixture is on |
|
@d-burg I'm lost in your AI verbosity.
As a side note, is think physically that allowing finite displacement at psilow would be all the more important at higher psilow... but yes the expansion we use is for near zero. correct initialization at higher values will take more thought by future us. |
|
@logan-nc sorry, I insufficiently edited that one – this PR is still not fully within my understanding and I've tried to learn too many new PRs today...
|
|
gotcha. just make it >=0.005 then! that's good with me. other than that, is this one good to merge @d-burg ? (or did you skim the diff as a human as well as sicking claude on it?) |
The field's rationale carried a four-point benchmark table; that belongs in the pull request, not in a struct's field list. The contract and the default are unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BzKDmtKYDotJWrcxWf1oJu
…ates-interior-start-initialization
ebursch
left a comment
There was a problem hiding this comment.
This looks ready to merge.
Found while benchmarking the original OMFIT project's error-field case against its Fortran GPEC run. That case starts the integration well inside the plasma rather than at the axis, and with both #457 and #458 applied its innermost resonant-coupling row was still 1.34× Fortran's and the total energies 3 % apart, insensitive to every resolution and tolerance knob in either code.
Cause.
initialize_el_at_axis!applies the Frobenius axis start [Glasser 2016 Eq. 51] wherever the integration begins. That start is a power series about the magnetic axis; at an interior surface it is neither the axis-regular solution nor Fortran DCON's start, which is always U₁ = 0, U₂ = I (zero displacement at the first surface). The DIII-D ideal example, which matches Fortran to four digits atpsilow = 1e-4, shows the drift directly:frobenius_psi_max = 0)On that case the fixed start takes the coupling rows to 1.0000 correlation with Fortran and every per-coil overlap to within 1 % of OMFIT.
Change. One control,
frobenius_psi_max(default 0.01), bounds where the Frobenius start is used. Above it the fixed start is used and a warning says so;0selects the fixed start everywhere, silently. It replaces the undocumentedfixed_axisflag (removed; no example, test or case file set it). Every example in the repo starts at or below 0.01, so nothing tracked moves; the!is for the interface and for interior-start runs, whose results change.Verification.
test/runtests_eulerlagrange.jlgains a Solovev testset: axis start keeps a nonzero Frobenius U₁ with U₂ = I; a start at ψ_N = 0.3 switches to U₁ = 0, U₂ = I and logs the warning; raisingfrobenius_psi_maxkeeps the Frobenius start;frobenius_psi_max = 0selects the fixed start silently even at the axis. ODE Tests 99/99.Not touched: which start is physically right for an interior surface. The fixed start is what DCON does and what the published numbers used; the switch reproduces that and stops an axis expansion from being applied silently far from the axis.
cc @matt-pharr
Release note
psiloworqlowplacing the start above ψ_N = 0.01) now begin from the fixed start and change; axis-started runs are unchanged (harness @ e93df8f: diiid_n1 develop vs branch: 47 unchanged; the 5 N/A rows are error-field quantities the main checkout's case TOML tracks that neither ref writes)fixed_axis = truebecomesfrobenius_psi_max = 0; setfrobenius_psi_maxabove the start to keep the Frobenius start for an interior startForceFreeStatesuses the Frobenius axis start only when the integration begins at or below the newfrobenius_psi_max(default 0.01); an interior start uses Fortran DCON's fixed start (U₁ = 0, U₂ = I) with a warning, andfrobenius_psi_max = 0selects it everywhere. Thefixed_axisflag is removed.Regression report
Notes for reviewers
develop.EulerLagrange.jlandRiccati/Driver.jlon first touch; the substantive diff is the block ininitialize_el_at_axis!, the two docstrings and the control fields.🤖 Generated with Claude Code
https://claude.ai/code/session_01BzKDmtKYDotJWrcxWf1oJu