Repository navigation
Conversation
…owth-rate search growth_rate stored the full solve of every γ² it evaluated, so memory grew by one solve per iterate (3 GB for one n = 5 solve, 21 GB after nine; 75 GB at n = 15). Only a bracket end can be returned, so keep the latest solve on each side of the root and drop the rest. The iterates and the returned result are unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
…holds and correct the EPED1 factor growth_rate applies no threshold to the ideal growth rate. State the EPED1 and EPED1.6 conventions in terms of gamma and omega_star_pi, their sources and caveats, and replace the docstring statement gamma > omega_star_pi/2 with omega_star_pi/4 (the effective frequency is half the peak). Co-Authored-By: Claude <noreply@anthropic.com>
…ith bisection When the free-boundary energy at one bracket end dwarfs the other, the interpolated point equals the opposite end in floating point and the search stalled there, then stopped on the bracket width. The iteration now lives in _sign_change_root and takes a geometric bisection step when the interpolated point is not strictly inside the bracket or the same end has been kept three times running. Co-Authored-By: Claude <noreply@anthropic.com>
…response solve The Euler-Lagrange frame's column magnitudes can differ by well over a hundred decades at the edge of a high-n integration. The unscaled U2/U1 solve then loses all accuracy when taken directly after a Gaussian reduction, giving a complex, non-Hermitian plasma energy. Scaling each column to unit norm leaves W unchanged and restores the solve. Co-Authored-By: Claude <noreply@anthropic.com>
…p from the eigenmode The slope of the least-stable free-boundary energy in γ² is the inertial energy of that solve's own eigenmode (Hellmann–Feynman), integrated from the saved solution with the eliminated in-surface displacement, so each solve gives a Newton step at no extra solve. Steps that leave the bracket fall back to the Illinois iteration; the stopping rules are unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
|
This pull request is missing a reviewer. If you are not ready to name them, mark this pull request as a draft. |
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.
Release note
lar_reversed_shear_growth_rate_n1only: γ moves by 1.9e-3 s⁻¹ (6e-7 relative, inside the root search's ownrtol/ftol) and the root-find history shortens from 9 to 7 entries; the other 27 cases are unchanged (harness @ ddc1ada)[GrowthRate]output: γ can differ within the root search'srtol/ftol, and theHistory/arrays hold fewer entriesgrowth_ratenow needs fewer force-balance solves to find γ. Each inertial solve also yields the slope of its least-stable energy in γ², taken from the eigenmode it already saved, so the root is closed by Newton steps instead of a bracketed secant iteration. The API, the stopping rules (ftol,rtol,maxiter) and the decade bracketing are unchanged.Stacked on #663 (base
feature/growth-rate-inertia). That branch has four local commits not yet on the remote (88a770e76,ffc9d47e6,eb37c4503,bce191e30); this branch sits on top of them, so they appear in this diff until #663's branch is pushed. Onlyddc1adab3belongs to this PR.What changed
Slope from the eigenmode. The edge energy Ξ†WΞ is the stationary value of δW + γ²K over the interior displacement at fixed edge Ξ, so by the Hellmann–Feynman theorem, for the Hermitian pencil W·v = λ·N·v of the free-boundary step,
dλ_min/dγ² = ∫ (Ξ_s†A_ρΞ_s + 2Re Ξ_s†C_ρΞ + Ξ†H_ρΞ) dψ / (ψ₀² Ξ_a†NΞ_a).
Ξ is the saved least-stable eigenmode (column 1 of the stored solution, which
normalize_eigenfunctions!has already put in the eigenvector basis), Ξ_s = −A⁻¹(BΞ′ + CΞ) the eliminated in-surface displacement (Glasser 2016 Eq. 18) with the inertial A and C, A_ρ, C_ρ, H_ρ the inertia bands per unit γ², and N the power norm at the edge. The kinetic reduction the inertial solves take is exactly the Glasser functional with A, C, H shifted by γ² times the bands (its B-like termbkmatis the same shift written against the factorized B), so the storedxi_s_storeis the Ξ_s the formula needs.Quadrature. Simpson's rule over each saved ODE step, with the midpoint Ξ and Ξ′ from the cubic Hermite interpolant of the stored Ξ, Ξ′ and one LU of A per midpoint. The trapezoid rule on the saved nodes alone is not good enough: it is 1.3–7 % high on the TJ fixture (58 nodes), where Simpson agrees with a finite difference to 2e-5–3e-4. The cost is a small fraction of one solve.
Root iteration. After the decade bracket (and the count bisection, unchanged), each step is a Newton step on γ² from the bracket end with the smaller |λ_min|. A step that would leave the bracket is an Illinois step instead (with its bisection safeguard, as before), and after a Newton step that fails to halve |λ_min| the slope is no longer used. A missing (NaN) or non-positive slope always lands outside the bracket, so it falls back automatically.
Verification
Derivative against a central difference of λ_min(γ²), TJ analytic fixture with q_a = 2.9 (external kink, ρ = 1e-7 kg/m³), relative step 1e-3 (1e-2 gives the same to 4e-6):
Solve counts, including the marginal solve, default
rtol = 1e-3,ftol = 1e-6. "Before" is this branch with the slope switched off, which the tests show reproduces the base branch's iteration exactly:Uniform-current cylinder, external kink m = 2, n = 1, zero pressure, no wall, against (γτ_A)² = 2(m − nq_a)(nq_a − m + 1)/q_a², τ_A = R₀√(μ₀ρ)/B₀:
The cylinder decks are my reconstruction of the #663 benchmark (large-aspect-ratio equilibrium with
sigma_type = "wesson",p_sig = 0,beta0 = 0, on the reversed-shear example's numerics), so q_a and the ratios differ slightly from that PR's table. On these cases the old iteration stopped on the bracket width with |λ_min| still ~1e-5 of the marginal value; the Newton iteration stops onftol, so it returns a root about 300 times closer in one fewer solve. The last row saves nothing: the first Newton step lands within 1e-6 of the root but one more solve is needed to certify it.Tests
test/runtests_inertia.jl: 103 pass (92 on the base branch plus 11 new). New: the slope against a central difference on the TJ kink fixture to 1 % (measured 1.3e-4; the reference's own error at h = 1e-3 is ~1e-5); the fixture's root in fewer than the previous 8 solves with γ withinrtol; at the function level, Newton steps reach the same root as the Illinois iteration in fewer evaluations, a NaN or wrong-signed slope reproduces the Illinois iteration exactly, and a slope 100 times too steep still converges.test/runtests_solve_api.jl: 209 pass.Regression report
Notes for reviewers
psilowdoes not depend on γ². The finite-difference agreement above bounds that term at the 1e-4 level on the fixture; it is not checked on shaped equilibria with a Frobenius axis start.rtol·γ²would save one more solve per root (5 → 4 on the cylinder), but it is a new stopping rule, so it needs approval.apijobs fail ontest/runtests_result_struct.jl:48, which still expectsmain's return keys withoutgrowth_rate. That failure is inherited from ForceFreeStates - FEATURE! - Add perpendicular inertia and an ELITE-style growth-rate solve #663 (its own CI fails the same way) and is not touched here.!because the tracked γ of the growth-rate harness case moves above its noise floor; the commit subject does not.NO MERGE WITHOUT HUMAN REVIEW. Draft, assignee @d-burg, no reviewer requested yet.
🤖 Generated with Claude Code