bluemira.equilibria.find

Methods for finding O- and X-points and flux surfaces on 2-D arrays.

Classes

Xpoint

X-point class.

Opoint

O-point class.

Lpoint

Limiter point class.

OPointCalcOptions

O point estimation fallback options

Functions

o_point_fallback_calculator(→ list[Opoint])

Calculate fallback options for O point finding.

find_OX_points(→ tuple[list[Opoint], ...)

Finds O-points and X-points by minimising the poloidal field.

get_contours(→ list[numpy.typing.NDArray[numpy.float64]])

Get the contours of a value in continuous array.

find_flux_surf(→ numpy.typing.NDArray[numpy.float64])

Picks a flux surface with a normalised psinorm relative to the separatrix.

find_LCFS_separatrix(...)

Find the "true" LCFS and separatrix(-ices) in an Equilibrium.

grid_2d_contour(→ tuple[numpy.ndarray, numpy.ndarray])

Grid a smooth contour and get the outline of the cells it encompasses.

in_plasma(→ numpy.typing.NDArray[numpy.float64])

Get a psi-shaped mask of psi where 1 is inside the plasma, 0 outside.

in_zone(x, z, zone, *[, include_edges])

Get a masking matrix for a specified zone.

Module Contents

class bluemira.equilibria.find.Xpoint(x: float, z: float, psi: float)

Bases: PsiPoint

Inheritance diagram of bluemira.equilibria.find.Xpoint

X-point class.

Parameters:
  • x (float)

  • z (float)

  • psi (float)

__slots__ = ()
class bluemira.equilibria.find.Opoint(x: float, z: float, psi: float)

Bases: PsiPoint

Inheritance diagram of bluemira.equilibria.find.Opoint

O-point class.

Parameters:
  • x (float)

  • z (float)

  • psi (float)

__slots__ = ()
class bluemira.equilibria.find.Lpoint(x: float, z: float, psi: float)

Bases: PsiPoint

Inheritance diagram of bluemira.equilibria.find.Lpoint

Limiter point class.

Parameters:
  • x (float)

  • z (float)

  • psi (float)

__slots__ = ()
class bluemira.equilibria.find.OPointCalcOptions(*args, **kwds)

Bases: enum.Enum

Inheritance diagram of bluemira.equilibria.find.OPointCalcOptions

O point estimation fallback options

RAISE
GRID_CENTRE
MAJOR_RADIUS
bluemira.equilibria.find.o_point_fallback_calculator(o_point_fallback: OPointCalcOptions, x: numpy.typing.NDArray, z: numpy.typing.NDArray, psi: numpy.typing.NDArray | collections.abc.Callable[[float, float], float] | None, R_0: float | None = None) list[Opoint]

Calculate fallback options for O point finding.

Parameters:
  • o_point_fallback (OPointCalcOptions) – Selection of fallback type

  • x (numpy.typing.NDArray) – x point(s) to use. If using psi callable the x point itself

  • z (numpy.typing.NDArray) – z point(s) to use. If using psi callable the z point itself

  • psi (numpy.typing.NDArray | collections.abc.Callable[[float, float], float] | None) – psi array or callable. When the callable is used psi is calculated with x and z as inputs,

  • R_0 (float | None) – R_O value used for major radius fallback

Returns:

Calculated O-point

Raises:
  • ValueError – Raised when R_0 not provided for major radius fallback

  • EquilibriaError – Raised when raise fallback is used

Return type:

list[Opoint]

bluemira.equilibria.find.find_OX_points(x: numpy.typing.NDArray[numpy.float64], z: numpy.typing.NDArray[numpy.float64], psi: numpy.typing.NDArray[numpy.float64], limiter: bluemira.equilibria.limiter.Limiter | None = None, *, field_cut_off: float = 1.0, o_point_fallback: OPointCalcOptions = OPointCalcOptions.GRID_CENTRE, R_0: float | None = None) tuple[list[Opoint], list[Xpoint | Lpoint]]

Finds O-points and X-points by minimising the poloidal field.

Parameters:
  • x (numpy.typing.NDArray[numpy.float64]) – The spatial x coordinates of the grid points [m]

  • z (numpy.typing.NDArray[numpy.float64]) – The spatial z coordinates of the grid points [m]

  • psi (numpy.typing.NDArray[numpy.float64]) – The poloidal magnetic flux map [V.s/rad]

  • limiter (bluemira.equilibria.limiter.Limiter | None) – The limiter to use (if any)

  • field_cut_off (float) – The field above which local minima are not searched [T]. Must be > 0.1 T

  • o_point_fallback (OPointCalcOptions)

  • R_0 (float | None)

Returns:

  • o_points – The O-points in the psi map

  • x_points (List[Union[Xpoint,LPoint]]) – The X-points and L-points in the psi map

Return type:

tuple[list[Opoint], list[Xpoint | Lpoint]]

Notes

\(\lvert{\nabla}{\psi}{\lvert}^{2} = 0\)

Local minima brute-forced, and subsequent accurate locations of the points found by local optimisation.

For speed, does this on existing psi map (not exactly at optimum).

Points are order w.r.t. central grid coordinates.

bluemira.equilibria.find.get_contours(x: numpy.typing.NDArray[numpy.float64], z: numpy.typing.NDArray[numpy.float64], array: numpy.typing.NDArray[numpy.float64], value: float) list[numpy.typing.NDArray[numpy.float64]]

Get the contours of a value in continuous array.

Parameters:
  • x (numpy.typing.NDArray[numpy.float64]) – The x value array

  • z (numpy.typing.NDArray[numpy.float64]) – The z value array

  • array (numpy.typing.NDArray[numpy.float64]) – The value array

  • value (f) – The value of the desired contour in the array

Returns:

The list of arrays of value contour(s) in the array

Return type:

list[numpy.typing.NDArray[numpy.float64]]

bluemira.equilibria.find.find_flux_surf(x: numpy.typing.NDArray[numpy.float64], z: numpy.typing.NDArray[numpy.float64], psi: numpy.typing.NDArray[numpy.float64], psinorm: float, o_points: list[Opoint] | None = None, x_points: list[Xpoint] | None = None) numpy.typing.NDArray[numpy.float64]

Picks a flux surface with a normalised psinorm relative to the separatrix. Uses least squares to retain only the most appropriate flux surface. This is taken to be the surface whose geometric centre is closest to the O-point

Parameters:
  • x (numpy.typing.NDArray[numpy.float64]) – The spatial x coordinates of the grid points [m]

  • z (numpy.typing.NDArray[numpy.float64]) – The spatial z coordinates of the grid points [m]

  • psi (numpy.typing.NDArray[numpy.float64]) – The poloidal magnetic flux map [V.s/rad]

  • psinorm (float) – The normalised psi value of the desired flux surface [-]

  • o_points (list[Opoint] | None) – O-points to use to calculate psinorm

  • x_points (list[Xpoint] | None) – X-points to use to calculate psinorm (saves time if you have them)

Returns:

The flux surface coordinate array

Raises:

EquilibriaError – No flux surface found at psi_norm

Return type:

numpy.typing.NDArray[numpy.float64]

Notes

\({\Psi}_{N} = {\psi}_{O}-N({\psi}_{O}-{\psi}_{X})\)

Uses matplotlib hacks to pick contour surfaces on psi(X, Z).

bluemira.equilibria.find.find_LCFS_separatrix(x: numpy.typing.NDArray[numpy.float64], z: numpy.typing.NDArray[numpy.float64], psi: numpy.typing.NDArray[numpy.float64], o_points: list[Opoint] | None = None, x_points: list[Xpoint] | None = None, *, double_null: bool = False, psi_n_tol: float = 1e-06, delta_start: float = 0.01, rtol: float = 0.001) tuple[bluemira.geometry.coordinates.Coordinates, bluemira.geometry.coordinates.Coordinates | list[bluemira.geometry.coordinates.Coordinates]]

Find the “true” LCFS and separatrix(-ices) in an Equilibrium.

Parameters:
  • x (numpy.typing.NDArray[numpy.float64]) – The spatial x coordinates of the grid points [m]

  • z (numpy.typing.NDArray[numpy.float64]) – The spatial z coordinates of the grid points [m]

  • psi (numpy.typing.NDArray[numpy.float64]) – The poloidal magnetic flux map [V.s/rad]

  • o_points (list[Opoint] | None) – The O-points in the psi map

  • x_points (list[Xpoint] | None) – The X-points in the psi map

  • double_null (bool) – Whether or not to search for a double null separatrix.

  • psi_n_tol (float) – The normalised psi tolerance to use

  • delta_start (float) – Search range value. Will search for the transition from a “closed” to “open” flux surface for normalised flux values between 1 - delta_start and 1 + delta_start.

  • rtol (float)

Returns:

  • lcfs – The last closed flux surface

  • separatrix – The plasma separatrix (first open flux surface). Will return a list of Coordinates for double_null=True, with all four separatrix legs being captured.

Return type:

tuple[bluemira.geometry.coordinates.Coordinates, bluemira.geometry.coordinates.Coordinates | list[bluemira.geometry.coordinates.Coordinates]]

Notes

We need to find the transition between the LCFS and the first “open” flux surface. In theory this would be for psi_norm = 1, however because of grids and interpolation this isn’t exactly the case. So we search for the normalised flux value where the flux surface first goes from being open to closed.

bluemira.equilibria.find.grid_2d_contour(x: numpy.ndarray, z: numpy.ndarray) tuple[numpy.ndarray, numpy.ndarray]

Grid a smooth contour and get the outline of the cells it encompasses.

Parameters:
  • x (numpy.ndarray) – The closed ccw x coordinates

  • z (numpy.ndarray) – The closed ccw z coordinates

Returns:

  • x_new – The x coordinates of the grid-coordinates

  • z_new – The z coordinates of the grid-coordinates

Return type:

tuple[numpy.ndarray, numpy.ndarray]

bluemira.equilibria.find.in_plasma(x: numpy.typing.NDArray[numpy.float64], z: numpy.typing.NDArray[numpy.float64], psi: numpy.typing.NDArray[numpy.float64], o_points: list[Opoint] | None = None, x_points: list[Xpoint] | None = None, *, include_edges: bool = False) numpy.typing.NDArray[numpy.float64]

Get a psi-shaped mask of psi where 1 is inside the plasma, 0 outside.

Parameters:
  • x (numpy.typing.NDArray[numpy.float64]) – The radial coordinates of the grid points

  • z (numpy.typing.NDArray[numpy.float64]) – The vertical coordinates of the grid points

  • psi (numpy.typing.NDArray[numpy.float64]) – The poloidal magnetic flux map [V.s/rad]

  • o_points (list[Opoint] | None) – O-points to use to calculate psinorm

  • x_points (list[Xpoint] | None) – X-points to use to calculate psinorm (saves time if you have them)

  • include_edges (bool)

Return type:

Masking matrix for the location of the plasma [0 outside/1 inside]

bluemira.equilibria.find.in_zone(x: numpy.typing.NDArray[numpy.float64], z: numpy.typing.NDArray[numpy.float64], zone: numpy.typing.NDArray[numpy.float64], *, include_edges: bool = False)

Get a masking matrix for a specified zone.

Parameters:
  • x (numpy.typing.NDArray[numpy.float64]) – The x coordinates array

  • z (numpy.typing.NDArray[numpy.float64]) – The z coordinates array

  • zone (numpy.typing.NDArray[numpy.float64]) – The array of point coordinates delimiting the zone

  • include_edges (bool)

Return type:

The masking array where 1 denotes inside the zone, and 0 outside