EQUIL - BUGFIX - Detect field-line ODE failure instead of consuming a truncated surface - #442
Open
logan-nc wants to merge 1 commit into
Open
EQUIL - BUGFIX - Detect field-line ODE failure instead of consuming a truncated surface#442logan-nc wants to merge 1 commit into
logan-nc wants to merge 1 commit into
Conversation
… truncated surface direct_fieldline_int solved the flux-surface field-line ODE and never checked sol.retcode, then read sol.u[end] as though the surface had closed at eta = 2*pi. A failed solve does not throw -- it returns a solution truncated wherever the integrator gave up -- so the caller silently built a wrong flux surface and the damage surfaced downstream as unrelated nonsense, or not at all. Check both the retcode and the endpoint: a solve can stop early through a callback-driven terminate and still report Success, so neither check subsumes the other. Both errors name the psifac that failed and point at psihigh sitting too close to the separatrix, which is the usual cause. No healthy deck is affected: runtests_equil.jl passes 281/281 and the DIII-D-like ideal example runs end to end with neither guard firing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSrf6JCViFfVzqzkQ66o6b
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
direct_fieldline_intsolves the flux-surface field-line ODE and never checkssol.retcode:https://github.com/OpenFUSIONToolkit/GPEC/blob/develop/src/Equilibrium/DirectEquilibrium.jl#L293-L296
The very next line consumes
sol.u[end]as though the field line had closed ateta = 2*pi. But afailed solve does not throw — it returns a solution truncated wherever the integrator gave up. So
the caller silently builds a flux surface from a partial trace, and the damage surfaces downstream as
unrelated nonsense, or not at all.
The fix
Two checks, because neither subsumes the other:
sol.retcode != ReturnCode.Success— the ordinary failure.sol.t[end]did not reach2*pi— a solve can stop early through a callback-driven terminate andstill report
Success.direct_fieldline_intinstalls aDiscreteCallback, so this is reachable.Both errors name the
psifacthat failed, and the first points atpsihighsitting too close to theseparatrix, which is the usual cause. The failure becomes attributable to a surface rather than a
stack trace somewhere further down the pipeline.
Verification
test/runtests_equil.jl— 281/281 pass.guard firing.
diiid_n1,--refs develop,localagainstdevelop @ 4e430f170:47 quantities, all unchanged, 0.0e+00 across the board. Expected — on a healthy equilibrium this
adds two predicates and changes nothing.
A note on the test
The added testset asserts the guards against the source text rather than triggering them. A genuinely
non-closing field line is not cheap to synthesize here, and forcing
psifactoward the separatrixwould likely hit a different error first and be flaky across machines. The standing positive control
that neither guard false-fires is the EFIT testsets already in that file, which trace real surfaces
through this function. Happy to swap in a behavioral trigger if a reviewer sees a clean way to build one.
Scope
Equilibriumonly; no SLAYER/Tearing code touched. Split out of theFKR-widthwork as anindependent fix, same shape as #399.
🤖 Generated with Claude Code
https://claude.ai/code/session_01PSrf6JCViFfVzqzkQ66o6b