ForceFreeStates - BUG FIX - Power-normalized Jacobian-invariant eigenmode energies via generalized eigenproblem#314
Conversation
The mode-converged kinetic deck referenced sol.toml via eq_filename, but no code path loads a separate sol.toml for analytic equilibria — the deck (and both kinetic regression cases) has been unrunnable since 8bf5d01. Embed the [SOL_INPUT] section in gpec.toml like the other Solovev decks and drop sol.toml. Co-Authored-By: Claude Fable 5 <[email protected]>
…mode energies via generalized eigenproblem Closes #304. FreeBoundaryStability/eigenmode_energies wrote the raw root-area-weighted quadratic-form spectrum, whose low end collapses to the numerical noise floor (~1e-15 on DIII-D) because the unit-b-tilde metric is unphysical for high |m-nq| modes. Replace the eigendecomposition with the Hermitian-definite pencil W v = lambda N v, where N is the power-normalization surface-norm matrix (the DCON jmat normalization, xi'Nxi = <|xi|^2>, promoted from a post-hoc division into the metric of the eigenproblem). The eigenvalues are stationary values of the power quotient: physical mode energies in the familiar convention, and exactly invariant under congruent changes of representation (the b-tilde-space and xi-space spectra are now the same spectrum, verified to ~1e-8). - power_norm_matrix! assembles N from the Jacobian Fourier band; ffit.jmats splines that band over psi so N is evaluated on the same surface as W (psilim in free_run! — a 4% consistency fix on truncated equilibria — and the local surface at each edge-scan step). - vacuum_eigenvalue is the smallest eigenvalue of the pencil (wv, N). - Raw rootA spectra, eigenvectors, matrices, and the RootAreaWeighted/ and XiNorm/ HDF5 groups are removed; compute_rootarea_eigenvalues and RootAreaWeighted.jl are deleted (shared root-area operators remain in Equilibrium/CoordinateInvariant.jl for the perturbed-equilibrium response). - Edge scan stores only the pencil energies; no NaN guard needed at rational crossings; truncation-peak selection values unchanged in role. - Regression cases, benchmarks, tests, and conventions.md updated to the single top-level spectrum. Headline re-pins: Solovev n=1 et[1] 4.4e-13 -> 0.5749 (XiNorm reference 0.5785; -0.6% stationarity shift); DIII-D n=1 et[1] 1.5e-15 -> 1.4541 (XiNorm reference 1.3954; +4.2% psilim surface consistency). Co-Authored-By: Claude Fable 5 <[email protected]>
Independent assessment from the overview-paper benchmarks (Sec. 3.2.1)While drafting the normalization/truncation section of the Julia GPEC 2.0 overview paper, we ran this PR through an independent truncation-scan study on the DIII-D-like reference case (PR #295 equilibrium; local merges of What we confirmed
What we found that argues against full removalProjecting out the metric null directions (threshold 1e-6 of the spectral radius) and tracking the least physical b-tilde eigenvalue along the same scans:
So the two normalizations answer different questions: the pencil is the correct variational form of the DCON convention (comparability, tight invariance), while the regularized b-tilde margin is truncation-robust — a stability margin quoted at the standard truncation is insensitive to the exact truncation choice. That robustness is a core motivation of the normalization work and is lost if the b-tilde spectrum is deleted rather than repaired. NaN at exact rational crossings is fine (the metric is singular there and those truncations are invalid anyway). [figure: least-stable eigenvalue vs truncation surface, panel (a) pencil / panel (b) regularized b-tilde — attached below] Actionable suggestions (scoped for a follow-up session)
# after: sqrtamat_local/jarea_local evaluated from es.sqrtamat_spline
rootA_result = compute_rootarea_eigenvalues(wt_saved, wp, wv, sqrtamat_local,
jarea_local, equil, odet.psifac, intr; all_eigenvalues=true)
if isdefined(Main, :ROOTA_COLLECTOR)
push!(Main.ROOTA_COLLECTOR, (odet.psifac, sort(real.(rootA_result.rootA_et_all))))
endNumbers above were measured on an Apple M-series laptop with |
Closes #304.
Problem
FreeBoundaryStability/eigenmode_energies(and the EdgeScan defaults) wrote the raw root-area-weighted quadratic-form spectrum. The congruencejarea·M†·W·Mpreserves eigenvalue signs (instability counts were right), but the values are energies per unit ‖b̃‖₂ — an unphysical metric under which the low end of the spectrum collapses to the numerical noise floor (DIII-D: 1.5e-15, 13 decades of dynamic range). The regression harness re-pinned the junk as expected values, and tests/benchmarks had been quietly repointed to theXiNorm/escape hatch.Fix
Solve the Hermitian-definite pencil W·v = λ·N·v instead of
eigen(W)+ post-hoc division, whereN = Toeplitz(jmat)/(dV/dψ)is the power-normalization surface norm both codes already computed as a loop (ξ†Nξ = ⟨|ξ|²⟩; Fortranfree.f:193-206). The eigenvalues are stationary values of the power quotient:Consistency upgrades: the Jacobian band is now a ψ-spline (
ffit.jmats), so N lives on the same surface as W (ψ_lim infree_run!— a 4% fix on truncated equilibria — and the local surface at each edge-scan step);vacuum_eigenvalueuses the pencil (wv, N). All raw rootA outputs,RootAreaWeighted.jl, and theRootAreaWeighted//XiNorm/h5 groups are removed — there is one spectrum now.A separate commit fixes the mode-converged kinetic example deck, broken on develop since 8bf5d01 (
sol.tomlwas referenced but never loaded):[SOL_INPUT]is embedded ingpec.toml, restoring both kinetic regression cases.Validation
Full report with equations and 15 figures (before/after spectra, cross-Jacobian invariance of eigenvalues and physical mode shapes, mpert-convergence study, energy bookkeeping, edge-scan trajectories, regression tables): https://claude.ai/code/artifact/581b0ab5-2850-460e-bd65-87d99e27e0a2
Scope note: cross-run agreement between different
jac_typechoices remains at the discretization floor of W itself (~4% bulk modes; the near-marginal Solovev leading kink is hypersensitive and not mpert-converged) — identical for the old convention, not addressable by normalization. Details and figures in report §3; suggest a follow-up issue for the near-marginal edge-kink convergence.🤖 Generated with Claude Code