Repository navigation
ForceFreeStates - BUGFIX - Count every fixed-boundary zero crossing: inside Riccati chunks, and after a switch of the smallest eigenvalue - #668
Draft
StuartBenjamin wants to merge 2 commits into
Conversation
…ach chunk, not only at chunk endpoints The Riccati integrator evaluated the fixed-boundary stability criterion only on the stored chunk-endpoint states in the core, so crossings inside a chunk were missed or cancelled (DIII-D 174956 at 1715 ms: 0 at n=1 and n=2 where RDCON finds 2 and 1). Each chunk now counts the crossings of its principal solution at every step of its propagator solve (step_zero_crossings: inertia of U₂ᴴU₁ by Bunch–Kaufman, crit checked only where it changes), and the assembly adds the crossings of the actual solution beyond those from the chunk's end data (crossings_beyond_principal, a Morse index split exact for F̄ > 0). The re-integrated outer plasma keeps its dense check. Same method as the Fortran STRIDE fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… by the inertia of W⁻¹, not an interpolated midpoint The midpoint test rejects a real crossing when crit changed eigenvalue at the step before. A crossing lowers the number of negative eigenvalues of W⁻¹ (F̄ > 0); a switch of the smallest eigenvalue or a passage through ∞ does not. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 tasks
This branch has not been deployed
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.
Problem. With
integrator = "Riccati",nzerotestscritonly at chunk endpoints, about 8 per singular surface. A crossing inside a chunk is missed, and two crossings in one chunk cancel. On a DIII-D equilibrium that RDCON and Fortran STRIDE find fixed-boundary unstable at n = 1 and 2, the Riccati path reports 0 at both. The forward path, which checks every step, has a separate gap. It confirms acritsign change with an interpolated midpoint, and that check rejects a real crossing when the smallest eigenvalue switched at the step before.Fix.
critis evaluated only on the steps where the inertia changes.critcounts when the number of negative eigenvalues of W⁻¹ drops. With F̄ > 0, a crossing raises an eigenvalue through 0; a switch of the smallest eigenvalue or a passage through ∞ does not.critnever changes sign (closest |crit| = 0.2 at ψ = 0.13, the same on develop), so there is nothing for it to count. On the previous develop (728a7e7) both paths gave 1 / 1, and Riccati matched an exact count of the code's own axis solution (eigenphases of (X + iU)(X − iU)⁻¹, 5000 steps per chunk). The remaining n = 1 gap to Fortran comes from small equilibrium differences, not the counting.The Solovev example is Mercier unstable at q = 2: its crossings pile up log-periodically into that surface, so their number depends on resolution, and the test compares only the verdict.
🤖 Generated with Claude Code