Toroidal surfaces object Define surfaces \(s(\vartheta, \zeta) \) and the angle transformations \( \theta (\vartheta, \zeta) \).
More...
|
| __init__ (self, nsurfaces=2, mpol=10, ntor=10, Nfp=1, stellar_sym=True) |
| Initialise the toroidal surface object.
|
|
| remove_surface (self, int i) |
| Remove a surface.
|
|
| add_surface (self, float rho, scn, tsn, ssn=None, tcn=None) |
| Adding a surface into the system with radial label rho.
|
|
| replace_surface (self, int idx, float rho=None, scn=None, tsn=None, ssn=None, tcn=None) |
| Replacing a surface by the new one.
|
|
| get_coords (self, sarr=[0], tarr=[0], zarr=[0], derivative=0, input1D=True) |
| Compute the coordinates and their derivatives given \(\rho, \vartheta, \zeta\).
|
|
| jacobi_transform (self, jacobi, CoordsOutput coords) |
| Compute the derivatives wrt the new coordinate given the derivatives in the old coordinates.
|
|
| metric_transform (self, g, CoordsOutput coords) |
| Compute the coordinate transformation for a metric tensor \(g_{ij}\) (lower!) (derivative computation under construction)
|
|
| contra_vector_transform (self, v, CoordsOutput coords, has_jacobian=False, derivative=False, dv=None) |
| Compute the coordinate transformation for a contravariant vector \(v^i\) (upper!)
|
|
| construct_interpolant (self, rhosurfs=None, method="cubic_spline", **kwargs) |
| Construct the interpolant between surfaces for the given method.
|
|
| plot (self, zeta=0, npoints=129, **kwargs) |
| Plot the surfaces.
|
|
| read_surfaces_from_file (self, filename="data.npz", Nfp=None) |
| Read the surfaces into a numpy array on disk.
|
|
| write_surfaces_to_file (self, filename="data.npz") |
| Save the surfaces into a numpy array on disk.
|
|
|
int | mpol = mpol |
| The poloidal mode number.
|
|
tuple | ntor = ntor |
| The toroidal mode number.
|
|
| Nfp = Nfp |
| The field period.
|
|
bool | sym = stellar_sym |
| Stellarator symmetry.
|
|
| nsurfaces = nsurfaces |
| Number of surfaces.
|
|
| rhosurfs = np.linspace(0, 1, nsurfaces) |
| The rho coordinate for each surface.
|
|
| scn = np.zeros([nsurfaces, mpol + 1, 2 * ntor + 1]) |
| The cosine coefficients of \(s\), dimension (#interfaces, mpol, 2*ntor+1)
|
|
| tsn = self.scn.copy() |
| The sine coefficients of \(\vartheta\), dimension (#interfaces, mpol, 2*ntor+1)
|
|
| ssn = self.tsn.copy() |
| The sine coefficients of \(s\), dimension (#interfaces, mpol, 2*ntor+1)
|
|
| tcn = self.tsn.copy() |
| The cosine coefficients of \(\vartheta\), dimension (#interfaces, mpol, 2*ntor+1)
|
|
str | _tcn_int = "pchip": |
|
int | tsn = 4: |
|
|
| _mlist = np.arange(0, self.mpol + 1) |
|
tuple | _nlist |
|
| _scn_int = CubicSpline(rhosurfs, self.scn, axis=0, **kwargs) |
| The radial interpolant for s cosine components.
|
|
| _tsn_int = CubicSpline(rhosurfs, self.tsn, axis=0, **kwargs) |
| The radial interpolant for theta sine components.
|
|
| _ssn_int = CubicSpline(rhosurfs, self.ssn, axis=0, **kwargs) |
| The radial interpolant for s sine components.
|
|
| _tcn_int = CubicSpline(rhosurfs, self.tcn, axis=0, **kwargs) |
| The radial interpolant for theta cosine components.
|
|
| _scn_d1 = self._scn_int.derivative(1) |
| The radial interpolant for s cosine components, first derivative.
|
|
| _scn_d2 = self._scn_int.derivative(2) |
| The radial interpolant for s cosine components, second derivative.
|
|
| _tsn_d1 = self._tsn_int.derivative(1) |
| The radial interpolant for theta sine components, first derivative.
|
|
| _tsn_d2 = self._tsn_int.derivative(2) |
| The radial interpolant for theta sine components, second derivative.
|
|
| _ssn_d1 = self._ssn_int.derivative(1) |
| The radial interpolant for s sine components,first derivative.
|
|
| _ssn_d2 = self._ssn_int.derivative(2) |
| The radial interpolant for s sine components, second derivative.
|
|
| _tcn_d1 = self._tcn_int.derivative(1) |
| The radial interpolant for theta cosine components, first derivative.
|
|
| _tcn_d2 = self._tcn_int.derivative(2) |
| The radial interpolant for theta cosine components, second derivative.
|
|
Toroidal surfaces object Define surfaces \(s(\vartheta, \zeta) \) and the angle transformations \( \theta (\vartheta, \zeta) \).
\(s, \vartheta\) are written in terms of Fourier harmonics
\[
s(\vartheta, \zeta) = \sum_{m=0}^{\text{mpol}}\sum_{n=-\text{ntor}}^{\text{ntor}}
s_{c,m,n} \cos(m \vartheta - n \text{N} \zeta) + s_{s,m,n} \sin(m \vartheta - n \text{N} \zeta),
\]
where \(N = \text{Nfp}\).
\[
\theta(\vartheta, \zeta) = \vartheta + \sum_{m=0}^{\text{mpol}}\sum_{n=-\text{ntor}}^{\text{ntor}}
\theta_{c,m,n} \cos(m \vartheta - n \text{N} \zeta) + \theta_{s,m,n} \sin(m \vartheta - n \text{N} \zeta).
\]
If stellarator symmetry is assumed, then \(s\) will only have cosine components and \(\theta \) will only have sine components.
Each surface is assigned a new radial label \(\rho_i\). Now a new set of coordinates \((\rho, \vartheta, \zeta)\) will be constructed given the relationship \(s(\rho, \vartheta, \zeta), \theta(\rho, \vartheta, \zeta)\). If \(\rho\) is not on one of the known surfaces, an interpolation will be performed on all the Fourier harmonics radially using the method of the user's choice.
pyoculus.problems.interpolate_coordinates.SurfacesToroidal.contra_vector_transform |
( |
| self, |
|
|
| v, |
|
|
CoordsOutput | coords, |
|
|
| has_jacobian = False, |
|
|
| derivative = False, |
|
|
| dv = None ) |
Compute the coordinate transformation for a contravariant vector \(v^i\) (upper!)
- Parameters
-
v | the vector \(v^i\) to be transformed, should have the dimension (3,...) |
coords | the output of get_coords, should match the dimension of v |
has_jacobian | if the given vector already contains the jacobian |
derivative | if the derivatives are needed or not. If True, dv is required. |
dv | the derivative of v wrt \((s,\theta,\zeta)\), have the dimension (3 derivatives, 3 component,...) |
- Returns
- voutput, dvoutput, the transformed metric and the derivative wrt \((\rho,\vartheta,\zeta)\)
The vector transformation is given by
\[
\left(\begin{array}{c}
v^{\rho} \\ v^{\vartheta} \\ v^{\zeta}
\end{array}\right)
= \mathbf{J}^{-1}
\left(\begin{array}{c}
v^{{s}} \\ v^{\theta} \\ v^{\zeta}
\end{array}\right),
\]
where
\[
\mathbf{J} = \frac{\partial(s,\theta,\zeta)}{\partial(\rho,\vartheta,\zeta)}
\]
is the Jacobi matrix. For computing the result we use matrix solve instead of matrix inversion.
When the derivative is needed, we note that
\[
\frac{\partial }{\partial \rho}\mathbf{J}
\left(\begin{array}{c}
v^{\rho} \\ v^{\vartheta} \\ v^{\zeta}
\end{array}\right)
+\mathbf{J}
\frac{\partial }{\partial \rho}\left(\begin{array}{c}
v^{\rho} \\ v^{\vartheta} \\ v^{\zeta}
\end{array}\right)
=
\frac{\partial }{\partial \rho}\left(\begin{array}{c}
v^{{s}} \\ v^{\theta} \\ v^{\zeta}
\end{array}\right),
\]
therefore
\[
\frac{\partial}{\partial \rho}\left(\begin{array}{c}
v^{\rho} \\ v^{\vartheta} \\ v^{\zeta}
\end{array}\right)
=
\mathbf{J}^{-1}
\left[\frac{\partial }{\partial \rho}\left(\begin{array}{c}
v^{{s}} \\ v^{\theta} \\ v^{\zeta}
\end{array}\right)
-\frac{\partial \mathbf{J}}{\partial\rho}
\left(\begin{array}{c}
v^{\rho} \\ v^{\vartheta} \\ v^{\zeta}
\end{array}\right)\right].
\]
Similarly we can compute the \(\vartheta\) and \(\zeta\) derivatives.
Now,
\[
\frac{\partial (v^{{s}}, v^{\theta}, v^{\zeta})}{\partial(\rho, \vartheta, \zeta)} =
\frac{\partial (v^{{s}}, v^{\theta}, v^{\zeta})}{\partial(s, \theta, \zeta)}
\times
\frac{\partial(s, \theta, \zeta)}{\partial(\rho, \vartheta, \zeta)}
\]
Summing up
\[
\frac{\partial ( v^{\rho}, v^{\vartheta}, v^{\zeta})}{\partial(\rho, \vartheta, \zeta)} =
\mathbf{J}^{-1} \cdot \frac{\partial (v^{{s}}, v^{\theta}, v^{\zeta})}{\partial(s, \theta, \zeta)} \cdot \mathbf{J}
- \mathbf{J}^{-1} \cdot (\mathbf{J}_\rho, \mathbf{J}_\vartheta, \mathbf{J}_\zeta) \cdot \left(\begin{array}{c}
v^{\rho} \\ v^{\vartheta} \\ v^{\zeta}
\end{array}\right)
\]
pyoculus.problems.interpolate_coordinates.SurfacesToroidal.jacobi_transform |
( |
| self, |
|
|
| jacobi, |
|
|
CoordsOutput | coords ) |
Compute the derivatives wrt the new coordinate given the derivatives in the old coordinates.
- Parameters
-
jacobi | the Jacobi matrix \(\partial(f_1, \cdots, f_N) / \partial (s,\theta,\zeta)\) |
coords | the output of get_coords, should match the dimension of J |
- Returns
- jacobi_output the transformed Jacobi matrix and the derivatives wrt \((\rho,\vartheta,\zeta)\)
Given \(N\) variables \(f_1, \cdots, f_N \), the jacobi matrix (derivatives wrt the new coordinate is given by the chain rule
\[
\frac{\partial(f_1, \cdots, f_N)}{\partial(\rho, \vartheta, \zeta)} = \frac{\partial(f_1, \cdots, f_N)}{\partial(s, \theta, \zeta)}
\cdot \frac{\partial(s, \theta, \zeta)}{\partial(\rho, \vartheta, \zeta)}
\]
pyoculus.problems.interpolate_coordinates.SurfacesToroidal.metric_transform |
( |
| self, |
|
|
| g, |
|
|
CoordsOutput | coords ) |
Compute the coordinate transformation for a metric tensor \(g_{ij}\) (lower!) (derivative computation under construction)
- Parameters
-
g | the metric \(g_{ij}\) of the old coordinate \((s,\theta,\zeta)\) to be transformed, should have the dimension (3,3,...) |
coords | the output of get_coords, should match the dimension of g |
- Returns
- goutput, [dgoutput], the transformed metric and the derivative wrt \((\rho,\vartheta,\zeta)\)
Let the input metric for \((s, \theta, \zeta)\) being \(\mathbf{g}\), the metric for \((\rho, \vartheta, \zeta)\) is given by
\[
\mathbf{G} = \mathbf{J}^T \mathbf{g} \mathbf{J},
\]
where
\[
\mathbf{J} = \frac{\partial(s,\theta,\zeta)}{\partial(\rho,\vartheta,\zeta)}
\]
is the Jacobi matrix.