Uh oh!
There was an error while loading. Please reload this page.
Conform PerturbedEquilibrium response & coupling matrices to coordinate-invariant field space (#233, first slice) - #277
Conversation
…rices to coordinate-invariant field space Implements the first slice of issue #233: form the PerturbedEquilibrium control-surface response matrices and resonant coupling matrices in the coordinate-invariant power-normalized field (b-tilde) space of Pharr (2026), extending the convention PR #225 introduced for the DCON energy eigenvalues. - Extract the shared power-norm transform (compute_sqrtamat, compute_sqrt_jac_delpsi, new control_surface_ptof = sqrtamat*sqrt(jarea)) from ForceFreeStates/PowerNorm.jl into Equilibrium/CoordinateInvariant.jl as one source of truth for FFS and PE. - Conform the control-surface matrices in place: P~=ptof^-1*P*ptof (similarity), L~/Lambda~=ptof^-1*(.)*ptof^-dagger and rho~=ptof^dagger*rho*ptof (congruence). Internal physics (singular coupling, field reconstruction, energies) stays in flux space, so all physical quantities are bit-identical. - Expose ptof in HDF5 (response_matrices/powernorm_field_to_flux_operator) with documented recovery formulas so users can recover the flux-space matrices. - Conform the resonant coupling matrices on input (C~=C*ptof); evaluate the applied resonant scalars from flux-space C first so they carry no round-trip noise. Add LHS coordinate-invariance audit annotations (resonant field, penetrated field, Delta', shielding current). - Rename tesla quantities flux->field per Pharr 2026 to remove units confusion: resonant_flux->resonant_field, C_resonant_flux->C_resonant_field, plot_resonant_flux->plot_resonant_field_amplitude. Genuine flux quantities (psi, Phi_x, chi1) are untouched. Regression case and Fortran benchmark updated in lockstep. Verification: physics review PASS (all transform rules exact and consistent); new unit test runtests_coordinate_invariant.jl 9/9 (recovery round-trip, consistency, energy invariance); regression diiid_n1 develop vs local 28/28 quantities 0.0e+00 (the 2 N/A rows are the intended resonant_flux->resonant_field key rename). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…arr 2026 weighting language Pharr (2026) names the three normal-field Fourier decompositions by the area weight applied to the FT integrand, all in tesla: bare b (normal field), b-bar (full-area weighted), b-tilde (square-root-area weighted). "Power-normalized" was a Parseval property, not Pharr's term, and is not intuitive. This pass conforms all code, h5 keys, comments, docstrings, and regression labels to the weighting language. - b-tilde "power-normalized field" -> "root-area-weighted field" everywhere (CoordinateInvariant.jl, RootAreaWeighted.jl, PE Response/ResponseMatrices/Structs/Utils). h5 key powernorm_field_to_flux_operator -> rootarea_field_to_flux_operator. - Resonant/penetrated b-bar fields -> "area-weighted field": resonant_field -> resonant_area_weighted_field (+ C_, penetrated_ variants) across struct fields, h5 keys, doc-tree, Analysis plot fn, Fortran benchmark, and the diiid_n1 regression case. - psi_area -> b_psi_area_weighted: it is b^psi/<J|grad psi|> (the gpout_xbnormal normal field, tesla), not the surface area — the old name was misleading. - Kill "Power Normalized" in FFS: prose + regression labels (4 cases) -> "root-area- weighted"; internal pn_* -> rootA_*; compute_power_norm_eigenvalues -> compute_rootarea_eigenvalues; PowerNorm.jl -> RootAreaWeighted.jl. The h5 dataset/group structure (eigenmode_energies, XiNorm) is term-neutral and unchanged. - Add docs/src/field_conventions.md: authoritative b/b-bar/b-tilde <-> English <-> h5 table with an admonition prompting #267's conventions page to conform on merge. Verification: package loads; runtests_coordinate_invariant 9/9; docs build clean (field_conventions renders, no missing_docs/cross_reference errors); regression diiid_n1 develop vs local 28/28 quantities 0.0e+00 (pure rename — the 2 N/A rows are the resonant_field -> resonant_area_weighted_field key rename, value bit-identical). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
logan-nc
commented
Jun 12, 2026
Added: field-terminology standardization (commit |
| symbol | weight | name | h5 token |
|---|---|---|---|
b (bare) | 1 | normal field | b_n |
b̄ | 𝒥|∇ψ| | area-weighted field | area |
b̃ | √(𝒥|∇ψ|) | root-area-weighted field | root_area |
Changes:
b̃"power-normalized field" → "root-area-weighted field" (+ h5 keypowernorm_field_to_flux_operator→rootarea_field_to_flux_operator).resonant_field/penetrated_field→resonant_area_weighted_field/penetrated_area_weighted_field(struct fields, h5 keys, Analysis, benchmark, regression case — all in lockstep).psi_area→b_psi_area_weighted(it's thegpout_xbnormalnormal field in tesla, not the surface area — the old name misled).- "Power Normalized" killed in FFS: prose + regression labels (4 cases); internal
pn_*→rootA_*;compute_power_norm_eigenvalues→compute_rootarea_eigenvalues;PowerNorm.jl→RootAreaWeighted.jl. The h5 dataset/group structure (eigenmode_energies,XiNorm) is term-neutral and unchanged. - New
docs/src/field_conventions.md: authoritative terminology table with an admonition prompting DOCS - NEW FEATURE - Conventions Reference page: sign, coordinate, and field-amplitude/units conventions #267 to conform its conventions page on merge.
Verification: package loads; runtests_coordinate_invariant 9/9; docs build clean; regression diiid_n1 develop vs local 28/28 quantities 0.0e+00 (pure rename — the 2 N/A rows are the resonant_field → resonant_area_weighted_field key rename, value bit-identical). No numeric behavior changed.
🤖 Generated with Claude Code
cdd05e0 to
378cb4cCompare… operator
`ptof` ("power-norm to flux") is stale after the power-normalized → root-area-weighted
terminology change. Verified from Pharr (2026)'s definitions that the operator
sqrtamat·√jarea maps the root-area-weighted field b̃ (tesla) to the poloidal flux Φ
(weber): Φ = √A·sqrtamat·b̃, and the inductances act on it as energy = Φ†L⁻¹Φ. So the
"field → flux" description is correct; rename the mnemonic accordingly:
- ptof → rootareafield_to_flux (incl. _block/_full/_inv locals)
- Equilibrium.control_surface_ptof → control_surface_rootareafield_to_flux (+ export)
- build_control_surface_ptof → build_control_surface_rootareafield_to_flux
- Introduce `R ≡ rootareafield_to_flux` shorthand in two dense math docstrings to keep
them under the 180-col margin.
- Sweep two leftover "power-norm" comments in the test files (reverted-commit fallout).
Operating the response/coupling layer directly in the three tesla fields (b, b̄, b̃) was
considered but deferred: it rescales the FFS energy eigenvalues by 1/A² and the stored
inductances by A² (moves tracked regression values, reopens the PR #225 energy
normalization) — a normalization change for its own issue, not a naming cleanup.
Pure rename — no behavior change. Package precompiles; runtests_coordinate_invariant
9/9; regression diiid_n1 develop vs local unchanged (28/28 OK; the 2 N/A are the earlier
resonant_field key rename, not this commit).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>…, drop flux from outputs Eliminate poloidal flux Φ (weber) from the control-surface vocabulary and HDF5 output, operating instead in the three Pharr (2026) field representations (all tesla): bare b, root-area-weighted b̃ (coordinate-invariant), area-weighted b̄. Flux is recovered, only if a user supplies/requests it, as the scalar product Φ = A·b̄ — it is never stored. - Equilibrium/CoordinateInvariant.jl: replace the flux operator control_surface_rootareafield_to_flux with the field-translation operators rootarea_to_area_weight (Σ/√A, b̃→b̄) and area_to_rootarea_weight (√A·Σ⁻¹, b̄→b̃). - ForceFreeStates/RootAreaWeighted.jl: factor the surface area out of the energy operator. The operator is now the pure √weight Σ and the energy is dW = c·b̃†·W_t·b̃ with the explicit scalar c = jarea. Net-zero (verified): FFS et/ep/ev unchanged to within-ULP. - PerturbedEquilibrium: store the b̃ response matrices unchanged (b̄ is not coordinate-invariant); store the b̃→b̄ operator + scalar surface_area as recovery aids (replacing the flux operator). Output forcing AND response control-surface spectra in b, b̃, b̄. SingularCoupling C-conform and the scalar energies/torque are bit-identical (the latter kept in the well-conditioned flux basis). - docs/field_conventions.md, tests, benchmark updated; benchmark reconstructs Φ = A·b̄ for the Fortran Phi_x/Phi_tot comparison. Regression diiid_n1 + solovev_n1 (develop vs local): all tracked quantities OK — PE energies/torque 0.0e+00, FFS energies within-ULP, every stability quantity identical. Only the (untracked) stored operator and the new b/b̃/b̄ spectra change. runtests_coordinate_invariant: 16/16. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
logan-nc
commented
Jun 12, 2026
@ebursch can consult @matt-pharr if needed. Really, this is mostly a no-op naming convention change to conform the code to @matt-pharr 's paper terminology |
| These building blocks implement the √area weighting of Pharr (2026), | ||
| "Coordinate-invariant flux-surface Fourier analysis in tokamaks". They are the | ||
| single source of truth for translating a flux-surface field component between the | ||
| three Pharr field representations (all in tesla), shared by the ForceFreeStates and |
There was a problem hiding this comment.
I think using the term Pharr field could be confusing. Something like "between the three types of weighted fields (all in tesla) from Pharr 2026." would be more clear.
Uh oh!
There was an error while loading. Please reload this page.
…field-matrices Bring 99 commits of develop (kinetic/ballooning restructure, conventions docs) into the field-space conform branch. Conflict resolutions: - docs/make.jl: keep develop's "Conventions Reference" nav entry; our field_conventions.md content folded into docs/src/conventions.md after the Root-Area Normalized Field section, and field_conventions.md removed. - FieldReconstruction.jl: keep our b_psi_area_weighted rename (consistent across the merged tree) with develop's no-space kwarg formatting. - GeneralizedPerturbedEquilibrium.jl: keep our "root-area-weighted" terminology. - runtests_fullruns.jl: combine both smoke-test comment rationales. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…esonant field Add 2008-Park-Spectral_asymmetry_due_to_magnetic_coordinates.pdf to docs/resources, cite it in the Resonant Field section of conventions.md to motivate area-normalization of the resonant harmonic, and add the full entry to the PerturbedEquilibrium citations list. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- conventions.md: "cooridante" -> "coordinate" - citations.md: doubled "the the" -> "the" - equilibrium.md: "Solev'ev" -> "Solovev"; "SolevevConfig" -> "SolovevConfig" (matches the real struct name); "lorcfg" -> "larcfg" in a runnable example - set_up.md: "for you installation" -> "for your installation" Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Summary
First slice of #233: form the PerturbedEquilibrium control-surface response matrices and resonant coupling matrices in the coordinate-invariant power-normalized field (b̃) space of Pharr (2026), extending the convention PR #225 introduced for the DCON energy eigenvalues. Closes the response matrices + coupling audit portion of #233 (field reconstruction, torque matrix, and the FFS displacement-space integration are explicitly deferred — see Follow-ons).
The matrices are replaced in place with their b̃-space forms; the flux-space forms remain fully recoverable from a newly exposed operator.
What changed
compute_sqrtamat/compute_sqrt_jac_delpsiout ofForceFreeStates/PowerNorm.jlinto a newEquilibrium/CoordinateInvariant.jl, pluscontrol_surface_ptof = sqrtamat·√jarea. One source of truth for FFS and PE (FFS now delegates).ResponseMatrices.jl,Response.jl) —field_space_response_matricesappliesP̃=ptof⁻¹·P·ptof(similarity),L̃/Λ̃=ptof⁻¹·(·)·ptof⁻†andϱ̃=ptof†·ϱ·ptof(congruence). Internal physics (singular coupling, field reconstruction, scalar energies) stays in flux space, so all physical outputs are bit-identical.control_surface_field_operator(ptof) written to HDF5 asresponse_matrices/powernorm_field_to_flux_operator, with recovery formulas (P_flux = ptof·P̃·ptof⁻¹,L_flux = ptof·L̃·ptof†, …) documented in the struct docstring and the Utils doc-tree.SingularCoupling.jl) —C̃ = C·ptofon input; applied resonant scalars evaluated from flux-spaceC·Φ_xbefore conformance (bit-identical, no round-trip noise). LHS coordinate-invariance audit annotations added for resonant field, penetrated field, Δ′, and shielding current.flux→fieldrename (Pharr 2026) — tesla quantities consistently named "field" to remove units confusion:resonant_flux→resonant_field,C_resonant_flux→C_resonant_field,plot_resonant_flux→plot_resonant_field_amplitude(renamed to avoid colliding with the pre-existingplot_resonant_fieldsummary). Genuine flux quantities (ψ, Φ_x, χ₁) untouched. Regression case (diiid_n1.toml) and the Fortran-comparison benchmark updated in lockstep.Verification
P̃=Λ̃·L̃⁻¹,ϱ̃=L̃⁻¹(Λ̃−L̃)L̃⁻¹);control_surface_ptofidentical to PowerNorm's ptof; all LHS invariance annotations justified with no overclaim.test/runtests_coordinate_invariant.jl— 9/9 (recovery round-trip, transform consistency, energy-scalar invariance).regress --cases diiid_n1 --refs develop,local— 28/28 tracked physical quantities0.0e+00(energies, Δ′, island half-widths, Chirikov, PE energies/torque, q-profile, singular surfaces). The 2N/Arows are the intendedresonant_flux→resonant_fieldkey rename (develop predates the key); the local value is bit-identical to develop's oldresonant_fluxby construction.Follow-ons (out of scope, tracked under #233)
🤖 Generated with Claude Code