Skip to content

Commit

Permalink
Tweaks to docs
Browse files Browse the repository at this point in the history
  • Loading branch information
landreman committed Oct 4, 2023
1 parent b03fa7d commit e2a7649
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 18 deletions.
8 changes: 8 additions & 0 deletions docs/source/simsopt.geo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ simsopt.geo.curverzfourier module
:undoc-members:
:show-inheritance:

simsopt.geo.curveplanarfourier module
-------------------------------------

.. automodule:: simsopt.geo.curveplanarfourier
:members:
:undoc-members:
:show-inheritance:

simsopt.geo.curvexyzfourier module
----------------------------------

Expand Down
26 changes: 15 additions & 11 deletions examples/2_Intermediate/stage_two_optimization_planar_coils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#!/usr/bin/env python
r"""
This coil optimization script is similar to stage_two_optimization.py. However
in this version, the coils are constrained to be planar, by using the curve type
CurvePlanarFourier. Also the LinkingNumber objective is used to prevent coils
from becoming topologically linked with each other.
In this example we solve a FOCUS like Stage II coil optimisation problem: the
goal is to find coils that generate a specific target normal field on a given
surface. In this particular case we consider a vacuum field, so the target is
Expand All @@ -12,6 +17,7 @@
+ DISTANCE_WEIGHT * MininumDistancePenalty(DISTANCE_THRESHOLD)
+ CURVATURE_WEIGHT * CurvaturePenalty(CURVATURE_THRESHOLD)
+ MSC_WEIGHT * MeanSquaredCurvaturePenalty(MSC_THRESHOLD)
+ LinkingNumber
if any of the weights are increased, or the thresholds are tightened, the coils
are more regular and better separated, but the target normal field may not be
Expand All @@ -25,15 +31,14 @@
from pathlib import Path
import numpy as np
from scipy.optimize import minimize
from simsopt.objectives import Weight
from simsopt.geo import SurfaceRZFourier
from simsopt.objectives import SquaredFlux
from simsopt.objectives import QuadraticPenalty
from simsopt.geo import curves_to_vtk, create_equally_spaced_planar_curves
from simsopt.field import BiotSavart
from simsopt.field import Current, coils_via_symmetries
from simsopt.geo import CurveLength, CurveCurveDistance, \
MeanSquaredCurvature, LpCurveCurvature, CurveSurfaceDistance, LinkingNumber
from simsopt.field import BiotSavart, Current, coils_via_symmetries
from simsopt.geo import (
CurveLength, CurveCurveDistance,
MeanSquaredCurvature, LpCurveCurvature, CurveSurfaceDistance, LinkingNumber,
SurfaceRZFourier, curves_to_vtk, create_equally_spaced_planar_curves,
)
from simsopt.objectives import Weight, SquaredFlux, QuadraticPenalty
from simsopt.util import in_github_actions

# Number of unique coil shapes, i.e. the number of coils per half field period:
# (Since the configuration has nfp = 2, multiply by 4 to get the total number of coils.)
Expand Down Expand Up @@ -70,8 +75,7 @@
MSC_WEIGHT = 1e-6

# Number of iterations to perform:
ci = "CI" in os.environ and os.environ['CI'].lower() in ['1', 'true']
MAXITER = 50 if ci else 400
MAXITER = 50 if in_github_actions else 400

# File for the desired boundary magnetic surface:
TEST_DIR = (Path(__file__).parent / ".." / ".." / "tests" / "test_files").resolve()
Expand Down
1 change: 1 addition & 0 deletions examples/run_serial_examples
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ set -ex
./2_Intermediate/QSC.py
./2_Intermediate/boozer.py
./2_Intermediate/stage_two_optimization.py
./2_Intermediate/stage_two_optimization_planar.py
./2_Intermediate/stage_two_optimization_stochastic.py
./2_Intermediate/stage_two_optimization_finite_beta.py
./2_Intermediate/strain_optimization.py
Expand Down
2 changes: 2 additions & 0 deletions src/simsopt/geo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .curvexyzfourier import *
from .curveperturbed import *
from .curveobjectives import *
from .curveplanarfourier import *
from .framedcurve import *
from .finitebuild import *
from .plotting import *
Expand All @@ -28,6 +29,7 @@
__all__ = (curve.__all__ + curvehelical.__all__ +
curverzfourier.__all__ + curvexyzfourier.__all__ +
curveperturbed.__all__ + curveobjectives.__all__ +
curveplanarfourier.__all__ +
finitebuild.__all__ + plotting.__all__ +
boozersurface.__all__ + qfmsurface.__all__ +
surface.__all__ +
Expand Down
26 changes: 19 additions & 7 deletions src/simsopt/geo/curveplanarfourier.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,27 @@

class CurvePlanarFourier(sopp.CurvePlanarFourier, Curve):
r"""
``CurvePlanarFourier`` is a curve that is represented by a polar coordinate fourier serires, a rotation quaternion, and a center point following the form:
``CurvePlanarFourier`` is a curve that is represented by a polar coordinate
Fourier serires, a rotation quaternion, and a center point following the
form:
.. math::
r(\phi) &= \sum_{m=0}^{\text{order}} r_{c,m}\cos(n_{\text{fp}} m \phi) + \sum_{m=1}^{\text{order}} r_{s,m}\sin(n_{\text{fp}} m \phi)
\bf{q} &= [q_0,q_i,q_j,q_k] &= [\cos(\theta / 2), \hat{x}\sin(\theta / 2), \hat{y}\sin(\theta / 2), \hat{z}\sin(\theta / 2)]
where :math:'\theta' is the counterclockwise rotation about a unit axis :math:'(\hat{x},\hat{y},\hat{z})'.
The quaternion is normalized for calculations to prevent scaling. The dofs themselves are not normalized. This results in a redundancy in the optimization,
where several different sets of dofs may correspond to the same normalized quaternion.
Normalizing the dofs directly would create a dependence between the quaternion dofs, which may cause issues during optimization.
r(\phi) &= \sum_{m=0}^{\text{order}} r_{c,m}\cos(m \phi) + \sum_{m=1}^{\text{order}} r_{s,m}\sin(m \phi)
\bf{q} &= [q_0,q_i,q_j,q_k]
&= [\cos(\theta / 2), \hat{x}\sin(\theta / 2), \hat{y}\sin(\theta / 2), \hat{z}\sin(\theta / 2)]
where :math:`\theta` is the counterclockwise rotation about a unit axis
:math:`(\hat{x},\hat{y},\hat{z})`.
The quaternion is normalized for calculations to prevent scaling. The dofs
themselves are not normalized. This results in a redundancy in the
optimization, where several different sets of dofs may correspond to the
same normalized quaternion. Normalizing the dofs directly would create a
dependence between the quaternion dofs, which may cause issues during
optimization.
The dofs are stored in the order
Expand Down

0 comments on commit e2a7649

Please sign in to comment.