Perturbed Equilibrium

The PerturbedEquilibrium module computes the plasma response to external magnetic perturbations.

Types

GeneralizedPerturbedEquilibrium.PerturbedEquilibrium.PerturbedEquilibriumControlType
PerturbedEquilibriumControl

User-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.
source
GeneralizedPerturbedEquilibrium.PerturbedEquilibrium.PerturbedEquilibriumInternalType
PerturbedEquilibriumInternal

Internal state variables for perturbed equilibrium calculations.

Fields

  • dir_path::String - Working directory path
  • forcing_modes::Vector{ForcingMode} - Loaded forcing mode data
  • coil_sets::Vector{CoilSet} - Coil geometry used (when forcing_data_format = "coil"); captured for the gpec.h5 rerun snapshot
  • plasma_response::Matrix{ComplexF64} - Plasma response matrix
  • singular_coupling_metrics::Dict{String,Float64} - Coupling metrics at singular surfaces
  • m_modes::Vector{Int} - Poloidal mode numbers for each index i in 1:numpert_total
  • n_modes::Vector{Int} - Toroidal mode numbers for each index i in 1:numpert_total
source
GeneralizedPerturbedEquilibrium.PerturbedEquilibrium.PerturbedEquilibriumStateType
PerturbedEquilibriumState

Results 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 forcing
  • chirikov_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 )
source

Functions

GeneralizedPerturbedEquilibrium.PerturbedEquilibrium.compute_perturbed_equilibriumFunction
compute_perturbed_equilibrium(
    equil, ForceFreeStates_results, vac_data, ffs_intr,
    ft_ctrl, ctrl, intr, metric, ffit
)::PerturbedEquilibriumState

Main entry point for perturbed equilibrium calculations.

Computes plasma response to external forcing and calculates singular layer coupling metrics.

Arguments

  • equil: Equilibrium solution from Equilibrium module
  • ForceFreeStates_results: Stability calculation results from ForceFreeStates module
  • vac_data: Vacuum response data from ForceFreeStates free boundary calculation
  • ffs_intr: ForceFreeStates internal state with mode information
  • ft_ctrl: Forcing terms control parameters from [ForcingTerms] section
  • ctrl: Control parameters from [PerturbedEquilibrium] section
  • intr: Internal state variables
  • metric: Metric tensor data with Fourier coefficients for Jacobian convolution
  • ffit: FourFitVars with stability matrix interpolants (A, B, C) for regularization

Returns

  • PerturbedEquilibriumState: Calculation results
source
GeneralizedPerturbedEquilibrium.PerturbedEquilibrium.write_outputs_to_HDF5Function
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
source