Particle¶
dexter.InitialFlux(kind: FluxCoordinate, value: float)
¶
Defines the flux coordinate to be used in the initial conditions of a Particle.
Parameters:
-
kind(FluxCoordinate) –The kind of initial flux.
-
value(float) –The flux' value
Example
Attributes:
-
kind(FluxCoordinate) –The kind of initial flux (\(\psi\) or \(\psi_p\))
-
value(float) –The contained value, regardless of kind.
dexter.InitialConditions()
¶
Initial Conditions set for a Particle.
The set can be in either Boozer or Mixed coordinates.
Use InitialConditions.boozer
and InitialConditions.mixed class methods to
construct the set.
Methods:
-
boozer–Creates initial conditions for a Particle in Boozer coordinates.
-
mixed–Creates initial conditions for a Particle in Mixed coordinates.
Attributes:
-
t0(float) –The initial time, in Normalized Units.
-
flux0(InitialFlux) –The initial \(\psi / \psi_p\), in Normalized Units.
-
theta0(float) –The initial \(\theta\) angle, in Normalized Units.
-
zeta0(float) –The initial \(\zeta\) angle, in Normalized Units.
-
mu0(float) –The initial magnetic moment \(\mu\), in Normalized Units.
-
rho0(float) –The initial parallel radius \(\rho_{||}\), in Normalized Units.
-
pzeta0(float) –The initial canonical momentum \(P_\zeta\), in Normalized Units.
-
coordinate_set(CoordinateSet) –The kind of InitialConditions set.
dexter.InitialConditions.t0: float
property
¶
The initial time, in Normalized Units.
dexter.InitialConditions.flux0: InitialFlux
property
¶
The initial \(\psi / \psi_p\), in Normalized Units.
dexter.InitialConditions.theta0: float
property
¶
The initial \(\theta\) angle, in Normalized Units.
dexter.InitialConditions.zeta0: float
property
¶
The initial \(\zeta\) angle, in Normalized Units.
dexter.InitialConditions.mu0: float
property
¶
The initial magnetic moment \(\mu\), in Normalized Units.
dexter.InitialConditions.rho0: float
property
¶
The initial parallel radius \(\rho_{||}\), in Normalized Units.
dexter.InitialConditions.pzeta0: float
property
¶
The initial canonical momentum \(P_\zeta\), in Normalized Units.
dexter.InitialConditions.coordinate_set: CoordinateSet
property
¶
The kind of InitialConditions set.
dexter.InitialConditions.boozer(t0: float, flux0: InitialFlux, theta0: float, zeta0: float, rho0: float, mu0: float) -> InitialConditions
classmethod
¶
Creates initial conditions for a Particle in Boozer coordinates.
The initial conditions are defined on the
\((t, \psi, \theta, \zeta, \rho, \mu)\) or
\((t, \psi_p, \theta, \zeta, \rho, \mu)\)
space, depending on the value of flux0.
Parameters:
-
t0(float) –The initial time, in Normalized Units.
-
flux0(InitialFlux) –The initial \(\psi / \psi_p\), in Normalized Units.
-
theta0(float) –The initial \(\theta\) angle, in rads.
-
zeta0(float) –The initial \(\zeta\) angle, in rads.
-
rho0(float) –The initial \(\rho_{||}\), in Normalized Units.
-
mu0(float) –The initial magnetic moment \(\mu\), in Normalized Units.
dexter.InitialConditions.mixed(t0: float, flux0: InitialFlux, theta0: float, zeta0: float, pzeta0: float, mu0: float) -> InitialConditions
classmethod
¶
Creates initial conditions for a Particle in Mixed coordinates.
The initial conditions are defined on the
\((t, \psi, \theta, \zeta, P\zeta, \mu)\) or
\((t, \zeta, \psi_p, \theta, \zeta, P\zeta, \mu)\)
space, depending on the value of flux0.
Parameters:
-
t0(float) –The initial time, in Normalized Units.
-
pzeta0(float) –The initial \(P_\zeta\), in Normalized Units.
-
flux0(InitialFlux) –The initial \(\psi / \psi_p\), in Normalized Units.
-
theta0(float) –The initial \(\theta\) angle, in rads.
-
zeta0(float) –The initial \(\zeta\) angle, in rads.
-
mu0(float) –The initial magnetic moment \(\mu\), in Normalized Units.
dexter.IntersectParams(intersection: Intersection, angle: float, turns: int)
¶
Parameters for the Particle's intersect() method.
Parameters:
-
intersection(Intersection) –The surface of section Σ, defined by an equation \(\chi_i = \alpha\), where \(\chi_i = \theta\) or \(\zeta\).
-
angle(float) –The constant that defines the surface of section.
-
turns(int) –The number of intersections to calculate.
Example
Attributes:
-
intersection(Intersection) –The intersection surface.
-
angle(float) –The intersection surface's angle.
-
turns(int) –The number of intersections to calculate.
dexter.Particle(initial_conditions: InitialConditions)
¶
A Particle.
By taking \(\mu = 0\) and \(\rho \rightarrow 0\), the particle traces magnetic field lines.
Parameters:
-
initial_conditions(InitialConditions) –The initial conditions set.
Example
Methods:
-
plot_evolution–Plots the time evolution of an integrated Particle.
-
plot_db_drift–Plots the magnetic field strength \(B(\psi/\psi_p, \theta)\) along the particle's orbit.
-
integrate–Integrates the particle for a certain time interval.
-
intersect–Integrates the particle, calculating its intersections with a constant \(\theta\) or \(\zeta\) surface.
-
close–Integrates the particle for a certain amount of \(\theta-\psi\) periods.
-
classify–Classifies the particle’s orbit using its position on the \((E, P_\zeta, \mu=const)\)
Attributes:
-
initial_conditions(InitialConditions) –The initial conditions set.
-
integration_status(IntegrationStatus) –The particle's integration status.
-
steps_taken(int) –The total number of steps taken during the integration.
-
steps_stored(int) –The number of steps stored in the the time series arrays.
-
initial_energy(float) –The particle's initial energy before the integration in Normalized Units.
-
final_energy(float) –The particle's final energy after the integration in Normalized Units.
-
energy_var(float) –The variance of energy throughout the integration.
-
energy_pzeta_position(EnergyPzetaPosition) –The particle's position on the \(E-P_\zeta\) plane, relative to the orbit
-
orbit_type(OrbitType) –The particle's orbit type.
-
omega_theta(float) –The particle's calculated \(\omega_\theta\)
-
omega_zeta(float) –The particle's calculated \(\omega_\zeta\)
-
qkinetic(float) –The particle's calculated \(q_{kinetic}\)
-
t_array(Array1) –The times of the integration steps.
-
psi_array(Array1) –The \(\psi\) time series.
-
psip_array(Array1) –The \(\psi_p\) time series.
-
theta_array(Array1) –The \(\theta\) time series.
-
zeta_array(Array1) –The \(\zeta\) time series.
-
rho_array(Array1) –The \(\rho\) time series.
-
mu_array(Array1) –The \(\mu\) time series.
-
ptheta_array(Array1) –The \(P_\theta\) time series.
-
pzeta_array(Array1) –The \(P_\zeta\) time series.
-
energy_array(Array1) –The energy time series.
dexter.Particle.initial_conditions: InitialConditions
property
¶
The initial conditions set.
dexter.Particle.integration_status: IntegrationStatus
property
¶
The particle's integration status.
dexter.Particle.steps_taken: int
property
¶
The total number of steps taken during the integration.
This number is not necessarily the same as the number of steps stored.
dexter.Particle.steps_stored: int
property
¶
The number of steps stored in the the time series arrays.
dexter.Particle.initial_energy: float
property
¶
The particle's initial energy before the integration in Normalized Units.
dexter.Particle.final_energy: float
property
¶
The particle's final energy after the integration in Normalized Units.
dexter.Particle.energy_var: float
property
¶
The variance of energy throughout the integration.
dexter.Particle.energy_pzeta_position: EnergyPzetaPosition
property
¶
The particle's position on the \(E-P_\zeta\) plane, relative to the orbit classification curves.
See the diagram for explanation.
dexter.Particle.orbit_type: OrbitType
property
¶
The particle's orbit type.
dexter.Particle.omega_theta: float
property
¶
The particle's calculated \(\omega_\theta\)
dexter.Particle.omega_zeta: float
property
¶
The particle's calculated \(\omega_\zeta\)
dexter.Particle.qkinetic: float
property
¶
The particle's calculated \(q_{kinetic}\)
dexter.Particle.t_array: Array1
property
¶
The times of the integration steps.
dexter.Particle.psi_array: Array1
property
¶
The \(\psi\) time series.
dexter.Particle.psip_array: Array1
property
¶
The \(\psi_p\) time series.
dexter.Particle.theta_array: Array1
property
¶
The \(\theta\) time series.
dexter.Particle.zeta_array: Array1
property
¶
The \(\zeta\) time series.
dexter.Particle.rho_array: Array1
property
¶
The \(\rho\) time series.
dexter.Particle.mu_array: Array1
property
¶
The \(\mu\) time series.
dexter.Particle.ptheta_array: Array1
property
¶
The \(P_\theta\) time series.
dexter.Particle.pzeta_array: Array1
property
¶
The \(P_\zeta\) time series.
dexter.Particle.energy_array: Array1
property
¶
The energy time series.
dexter.Particle.plot_evolution(percentage: float = 100, downsample: bool = True, show: bool = True) -> MultiCanvas
¶
Plots the time evolution of an integrated Particle.
Parameters:
-
percentage(float, default:100) –The percentage of the evolution to plot. Defaults to 100.
-
downsample(bool, default:True) –Whether or not to downsample the evolution arrays. This can be really helpful when plotting arrays with a lot of points, since it drastically improves both figure creation and interaction performance. Downsampling is done by increasing the [::step] just enough so that the final number of points is more than 50.000. Defaults to True
-
show(bool, default:True) –Whether or not to call
plt.show(). Defaults to True.
Returns:
-
MultiCanvas–The produced
FigureandAxes.
dexter.Particle.plot_db_drift(equilibrium: Equilibrium, show: bool = True) -> MultiCanvas
¶
Plots the magnetic field strength \(B(\psi/\psi_p, \theta)\) along the particle's orbit.
Parameters:
-
equilibrium(Equilibrium) –The equilibrium in which the particle was integrated.
-
show(bool, default:True) –Whether or not to call
plt.show(). Defaults to True.
Returns:
-
MultiCanvas–The produced
FigureandAxes.
dexter.Particle.integrate(equilibrium: Equilibrium, teval: tuple[float, float], *, stepping_method: Optional[SteppingMethod] = 'EnergyAdaptiveStep', max_steps: Optional[int] = 1000000, first_step: Optional[float] = 0.1, safety_factor: Optional[float] = 0.9, energy_rel_tol: Optional[float] = 1e-12, energy_abs_tol: Optional[float] = 1e-14, error_rel_tol: Optional[float] = 1e-12, error_abs_tol: Optional[float] = 1e-14)
¶
Integrates the particle for a certain time interval.
The time interval is in Normalized Units (inverse gyro-frequency).
Parameters:
-
equilibrium(Equilibrium) –The equilibrium in which to integrate the particle.
-
teval(tuple[float, float]) –The time span \((t_0, t_f)\) in which to integrate the particle, in Normalized Units.
Other Parameters:
-
stepping_method(Optional[SteppingMethod]) –The optimal step calculation method. Defaults to "EnergyAdaptiveStep".
-
max_steps(Optional[int]) –The maximum amount of steps a particle can make before terminating its integration. Defaults to 1.000.000.
-
first_step(Optional[float]) –The initial time step for the RKF45 adaptive step method. The value is empirical. Defaults to 1e-1.
-
safety_factor(Optional[float]) –The safety factor of the solver. Should be less than 1.0. Defaults to 0.9.
-
energy_rel_tol(Optional[float]) –The relative tolerance of the energy difference in every step. Defaults to 1e-12.
-
energy_abs_tol(Optional[float]) –The absolute tolerance of the energy difference in every step. Defaults to 1e-14.
-
error_rel_tol(Optional[float]) –The relative tolerance of the local truncation error in every step. Defaults to 1e-12.
-
error_abs_tol(Optional[float]) –The absolute tolerance of the local truncation error in every step. Defaults to 1e-14.
Example
>>> # Equilibrium setup
>>> LCFS = dex.LastClosedFluxSurface(kind="Toroidal", value=0.45)
>>> equilibrium = dex.Equilibrium(
... qfactor=dex.ParabolicQfactor(qaxis=1.1, qlast=4.1, lcfs=LCFS),
... current=dex.LarCurrent(),
... bfield=dex.LarBfield(),
... perturbation=dex.Perturbation(
... [
... dex.CosHarmonic(epsilon=1e-3, lcfs=LCFS, m=1, n=3, phase=0),
... dex.CosHarmonic(epsilon=1e-3, lcfs=LCFS, m=2, n=3, phase=0),
... ]
... )
... )
>>>
>>> # Initial conditions setup
>>> initial_conditions = dex.InitialConditions.boozer(
... t0=0,
... flux0=dex.InitialFlux("Toroidal", 0.1),
... theta0=3.14,
... zeta0=0,
... rho0=1e-4,
... mu0=7e-6,
... )
>>>
>>> # Particle setup and integration
>>> particle = dex.Particle(initial_conditions)
>>> particle.integrate(
... equilibrium=equilibrium,
... teval=(0, 1e2),
... first_step=1e-3,
... energy_rel_tol=1e-11,
... )
dexter.Particle.intersect(equilibrium: Equilibrium, intersect_params: IntersectParams, *, stepping_method: Optional[SteppingMethod] = 'EnergyAdaptiveStep', max_steps: Optional[int] = 1000000, first_step: Optional[float] = 0.1, safety_factor: Optional[float] = 0.9, energy_rel_tol: Optional[float] = 1e-12, energy_abs_tol: Optional[float] = 1e-14, error_rel_tol: Optional[float] = 1e-12, error_abs_tol: Optional[float] = 1e-14)
¶
Integrates the particle, calculating its intersections with a constant \(\theta\) or \(\zeta\) surface.
Using the method described by Hénon we can force the solver to step exactly on the intersection surface.
The differences between two consecutive values of the corresponding angle variable are guaranteed to be \(2\pi \pm \epsilon\), where \(\epsilon\) a number smaller than the solver’s relative tolerance.
Parameters:
-
equilibrium(Equilibrium) –The equilibrium in which to integrate the particle.
-
intersect_params(IntersectParams) –The parameters of the integration.
Other Parameters:
-
stepping_method(Optional[SteppingMethod]) –The optimal step calculation method. Defaults to "EnergyAdaptiveStep".
-
max_steps(Optional[int]) –The maximum amount of steps a particle can make before terminating its integration. Defaults to 1.000.000.
-
first_step(Optional[float]) –The initial time step for the RKF45 adaptive step method. The value is empirical. Defaults to 1e-1.
-
safety_factor(Optional[float]) –The safety factor of the solver. Should be less than 1.0. Defaults to 0.9.
-
energy_rel_tol(Optional[float]) –The relative tolerance of the energy difference in every step. Defaults to 1e-12.
-
energy_abs_tol(Optional[float]) –The absolute tolerance of the energy difference in every step. Defaults to 1e-14.
-
error_rel_tol(Optional[float]) –The relative tolerance of the local truncation error in every step. Defaults to 1e-12.
-
error_abs_tol(Optional[float]) –The absolute tolerance of the local truncation error in every step. Defaults to 1e-14.
Example
>>> # Equilibrium setup
>>> LCFS = dex.LastClosedFluxSurface(kind="Toroidal", value=0.45)
>>> equilibrium = dex.Equilibrium(
... qfactor=dex.ParabolicQfactor(qaxis=1.1, qlast=4.1, lcfs=LCFS),
... current=dex.LarCurrent(),
... bfield=dex.LarBfield(),
... perturbation=dex.Perturbation(
... [
... dex.CosHarmonic(epsilon=1e-3, lcfs=LCFS, m=1, n=3, phase=0),
... dex.CosHarmonic(epsilon=1e-3, lcfs=LCFS, m=2, n=3, phase=0),
... ]
... )
... )
>>>
>>> # Initial conditions and Intersection Parameters setup
>>> initial_conditions = dex.InitialConditions.boozer(
... t0=0,
... flux0=dex.InitialFlux("Toroidal", 0.1),
... theta0=3.14,
... zeta0=0,
... rho0=1e-4,
... mu0=7e-6,
... )
>>> intersect_params = dex.IntersectParams(
... intersection = "ConstTheta",
... angle = 3.1415,
... turns = 5,
... )
>>>
>>> # Particle setup and intersection
>>> particle = dex.Particle(initial_conditions)
>>> particle.intersect(
... equilibrium=equilibrium,
... intersect_params=intersect_params,
... )
dexter.Particle.close(equilibrium: Equilibrium, *, periods: Optional[int] = 1, stepping_method: Optional[SteppingMethod] = 'EnergyAdaptiveStep', max_steps: Optional[int] = 1000000, first_step: Optional[float] = 0.1, safety_factor: Optional[float] = 0.9, energy_rel_tol: Optional[float] = 1e-12, energy_abs_tol: Optional[float] = 1e-14, error_rel_tol: Optional[float] = 1e-12, error_abs_tol: Optional[float] = 1e-14)
¶
Integrates the particle for a certain amount of \(\theta-\psi\) periods.
Parameters:
-
equilibrium(Equilibrium) –The equilibrium in which to integrate the particle.
-
periods(Optional[int], default:1) –The amount of periods to integrate. Defaults to 1.
Other Parameters:
-
stepping_method(Optional[SteppingMethod]) –The optimal step calculation method. Defaults to "EnergyAdaptiveStep".
-
max_steps(Optional[int]) –The maximum amount of steps a particle can make before terminating its integration. Defaults to 1.000.000.
-
first_step(Optional[float]) –The initial time step for the RKF45 adaptive step method. The value is empirical. Defaults to 1e-1.
-
safety_factor(Optional[float]) –The safety factor of the solver. Should be less than 1.0. Defaults to 0.9.
-
energy_rel_tol(Optional[float]) –The relative tolerance of the energy difference in every step. Defaults to 1e-12.
-
energy_abs_tol(Optional[float]) –The absolute tolerance of the energy difference in every step. Defaults to 1e-14.
-
error_rel_tol(Optional[float]) –The relative tolerance of the local truncation error in every step. Defaults to 1e-12.
-
error_abs_tol(Optional[float]) –The absolute tolerance of the local truncation error in every step. Defaults to 1e-14.
Example
>>> # Equilibrium setup
>>> LCFS = dex.LastClosedFluxSurface(kind="Toroidal", value=0.45)
>>> equilibrium = dex.Equilibrium(
... qfactor=dex.ParabolicQfactor(qaxis=1.1, qlast=4.1, lcfs=LCFS),
... current=dex.LarCurrent(),
... bfield=dex.LarBfield(),
... perturbation=dex.Perturbation([])
... )
>>>
>>> # Initial conditions setup
>>> initial_conditions = dex.InitialConditions.boozer(
... t0=0,
... flux0=dex.InitialFlux("Toroidal", 0.1),
... theta0=3.14,
... zeta0=0,
... rho0=1e-5,
... mu0=7e-6,
... )
>>>
>>> # Particle setup and integration
>>> particle = dex.Particle(initial_conditions)
>>> particle.close(
... equilibrium=equilibrium,
... periods=4,
... )
dexter.Particle.classify(equilibrium: Equilibrium)
¶
Classifies the particle’s orbit using its position on the \((E, P_\zeta, \mu=const)\) plane without integrating.
Parameters:
-
equilibrium(Equilibrium) –The equilibrium in which to integrate the particle.
Example
>>> # Equilibrium setup
>>> LCFS = dex.LastClosedFluxSurface(kind="Toroidal", value=0.45)
>>> equilibrium = dex.Equilibrium(
... qfactor=dex.ParabolicQfactor(qaxis=1.1, qlast=4.1, lcfs=LCFS),
... current=dex.LarCurrent(),
... bfield=dex.LarBfield(),
... )
>>>
>>> # Initial conditions setup
>>> initial_conditions = dex.InitialConditions.boozer(
... t0=0,
... flux0=dex.InitialFlux("Toroidal", 0.1),
... theta0=3.14,
... zeta0=0,
... rho0=1e-4,
... mu0=7e-6,
... )
>>>
>>> # Particle setup and classification
>>> particle = dex.Particle(initial_conditions)
>>> particle.close(equilibrium=equilibrium)