This release introduces boozer surface and computation of aspect ratio of surfaces and some major refactoring of surfaces-related code.
**Major changes**:
1. SurfaceXYZFourier surfaces are introduced, where (phi, theta) correspond to the Boozer angles on the surface, by solving a nonlinear least squares problem in boozersurface.py.
2. minimizeBoozerScalarizedLBFGS solves a scalarized constrained optimization problem using LBFGS, where
min 0.5* || f(x) ||^2_2 + 0.5 * constraint_weight * (label - labeltarget)^2
+0.5*constraint_weight * (y(varphi=0,theta=0) -0)^2+0.5*constraint_weight * (z(varphi=0,theta=0) -0)^2
where || f(x)||^2_2 is the sum of squares of the Boozer residual at
a set of quadrature points.
The final two terms in the objective function are boundary conditions to ensure that the parametrization of the surface is unique.
3. minimizeBoozerScalarizedNewton solves the same scalarized constrained optimization problem as above, but instead of LBFGS, Newton's method is used.
4. minimizeBoozerConstrainedNewton solves the full constrained optimization problem using Newton's method.
min 0.5*|| f(x) ||^2_2
subject to
label - labeltarget = 0
y(varphi=0,theta=0) - 0 = 0
z(varphi=0,theta=0) - 0 = 0
The user is free to choose either a geometric constraint, e.g. area, or a toroidal flux constraint.
objectives.py is split into coilobjectives.py and surfaceobjectives.py
5. Computation of aspect ratio of surfaces using the VMEC definition of aspect ratio is done in the Surface.aspect_ratio.
6. New capability of computing cross-sections of surfaces at a given cylindrical angle. This is done using bisection in the Surface.cross_section.
7. An implementation of SurfaceXYZFourier.to_RZFourier using Surface.cross_section. This is done by computing cross-sections of the SurfaceXYZFourier object and then fitting a SurfaceRZFourier to those cross-sections.