bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions
A collection of functions used to approximate toroidal harmonics.
Classes
A Dataclass holding necessary parameters for the toroidal harmonics approximation |
|
TauLimit Enum |
|
Toroidal harmonic selection result dataclass |
Functions
|
Evaluates the hypergeometric power series up to n_max. |
|
Evaluates the associated Legendre function of the first kind as a function of x. |
|
Evaluates Olver's definition of the associated Legendre function of the second |
Set up the grid and coils to be used in toroidal harmonic approximation. |
|
Construct coefficient matrices from toroidal harmonic amplitudes at given coil |
|
Approximate psi using toroidal harmonic amplitudes for the specified cos and sin |
|
|
Separate the psi contributions from fixed sources (plasma + excluded coils) and from |
|
Determine the number of degrees of freedom to use. This is limited by the number |
|
Get a plasma mask to apply to the psi field. |
|
Matrix for collocation psi fitting or psi calculation across |
Calculate the toroidal harmonic (TH) amplitudes/coefficients for a given |
|
|
Approximate psi using the equation for toroidal harmonic amplitudes that |
|
Approximate psi by fitting for psi at collocation points using |
|
Plot the toroidal harmonic approximation of the coilset psi and the bluemira |
Module Contents
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions.f_hypergeometric(a, b, c, z, n_max=20)
Evaluates the hypergeometric power series up to n_max. Valid for |z| < 1
\[F(a, b; c; z) = \sum_0^{n_max} \frac{(a)_{s} (b)_{s}}{Gamma(c + s) s!} z^{s}\]See https://dlmf.nist.gov/15.2#E2 and https://dlmf.nist.gov/5.2#iii for more information.
- Parameters:
a – hypergeometric function term, as defined in the equation above
b – hypergeometric function term, as defined in the equation above
c – hypergeometric function term, as defined in the equation above
z – hypergeometric function term, as defined in the equation above Require |z|<1.
n_max – upper limit of summation, default=20
- Returns:
hypergeometric function result.
- Return type:
F
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions.legendre_p(lam, mu, x, n_max=20)
Evaluates the associated Legendre function of the first kind as a function of x. See https://dlmf.nist.gov/14.3#E18 for more information. Works for half integers.
Valid for 1<x<infinity, and real mu and lambda
\[ \begin{align}\begin{aligned}P_{\lambda}^{-\mu}(x) = 2^{-\mu} x^{\lambda - \mu} (x^2 - 1)^{\mu/2} F(\frac{1}{2}(\mu - \lambda), \frac{1}{2}(\mu - \lambda + 1); \mu + 1; 1 - \frac{1}{x^2})\\where F is the hypergeometric function defined above as f_hypergeometric.\end{aligned}\end{align} \]- Parameters:
lam – legendre function term, as defined in the equation above
mu – legendre function term, as defined in the equation above
x – points at which to evaluate legendreP
n_max – upper value for summation in f_hypergeometric
- Returns:
value of legendreP.
- Return type:
legP
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions.legendre_q(lam, mu, x, n_max=20)
Evaluates Olver’s definition of the associated Legendre function of the second kind as a function of x. See https://dlmf.nist.gov/14, https://dlmf.nist.gov/14.3#E10, and https://dlmf.nist.gov/14.3#E7 for more information. Works for half integers.
Valid for 1<x<infinity, and real mu and lambda
\[ \begin{align}\begin{aligned}\textbf{Q}_{\lambda}^{\mu}(x) = \frac{\pi^{\frac{1}{2}} (x^2 - 1)^ {\frac{\mu}{2}}}{2^{\lambda + 1} x^{\lambda + \mu + 1}} F(\frac{1}{2}(\lambda + \mu)+1, \frac{1}{2}(\lambda + \mu); \lambda + \frac{3}{2}; \frac{1}{x^2})\\where F is the hypergeometric function defined above as f_hypergeometric.\end{aligned}\end{align} \]- Parameters:
lam – legendre function term, as defined in the equation above
mu – legendre function term, as defined in the equation above
x – points at which to evaluate legendreQ
n_max – upper value for summation in f_hypergeometric
- Returns:
value of legendreQ.
- Return type:
legQ
- Raises:
EquilibriaError – If too many dimensions are input.
- class bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions.ToroidalHarmonicsParams
A Dataclass holding necessary parameters for the toroidal harmonics approximation
- R_0: float
R coordinate of the focus point in cylindrical coordinates
- Z_0: float
Z coordinate of the focus point in cylindrical coordinates
- min_tau: float
The minimum tau for the toroidal coordinate approximation region
- R: numpy.ndarray
R coordinates of the grid in cylindrical coordinates
- Z: numpy.ndarray
Z coordinates of the grid in cylindrical coordinates
- R_coils: numpy.ndarray
R coordinates of the coils in cylindrical coordinates
- Z_coils: numpy.ndarray
Z coordinates of the coils in cylindrical coordinates
- tau: numpy.ndarray
tau coordinates of the grid in toroidal coordinates
- sigma: numpy.ndarray
sigma coordinates of the grid in toroidal coordinates
- tau_c: numpy.ndarray
tau coordinates of the coils in toroidal coordinates
- sigma_c: numpy.ndarray
sigma coordinates of the coils in toroidal coordinates
- th_coil_names: list
names of coils to use with TH approximation (always outside the LCFS tau limit)
- class bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions.TauLimit(*args, **kwds)
Bases:
enum.EnumTauLimit Enum
- LCFS
- COIL
- MANUAL
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions.toroidal_harmonic_grid_and_coil_setup(eq: bluemira.equilibria.equilibrium.Equilibrium, R_0: float, Z_0: float, tau_limit=TauLimit.LCFS, min_tau_value: float | None = None) ToroidalHarmonicsParams
Set up the grid and coils to be used in toroidal harmonic approximation.
Use the LCFS to find the region over which to approximate psi using TH. Find the coils located outside this region, which can be used in the TH approximation, and find the coils located inside this region which need to be held fixed.
- Parameters:
eq (bluemira.equilibria.equilibrium.Equilibrium) – Starting equilibrium to use in our approximation
R_0 (float) – R coordinate of the toroidal focus point in cylindrical coordinates
Z_0 (float) – Z coordinate of the toroidal focus point in cylindrical coordinates
tau_limit –
- How the maximum tau value is chosen. The three options are:
LCFS: use the maximum extent of the LCFS
COIL: use the maximum area within all the coils
MANUAL: use a specified limit
min_tau_value (float | None) – The minimum tau for the toroidal coordinate approximation region, lower min tau means a larger region of space (maximum tau is at focus)
- Returns:
Dataclass holding necessary parameters for the TH approximation
- Return type:
- Raises:
EquilibriaError – If MANUAL tau_limit is specified but no min_tau_value chosen.
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions.coil_toroidal_harmonic_amplitude_matrix(input_coils: bluemira.equilibria.coils._grouping.CoilSet, th_params: ToroidalHarmonicsParams, cos_m_chosen: numpy.ndarray | None = None, sin_m_chosen: numpy.ndarray | None = None, sig_figures: int = 15) tuple[numpy.ndarray, numpy.ndarray]
Construct coefficient matrices from toroidal harmonic amplitudes at given coil locations, for the specified cos and sin poloidal mode numbers (m).
To get the individual cos and sin arrays of toroidal harmonic amplitudes/coefficients (Am_cos, Am_sin) which can be used in a toroidal harmonic approximation of the vacuum/coil contribution to the poloidal flux (psi) do:
A_m = matrix harmonic amplitudes @ vector of coil currents
Am_cos and Am_sin can be used as constraints in optimisation, see ToroidalHarmonicsConstraint.
N.B. for a single filament (coil):
\[ \begin{align}\begin{aligned}A_{m} = \frac{\mu_{0} I_{c}}{2^{5/2}} \frac{(2m+1)!!}{2^m m!} \frac{\sinh{\tau_{c}}}{\Delta_{c}^{1/2}} P_{m-\frac{1}{2}}^{-1}(\cosh{\tau_c})\\A_{m}^{\sin} = A_m \sin(m \sigma_c) A_{m}^{\cos} = A_m \cos(m \sigma_c)\end{aligned}\end{align} \]Where: m is the poloidal mode number, :math: P_{lambda}^{-mu} are the associated Legendre functions of the first kind, with lambda = m - 1/2 and mu = 1 (i.e., we use multiple poloidal mode numbers but toroidal mode number is fixed), :math: Delta_c = cosh{tau_c} - cos{sigma_c}.
Note: the factorial term frac{(2m+1)!!}{2^m m!} is equivalent to 1 if m = 0, otherwise prod_{i=0}^{m-1} left( 1 + frac{1}{2(m-i)}right)
- Parameters:
input_coils (bluemira.equilibria.coils._grouping.CoilSet) – Bluemira CoilSet
th_params (ToroidalHarmonicsParams) – Dataclass holding necessary parameters for the TH approximation
cos_m_chosen (numpy.ndarray | None) – Poloidal mode numbers (m) chosen to be used for the cos components
sin_m_chosen (numpy.ndarray | None) – Poloidal mode numbers (m) chosen to be used for the sin components
sig_figures (int) – Number of significant figures for rounding currents2harmonics values
- Returns:
Am_cos – Cos component of matrix of harmonic amplitudes,
Am_sin – Sin component of matrix of harmonic amplitudes
- Return type:
tuple[numpy.ndarray, numpy.ndarray]
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions.toroidal_harmonic_approximate_psi(eq: bluemira.equilibria.equilibrium.Equilibrium, th_params: ToroidalHarmonicsParams, cos_m_chosen: numpy.ndarray | None = None, sin_m_chosen: numpy.ndarray | None = None) tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]
Approximate psi using toroidal harmonic amplitudes for the specified cos and sin poloidal mode numbers (m) as calculated in coil_toroidal_harmonic_amplitude_matrix.
coil_toroidal_harmonic_amplitude_matrix returns Am_cos and Am_sin, which we use here.
- ..math::
A_{m} = frac{mu_{0} I_{c}}{2^{5/2}} frac{(2m+1)!!}{2^m m!} frac{sinh{tau_{c}}}{Delta_{c}^{1/2}} P_{m-frac{1}{2}}^{-1}(cosh(tau_c))
A_{m}^{sin} = A_m sin(m sigma_c) A_{m}^{cos} = A_m cos(m sigma_c) A(tau, sigma) = sum_{m=0}^{infty} A_{m}^{cos} epsilon_{m} m! sqrt{frac{2}{pi}}Delta^{frac{1}{2}} textbf{Q}_{m-frac{1}{2}}^{1} (cosh tau) cos(m sigma) + A_{m}^{sin}epsilon_{m} m! sqrt{frac{2} {pi}} Delta^{frac{1}{2}} textbf{Q}_{m-frac{1}{2}}^{1}(cosh tau) sin(m sigma)
- Parameters:
eq (bluemira.equilibria.equilibrium.Equilibrium) – Bluemira Equilibrium
th_params (ToroidalHarmonicsParams) – Dataclass holding necessary parameters for the TH approximation
cos_m_chosen (numpy.ndarray | None) – Poloidal mode numbers (m) chosen to be used for the cos components
sin_m_chosen (numpy.ndarray | None) – Poloidal mode numbers (m) chosen to be used for the sin components
- Returns:
approx_coilset_psi – Matrix of coilset psi values approximated using TH
Am_cos @ currents – TH cos coefficients for required number of poloidal mode numbers (m)
Am_sin @ currents – TH sin coefficients for required number of poloidal mode numbers (m)
- Return type:
tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions._separate_psi_contributions(eq: bluemira.equilibria.equilibrium.Equilibrium, th_params: ToroidalHarmonicsParams, collocation: bluemira.equilibria.optimisation.harmonics.harmonics_approx_functions.Collocation | None = None) tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]
Separate the psi contributions from fixed sources (plasma + excluded coils) and from potentially variable sources (coilset).
Excluded coils are any coils not being used in the toroidal harmonic approximation, e.g. they fall within the region over which we are approximating and so their contribution must be fixed.
- Parameters:
eq (bluemira.equilibria.equilibrium.Equilibrium) – Bluemira Equilibrium
th_params (ToroidalHarmonicsParams) – Dataclass holding necessary parameters for the TH approximation
collocation (bluemira.equilibria.optimisation.harmonics.harmonics_approx_functions.Collocation | None) – Collocation points at which to calculate psi
- Returns:
coilset_psi - excluded_coil_psi – The psi contribution from coils for which we allow the currents to vary. These coils are outside of our approximation region
plasma_psi + excluded_coil_psi – The psi contribution from fixed sources
collocation_coilset_psi – The psi contribution from the coilset at the specified collocation points. If no collocation points are specified, this is None
- Return type:
tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions._set_n_degrees_of_freedom(n_dof: int | None, max_harmonic_mode: int, max_n_dof: int) int
Determine the number of degrees of freedom to use. This is limited by the number of coils and by the maximum poloidal mode number (m) of the harmonic functions.
- Parameters:
n_dof (int | None) – The number of harmonic functions (and amplitudes) to choose. If this is None, then n_dof is calculated as the minimum of max_n_dof and 2 * max_harmonic_mode
max_harmonic_mode (int) – The maximum poloidal mode number of the harmonic functions to use
max_n_dof (int) – The maximum number of degrees of freedom that could be used. This is equal to the number of coils used in the approximation
- Returns:
The number of harmonic functions (and amplitudes) to choose. If None, will default to the number of “free” coils. Will warn if input n_dof is inappropriate and will instead select an appropriate n_dof to return
- Return type:
n_dof
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions._get_plasma_mask(eq: bluemira.equilibria.equilibrium.Equilibrium, th_params: ToroidalHarmonicsParams, psi_norm: float, *, plasma_mask: bool) int | numpy.ndarray
Get a plasma mask to apply to the psi field.
- Parameters:
eq (bluemira.equilibria.equilibrium.Equilibrium) – Bluemira Equilibrium
th_params (ToroidalHarmonicsParams) – Dataclass holding necessary parameters for the TH approximation
plasma_mask (bool) – Whether or not to apply a mask to the error metric (within the psi_norm flux surface)
psi_norm (float) – Normalised flux value of the surface of interest.
- Returns:
The plasma mask to be applied to the psi field
- Return type:
mask
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions.toroidal_harmonics_to_positions(th_params: ToroidalHarmonicsParams, n_allowed: int, collocation: bluemira.equilibria.optimisation.harmonics.harmonics_approx_functions.Collocation | None = None) tuple[numpy.ndarray, numpy.ndarray]
Matrix for collocation psi fitting or psi calculation across grid with known amplitude values.
- Parameters:
th_params (ToroidalHarmonicsParams) – Dataclass holding necessary parameters for the TH approximation
n_allowed (int) – The number of harmonic functions (and amplitudes) to use
collocation (bluemira.equilibria.optimisation.harmonics.harmonics_approx_functions.Collocation | None) – Collocation points at which to calculate psi
- Returns:
harmonics2collocation_cos – collocation matrix for cos components
harmonics2collocation_sin – collocation matrix for sin components
- Raises:
EquilibriaError – If there are too few collocation points used.
- Return type:
tuple[numpy.ndarray, numpy.ndarray]
- class bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions.ToroidalHarmonicsSelectionResult
Toroidal harmonic selection result dataclass
- cos_m: numpy.ndarray
Selected cosine poloidal mode numbers
- sin_m: numpy.ndarray
Selected sine poloidal mode numbers
- cos_amplitudes: numpy.ndarray
Selected cosine toroidal harmonic amplitudes
- sin_amplitudes: numpy.ndarray
Selected sine toroidal harmonic amplitudes
- error: float
Error of L2 norm when comparing approximated coilset psi to desired coilset psi
- coilset_psi: numpy.ndarray
Approximated coilset psi
- fixed_psi: numpy.ndarray
Background (fixed) psi
- true_unfixed_psi: numpy.ndarray
Bluemira psi for toroidal harmonic coils
- th_params: ToroidalHarmonicsParams
Set up info
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions.toroidal_harmonic_approximation(eq: bluemira.equilibria.equilibrium.Equilibrium, th_params: ToroidalHarmonicsParams | None = None, psi_norm: float = 0.95, n_degrees_of_freedom: int | None = None, max_harmonic_mode: int = 5, *, plasma_mask: bool = False) ToroidalHarmonicsSelectionResult
Calculate the toroidal harmonic (TH) amplitudes/coefficients for a given number of degrees of freedom, using TH functions up to a given maximum poloidal mode number.
The optimal selection of harmonic functions is carried out by brute force for the different combinations, using an L2 norm of the error across the full psi map. If plasma_mask is specified the error is evaluated as the L2 norm of the psi map within the specified flux surface.
- Parameters:
eq (bluemira.equilibria.equilibrium.Equilibrium) – Equilibrium to use as starting point for approximation. We will approximate psi using THs - the aim is to keep the core plasma contribution fixed (using TH amplitudes as constraints) while being able to vary the vacuum (coil) contribution, so that we do not need to re-solve for the equilibria during optimisation
th_params (ToroidalHarmonicsParams | None) – Dataclass containing necessary parameters for use in TH approximation. If th_params is None, then function defaults to finding the th_params by using toroidal_harmonic_grid_and_coil_setup with the focus point set to the effective centre.
psi_norm (float) – Normalised flux value of the surface of interest. None value will default to 0.95 flux surface.
n_degrees_of_freedom (int | None) – The number of harmonic functions (and amplitudes) to choose. If None, will default to the number of “free” coils
max_harmonic_mode (int) – The maximum poloidal mode number of the harmonic functions to use
plasma_mask (bool) – Whether or not to apply a mask to the error metric (within the psi_norm flux surface)
- Returns:
ToroidalHarmonicsSelectionResult
- Return type:
result
- Raises:
EquilibriaError – Problem not setup for harmonics
ValueError – Number of degrees of freedom inappropriate
Notes
If no th_params are provided, the focus is set to the effective centre of the plasma, and the region defaults to using the maximum extent of the LCFS
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions._approximation_direct_from_currents(eq, th_params, cos_m_chosen, sin_m_chosen, true_coilset_psi, mask)
Approximate psi using the equation for toroidal harmonic amplitudes that is dependent on current
- Returns:
error – Error of L2 norm when comparing approximated coilset psi to desired coilset psi
approximate_coilset_psi – Approximated coilset psi
cos_amps – Selected cosine toroidal harmonic amplitudes
sin_amps – Selected sine toroidal harmonic amplitudes
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions._approximation_from_psi_fitting(th_params, n_degrees_of_freedom, collocation, mode_id, max_harmonic_mode, collocation_psi, mask, true_coilset_psi)
Approximate psi by fitting for psi at collocation points using toroidal harmonic equations
- Returns:
error – Error of L2 norm when comparing approximated coilset psi to desired coilset psi
approximate_coilset_psi – Approximated coilset psi
cos_amps – Selected cosine toroidal harmonic amplitudes
sin_amps – Selected sine toroidal harmonic amplitudes
Notes
The length of mode_id must be equal to n_degrees_of_freedom
- bluemira.equilibria.optimisation.harmonics.toroidal_harmonics_approx_functions.plot_toroidal_harmonic_approximation(eq: bluemira.equilibria.equilibrium.Equilibrium, th_params: ToroidalHarmonicsParams, result: ToroidalHarmonicsSelectionResult, psi_norm: float = 0.95)
Plot the toroidal harmonic approximation of the coilset psi and the bluemira true coilset psi on the same graph to allow comparison. Also plot the psi_norm flux surfaces for the approximation psi and the equilibrium coilset psi
- Parameters:
eq (bluemira.equilibria.equilibrium.Equilibrium) – Bluemira Equilibrium
th_params (ToroidalHarmonicsParams) – Dataclass holding necessary parameters for the TH approximation
result (ToroidalHarmonicsSelectionResult) – ToroidalHarmonicsSelectionResult object returned from the brute_force_toroidal_approximation function
psi_norm (float) – Normalised flux value of the surface of interest.
- Returns:
The Matplotlib figure and axis
- Return type:
f, ax