spectre.file_io.input_parameters

Define the data models for SPEC input parameters using Pydantic. The model uses serializers to generate human-readable files for writing with toml (in toml_io.py), and uses validators to cast incoming data into the format expected by SPEC, which are numpy arrays of much larger sizes.

Module Contents

spectre.file_io.input_parameters.mnvol = 256
spectre.file_io.input_parameters.mmpol = 128
spectre.file_io.input_parameters.mntor = 128
spectre.file_io.input_parameters.mnmax = 33025
spectre.file_io.input_parameters.arrays_of_length_nvol = ['pressure', 'adiabatic', 'mu', 'isurf']
spectre.file_io.input_parameters.arrays_of_length_mvol = ['lrad', 'tflux', 'ivolume', 'pflux', 'helicity', 'pl', 'ql', 'pr', 'qr', 'lp', 'lq', 'rp', 'rq']
spectre.file_io.input_parameters.arrays_of_length_mvol_plus = ['iota', 'oita']
spectre.file_io.input_parameters.arrays_of_length_nvol_minus_1 = []
spectre.file_io.input_parameters.arrays_fourier = ['rbc', 'zbs', 'rbs', 'zbc', 'rwc', 'zws', 'rws', 'zwc', 'vns', 'bns', 'vnc', 'bnc']
class spectre.file_io.input_parameters.PhysicsParameters

Bases: pydantic.BaseModel

igeometry: int
nfp: int = 1
nvol: int = 1
mpol: int = 0
ntor: int = 0
lconstraint: int = -1
mupfits: int = 8
ladiabatic: int = 0
num_modes: int
mupftol: float = 1e-14
rpol: float = 1.0
rtor: float = 1.0
lreflect: int = 0
lbdybnzero: bool = True
lbnszero: bool = False
lfreebound: int = 0
phiedge: float = 1.0
curtor: float = 0.0
curpol: float = 0.0
gamma: float = 0.0
pscale: float = 0.0
enforce_stell_sym: bool = True
lrad: numpy.typing.NDArray[numpy.int32]
pl: numpy.typing.NDArray[numpy.int32]
ql: numpy.typing.NDArray[numpy.int32]
pr: numpy.typing.NDArray[numpy.int32]
qr: numpy.typing.NDArray[numpy.int32]
lp: numpy.typing.NDArray[numpy.int32]
lq: numpy.typing.NDArray[numpy.int32]
rp: numpy.typing.NDArray[numpy.int32]
rq: numpy.typing.NDArray[numpy.int32]
tflux: numpy.typing.NDArray[numpy.float64]
pflux: numpy.typing.NDArray[numpy.float64]
pressure: numpy.typing.NDArray[numpy.float64]
adiabatic: numpy.typing.NDArray[numpy.float64]
mu: numpy.typing.NDArray[numpy.float64]
ivolume: numpy.typing.NDArray[numpy.float64]
iota: numpy.typing.NDArray[numpy.float64]
oita: numpy.typing.NDArray[numpy.float64]
isurf: numpy.typing.NDArray[numpy.float64]
helicity: numpy.typing.NDArray[numpy.float64]
rac: numpy.typing.NDArray[numpy.float64]
zas: numpy.typing.NDArray[numpy.float64]
ras: numpy.typing.NDArray[numpy.float64]
zac: numpy.typing.NDArray[numpy.float64]
rbc: numpy.typing.NDArray[numpy.float64]
zbs: numpy.typing.NDArray[numpy.float64]
rbs: numpy.typing.NDArray[numpy.float64]
zbc: numpy.typing.NDArray[numpy.float64]
rwc: numpy.typing.NDArray[numpy.float64]
zws: numpy.typing.NDArray[numpy.float64]
rws: numpy.typing.NDArray[numpy.float64]
zwc: numpy.typing.NDArray[numpy.float64]
vns: numpy.typing.NDArray[numpy.float64]
bns: numpy.typing.NDArray[numpy.float64]
vnc: numpy.typing.NDArray[numpy.float64]
bnc: numpy.typing.NDArray[numpy.float64]
allrzrz: numpy.typing.NDArray[numpy.float64] = None
mmrzrz: numpy.typing.NDArray[numpy.int32]
nnrzrz: numpy.typing.NDArray[numpy.int32]
model_config
serialize_radial_arrays_nvol(value)

serialize the radial arrays that provide a value for each volume/interface internal to the configuration

serialize_radial_arrays_mvol(value)

serialize the arrays that are not always nvol long but depending on freeboundary can be one longer (are thus defined in the vacuum region enclosing the plasma).

serialize_radial_arrays_mvol_plus(value)

serialize the arrays that are not always nvol long but depending on freeboundary can be one longer (are thus defined in the vacuum region enclosing the plasma).

serialize_radial_arrays_nvol_minus_1(value)

serialize the radial arrays that are only nvol-1 long

serialize_toroidal_arrays(value)
serialize_fourier_arrays(value)
serialize_guess(allrzrz)

The interface guess is stored in allrzrz with index helper arrays mmrzrz and nnrzrz. Our job is to reconstruct a human readable mapping from this.

This helper array has the shape it has because it was dumped at the end of the namelist. In the future this will be deprecated for direct writing of the interface guesses one by one.

classmethod set_guess(values)

prepare the allrzrz array from the input mapping if provided. don’t judge me, this keeps the toml file with a clean, readable guess, and keeps the changes to the interface to the SPEC fortran side minimal. In the future the input_list_mod will (hopefully) be replaced with a interface_mod that passes all relevant information for the SPEC state to the FORTRAN memory, allowing switching between configurations without running all intialization steps…

pad_radial_int_arrays(value)

pad the 1D int arrays to the SPEC expected size

pad_radial_float_arrays_mnvolplus(value)

pad the 1D float arrays to the SPEC expected size

pad_radial_float_arrays_mnvol(value)

pad the 1D float arrays to the SPEC expected size

pad_toroidal_arrays(value)

pad the 1D toroidal arrays to the SPEC expected size

pad_fourier_arrays(value)

pad the 2D fourier arrays to the SPEC expected size.

pad_fourier_arrays_input()

pad the fourier arrays to the spec expected size if they were not suppied as a nested dict (for example if read as a namelist or supplied by a different code). The array is expected to be of shape (ntor_input+1, 2*mpol_input+1) (VMEC convention) with negative m values stored in the upper half of the second axis.

classmethod check_correct_fields_provided(values)

ensure that depending on lconstraint, the necessary info was provided

class spectre.file_io.input_parameters.NumericParameters

Bases: pydantic.BaseModel

linitialize: int = 0
lchangeangle: bool = False
lautoinitbn: int = 1
lzerovac: int = 0
ndiscrete: int = 2
nquad: int = -1
impol: int = -4
intor: int = -4
lsparse: int = 0
lsvdiota: int = 0
lrzaxis: int = 1
ntoraxis: int = 3
lvcgrid: int = 0
class spectre.file_io.input_parameters.GlobalParameters

Bases: pydantic.BaseModel

escale: float = 0.0
opsilon: float = 1.0
pcondense: float = 2.0
epsilon: float = 0.0
wpoloidal: float = 1.0
upsilon: float = 1.0
mfreeits: int = 0
gbntol: float = 1e-06
gbnbld: float = 0.666
vcasingeps: float = 1e-12
vcasingtol: float = 1e-08
vcasingits: int = 8
vcasingper: int = 1
vcnt: int = 256
vcnz: int = 256
class spectre.file_io.input_parameters.DiagnosticsParameters

Bases: pydantic.BaseModel

odetol: float = 1e-07
nppts: int = 0
ppts: float = 0.0
nptrj: int | numpy.typing.NDArray[numpy.int32]
lhevalues: bool = False
lhevectors: bool = False
lhmatrix: bool = False
lerrortype: int = 0
ngrid: int = -1
lcheck: int = 0
ltransform: bool = False
model_config
pad_nptrj(value)

pad the 1D toroidal arrays to the SPEC expected size

serialize_nptrj(value)

Serialize the 1D toroidal arrays to the SPEC expected format

class spectre.file_io.input_parameters.ScreenParameters

Bases: pydantic.BaseModel

wmanual: bool = False
wrzaxis: bool = False
wpackxi: bool = False
wvolume: bool = False
wcompute_coordinates: bool = False
wbasefn: bool = False
wmemory: bool = False
wcompute_metric_quantities: bool = False
wvolume_integrate_chebyshev: bool = False
wmatrix: bool = False
wspsint: bool = False
wsolve_beltrami_system: bool = False
wconstruct_beltrami_field: bool = False
wpackab: bool = False
wcompute_rotational_transform: bool = False
wcompute_plasma_current: bool = False
wdf0ab: bool = False
wlforce: bool = False
wintghs: bool = False
wmtrxhs: bool = False
wlbpol: bool = False
wbroadcast_profile_data: bool = False
wdfp100: bool = False
wdfp200: bool = False
wdforce: bool = False
wnewton: bool = False
wcasing: bool = False
wbnorml: bool = False
wcompute_beltrami_error: bool = False
wconstruct_poincare_plot: bool = False
wpp00ab: bool = False
wget_position_vetor_x: bool = False
whesian: bool = False
wwrite_vector_potentials: bool = False
wnumrec: bool = False
wdcuhre: bool = False
wminpack: bool = False
wiqpack: bool = False
wrksuite: bool = False
wi1mach: bool = False
wd1mach: bool = False
wilut: bool = False
witers: bool = False
wsphdf5: bool = False
winitialize_internal_arrays: bool = False
wglobal: bool = False
wxspech: bool = False
wbuild_vector_potential: bool = False
wreadin: bool = False
wwrtend: bool = False
wmacros: bool = False
class spectre.file_io.input_parameters.MinimizationParameters

Bases: pydantic.BaseModel

gtol: float = 1e-13
xtol: float = 1e-22
ftol: float = 1e-13
max_nfev: int = 10000
max_niter: int = 10000
method: Literal['trf', 'dogbox', 'lm'] = 'dogbox'
rcond_lstsq: float | None = None
save_xin_fixb: bool = True
freeb_max_iter: int = 1
freeb_bnorm_tol: float = 1e-05
nt_dbb: int | None = None
nz_dbb: int | None = None
filter_stellsym: bool = True
objective: Literal['freal', 'freal,len'] = 'freal'
resume: bool = False
mpol_rz: int | None = None
ntor_rz: int | None = None
len_factor: float = 1.0
inface_repr: Literal['fourier', 'fourier red', 'henn'] = 'fourier'
mmax: int = 8
nmax: int = 8
class spectre.file_io.input_parameters.InputParameters

Bases: pydantic.BaseModel

minimization: MinimizationParameters
physics: PhysicsParameters
numeric: NumericParameters
global_: GlobalParameters
diagnostics: DiagnosticsParameters
validate_parameters() InputParameters

Placeholder for cross-field validation between parameter groups.

classmethod check_henneberg_res(values)

Ensure that resolution used for Henneberg representation is representable (mmax<mpol and nmax<ntor).