55"""
66 EquilibriumConfig(...)
77
8- A mutable struct containing configuration parameters for equilibrium reconstruction.
9- Bundles all necessary settings originally specified in the equil fortran namelists .
8+ An immutable struct containing configuration parameters for equilibrium reconstruction
9+ specified in the input .
1010
1111## Fields
1212
@@ -27,7 +27,11 @@ Bundles all necessary settings originally specified in the equil fortran namelis
2727 refinement when mpsi=0, three-region log layout when mpsi>0; "ldp", "pow1", "uniform";
2828 "log_asymptotic" is a legacy alias for "auto")
2929 - `psilow::Float64` - Lower limit of normalized flux coordinate
30- - `psihigh::Float64` - Upper limit of normalized flux coordinate
30+ - `psihigh::Float64` - Requested upper limit of normalized flux coordinate. For efit-family
31+ equilibria this is the user's request, which may lie outside the closed-flux region; the
32+ value the equilibrium is actually formed on is `DirectRunInput.psihigh_resolved` (carried
33+ onto the equilibrium as `EquilibriumParameters.psihigh_resolved`). Read that, not this,
34+ for anything downstream of `setup_equilibrium`.
3135 - `mpsi::Int` - Number of radial grid intervals; 0 with grid_type="auto" selects the
3236 two-pass auto grid: the main driver forms a coarse pass-1 equilibrium, measures its curvature,
3337 pins knots on rational surfaces, and re-forms on the refined grid. Standalone `setup_equilibrium`
@@ -40,7 +44,7 @@ Bundles all necessary settings originally specified in the equil fortran namelis
4044 - `force_termination::Bool` - Terminate after equilibrium setup (skip stability calculations)
4145 - `use_galgrid::Bool` - Use the same grid as galerkin method
4246"""
43- @kwdef mutable struct EquilibriumConfig
47+ @kwdef struct EquilibriumConfig
4448 eq_type:: String = " efit"
4549 eq_filename:: String = " mypath"
4650 r0exp:: Float64 = 1.0
@@ -176,15 +180,14 @@ function EquilibriumConfig(equil_dict::Dict{String,Any}, base_path::String="./")
176180 end
177181 end
178182
179- # Construct validated struct
180- config = EquilibriumConfig (; symbolize_keys (config_data)... )
181- # Only resolve `eq_filename` against `base_path` if the user actually
182- # supplied one (otherwise leave the kwdef sentinel for the embedded path).
183- if haskey (config_data, " eq_filename" ) && ! isabspath (config. eq_filename)
184- config. eq_filename = normpath (joinpath (base_path, config. eq_filename))
183+ # Only resolve `eq_filename` against `base_path` if the user actually supplied one
184+ # (otherwise leave the kwdef sentinel for the embedded path). The empty string is the
185+ # rerun path's "no input file" marker and must stay empty, not become `base_path`.
186+ if haskey (config_data, " eq_filename" ) && ! isempty (config_data[" eq_filename" ]) && ! isabspath (config_data[" eq_filename" ])
187+ config_data[" eq_filename" ] = normpath (joinpath (base_path, config_data[" eq_filename" ]))
185188 end
186189
187- return config
190+ return EquilibriumConfig (; symbolize_keys (config_data) ... )
188191end
189192
190193"""
@@ -208,12 +211,7 @@ function EquilibriumConfig(path::String)
208211 end
209212
210213 # Construct validated struct
211- config = EquilibriumConfig (; symbolize_keys (config_data)... )
212- if ! isabspath (config. eq_filename)
213- config. eq_filename = normpath (joinpath (dirname (path), config. eq_filename))
214- end
215-
216- return config
214+ return EquilibriumConfig (Dict {String,Any} (config_data), dirname (path))
217215end
218216
219217"""
@@ -444,6 +442,10 @@ raw equilibrium data and preparing the initial splines.
444442 - `bt_sign::Int` — Sign of the toroidal field (+1 or -1); read from fpol sign in EFIT g-files
445443 - `ingest::EquilibriumIngest` — captured raw arrays for the `gpec.h5` rerun snapshot
446444 (a [`DirectIngest`](@ref) for file-based reads, or `nothing` for analytic equilibria)
445+ - `psihigh_resolved::Float64` — outer flux limit the equilibrium is formed on: `config.psihigh`
446+ clamped to the outermost closed flux surface by [`resolve_psihigh!`](@ref). Defaults to
447+ `config.psihigh` and only differs for efit-family equilibria whose requested limit falls
448+ outside the closed-flux region. The solvers build their ψ grid from this field.
447449"""
448450mutable struct DirectRunInput{S<: FastInterpolations.CubicSeriesInterpolant ,I2D<: FastInterpolations.CubicInterpolantND }
449451 config:: EquilibriumConfig
@@ -458,8 +460,16 @@ mutable struct DirectRunInput{S<:FastInterpolations.CubicSeriesInterpolant,I2D<:
458460 psio:: Float64 # The total flux difference |ψ_axis - ψ_boundary| [Weber / radian].
459461 bt_sign:: Int # Sign of the toroidal field: +1 or -1 (from fpol sign in g-file)
460462 ingest:: EquilibriumIngest
463+ psihigh_resolved:: Float64
461464end
462465
466+ # Readers construct without a resolved psihigh; it starts at the request and `resolve_psihigh!`
467+ # clamps it for efit-family equilibria.
468+ DirectRunInput (config:: EquilibriumConfig , sq_in, psi_in, psi_in_xs, psi_in_ys,
469+ rmin, rmax, zmin, zmax, psio, bt_sign, ingest) =
470+ DirectRunInput (config, sq_in, psi_in, psi_in_xs, psi_in_ys,
471+ rmin, rmax, zmin, zmax, psio, bt_sign, ingest, config. psihigh)
472+
463473"""
464474 InverseRunInput(...)
465475
@@ -478,6 +488,9 @@ A container struct for inputs to the `inverse_run` function.
478488 - `psio::Float64` - Total flux difference |ψ_axis - ψ_boundary| [Wb/rad]
479489 - `ingest::EquilibriumIngest` - captured raw arrays for the `gpec.h5` rerun snapshot
480490 (an [`InverseIngest`](@ref) for file-based reads, or `nothing` for analytic equilibria)
491+ - `psihigh_resolved::Float64` - outer flux limit the equilibrium is formed on; see
492+ [`DirectRunInput`](@ref). Equals `config.psihigh` for every inverse reader (CHEASE,
493+ analytic); `efit_by_inversion` forwards the clamped value from its `DirectRunInput`.
481494"""
482495mutable struct InverseRunInput{S<: FastInterpolations.CubicSeriesInterpolant ,I2D<: FastInterpolations.CubicInterpolantND }
483496 config:: EquilibriumConfig
@@ -490,8 +503,14 @@ mutable struct InverseRunInput{S<:FastInterpolations.CubicSeriesInterpolant,I2D<
490503 zo:: Float64 # Z axis location
491504 psio:: Float64 # Total flux difference |psi_axis - psi_boundary|
492505 ingest:: EquilibriumIngest
506+ psihigh_resolved:: Float64
493507end
494508
509+ InverseRunInput (config:: EquilibriumConfig , sq_in, rz_in_xs, rz_in_ys, rz_in_R, rz_in_Z,
510+ ro, zo, psio, ingest) =
511+ InverseRunInput (config, sq_in, rz_in_xs, rz_in_ys, rz_in_R, rz_in_Z,
512+ ro, zo, psio, ingest, config. psihigh)
513+
495514"""
496515 EquilibriumParameters
497516
@@ -502,6 +521,9 @@ A mutable struct containing computed equilibrium parameters and diagnostic flags
502521 - `ro::Union{Nothing,Float64}` - R-coordinate of the magnetic axis [m]
503522 - `zo::Union{Nothing,Float64}` - Z-coordinate of the magnetic axis [m]
504523 - `psio::Union{Nothing,Float64}` - Total flux difference |ψ_axis - ψ_boundary| [Wb/rad]
524+ - `psihigh_resolved::Union{Nothing,Float64}` - Outer flux limit the equilibrium was formed on,
525+ equal to the outermost ψ node. This is `config.psihigh` clamped to the outermost closed flux
526+ surface; downstream code wanting the plasma edge must read this, not `config.psihigh`.
505527 - `rsep::Union{Nothing,Vector{Float64}}` - R-coordinates of the plasma boundary [m]
506528 - `zsep::Union{Nothing,Vector{Float64}}` - Z-coordinates of the plasma boundary [m]
507529 - `rext::Union{Nothing,Vector{Float64}}` - R-coordinates of the plasma edge [m]
@@ -554,6 +576,7 @@ A mutable struct containing computed equilibrium parameters and diagnostic flags
554576 ro:: Union{Nothing,Float64} = nothing # R-coordinate of the magnetic axis [m]
555577 zo:: Union{Nothing,Float64} = nothing # Z-coordinate of the magnetic axis [m]
556578 psio:: Union{Nothing,Float64} = nothing # Total flux difference |ψ_axis - ψ_boundary| [Wb/rad]
579+ psihigh_resolved:: Union{Nothing,Float64} = nothing # Outer flux limit actually formed on (clamped config.psihigh)
557580 rsep:: Union{Nothing,Vector{Float64}} = nothing # R-coordinates of the plasma boundary [m]
558581 zsep:: Union{Nothing,Vector{Float64}} = nothing # Z-coordinates of the plasma boundary [m]
559582 rext:: Union{Nothing,Vector{Float64}} = nothing # R-coordinates of the plasma edge [m]
0 commit comments