PlasmaControl / DESC

Stellarator Equilibrium and Optimization Suite
MIT License
94 stars 27 forks source link

finite-build coils #1169

Open ddudt opened 1 month ago

ddudt commented 1 month ago

We need to decide on a class structure for finite-build coils. There are several categories of coil classes that we might want to support:

Possible ideas we discussed:

  1. Add new width/height attributes to the existing _Coil class, which could default to 0/None. Non-planar coils will also have to add a winding angle attribute. Then each coil class could have it's own implementation for finite-build stuff. This prevents needing to add any new classes, but is maybe not the cleanest object-oriented design.
  2. Add a new _FiniteBuildCoil class. Then there would be new classes that inherit from this and the existing coil classes. This keeps the filamentary coils separate, but adds a lot of new classes to keep track of.
  3. Add a new _CrossSection ABC with circular and rectangular options. Similar to the previous option, new coil classes will inherit from these new classes and the existing coil classes. This gives a lot of flexibility, but might be excessive.

Other ideas?

ryanwu4 commented 1 month ago

The finite build coil computation would be be an implementation of these papers by Hurtwitz et. al and Landreman et. al:

An existing Julia implementation of the finite build rectangular cross section method is here.

dpanici commented 1 month ago
dpanici commented 1 month ago

@ryanwu4 @ddudt We should have a solution for the twist angle as well, so we don't implement the single thing for planar coils

ryanwu4 commented 1 month ago

Regarding twist angle, I think the approach in Singh et. al 2020 has been used in the original Julia implementation for finding a coordinate frame for this.

Specifically, Section 3.1 of that paper would define the coil centroid coordinate frame at each coil point, and we can initialize the FiniteBuildCoil object with a $\alpha_n$ vector with corresponding Fourier modes such that the rotation vector $\alpha$ at each $\phi$ represents the rotation of the winding pack cross section within that coordinate frame at the corresponding value of $\phi$ (Section 3.3).

f0uriest commented 4 weeks ago

Another thought: how useful are circular cross sections in practice? Do people use them? Would just rectangular be enough? (I would assume rectangular is closer to reality?)

ryanwu4 commented 3 weeks ago

I'm starting with implementing just the rectangular cross section coils, but I think I'll leave the functionality open for circular cross sections since the formulas have been derived there anyways.

dpanici commented 3 weeks ago

Notes from meeting with Paul:

ryanwu4 commented 2 weeks ago

Regarding the first and third points, it almost sounds like the winding angle feature would be implemented separately from the finite build coil feature in that case? Should that be something else that the FiniteBuildCoil inherits from?

f0uriest commented 2 weeks ago

Yeah, I think the order would be something like

Coil(MagneticField): # base class
FramedCoil(Coil): # coil plus rotating reference frame, but no width/height - still filamentary
FiniteBuildCoil(FramedCoil): # as above but with width/height of winding pack
f0uriest commented 2 weeks ago

also here's some ideas from last week:

"""
A winding pack is defined by a width (w) and height (h), centered around a 
filamentary curve (x), carrying a total current Itot

           ^ e_2
           |
           |

  x10      w       x11
    |---------------|
    | *  *  *  *  * |
  h | *  *  x  *  * |  --> e_1
    | *  *  *  *  * |
    |---------------|
  x00              x01

The x coordinate of the winding pack is the centerline, parameterized by a fourier 
series or spline
the xij coordinates define the corners of the winding pack

x00 = x - h/2 e_2 - w/2 e_1
x10 = x + h/2 e_2 - w/2 e_1
x01 = x - h/2 e_2 + w/2 e_1
x11 = x + h/2 e_2 + w/2 e_1

where e_1 and e_2 are the normal and binormal basis vectors in the rotating 
reference frame about the centerline (eg frenet seret, or centroid frame 
is usually smoother). Using the corner coordinates we can easily 
discretize the finite build coil into polytopes (rectangular sections 
or tetrahedra).

For calculating magnetic fields, it is discretized into individual 
filaments (*) - nw in the width direction and nh in the height 
direction (in the example above, nw=5, nh=3), and integration over 
the cross section is done with gaussian quadrature (maybe lobatto 
if we want to include endpoints?). 

eg

y1, w1 = leggauss(nw)
y2, w2 = leggauss(nh)

B = biot_savart(x=(x + y2*h/2 e_2 + y1*w/2 e_1), 
                I=(I_tot*w1*w2))

(I feel like for uniform J in rectangular cross section there is an analytic answer for B?...)

"""