q-factor Objects¶
dexter.QfactorObject: TypeAlias = UnityQfactor | ParabolicQfactor | ArrayQfactor | NcQfactor
module-attribute
¶
Available Qfactor objects.
UnityQfactor: Analytical q-factor profile of $q=1$ and $\psi_t=\psi_p$.ParabolicQfactor: Analytical parabolic q-factor profile.ArrayQfactor: Numerical q-factor profile reconstructed from $\psi-q$ pairs.NcQfactor: Numerical q-factor profile reconstructed from a netCDF file.
dexter.UnityQfactor(lcfs: MagneticFlux)
¶
Bases: MachineObject, Qfactor
Analytical q-factor profile of $q=1$ and $\psi_t=\psi_p$.
Parameters:
-
lcfs(MagneticFlux) –The last closed flux surface. Only used for bounds checking.
dexter.ParabolicQfactor(qaxis: float, qlast: float, lcfs: MagneticFlux)
¶
Bases: MachineObject, Qfactor
Analytical parabolic q-factor profile.
Parameters:
-
qaxis(float) –The q-factor's value at the magnetic axis, $q_{axis}$.
-
qlast(float) –The q-factor's value at the last closed flux surface, $q_{LCFS}$.
Example
The ParabolicQfactor's profile is described by the following formulas:
$$ q(\psi_t) = q_{axis} + (q_{LCFS} - q_{axis}) \bigg( \dfrac{\psi_t}{\psi_{t,LCFS}} \bigg)^2 $$
$$ \psi_p(\psi_t) = \dfrac{\psi_{t,LCFS}}{\sqrt{q_{axis}(q_{LCFS} - q_{axis})}} \arctan\bigg[ \dfrac{\psi_t\sqrt{q_{LCFS} - q_{axis}}}{\psi_{t,LCFS}\sqrt{q_{axis}}} \bigg] $$
$$ \psi_t(\psi_p) = \dfrac{\psi_{t,LCFS}\sqrt{q_{axis}}}{\sqrt{q_{LCFS} - q_{axis}}} \tan\bigg[ \dfrac{\sqrt{q_{axis}(q_{LCFS} - q_{axis})}}{\psi_{t,LCFS}}\psi_p \bigg] $$
$$ \dfrac{d\psi_p(\psi_t)}{d\psi_t} = ... = \dfrac{1}{q(\psi_t)} = \iota(\psi_t) $$
$$ \dfrac{d\psi_t(\psi_p)}{d\psi_p} = \dfrac{q_{axis}}{\cos^2 \bigg[ \dfrac{\sqrt{q_{axis}(q_{LCFS} - q_{axis})}}{\psi_{t,LCFS}}\psi_p \bigg]} \overset{*}{=} q(\psi_p) $$
$$ q(\psi_p) = q_{axis} + q_{axis} \tan^2 \bigg[ \dfrac{\sqrt{q_{axis}(q_{LCFS}-q_{axis})}}{\psi_{t,LCFS}} \psi_p \bigg] $$
$$ \dfrac{dq(\psi_t)}{d\psi_t} = 2(q_{last} - q_{axis})\dfrac{\psi_t}{\psi_{t,LCFS}} $$
$$ \dfrac{dq(\psi_p)}{d\psi_p} = \dfrac{2 q_{axis} \sqrt{q_{axis}(q_{last} - q_{axis})} \sin(\beta)} {\psi_{t,LCFS}\cos^3(\beta)}, \qquad \text{where} \qquad \beta= \dfrac{\sqrt{q_{axis} (q_{last} - q_{axis})}\psi_p}{\psi_{t,LCFS}} $$
$$ \iota = \dfrac{1}{q} $$
$$ \iota' = -\dfrac{q'}{q^2} $$
$^*$ Identity: $\dfrac{1}{\cos^2\theta} = 1 + \tan^2\theta$
dexter.ArrayQfactor(flux_array: MagneticFluxArray, q_array: ArrayLike, interp_type: Interpolation1dType)
¶
Bases: MachineObject, Qfactor
Numerical q-factor profile reconstructed from $\psi-q$ pairs.
Consistency of evaluations
Regardless of the kind of the passed flux_array, two interpolators are built: a
$\iota(\psi_t)$ and a $q(\psi_p)$ interpolator, where the values of the other flux are
obtained by integrating the corresponding interpolator.
When calling an evaluation method, the kind of the passed flux argument determines the
interpolator that will be used; an evaluation with respect to a toroidal flux always uses
the $\iota(\psi_t)$ interpolator while an evaluation with resepct to a poloidal flux
always uses the $q(\psi_p)$ interpolator. For example, qfactor.eval_q(psi) returns
1/qfactor.eval_iota(psi) and qfactor.eval_iota_deriv(psip) returns
-qfactor.eval_q_deriv(psip)/qfactor.eval_q(psip)^2.
The above rule guarantees that no evaluation will pass through both interpolators (with the
exception of eval_deriv_wrt_other, which is a shorthand of eval_other -> eval_deriv_of_other).
This is important as passing through both interpolators introduces numerical inconsistencies.
However, when flux_array.kind() == Toroidal, the very construction of the $q(\psi_p)$
interpolator is inconsistent , as the extra step of calculating $\psi_p$ from $\psi_t$ is needed
before constructing the $q(\psi_p)$ interpolator (similarly when flux_array.kind() ==Poloidal for $\iota(\psi_t)$). Therefore, while the evaluation methods guarantee that the
correct interpolator will be used, it is up to you to ensure you evaluate the qfactor with
respect to the flux you constructed it with.
Tip
The defining_flux attribute stores the kind of flux w.r.t. which the ArrayQfactor was defined.
Parameters:
-
flux_array(MagneticFluxArray) –The magnetic flux array.
-
q_array(ArrayLike) –The $q$ values array.
-
interp_type(Interpolation1dType) –The 1D interpolation type.
Attributes:
-
interp_type(Interpolation1dType) –The 1D interpolation type.
-
defining_flux(MagneticFluxKind) –The flux w.r.t. which the
qfactorwas defined. -
psit_array(Array1) –The toroidal flux' values.
-
psip_array(Array1) –The poloidal flux' values.
-
q_array(Array1) –The q-factor's values.
Raises:
-
Exception–An exception is raised if:
- Data arrays are empty,
- Data arrays have different sizes,
- The first element of
flux_arrayis not0.0. flux_arrayvalues are non-rising.- The interpolators fail to build.
Example
dexter.NcQfactor(path: str, interp_type: Interpolation1dType)
¶
Bases: MachineObject, Qfactor
Numerical q-factor profile reconstructed from a netCDF file.
This type is a wrapper type of ArrayQfactor where the $\psi$ and $q$
data are extracted from the netCDF file.
Parameters:
-
path(str) –The path to the netCDF file.
-
interp_type(Interpolation1dType) –The 1D interpolation type.
Attributes:
-
path(str) –The path to the netCDF file.
-
netcdf_version(NetCDFVersion) –The netCDF file's version (SemVer).
-
interp_type(Interpolation1dType) –The 1D interpolation type.
-
psit_array(Array1) –The toroidal flux' values.
-
psip_array(Array1) –The poloidal flux' values.
-
q_array(Array1) –The q-factor's values.