Equilibrium API
As its name suggests, the Equilibrium class manages all information for a QS equilibrium or magnetic field. For the definition of quantities, see the sections on unknowns and free parameters.
Class attributes
self.unknown : {string:ChiPhiEpsFunc} (dict of traced)
All unknowns solved by pyAQSC. Contains keys:
'X_coef_cp' : ChiPhiEpsFunc- . At even order at all time.'Y_coef_cp' : ChiPhiEpsFunc- . At even order at all time.'Z_coef_cp' : ChiPhiEpsFunc- . At even order at all time.'B_psi_coef_cp' : ChiPhiEpsFunc- . At even order at all time.'B_theta_coef_cp' : ChiPhiEpsFunc- . At even order at all time.'p_perp_coef_cp' : ChiPhiEpsFunc- . At even order at all time.'Delta_coef_cp' : ChiPhiEpsFunc- . At even order at all time.
self.constant : {string:ChiPhiEpsFunc or ChiPhiFunc} (dict of traced)
All constants (inputs or calculated from inputs). Contains keys:
'B_denom_coef_c' : ChiPhiEpsFunc- . At even order at all time.'B_alpha_coef' : ChiPhiEpsFunc- . At order at all time.'iota_coef' : ChiPhiEpsFunc- . At order at all time.'kap_p' : ChiPhiFunc- .'dl_p' : float- .'tau_p' : ChiPhiFunc- .
self.axis_info : {string:jax.numpy.array} (dict of traced)
Axis information, not used in further iteration. The naming convention is the same as in pyQSC. Contains keys:
'phi_gbc' : array- The Boozer toroidal angle on a uniformly spaced grid of cylindrical toroidal angle .'Phi0' : array- , the axis shape in cylindrical coordinate. A uniformly spaced grid of cylindrical toroidal angle .'R0' : array- , the axis shape in cylindrical coordinate.'Z0' : array- , the axis shape in cylindrical coordinate.'R0p' : array- .'Z0p' : array- .'R0pp' : array- .'Z0pp' : array- .'R0ppp' : array- .'Z0ppp' : array- .'d_l_d_phi' : array- , rate of change of axis length w.r.t. the cylindrical toroidal angle .'axis_length' : array- Total axis length.'curvature' : array- Curvature in cylindrical coordinate.'torsion' : array- Torsion in cylindrical coordinate.'tangent_cylindrical' : array- Components of the unit tangent vector in cylindrical coordinate.'normal_cylindrical' : array- Components of the unit normal vector in cylindrical coordinate.'binormal_cylindrical' : array- Components of the unit binormal vector in cylindrical coordinate.
self.nfp : int (static)
The number of field period of an equilibrium
self.magnetic_only : bool (static)
Iteration mode. When set to False (default), is a QS equilibrium with anisotropic pressure. When set to True, is a QS magnetic field without force balance.
Constructor
Instead of the constructor, we recommend creating equilibria using aqsc.leading_orders() (see iteration API).
aqsc.Equilibrium(unknown, constant, nfp, magnetic_only, axis_info={})
Parameters:
self.unknown : {string:ChiPhiEpsFunc}(dict of traced) .self.constant : {string:ChiPhiEpsFunc or ChiPhiFunc}(dict of traced)self.axis_info : {string:jax.numpy.array}(dict of traced)self.nfp : int(static)self.magnetic_only : bool(static)
from_known(X_coef_cp, Y_coef_cp, Z_coef_cp, B_psi_coef_cp, B_theta_coef_cp, B_denom_coef_c, B_alpha_coef, kap_p, dl_p, tau_p, iota_coef, p_perp_coef_cp, Delta_coef_cp, axis_info={}, magnetic_only=False )
Constructs an equilibrium from known quantities. Does not check order consistency, nfp, grid number or whether the known quantities obey the ordered governing equations. We recommend creating equilibria using aqsc.leading_orders() (see Quick start).
Parameters:
X_coef_cp : ChiPhiEpsFunc- . Must be even order .Y_coef_cp : ChiPhiEpsFunc- . Must be even order .Z_coef_cp : ChiPhiEpsFunc- . Must be even order .B_psi_coef_cp : ChiPhiEpsFunc- . Must be even order .B_theta_coef_cp : ChiPhiEpsFunc- . Must be even order .B_denom_coef_c : ChiPhiEpsFunc- . Must be even order .B_alpha_coef : ChiPhiEpsFunc- . Must be order .kap_p : ChiPhiFunc- .dl_p : float- .tau_p :- .iota_coef : ChiPhiEpsFunc- . Must be order .p_perp_coef_cp : ChiPhiEpsFunc- . Must be even order .Delta_coef_cp : ChiPhiEpsFunc- . Must be even order .axis_info : ChiPhiEpsFunc- Axis information calculated byaqsc.leading_orders(). Not used in further iteration. Can be left blank.magnetic_only : ChiPhiEpsFunc- Whether the iteration is magnetic-only.Falseby default.
Functions for saving and loading
aqsc.Equilibrium.save(file_name)
Saves self as a .npy file.
Parameters:
file_name : str- The name of the save file (without extension).
aqsc.Equilibrium.load(file_name)
Loads from a .npy file created by aqsc.Equilibrium.save().
Parameters:
file_name : str- The name of the save file (with extension). Returns:- An
aqsc.Equilibrium.
aqsc.Equilibrium.save_plain(self, file_name)
Saves self as a .npy file. This .npy file contains a dict of list's from aqsc.ChiPhiEpsFunc.to_content_list() and does not require pyAQSC to load.
Parameters:
file_name : str: The name of the save file (without extension).
aqsc.Equilibrium.load_plain(filename)
Loads from a .npy file created by aqsc.Equilibrium.save_plain().
Parameters:
file_name : str- The name of the save file (without extension). Returns:- An
aqsc.Equilibrium.
Functions for calculating physical quantities
aqsc.Equilibrium.contravariant_basis_eps(n_max=float('inf'))
Calculates the contravariant basis of the equilibrium's GBC:
Parameters:
n_max(static) - Maximum order to evaluate to.
Returns:
deps_r_x-ChiPhiEpsFunc, the component ofdeps_r_y-ChiPhiEpsFunc, the ...deps_r_z-ChiPhiEpsFunc, the ...dchi_r_x-ChiPhiEpsFunc, the component ofdchi_r_y-ChiPhiEpsFunc, the ...dchi_r_z-ChiPhiEpsFunc, the ...dphi_r_x-ChiPhiEpsFunc, the component ofdphi_r_y-ChiPhiEpsFunc, the ...dphi_r_z-ChiPhiEpsFunc, the ...
aqsc.Equilibrium.jacobian(n_max=float('inf'))
aqsc.Equilibrium.jacobian_eps(n_max=float('inf'))
aqsc.Equilibrium.jacobian_nae(n_max=float('inf'))
Calculates - , - , - .
The difference between and increases at increasing . We strongly recommend evaluating at self.axis_info['phi_gbc'] to reduce interpolation error.
Parameters:
n_max(static) - Maximum order to evaluate to.
Returns:
jacobian : ChiPhiEpsFunc
aqsc.Equilibrium.covariant_basis_eps_j_eps(n_max=float('inf'))
aqsc.Equilibrium.covariant_basis_j_eps(n_max=float('inf'))
Calculates the covariant basis of the equilibrium's GBC, multiplied with : - -
We implemented this rather than the covariant basis because this can be represented by a power-Fourier series (or equivalently, a ChiPhiEpsFunc), but the covariant basis cannot.
is special because it is also the flux surface integral Jacobian.
Parameters:
n_max(static) - Maximum order to evaluate to.
Returns:
- j_eps_grad_eps_x or j_eps_grad_psi_x - ChiPhiEpsFunc, the component of or
- j_eps_grad_eps_y or j_eps_grad_psi_y - ChiPhiEpsFunc, the ...
- j_eps_grad_eps_z or j_eps_grad_psi_z - ChiPhiEpsFunc, the ...
- j_eps_grad_chi_x - ChiPhiEpsFunc, the component of
- j_eps_grad_chi_y - ChiPhiEpsFunc, the ...
- j_eps_grad_chi_z - ChiPhiEpsFunc, the ...
- j_eps_grad_phi_x - ChiPhiEpsFunc, the component of
- j_eps_grad_phi_y - ChiPhiEpsFunc, the ...
- j_eps_grad_phi_z - ChiPhiEpsFunc, the ...
aqsc.Equilibrium.volume_integral(y, n_max=float('inf'))
Calculates the volume integral of a scalar, ChiPhiFunc, or ChiPhiEpsFunc. Produces a ChiPhiEpsFunc with only dependence.
Parameters:
y(traced) - quantity to integrate.n_max(static) - Maximum order to evaluate to.
Returns:
ChiPhiEpsFunc- The volume integral as a function of .
aqsc.Equilibrium.get_psi_crit(n_max=float('inf'), n_grid_chi=100, n_grid_phi_skip=10, psi_init=None, maxiter=100, tol=1e-8)
Estimates the critical or where flux surface self-intersects
by numerically the smallest or with . Uses bisection. This function evaluates the Jacobian on a grid of and to find the minimum. The grid has n_grid_chi uniformly spaced points, and the \phi grid takes every n_grid_phi_skip element from self.axis_info['phi_gbc'] to reduce interpolation error.
This function can be slow to JIT compile. When good accuracy is not required, reducing n_newton_iter, n_grid_chi and increasing n_grid_phi_skip can substantially increase the compile speed.
JIT compiling the function setting eps_cap as traced will not cause errors, but it increases compile time and is not recommended.
Parameters:
-
n_max(static) - maximum order to evaluate coordinate transformation to. -
n_grid_chi, n_grid_phi : int(static) - Grid size to evaluate Jacobian on. The critical point occurs when . -
psi_init = None(static) - Initial guess for . By default, uses . -
maxiter = 50 : int(static) - Maximum number of steps in Newton's method. -
tol = 1e-8 : float(traced) - Tolerance for solving .
Returns:
(psi_crit, jacobian_residue, n_iter). The , the at , and the number of iterations performed.
aqsc.Equilibrium.B_vec_j_eps(self)
Calculates the components of using:
and aqsc.Equilibrium.covariant_basis_j_eps().
We implemented this rather than because this can be represented by a power-Fourier series (or equivalently, a ChiPhiEpsFunc), but cannot.
Returns:
j_eps_B_x, j_eps_B_y, j_eps_B_zasChiPhiEpsFuncs.
aqsc.Equilibrium.flux_to_frenet(psi, chi, phi, n_max=float('inf'))
aqsc.Equilibrium.flux_to_xyz(psi, chi, phi, n_max=float('inf'))
aqsc.Equilibrium.flux_to_cylinder(psi, chi, phi, n_max=float('inf'))
Vectorized functions that transforms points in the flux coordinte into points in the Frenet coordinate , Cartesian coordinate , or cylindrical coordinate using the self-consistently solved coordinate transformations . ( here is the inverse coordinate transform from the GBC to the Frenet frame, and is unrelated to in the cylindrical coordinate. See background for more.)
We strongly advise evaluating the coordinate transformation on phi=self.axis_info['phi_gbc'] to decrease interpolation error due to interpolation!
Parameters:
psi, chi, phi : array or scalar(traced) - Points in the flux coordinate.n_max : scalar(static) - Max order of the inverse coordinate transform to use. If larger than the highest known order, uses all known orders. By default uses all known orders.
Returns:
- 3
jnp.arrays.(curvature, binormal, tangent)or(x, y, z)
aqsc.Equilibrium.frenet_basis_phi(phi=None)
A vectorized function that evaluates the axis shape and Frenet basis in the cylindrical coordinate at a given . By default, phi is None, and the method uses self.axis_info['phi_gbc'] as evaluation points to minimize interpolation error.
Parameters:
phi : array or scalar(traced) - The toroidal angle on axis.
Returns:
phi : jnp.array- The phi grid points. Returns the input if it is notNone. Otherwise, retrnsself.axis_info['phi_gbc'].axis_r0_phi_x : jnp.arrayaxis_r0_phi_y : jnp.arrayaxis_r0_phi_z : jnp.arraytangent_phi_x : jnp.arraytangent_phi_y : jnp.arraytangent_phi_z : jnp.arraynormal_phi_x : jnp.arraynormal_phi_y : jnp.arraynormal_phi_z : jnp.arraybinormal_phi_x : jnp.arraybinormal_phi_y : jnp.arraybinormal_phi_z : jnp.array
Functions for output
aqsc.Equilibrium.get_order()
Gets the highest known order of self.
Returns:
- An int .
aqsc.Equilibrium.get_helicity()
Gets the helicity of self, same as the number of rotation of the normal
basis vector in the Frenet basis.
Returns:
- An int .
aqsc.Equilibrium.check_order_consistency()
Checks whether all items in self.unknown and self.constant has consistent highest known order. If not, throws AttributeError's. Cannot be JIT compiled.
aqsc.Equilibrium.check_governing_equations(n_unknown:int, normalize:bool=True)
Evaluates the residual (LHS-RHS) of all governing equations at a given order. The results should be as close to 0 as possible.
Parameters:
n_unknown : int(static) - Order to evaluate residuals at.normalize : bool(static) - Whether to normalize the maximum magnitude.
Returns:
J : ChiPhiFunc(traced) - The residual of the Jacobian equation. Normalized by:Cb : ChiPhiFunc(traced) - The residual of the co/contravariant equation's tangent component. Normalized by:Ck : ChiPhiFunc(traced) - The residual of the co/contravariant equation's normal component. Normalized by:Ct : ChiPhiFunc(traced) - The residual of the co/contravariant equation's binormal component Normalized by:I : ChiPhiFunc(traced) - The residual of the force balance equation I. (See Ref.2) Normalized by:II : ChiPhiFunc(traced) - The residual of the force balance equation II. Normalized by:III : ChiPhiFunc(traced) - The residual of the force balance equation III. Normalized by:
aqsc.Equilibrium.display_order(n:int)
Plots all quantities at order . By default, display flux surfaces up to .
Parameters:
n : int- Order to plot.
aqsc.Equilibrium.display(psi_max=None, n_max=float('inf'), n_fs=5)
aqsc.Equilibrium.display_wireframe(psi_max=None, n_max=float('inf'))
Plots a boundary with given and some additional features. By default, plots the surface.
Parameters:
psi_max : float- Max to plot to.n_max : float- Max order to plot to.n_fs- Number of flux surfaces to plot.
Returns:
(fig, ax)