Releases: PlasmaControl/DESC
Releases · PlasmaControl/DESC
v0.13.0
New Features
- Adds function
solve_regularized_surface_current
todesc.magnetic_fields
module that implements the REGCOIL algorithm (Landreman, (2017)) for surface current normal field optimization, which can run on both CPUs and GPUs.- Can specify the tuple
current_helicity=(M_coil, N_coil)
to determine if resulting contours correspond to helical topology (both(M_coil, N_coil)
not equal to 0), modular (N_coil
equal to 0 andM_coil
nonzero) or windowpane/saddle (M_coil
andN_coil
both zero) M_coil
is the number of poloidal transits a coil makes before returning to itself, whileN_coil
is the number of toroidal transits a coil makes before returning to itself (this is sort of like the QShelicity
)- if multiple values of the regularization parameter are input, will return a family of surface current fields (as a list) corresponding to the solution at each regularization value
- Can specify the tuple
- Adds method
to_CoilSet
toFourierCurrentPotentialField
which implements a coil cutting algorithm to discretize the surface current into coils- works for both modular and helical coils
- Adds a new objective
SurfaceCurrentRegularization
(which minimizesw*|K|
, the regularization term from surface current in the REGCOIL algorithm, withw
being the objective weight which act as the regularization parameter)- use of both this and the
QuadraticFlux
objective allows for REGCOIL solutions to be obtained through the optimization framework, and combined with other objectives as well.
- use of both this and the
- Adds a new tutorial showing how to use
REGCOIL
features, as well as a new section in the stage two optimization notebook using REGCOIL to obtain an initial guess for filamentary coil optimization. - Adds
from_input_file
method toEquilibrium
class to generate anEquilibrium
object with boundary, profiles, resolution and flux specified in a given DESC or VMEC input file - Adds
SurfaceQuadraticFlux
objective which minimizes the quadratic magnetic flux through aFourierRZToroidalSurface
object, allowing for optimizing for Quadratic flux minimizing (QFM) surfaces. - Allows
ToroidalFlux
objective to acceptFourierRZToroidalSurface
so it can be used to specify the toroidal flux through a QFM surface. - Adds
eq_fixed
flag toToroidalFlux
to allow for the equilibrium/QFM surface to vary during optimization, useful for single-stage optimizations. - Adds tutorial notebook showcasing QFM surface capability.
- Adds
rotate_zeta
function todesc.compat
to rotate anEquilibrium
around Z axis.
Minor Changes
- Changes local area weighting of Bn in
QuadraticFlux
objective to be the square root of the local area element (Note that any existing optimizations using this objective may need different weights to achieve the same result now.) - Adds an
NFP
attribute toScalarPotentialField
,VectorPotentialField
andDommaschkPotentialField
, to allowSplineMagneticField.from_field
andMagneticField.save_mgrid
to efficiently take advantage of the discrete toroidal symmetry of these fields, if present. - Adds support for
numpy
version2.0.0
- Various improvements to optimization algorithms for improving performance of equilibrium solving and optimization, especially on GPUs.
Bug Fixes
- Fixes bug that occurs when taking the gradient of
root
androot_scalar
with newer versions of JAX (>=0.4.34) and unpins the JAX version. - Changes
FixLambdaGauge
constraint to now enforce zero flux surface average for lambda, instead of enforcing lambda(rho,0,0)=0 as it was incorrectly doing before. - Fixes bug in
softmin/softmax
implementation. - Fixes bug that occurred when using
ProximalProjection
with a scalar optimization algorithm. - Fixes bug where
from desc.plotting import *
would not importdesc.plotting.poincare_plot
Full Changelog: v0.12.3...v0.13.0
v0.12.3
What's Changed
- Add
jac_chunk_size
keyword argument toObjectiveFunction
to reduce memory usage of forward mode Jacobian calculation , see docs for more details - Add objective using for Ideal-Ballooning Stability, see related paper for more details.
- Make naming of grids kwargs among free boundary objectives more uniform
- Add kwarg options to plot 3d without any axis visible
- Pin jax version temporarily to avoid JAX-related bug
Bug Fixes
- Fix error that can occur when
get_NAE_constraints
is called for only fixing the axis - bug fix for
most_rational
with negative arguments - fix bug. in
FixOmniBMax
New Contributors
- @lisamessier made their first contribution in #1269
- @missing-user made their first contribution in #1274
- @felicia22 made their first contribution in #1284
Full Changelog: v0.12.2...v0.12.3
v0.12.2
What's Changed
- Add Vector Potential Calculation to
Coil
classes and MostMagneticField
Classes - Add automatic intersection checking to
CoilSet
objects, and a methodis_self_intersecting
which check if the coils in theCoilSet
intersect one another. - Add
flip_theta
compatibility function to switch the zero-point of the poloidal angle between the inboard/outboard side of the plasma. - Change field line integration to use
diffrax
package instead of the deprecatedjax.experimental.odeint
function, allowing for specifying the integration method, the step-size used, and more. See the documentation offield_line_integrate
anddiffrax
for more details. - Add
use_signed_distance
keyword toPlasmaVesselDistance
objective to allow for specifying the desired relative position of the plasma and surface. - Vectorize Boozer transform over multiple surfaces, to allow for calculation of Boozer-related quantities on grids that contain multiple radial surfaces.
- Optimizer now automatically scales linearly-constrained optimization parameters to be of roughly the same magnitude, to improve optimization when parameter values range many orders of magnitude
- Add
HermiteSplineProfile
class, which allows for profile derivative information to be specified along with profile value information. - Add installation instructions for RAVEN cluster at IPP to the docs
- Change optimizer printed output to be easier to read
- Add
HeatingPower
andFusionPower
objectives - Reduce
QuadratureGrid
number of radial points to match its intended functionality - Fix some plotting issues that arose when NFP differs from 1 for objects, or when passed-in phi exceeds 2pi/nfp
- Update
VMECIO
to allow specification of Nyquist spectrum and fix some bugs with asymmetric wout files - The code no longer mods non-periodic angles (such as the field line label
$\alpha$ ) by$2\pi$ , as in field-line-following contexts, functions may not be periodic in these angles.
Full Changelog: v0.12.1...v0.12.2
v0.12.1
What's Changed
- Optimizers now default to use QR factorization for least squares which is much faster
especially on GPU. - Fix bug when reading VMEC input ZAXIS as ZAXIS_CS
- Some fixes/improvements for computing quantities along a fieldline.
- Adds compute quantities for PEST coordinate system basis vectors
- Many init methods now default to running on CPU, even when GPU is enabled, as CPU was found
to be much faster for these cases. - New objectives
desc.objectives.FixNearAxis{R,Z,Lambda}
for fixing near axis behavior. - Adds
from_values
method that was present inFourierRZCurve
but missing inFourierRZCoil
- Adds new
from_values
method forFourierPlanarCurve
andFourierPlanarCoil
Full Changelog: v0.12.0...v0.12.1
v0.12.0
New Features
- Coil optimization is now possible in DESC using various filamentary coils. This includes
a number of new objectives:desc.objectives.QuadraticFlux
desc.objectives.ToroidalFlux
desc.objectives.CoilLength
desc.objectives.CoilCurvature
desc.objectives.CoilTorsion
desc.objectives.CoilCurrentLength
desc.objectives.CoilSetMinDistance
desc.objectives.PlasmaCoilSetMinDistance
desc.objectives.FixCoilCurrent
desc.objectives.FixSumCoilCurrent
- Add Normal Field Error
"B*n"
as a plot quantity todesc.plotting.{plot_2d, plot_3d}
. - New function
desc.plotting.poincare_plot
for creating Poincare plots by tracing
field lines from coils or other external fields. - New profile type
desc.profiles.TwoPowerProfile
. - Add
desc.geometry.FourierRZCurve.from_values
method to fit curve with data. - Add
desc.geometry.FourierRZToroidalSurface.from_shape_parameters
method for generating a surface
with specified elongation, triangularity, squareness, etc. - New class
desc.magnetic_fields.MagneticFieldFromUser
for user defined B(R,phi,Z). - All vector variables are now computed in toroidal (R,phi,Z) coordinates by default.
Cartesian (X,Y,Z) coordinates can be requested with the compute keywordbasis='xyz'
. - Add method
desc.coils.CoilSet.is_self_intersecting
, which checks if any coils
intersect each other in the coilset.
Minor changes
- Improved heuristic initial guess for
Equilibrium.map_coordinates
. - Add documentation for default grid and target/bounds for objectives.
- Add documentation for compute function keyword arguments.
- Loading a coilset from a MAKEGRID file will now return a nested
MixedCoilSet
if there
are coil groups present in the MAKEGRID file. - Users must now pass in spacing/weights to custom
Grid
s (the previous defaults were
often wrong, leading to incorrect results) - The
normal
andcenter
parameters of aFourierPlanarCurve
can now be specified
in either cartesian or cylindrical coordinates, as determined by thebasis
parameter. - Misc small changes to reduce compile time and memory consumption (more coming soon!)
- Linear constraint factorization has been refactored to improve efficiency and reduce
floating point error. desc.objectives.{GenericObjective, ObjectiveFromUser}
can now work with other objects
besides anEquilibrium
(such as surfaces, curves, etc.)- Improve warning for missing attributes when loading desc objects.
Bug Fixes
- Several small fixes to ensure things that should be
int
s areint
s - Fix incorrect toroidal components of surface basis vectors.
- Fix a regression in performance in evaluating Zernike polynomials.
- Fix errors in
Equilibrium.map_coordinates
for prescribed current equilibria. - Fix definition of
b0
in VMEC output. - Fix a bug where calling
Equilibrium.compute(..., data=data)
would lead to excessive
recalculation and potentially wrong results. - Fixes a bug causing NaN in reverse mode AD for
Omnigenity
objective. - Fix a bug where
"A(z)"
would be zero if the grid doesn't contain nodes at rho=1.
New Contributors
Full Changelog: v0.11.1...v0.12.0
v0.11.1
What's Changed
- Change default symmetry to
"sin"
for current potential fields created with thefrom_surface
method when the surface is stellarator symmetric - Add objectives for coil length, curvature and torsion
- Improve Dommaschk potential magnetic field fitting by adding NFP option to only use potentials with the desired periodicity
- Fix incorrect Jacobian when bounds constraints are used by adding explicit Jacobian of
compute_scaled_error
- Fix bug in Dommaschk potentials that arose when evaluating the potential at Z=0
- Fix bug in Dommaschk potential fitting when symmetry is set to true
- Bump black version from 22.10.0 to 24.3.0
Full Changelog: v0.11.0...v0.11.1
v0.11.0
New Features
- Adds functionality to optimize for omnigenity. This includes the
OmnigenousField
magnetic field class, theOmnigenity
objective function, and an accompanying tutorial. - Adds new objectives for free boundary equilibria:
BoundaryError
and
VacuumBoundaryError
, along with a new tutorial notebook demonstrating their usage. - Objectives
Volume
,AspectRatio
,Elongation
now work for
FourierRZToroidalSurface
objects as well asEquilibrium
. MagneticField
objects now have a methodsave_mgrid
for saving field data
in the MAKEGRID format for use with other codes.SplineMagneticField.from_mgrid
now defaults to usingextcur
from the mgrid file.- When converting a near axis solution from QSC/QIC to a desc
Equilibrium
, the
least squares fit is now weighted inversely with the distance from the axis to improve
the accuracy for low aspect ratio. - Adds a bounding box to the
field_line_integrate
defined bybounds_R
andbounds_Z
keyword arguments, which form a hollow cylindrical bounding box. If the field line
trajectory exits these bounds, the RHS will be multiplied by an exponentially decaying
function of the distance to the box to stop the trajectory and prevent tracing the field
line out to infinity, which is both costly and unnecessary when making a Poincare plot,
the principle purpose of the function. - Adds a new class
DommaschkPotentialField
which allows creation of magnetic fields based
off of the vacuum potentials detailed in Representations for Vacuum Potentials in Stellarators
https://doi.org/10.1016/0010-4655(86)90109-8.
Speed Improvements
CoilSet
is now more efficient when stellarator or field period symmetry is used.- Improves the efficiency of
proximal
optimizers by reducing the number of objective
derivative evaluations. Optimization steps should now be 2-5x faster. - Improved performance of Zernike polynomial evaluation.
- Adds a bounding box to the
field_line_integrate
defined bybounds_R
andbounds_Z
keyword arguments, which form a hollow cylindrical bounding box. If the field line
trajectory exits these bounds, the RHS will be multiplied by an exponentially decaying
function of the distance to the box to stop the trajectory and prevent tracing the
field line out to infinity, which is both costly and unnecessary when making a Poincare
plot, the principle purpose of the function.
Bug Fixes
- Fix bug causing NaN in
ForceBalance
objective when the grid contained nodes at
the magnetic axis. - When saving VMEC output,
buco
andbvco
are now correctly saved on the half
mesh. Previously they were saved on the full mesh. - Fixed a bug where hdf5 files were not properly closed after reading.
- Fixed bugs relating to
Curve
objects not being optimizable. - Fixed incorrect rotation matrix for
FourierPlanarCurve
. - Fixed bug where
plot_boundaries
with a singlephi
value would return an
empty plot.
Breaking Changes
- Renames the method for comparing equivalence between DESC objects from
eq
toequiv
to avoid confusion with the common shorthand forEquilibrium
. - Minimum Python version is now 3.9
v0.10.4
Equilibrium.map_coordinates
is now differentiable.- Removes method
Equilibrium.compute_flux_coordinates
as it is now redundant with the
more generalEquilibrium.map_coordinates
. - Allows certain objectives to target
FourierRZToroidalSurface
objects as well as
Equilibrium
objects, such asMeanCurvature
,PrincipalCurvature
, andVolume
. - Allow optimizations where the only object being optimized is not an
Equilibrium
object e.g. optimizing only aFourierRZToroidalSurface
object to have a certain
Volume
. - Many functions from
desc.plotting
now also work for plotting quantities from
Curve
andSurface
classes. - Adds method
FourierRZToroidalSurface.constant_offset_surface
which creates
a surface with a specified constant offset from the base surface. - Adds method
FourierRZToroidalSurface.from_values
to create a surface by fitting
(R,phi,Z) points, along with a user-defined poloidal angle theta which sets the poloidal
angle for the created surface - Adds new objective
LinearObjectiveFromUser
for custom linear constraints. elongation
is now computed as a function of zeta rather than a single global scalar.- Adds
beta_vol
andbetaxis
to VMEC output. - Reorder steps in
solve_continuation_automatic
to avoid finite pressure tokamak with
zero current. - Fix error in lambda o(rho) constraint for near axis behavior.
- Fix bug when optimizing with only a single constraint.
- Fix some bugs causing NaN in reverse mode AD for some objectives.
- Fix incompatible array shapes when user supplies initial guess for lagrange multipliers
for augmented lagrangian optimizers. - Fix a bug caused when optimizing multiple objects at the same time and the order of
the objects gets mixed up.
Full Changelog: v0.10.3...v0.10.4
v0.10.3
What's Changed
- Adds
deriv_mode
keyword argument to allObjective
s for specifying whether to
use forward or reverse mode automatic differentiation. - Adds
desc.compat.rescale
for rescaling equilibria to a specified size and field
strength. - Adds new keyword
surface_fixed
toPlasmaVesselDistance
objective which says
whether or not the surface comparing the distance from the plasma to is fixed or not.
If True, then the surface coordinates can be precomputed, saving on computation during
optimization. Set to False by default. - Adds objective function
desc.objectives.GoodCoordinates
for finding "good" (ie,
non-singular, non-degenerate) coordinate mappings for initial guesses. This is applied
automatically when creating a newEquilibrium
if the default initial guess of scaling
the boundary surface produces self-intersecting surfaces. This can be disabled by
passingensure_nested=False
when constructing theEquilibrum
. - Adds
loss_function
argument to allObjective
s for applying one of min/max/mean
to objective function values (for targeting the average value of a profile, etc). Equilibrium.get_profile
now allows user to choose a profile type (power series, spline, etc)- Fixes a bug preventing linear objectives like
FixPressure
from being used as bounds. - Updates to tutorials and example scripts
desc.interpolate
module has been deprecated in favor of theinterpax
package.- Utility functions like
desc.objectives.get_fixed_boundary_constraints
now no longer
require the user to specify which profiles the equilibrium has, they will instead be
inferred from the equilibrium argument.
New Contributors
Full Changelog: v0.10.2...v0.10.3
v0.10.2
What's Changed
- Updates
desc.examples
:NCSX
now has a fixed current profile. Previously it used a fixed iota based on a
fit, but this was somewhat inaccurate.QAS
has been removed as it is now redundant withNCSX
.ARIES-CS
has been scaled to the correct size and field strength.WISTELL-A
is now a true vacuum solution, previously it approximated the vacuum
solution with fixed rotational transform.- Flips sign of iota for
W7-X
andATF
to account for positive jacobian. - new example for
HSX
.
- Adds new compute quantities
"iota current"
and"iota vacuum"
to compute the
rotational transform contributions from the toroidal current and background field. - Adds ability to compute equilibria with anisotropic pressure. This includes a new
profile,Equilibrium.anisotropy
, new compute quantityF_anisotropic
, and a new
objectiveForceBalanceAnisotropic
. plot_3d
andplot_coils
have been updated to use Plotly as a backend instead of
Matplotlib, since Matplotlib isn't great for 3d plots, especially ones with multiple
overlapping objects in the scene. Main API differences:- Plotly doesn't have "axes" like Matplotlib does, just figures. So the
ax
argument has been replaced byfig
forplot_3d
andplot_coils
, and they no
longer returnax
. - Names of colormaps, line patterns, etc are different, so use caution when
specifying those usingkwargs
. Thankfully the error messages Plotly generates are
usually pretty informative and list the available options.
- Plotly doesn't have "axes" like Matplotlib does, just figures. So the
- Adds zeroth and first order NAE constraints on the poloidal stream function lambda,
accessible by passing infix_lambda=True
to theget_NAE_constraint
getter function. - Implements
CurrentPotentialField
andFourierCurrentPotentialField
classes,
which allow for computation of the magnetic field from a surface current density
given byK = n x grad(Phi)
wherePhi
is a surface current potential.CurrentPotentialField
allows for an arbitrary current potential functionPhi
FourierCurrentPotentialField
assumes the current potential function to
be of the form of a periodic potential (represented by aDoubleFourierSeries
)
and two secular terms, one each linear in the poloidal and in the toroidal angle.
- Small fixes to make VMEC IO stuff more robust against different profile types, input file formatting etc.
- Improve Biot-Savart discretization, add new methods for converting between coil types
New Contributors
- @YigitElma made their first contribution in #718
Full Changelog: v0.10.1...v0.10.2