essos.dynamics¶
Attributes¶
Classes¶
Stop tracing when a signed-distance level set is crossed. |
|
Functions¶
|
Computes full orbit positions for given guiding center positions, |
|
|
|
|
|
|
|
|
|
Guiding-center field quantities, fused when the field provides them. |
|
|
|
|
|
|
|
|
|
|
|
Trace the same field line with physical arclength as the parameter. |
|
Trace a flux-coordinate field with toroidal angle as the parameter. |
|
Hold each trajectory at its last point inside all level sets. |
Map (s, theta, ...) to (sqrt(s) cos theta, sqrt(s) sin theta, ..., 0). |
|
Map (u, w, ..., Theta) back to (s, theta, ...), with theta in [0, 2 pi). |
|
|
Express a VMEC guiding-center vector field in a chart that is regular on the axis. |
|
LCFS event for VMEC guiding centers traced in (u, w). |
|
Trace field lines by toroidal angle or physical arclength. |
|
Connection length and wall strike points of field lines. |
Module Contents¶
- essos.dynamics.gc_to_fullorbit(field, initial_xyz, initial_vparallel, total_speed, mass, charge, phase_angle_full_orbit=0)¶
Computes full orbit positions for given guiding center positions, parallel speeds, and total velocities using JAX for efficiency.
The full-orbit start satisfies
x - b x v / Omega = Xwith the signed gyrofrequencyOmega = charge |B| / mass, so the guiding center of the returned state is the requested point for either sign of the charge.
- class essos.dynamics.Particles(initial_xyz=None, initial_vparallel_over_v=None, charge=ALPHA_PARTICLE_CHARGE, mass=ALPHA_PARTICLE_MASS, energy=FUSION_ALPHA_PARTICLE_ENERGY, min_vparallel_over_v=-1, max_vparallel_over_v=1, field=None, initial_vxvyvz=None, initial_xyz_fullorbit=None, phase_angle_full_orbit=0)¶
- charge = 3.204353268e-19¶
- mass = 6.69509884346e-27¶
- energy = 5.639661751679999e-13¶
- initial_xyz¶
- nparticles¶
- initial_xyz_fullorbit = None¶
- initial_vxvyvz = None¶
- phase_angle_full_orbit = 0¶
- particle_index¶
- random_keys¶
- total_speed¶
- initial_vparallel¶
- initial_vperpendicular¶
- to_full_orbit(field)¶
- join(other, field=None)¶
- classmethod InitializeParticlesAroundSurfaceAxis(surface, n_particles, distance_from_axis=0.0, charge=ALPHA_PARTICLE_CHARGE, mass=ALPHA_PARTICLE_MASS, energy=FUSION_ALPHA_PARTICLE_ENERGY, min_vparallel_over_v=-1, max_vparallel_over_v=1, field=None, random_seed=42, n_arc_samples=1000, boundary_surface=None, distance_mode='absolute', boundary_bisection_steps=32)¶
Initialize particles randomly distributed around/along a magnetic axis extracted from a surface.
- Parameters:
surface – SurfaceRZFourier object to extract axis from
n_particles – Number of particles to initialize
distance_from_axis – Perpendicular distance (in Frenet frame) from the axis (0.0 for particles on axis, >0 for particles around axis). If distance_mode=’fraction_to_boundary’, this is interpreted as a fraction in [0, 1] of the local axis-to-boundary distance.
charge – Particle charge (default: alpha particle charge)
mass – Particle mass (default: alpha particle mass)
energy – Particle kinetic energy
min_vparallel_over_v – Minimum parallel velocity fraction
max_vparallel_over_v – Maximum parallel velocity fraction
field – Magnetic field object (for converting to full orbit if needed)
random_seed – Seed for random number generation
n_arc_samples – Number of samples for arc-length parametrization
boundary_surface – Optional surface used as geometric boundary when distance_mode=’fraction_to_boundary’.
distance_mode – ‘absolute’ or ‘fraction_to_boundary’.
boundary_bisection_steps – Number of bisection iterations used to find axis-to-boundary distance along each particle direction.
- Returns:
Particles object with initial positions distributed around the axis
- essos.dynamics.GuidingCenterCollisionsDiffusionMu(t, initial_condition, args) jax.numpy.ndarray¶
- essos.dynamics.GuidingCenterCollisionsDriftMuStratonovich(t, initial_condition, args) jax.numpy.ndarray¶
- essos.dynamics.GuidingCenterCollisionsDriftMuIto(t, initial_condition, args) jax.numpy.ndarray¶
- essos.dynamics.GuidingCenterCollisionsDiffusion(t, initial_condition, args) jax.numpy.ndarray¶
- essos.dynamics.GuidingCenterCollisionsDrift(t, initial_condition, args) jax.numpy.ndarray¶
- essos.dynamics._gc_quantities(field, points)¶
Guiding-center field quantities, fused when the field provides them.
Fields that do not override
MagneticField.gc_quantities(for exampleVmec, or a field that is not a pytree) use their individual methods; the choice is made at trace time.
- essos.dynamics.GuidingCenter(t, initial_condition, args) jax.numpy.ndarray¶
- essos.dynamics.LorentzCollisionsDiffusion(t, initial_condition, args) jax.numpy.ndarray¶
- essos.dynamics.LorentzCollisionsDrift(t, initial_condition, args) jax.numpy.ndarray¶
- essos.dynamics.Lorentz(t, initial_condition, args) jax.numpy.ndarray¶
- essos.dynamics.FieldLine(t, initial_condition, field) jax.numpy.ndarray¶
- essos.dynamics.FieldLineArclength(t, initial_condition, field) jax.numpy.ndarray¶
Trace the same field line with physical arclength as the parameter.
- essos.dynamics.FieldLineToroidal(t, initial_condition, field) jax.numpy.ndarray¶
Trace a flux-coordinate field with toroidal angle as the parameter.
- essos.dynamics._fill_stopped_trajectories(trajectories, criteria, args)¶
Hold each trajectory at its last point inside all level sets.
- essos.dynamics._VMEC_GUIDING_CENTER_MODELS¶
- essos.dynamics._GUIDING_CENTER_COLLISION_MODELS¶
- essos.dynamics._AXIS_REGION = 0.01¶
- essos.dynamics._to_axis_regular(y)¶
Map (s, theta, …) to (sqrt(s) cos theta, sqrt(s) sin theta, …, 0).
- essos.dynamics._from_axis_regular(y)¶
Map (u, w, …, Theta) back to (s, theta, …), with theta in [0, 2 pi).
- essos.dynamics._axis_regular(vector_field)¶
Express a VMEC guiding-center vector field in a chart that is regular on the axis.
The state is (u, w, …, Theta) with (u, w) = sqrt(s) (cos a, sin a) and theta = a + Theta. (s, theta) is singular on the magnetic axis and (u, w) is not, so orbits cross it instead of stopping there. Of the poloidal rotation dtheta/dt, the fraction c = s / (s + _AXIS_REGION) goes to Theta and the rest rotates (u, w): du/dt = u/(2s) ds/dt - (1 - c) w dtheta/dt, dw/dt = w/(2s) ds/dt + (1 - c) u dtheta/dt, dTheta/dt = c dtheta/dt, all regular on the axis. Away from it, a fixed-step solver then advances theta as an angle, not by rotating (u, w) with a truncation error that spirals orbits outward. Drift vectors and diffusion matrices transform alike; the map involves position only and the position has no noise, so Ito and Stratonovich forms need no extra drift.
- essos.dynamics._vmec_boundary_event(t, y, args, **kwargs)¶
LCFS event for VMEC guiding centers traced in (u, w).
- class essos.dynamics.LevelsetStoppingCriterion(classifier, maximum_distance=0.0)¶
Stop tracing when a signed-distance level set is crossed.
classifiermust be positive inside its reference surface. A positivemaximum_distancepermits tracing that far outside the surface before stopping.- classifier¶
- maximum_distance¶
- __call__(t, y, args, **kwargs)¶
- class essos.dynamics.Tracing(trajectories_input=None, initial_conditions=None, times_to_trace=None, field=None, electric_field=None, model=None, maxtime: float = 1e-07, timestep: int = 1e-08, rtol=1e-07, atol=1e-07, particles=None, condition=None, species=None, tag_gc=1.0, boundary=None, rejected_steps=None, solver=None, stopping_criteria=None, progress=False, devices=None, max_steps=1000000)¶
- stopping_criteria = None¶
- devices¶
- rejected_steps = 100¶
- model = None¶
- initial_conditions = None¶
- times_to_trace = None¶
- maxtime = 1e-07¶
- timestep = 1e-08¶
- rtol = 1e-07¶
- atol = 1e-07¶
- _trajectories = None¶
- particles = None¶
- species = None¶
- tag_gc = 1.0¶
- _axis_regular¶
- _has_boundary_event = False¶
- max_steps = 1000000¶
- progress = False¶
- progress_meter¶
- solver = None¶
- total_particles_unresolved¶
- trace()¶
- _vector_field(vector_field)¶
- property trajectories¶
- energy()¶
- v_perp()¶
- to_vtk(filename)¶
- plot(ax=None, show=True, axis_equal=True, n_trajectories_plot=5, **kwargs)¶
- loss_fraction_BioSavart(boundary)¶
Memory-efficient boundary loss fraction evaluation.
Uses flattened single vmap instead of nested double vmap to reduce memory usage by ~80% while maintaining accuracy.
- Parameters:
boundary – SurfaceClassifier for boundary evaluation
- Returns:
Cumulative loss fraction over time total_particles_lost: Total number of particles lost lost_times: Time of loss for each particle
- Return type:
loss_fractions
- loss_fraction(r_max=1.0)¶
Cumulative loss fraction of a flux-coordinate trace.
A particle is lost at the first saved time with
s >= r_max, or with a non-finite state, which is what the LCFS event leaves after it stops a trace. The defaultr_maxis that LCFS.
- loss_fraction_BioSavart_collisions(boundary)¶
Memory-efficient boundary loss fraction for collision models.
Optimized version using flattened vmap.
- loss_fraction_collisions(r_max=1.0)¶
As
loss_fraction(), with the energy and position of each lost particle at its last finite saved state.
- poincare_plot(shifts=[jnp.pi / 2], orientation='toroidal', length=1, ax=None, show=True, color=None, **kwargs)¶
Plot Poincare sections from Cartesian trajectories. :param shifts: Apply a linear shift to dependent data. Default is [pi/2]. :type shifts: list, optional :param orientation: ‘toroidal’ - find time values when toroidal angle = shift [0, 2pi].
‘z’ - find time values where z coordinate = shift. Default is ‘toroidal’.
- Parameters:
length (float, optional) – A way to shorten data. 1 - plot full length, 0.1 - plot 1/10 of data length. Default is 1.
ax (matplotlib.axes._subplots.AxesSubplot, optional) – Matplotlib axis to plot on. Default is None.
show (bool, optional) – Whether to display the plot. Default is True.
color –
"time", one Matplotlib color, or one color per trajectory.**kwargs – Additional keyword arguments for plotting.
Toroidal crossings are found from the unwrapped Cartesian azimuth, so the branch cut at
phi=0does not create or discard intersections.
- _tree_flatten()¶
- classmethod _tree_unflatten(aux_data, children)¶
- essos.dynamics.trace_field_lines(field, initial_conditions, *, toroidal_turns=None, length=None, samples=1000, tolerance=1e-07, stopping_criteria=None, progress=True, label='field lines', devices=None)¶
Trace field lines by toroidal angle or physical arclength.
Specify exactly one of
toroidal_turnsorlength. Toroidal tracing is intended for fields represented in flux coordinates; Cartesian coil fields use arclength, so multiplying the magnetic field does not change the traced distance.samplesincludes both endpoints. The returnedTracingobject provides trajectories, event flags, plotting, and Poincare sections.- Parameters:
field – ESSOS-compatible magnetic field.
initial_conditions – One seed per row, in the field’s coordinates.
toroidal_turns – Number of full toroidal turns to follow.
length – Physical arclength to follow for a Cartesian field.
samples – Number of saved points along each line.
tolerance – Relative and absolute adaptive-integration tolerance.
stopping_criteria – Optional event callable or sequence of callables.
progress – Show Diffrax’s terminal progress bar.
label – Text printed before compilation and after completion; set to
Noneto suppress these two messages.devices – Optional explicit sequence of JAX devices.
- essos.dynamics.connection_length(field, initial_conditions, wall, *, max_length, tolerance=1e-08, max_steps=100000)¶
Connection length and wall strike points of field lines.
Each seed is followed along
+Band-Bby physical arclength until it crosses the wall or reachesmax_length. The crossing is located by Diffrax event root finding, so the strike point is exact up totolerancerather than limited by a sampling interval. The result is differentiable with respect to the seeds and field parameters.- Parameters:
field – ESSOS-compatible Cartesian magnetic field.
initial_conditions – Seeds of shape
(n, 3). Seeds on or outside the wall return zero length andhittrue.wall – Object with
evaluate_xyz(xyz)(e.g.SurfaceClassifier) or a callablewall(xyz), positive inside the wall and zero on it.max_length – Cap on the length followed in each direction.
tolerance – Relative and absolute integration and root-finding tolerance.
max_steps – Maximum adaptive steps per direction; a line that exhausts them returns
nanlength andhitfalse.
- Returns:
Dict with
lengths(n, 2)(forward, backward),connection_length(n,)(their sum),strike_points(n, 2, 3)(end points; the wall hit whenhitis true) andhit(n, 2)booleans.