surf_henneberg ============== .. py:module:: surf_henneberg Module Contents --------------- .. py:class:: SurfaceHenneberg(nfp: int = 1, alpha_fac: int = 1, mmax: int = 1, nmax: int = 0, quadpoints_phi=None, quadpoints_theta=None, dofs=None) Bases: :py:obj:`spectre.surfaces.surf.Surface` This class represents a toroidal surface using the parameterization in Henneberg, Helander, and Drevlak, Journal of Plasma Physics 87, 905870503 (2021). The main benefit of this representation is that there is no freedom in the poloidal angle, i.e. :math:`\theta` is uniquely defined, in contrast to other parameterizations like :obj:`~.surfacerzfourier.SurfaceRZFourier`. Stellarator symmetry is assumed. In this representation by Henneberg et al, the cylindrical coordinates :math:`(R,\phi,Z)` are written in terms of a unique poloidal angle :math:`\theta` as follows: .. math:: R(\theta,\phi) = R_0^H(\phi) + \rho(\theta,\phi) \cos(\alpha\phi) - \zeta(\theta,\phi) \sin(\alpha\phi), \\ Z(\theta,\phi) = Z_0^H(\phi) + \rho(\theta,\phi) \sin(\alpha\phi) + \zeta(\theta,\phi) \cos(\alpha\phi), where .. math:: R_0^H(\phi) &=& \sum_{n=0}^{nmax} R_{0,n}^H \cos(n_{fp} n \phi), \\ Z_0^H(\phi) &=& \sum_{n=1}^{nmax} Z_{0,n}^H \sin(n_{fp} n \phi), \\ \zeta(\theta,\phi) &=& \sum_{n=0}^{nmax} b_n \cos(n_{fp} n \phi) \sin(\theta - \alpha \phi), \\ \rho(\theta,\phi) &=& \sum_{n,m} \rho_{n,m} \cos(m \theta - n_{fp} n \phi - \alpha \phi). The continuous degrees of freedom are :math:`\{\rho_{m,n}, b_n, R_{0,n}^H, Z_{0,n}^H\}`. These variables correspond to the attributes ``rhomn``, ``bn``, ``R0nH``, and ``Z0nH`` respectively, which are all numpy arrays. There is also a discrete degree of freedom :math:`\alpha` which should be :math:`\pm n_{fp}/2` where :math:`n_{fp}` is the number of field periods. The attribute ``alpha_fac`` corresponds to :math:`2\alpha/n_{fp}`, so ``alpha_fac`` is either 1, 0, or -1. Using ``alpha_fac = 0`` is appropriate for axisymmetry, while values of 1 or -1 are appropriate for a stellarator, depending on the handedness of the rotating elongation. For :math:`R_{0,n}^H` and :math:`b_n`, :math:`n` is 0 or any positive integer up through ``nmax`` (inclusive). For :math:`Z_{0,n}^H`, :math:`n` is any positive integer up through ``nmax``. For :math:`\rho_{m,n}`, :math:`m` is an integer from 0 through ``mmax`` (inclusive). For positive values of :math:`m`, :math:`n` can be any integer from ``-nmax`` through ``nmax``. For :math:`m=0`, :math:`n` is restricted to integers from 1 through ``nmax``. Note that we exclude the element of :math:`\rho_{m,n}` with :math:`m=n=0`, because this degree of freedom is already represented in :math:`R_{0,0}^H`. For the 2D array ``rhomn``, functions :func:`set_rhomn()` and :func:`get_rhomn()` are provided for convenience so you can specify ``n``, since the corresponding array index is shifted by ``nmax``. There are no corresponding functions for the 1D arrays ``R0nH``, ``Z0nH``, and ``bn`` since these arrays all have a first index corresponding to ``n=0``. Args: nfp: The number of field periods. alpha_fac: Should be +1 or -1 for a stellarator, depending on the handedness by which the elongation rotates, or 0 for axisymmetry. mmax: Maximum poloidal mode number included. nmax: Maximum toroidal mode number included, divided by ``nfp``. quadpoints_phi: Set this to a list or 1D array to set the :math:`\phi_j` grid points directly. quadpoints_theta: Set this to a list or 1D array to set the :math:`\theta_j` grid points directly. .. py:attribute:: nfp :value: 1 .. py:attribute:: alpha_fac :value: 1 .. py:attribute:: mmax :value: 1 .. py:attribute:: nmax :value: 1 .. py:attribute:: stellsym :value: True .. py:attribute:: quadpoints_theta .. py:attribute:: quadpoints_phi .. py:method:: allocate() Create the arrays for the continuous degrees of freedom. Also set the names of the dofs. .. py:method:: get_rhomn(m, n) Return a particular :math:`\rho_{m,n}` coefficient. .. py:method:: set_rhomn(m, n, val) Set a particular :math:`\rho_{m,n}` coefficient. .. py:method:: get_dofs() Return a 1D numpy array with all the degrees of freedom. .. py:method:: set_dofs(dofs) .. py:method:: num_dofs() Return the number of degrees of freedom. .. py:method:: set_dofs_impl(v) Set the shape coefficients from a 1D list/array .. py:method:: fixed_range(mmax, nmax, fixed=True) Set the ``fixed`` property for a range of ``m`` and ``n`` values. All modes with ``m <= mmax`` and ``|n| <= nmax`` will have their fixed property set to the value of the ``fixed`` parameter. Note that ``mmax`` and ``nmax`` are included. Both ``mmax`` and ``nmax`` must be >= 0. For any value of ``mmax``, the ``fixed`` properties of ``R0nH``, ``Z0nH``, and ``rhomn`` are set. The ``fixed`` properties of ``bn`` are set only if ``mmax > 0``. In other words, the ``bn`` modes are treated as having ``m=1``. .. py:method:: to_RZFourier(mpol_tgt=None, ntor_tgt=None) Return a :obj:`~.surfacerzfourier.SurfaceRZFourier` object with the identical shape. This routine implements eq (4.5)-(4.6) in the Henneberg paper, plus m=0 terms for R0 and Z0. .. py:method:: from_RZFourier(surf, alpha_fac: int, mmax=None, nmax=None, ntheta=None, nphi=None, verbose=False) :classmethod: Convert a :obj:`~.surfacerzfourier.SurfaceRZFourier` surface to a :obj:`SurfaceHenneberg` surface. Args: surf: The :obj:`~.surfacerzfourier.SurfaceRZFourier` object to convert. mmax: Maximum poloidal mode number to include in the new surface. If ``None``, the value ``mpol`` from the old surface will be used. nmax: Maximum toroidal mode number to include in the new surface. If ``None``, the value ``ntor`` from the old surface will be used. ntheta: Number of grid points in the poloidal angle used for the transformation. If ``None``, the value ``3 * ntheta`` will be used. nphi: Number of grid points in the toroidal angle used for the transformation. If ``None``, the value ``3 * nphi`` will be used. .. py:method:: surfaces_from_spectre_xmn(xmn, bnd_rc, bnd_zs, test, alpha_fac=1, nmax=6, mmax=6, ntheta=48, nphi=24, verbose=False) :classmethod: .. py:method:: surfaces_to_spectre_xmn(surfaces, test) :classmethod: .. py:method:: surfaces_to_spectre_dxmn_dxdof(surfaces, test) :classmethod: .. py:method:: gamma() .. py:method:: gammadash1() .. py:method:: gammadash2() .. py:method:: gamma_lin(data, quadpoints_phi, quadpoints_theta) Evaluate the position vector on the surface in Cartesian coordinates, for a list of (phi, theta) points. .. py:method:: gamma_impl(data, quadpoints_phi, quadpoints_theta) Evaluate the position vector on the surface in Cartesian coordinates, for a tensor product grid of points in theta and phi. .. py:method:: gammadash1_impl(data) Evaluate the derivative of the position vector with respect to the toroidal angle phi. .. py:method:: gammadash2_impl(data) Evaluate the derivative of the position vector with respect to theta. .. py:method:: normal() .. py:method:: volume() .. py:method:: area() .. py:function:: b_min(theta, rc, zs, phi0, cosaphi, sinaphi, mpol, ntor, nfp) This function is minimized as part of finding b. .. py:function:: b_max(theta, rc, zs, phi0, cosaphi, sinaphi, mpol, ntor, nfp)