Perturbed Equilibrium
The PerturbedEquilibrium module computes the plasma response to external magnetic perturbations.
Types
GeneralizedPerturbedEquilibrium.PerturbedEquilibrium.PerturbedEquilibriumControl — Type
PerturbedEquilibriumControlUser-facing control parameters from TOML [PerturbedEquilibrium] section.
Fields
Note: Forcing data file settings are now in [ForcingTerms] section.
High Priority (MWE):
fixed_boundary::Bool- Fixed boundary flag (default: false)output_eigenmodes::Bool- Output mode fields as b-fields (default: true)compute_response::Bool- Compute plasma response (default: true)compute_singular_coupling::Bool- Compute singular coupling metrics (default: true)verbose::Bool- Enable verbose logging (default: true)
Output Settings:
output_filename::String- Combined output file with ForceFreeStates results (default: uses ForceFreeStates HDF5_filename)write_outputs_to_HDF5::Bool- Write perturbed equilibrium outputs to HDF5 (default: true)
Medium Priority (defer for MWE):
filter_modes::Bool- Enable mode filtering (default: false)singular_point_method::String- Method for singular point treatment (default: "standard")
Regularization: # High Priority (MWE)
reg_spot::Float64- Regularization width for singular surface smoothing (default: 0.05). Set to 0 to disable. Must be ≥ 0.
GeneralizedPerturbedEquilibrium.PerturbedEquilibrium.PerturbedEquilibriumInternal — Type
PerturbedEquilibriumInternalInternal state variables for perturbed equilibrium calculations.
Fields
dir_path::String- Working directory pathforcing_modes::Vector{ForcingMode}- Loaded forcing mode datacoil_sets::Vector{CoilSet}- Coil geometry used (whenforcing_data_format = "coil"); captured for the gpec.h5 rerun snapshotplasma_response::Matrix{ComplexF64}- Plasma response matrixsingular_coupling_metrics::Dict{String,Float64}- Coupling metrics at singular surfacesm_modes::Vector{Int}- Poloidal mode numbers for each index i in 1:numpert_totaln_modes::Vector{Int}- Toroidal mode numbers for each index i in 1:numpert_total
GeneralizedPerturbedEquilibrium.PerturbedEquilibrium.PerturbedEquilibriumState — Type
PerturbedEquilibriumStateResults from perturbed equilibrium calculations.
Fields
Response fields (mode space):
xi_modes::Union{Nothing, NamedTuple}- Displacement (psi, theta, zeta) [npsi, mpert]b_modes::Union{Nothing, NamedTuple}- Magnetic field; psi=b^ψ, bpsiareaweighted=b^ψ/⟨J·|∇ψ|⟩θ, theta/zeta=unregularized, thetareg/zetareg=regularized [npsi, mpert]b_n_modes::Union{Nothing, Matrix{ComplexF64}}- Physical normal field b_n [npsi, mpert]xi_n_modes::Union{Nothing, Matrix{ComplexF64}}- Physical normal displacement xi_n [npsi, mpert]
Coupling matrices [nrational × numperttotal] — one row per resonant (surface, n) pair. Each row maps the full applied field to the resonant response at that surface. Matches Fortran C_f_x_out, C_i_x_out, etc. (shape [modeC, mout]).
C_resonant_area_weighted_field- Φ_r/A^r coupling (resonant area-weighted field b^r in tesla; singcoup row 1) [Pharr 2026]C_resonant_current- Resonant current coupling (singcoup row 2)C_island_width_sq- (w/2)² coupling (singcoup row 3)C_penetrated_area_weighted_field- Penetrated area-weighted field coupling (singcoup row 4)C_delta_prime- Δ' coupling (singcoup row 5)
Applied resonant vectors [nrational] = C · forcingamplitudes. Matches Fortran Phi_res, w_isl, K_isl, Delta.
resonant_area_weighted_field,resonant_current,island_width_sq,penetrated_area_weighted_field,delta_prime
Diagnostics [n_rational]:
island_half_width::Vector{Float64}- w/2 = sqrt(|islandwidthsq|) from applied forcingchirikov_parameter::Vector{Float64}- Island overlap metric
Metadata [n_rational] — identifies each (surface, n) row:
rational_psi,rational_q,rational_m_res,rational_n,rational_surface_idx
Control-surface forcing/response spectra [numpert_total], in the three Pharr (2026) field representations (all tesla; no flux/weber is stored):
forcing_b/response_b- bare normal field b (Σ⁻¹·b̃)forcing_b_rootarea/response_b_rootarea- root-area-weighted field b̃ (coordinate-invariant)forcing_b_area/response_b_area- area-weighted field b̄ (= S·b̃; flux is Φ = A·b̄)
Control surface matrices [numperttotal × numperttotal], stored in the coordinate-invariant root-area-weighted field (b̃) space (issue #233 / Pharr 2026). Writing S ≡ rootarea_to_area_weight (b̃→b̄) and A ≡ surface_area, the brief internal flux-conform operator is R = S·A (Φ = R·b̃). Recover the area-weighted (b̄) forms by conforming with S (e.g. L_b̄ = S·L̃·S†); recover flux with Φ = A·b̄.
plasma_inductance- Λ̃ = R⁻¹·Λ·R⁻† (wt0-based plasma inductance, congruence)surface_inductance- L̃ = R⁻¹·L·R⁻† (vacuum surface inductance, congruence)permeability- P̃ = R⁻¹·P·R (plasma response operator P=Λ·L⁻¹, similarity)reluctance- ϱ̃ = R†·ϱ·R (ϱ = L⁻¹·(Λ−L)·L⁻¹, congruence)rootarea_to_area_weight- S = Σ/√A at psilim (b̃→b̄ recovery operator)surface_area- scalar A = ∫J|∇ψ|dθ at psilim (flux recovery Φ = A·b̄)
Energies (Joules; Fortran gpout convention). Congruence-invariant scalars (energy = Φ†·G⁻¹·Φ = b̃†·G̃⁻¹·b̃), evaluated from the brief internal flux vectors Φx, Φtot with the well-conditioned flux-space inductances L, Λ:
vacuum_energy- Re( ⟨Φx, L⁻¹·Φx⟩ ) / 4 (energy to perturb the vacuum)surface_energy- Re( ⟨Φtot, L⁻¹·Φtot⟩ ) / 4 (energy at the control surface)plasma_energy- Re( ⟨Φtot, Λ⁻¹·Φtot⟩ ) / 4 (energy to perturb the plasma; Fortran's "total energy") # Response fields in mode space [npsi, mpert]toroidal_torque- -2·n·Im( ⟨Φtot, Λ⁻¹·Φtot⟩ / 4 )
Functions
GeneralizedPerturbedEquilibrium.PerturbedEquilibrium.compute_perturbed_equilibrium — Function
compute_perturbed_equilibrium(
equil, ForceFreeStates_results, vac_data, ffs_intr,
ft_ctrl, ctrl, intr, metric, ffit
)::PerturbedEquilibriumStateMain entry point for perturbed equilibrium calculations.
Computes plasma response to external forcing and calculates singular layer coupling metrics.
Arguments
equil: Equilibrium solution from Equilibrium moduleForceFreeStates_results: Stability calculation results from ForceFreeStates modulevac_data: Vacuum response data from ForceFreeStates free boundary calculationffs_intr: ForceFreeStates internal state with mode informationft_ctrl: Forcing terms control parameters from [ForcingTerms] sectionctrl: Control parameters from [PerturbedEquilibrium] sectionintr: Internal state variablesmetric: Metric tensor data with Fourier coefficients for Jacobian convolutionffit: FourFitVars with stability matrix interpolants (A, B, C) for regularization
Returns
PerturbedEquilibriumState: Calculation results
GeneralizedPerturbedEquilibrium.PerturbedEquilibrium.write_outputs_to_HDF5 — Function
write_outputs_to_HDF5(
state::PerturbedEquilibriumState,
intr::PerturbedEquilibriumInternal,
filename::String
)Write perturbed equilibrium results to HDF5 file (appends to existing ForceFreeStates output).
Output Structure
perturbed_equilibrium/
├── forcing_modes/
│ ├── n # Toroidal mode numbers
│ ├── m # Poloidal mode numbers
│ └── amplitude # ComplexF64 forcing amplitudes
├── forcing_b / forcing_b_root_area / forcing_b_area # control-surface forcing spectrum (b, b̃, b̄) [numpert_total], tesla
├── response_b / response_b_root_area / response_b_area # control-surface response spectrum (b, b̃, b̄) [numpert_total], tesla
├── response/
│ ├── xi_psi # Radial displacement ξ^ψ = ξ·∇ψ (ComplexF64 [npsi, mpert])
│ ├── xi_psi_J # J·ξ^ψ Jacobian-weighted (from gpeq_contra)
│ ├── b_psi_area_weighted # b^ψ / ⟨J·|∇ψ|⟩_θ area-normalized (ComplexF64 [npsi, mpert])
│ ├── b_n # Physical normal field b_n (ComplexF64 [npsi, mpert])
│ ├── xi_n # Physical normal displacement xi_n (ComplexF64 [npsi, mpert])
│ ├── b_theta
│ └── b_zeta
├── response_matrices/ # [numpert_total × numpert_total], root-area-weighted field (b̃) space; R = S·A
│ ├── plasma_inductance # Λ̃ = R⁻¹·Λ·R⁻†
│ ├── surface_inductance # L̃ = R⁻¹·L·R⁻†
│ ├── permeability # P̃ = R⁻¹·P·R (P = Λ·L⁻¹)
│ ├── reluctance # ϱ̃ = R†·ϱ·R
│ ├── rootarea_to_area_weight_operator # S = Σ/√A at psilim; recover area-weighted field b̄ = S·b̃
│ └── surface_area # scalar A = ∫J|∇ψ|dθ; recover flux via Φ = A·b̄
├── singular_coupling/
│ ├── C_resonant_area_weighted_field # [n_rational × numpert_total] coupling matrix (b̃-space input, resonant area-weighted field b^r=Φ^r/A^r [T])
│ ├── C_resonant_current
│ ├── C_island_width_sq
│ ├── C_penetrated_area_weighted_field
│ ├── C_delta_prime
│ ├── resonant_area_weighted_field # [n_rational] applied vector = C̃ · b̃_x (resonant area-weighted field b^r [T])
│ ├── resonant_current
│ ├── island_width_sq
│ ├── penetrated_area_weighted_field
│ ├── delta_prime
│ ├── island_half_width # [n_rational] Float64
│ ├── chirikov_parameter
│ ├── rational_psi # [n_rational] surface metadata
│ ├── rational_q
│ ├── rational_m_res
│ └── rational_n
└── energies/
├── vacuum_energy
├── surface_energy
├── plasma_energy
└── toroidal_torque