bluemira.equilibria.coils._grouping
Coil and coil grouping objects
Classes
Coil Grouping object |
|
A CoilGroup where all coils have the same current |
|
A Circuit with positional symmetry |
|
State of the optimisation of a CoilSet |
|
CoilSet is a CoilGroup with the concept of control coils |
Functions
|
Symmetrise a CoilSet by converting any coils that are up-down symmetric about |
Module Contents
- bluemira.equilibria.coils._grouping.symmetrise_coilset(coilset: CoilSet, *, rtol: float | None = None, symmetrise_singular: bool = False) CoilSet
Symmetrise a CoilSet by converting any coils that are up-down symmetric about z=0 to SymmetricCircuits.
- Parameters:
coilset (CoilSet) – CoilSet to symmetrise
rtol (float | None) – Relative tolerance used when comparing coil values. The values for the secondary coil in the pair will be set to be equal to the primary coil values if they are within rtol.
symmetrise_singular (bool) – make singular coils symmetric about z=0
- Returns:
New CoilSet with SymmetricCircuits where appropriate
- Raises:
EquilibriaError – Superposition of coils or unrecognised type
- Return type:
- class bluemira.equilibria.coils._grouping.CoilGroup(*coils: bluemira.equilibria.coils._coil.Coil | CoilGroup, psi_analytic: bool = False, Bx_analytic: bool = True, Bz_analytic: bool = True)
Bases:
bluemira.equilibria.coils._field.CoilGroupFieldsMixinCoil Grouping object
Allow nested coils or groups of coils with access to the methods and properties in the same way to a vanilla Coil
- Parameters:
coils (bluemira.equilibria.coils._coil.Coil | CoilGroup) – Coils and groups of Coils to group
psi_analytic (bool)
Bx_analytic (bool)
Bz_analytic (bool)
- __slots__ = ('_Bx_analytic', '_Bz_analytic', '_coils', '_pad_size', '_psi_analytic')
- _coils = ()
- __repr__()
Pretty print
- n_coils(ctype: str | bluemira.base.constants.CoilType | None = None) int
Get number of coils
- Parameters:
ctype (str | bluemira.base.constants.CoilType | None) – get number of coils of a specific type
- Returns:
Number of coils
- Return type:
int
- plot(ax: matplotlib.axes.Axes | None = None, *, subcoil: bool = True, label: bool = False, force: collections.abc.Iterable | None = None, **kwargs) bluemira.equilibria.plotting.CoilGroupPlotter | None
Plot a CoilGroup
- Parameters:
ax (matplotlib.axes.Axes | None) – Matplotlib axis object
subcoil (bool) – plot coil discretisations
label (bool) – show coil labels on plot
force (collections.abc.Iterable | None) – force arrows iterable
kwargs – passed to matplotlib’s Axes.plot
- Return type:
- fix_sizes()
Fix the sizes of coils in CoilGroup
- resize(currents: float | list | numpy.ndarray)
Resize coils based on their current if their size is not fixed
- Parameters:
currents (float | list | numpy.ndarray)
- _resize(currents: float | list | numpy.ndarray)
Resize coils based on their current
Notes
Ignores any protections on their size
- Parameters:
currents (float | list | numpy.ndarray)
- __run_func(func: str, *args, **kwargs)
Runs a function with no outputs that exists on a coil or coilgroup
This function aims to deal with the edge cases that are around nested coilgroups If kwargs are passed they will be passed to all function calls as is. If args are passed an attempt is made to push the right shaped argument to a given function.
- Raises:
ValueError – Number of arguments not equal to number og coil groups
- Parameters:
func (str)
- add_coil(*coils: bluemira.equilibria.coils._coil.Coil | CoilGroup)
Add coils to the coil group
- Parameters:
- remove_coil(*coil_name: str, _top_level: bool = True) list[str] | None
Remove coil from CoilGroup
- Parameters:
coil_name (str) – coil(s) to remove
_top_level (bool) – FOR INTERNAL USE, flags if at top level of nested coilgroup stack
- Returns:
Removed names if not at top level of nested stack
- Raises:
EquilibriaError – Unknown coils
- Return type:
list[str] | None
Notes
If a nested coilgroup is empty it is also removed from the parent coilgroup
- classmethod from_group_vecs(eqdsk: eqdsk.EQDSKInterface) CoilGroup
Initialises an instance of CoilSet from group vectors.
This has been implemented as a dict operation, because it will occur for eqdsks only. Future dict instantiation methods will likely differ, hence the confusing name of this method.
There should always be a coilset but… if for some reason the coilset is missing, and the user has not provided ‘user_coils’ as an input for ‘from_eqdsk’, then a dummy coilset is used and a warning message is printed.
- Parameters:
eqdsk (eqdsk.EQDSKInterface)
- Return type:
- to_group_vecs() tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray]
Output CoilGroup properties as numpy arrays
- Returns:
x – The x-positions of coils
z – The z-positions of coils.
dx – The coil size in the x-direction.
dz – The coil size in the z-direction.
currents – The coil currents.
- Return type:
tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray]
- __list_getter(attr: str) list
Get attributes from coils tuple
- Parameters:
attr (str)
- Return type:
list
- __getter(attr: str) numpy.ndarray
- Returns:
Attribute from coils and convert to flattened numpy array
- Parameters:
attr (str)
- Return type:
numpy.ndarray
- __quad_getter(attr: str) numpy.ndarray
- Returns:
Quadratures and autopad to create non ragged array
- Parameters:
attr (str)
- Return type:
numpy.ndarray
- __setter(attr: str, values: bluemira.base.constants.CoilType | float | collections.abc.Iterable[bluemira.base.constants.CoilType | float], dtype: type | None = None)
Set attributes on coils
- Raises:
ValueError – Number of elements < number of coils
- Parameters:
attr (str)
values (bluemira.base.constants.CoilType | float | collections.abc.Iterable[bluemira.base.constants.CoilType | float])
dtype (type | None)
- __getitem__(item)
Get coils
- __copy__()
Copy dunder method, needed because attribute setter fails for quadratures
- __deepcopy__(memo)
Deepcopy dunder method, needed because attribute setter fails for quadratures
- _pad_discretisation(_to_pad: list[numpy.ndarray])
Convert quadrature list of array to rectangular arrays. Padding quadrature arrays with zeros to allow array operations on rectangular matricies.
- Parameters:
_to_pad (list[numpy.ndarray]) – x quadratures
Notes
Padding exists for coils with different discretisations or sizes within a coilgroup. There are a few extra calculations of the greens functions where padding exists in
_combined_control().
- _find_coil(name)
Find coil by name
- Raises:
KeyError – Coil not found in group
- _get_coiltype(*ctype: bluemira.base.constants.CoilType | str) list[bluemira.equilibria.coils._coil.Coil]
Find coil by type
- Parameters:
ctype (bluemira.base.constants.CoilType | str)
- Return type:
- all_coils() list[bluemira.equilibria.coils._coil.Coil]
- Returns:
All coils as a flattened list (no CoilGroups)
- Return type:
- _get_type_index(*ctype: bluemira.base.constants.CoilType | str) numpy.typing.NDArray[int]
- Parameters:
ctype (bluemira.base.constants.CoilType | str)
- Return type:
numpy.typing.NDArray[int]
- get_coiltype(*ctype: str | bluemira.base.constants.CoilType) CoilGroup | None
- Returns:
Coils matching coil type
- Parameters:
ctype (str | bluemira.base.constants.CoilType)
- Return type:
CoilGroup | None
- assign_material(ctype, j_max, b_max)
Assign material J and B to Coilgroup
- get_max_current(max_current: float = np.inf) numpy.ndarray
Get max currents
If a max current argument is provided and the max current isn’t set, the value will be as input.
- Parameters:
max_current (float) – max current value if j_max == nan
- Returns:
Maximum currents
- Return type:
numpy.ndarray
- property name: list
Get coil names
- Return type:
list
- property primary_coil: bluemira.equilibria.coils._coil.Coil
Get primary coil, which is arbitrarily taken to be the first coil in the group.
Will recurse if the first coil itself is a CoilGroup.
- Return type:
- get_coil_or_group_with_coil_name(coil_name: str) bluemira.equilibria.coils._coil.Coil | CoilGroup
Get the coil or coil group with the coil with coil_name in it.
This will be the lowest level group that contains the coil.
- Parameters:
coil_name (str) – The coil name to search for
- Returns:
The coil or coil group with the given coil name in it
- Raises:
ValueError – No coil found with given name
- Return type:
- property x: numpy.ndarray
Get coil x positions
- Return type:
numpy.ndarray
- property z: numpy.ndarray
Get coil z positions
- Return type:
numpy.ndarray
- property position
Get coil x, z positions
- property ctype: list
Get coil types
- Return type:
list
- property dx: numpy.ndarray
Get coil widths (half)
- Return type:
numpy.ndarray
- property dz: numpy.ndarray
Get coil heights (half)
- Return type:
numpy.ndarray
- property current: numpy.ndarray
Get coil currents
- Return type:
numpy.ndarray
- property j_max: numpy.ndarray
Get coil max current density
- Return type:
numpy.ndarray
- property b_max: numpy.ndarray
Get coil max field
- Return type:
numpy.ndarray
- property resistance: numpy.ndarray
Get coil resistance
- Return type:
numpy.ndarray
- property discretisation: numpy.ndarray
Get coil discretisations
- Return type:
numpy.ndarray
- property n_turns: numpy.ndarray
Get coil number of turns
- Return type:
numpy.ndarray
- property area: numpy.ndarray
Get coil areas
- Return type:
numpy.ndarray
- property volume: numpy.ndarray
Get coil volumes
- Return type:
numpy.ndarray
- property x_boundary: numpy.ndarray
Get coil x coordinate boundary
- Return type:
numpy.ndarray
- property z_boundary: numpy.ndarray
Get coil z coordinate boundary
- Return type:
numpy.ndarray
- property _flag_sizefix: numpy.ndarray
Get coil current radius
- Return type:
numpy.ndarray
- property _current_radius: numpy.ndarray
Get coil current radius
- Return type:
numpy.ndarray
- property _quad_x
Get coil x quadratures
- property _quad_z
Get coil z quadratures
- property _quad_dx
Get coil dx quadratures
- property _quad_dz
Get coil dz quadratures
- property _quad_weighting
Get coil quadrature weightings
- property _quad_boundary
Get coil quadrature boundaries
- class bluemira.equilibria.coils._grouping.Circuit(*coils: bluemira.equilibria.coils._coil.Coil | CoilGroup, current: float | None = None, psi_analytic: bool = False, Bx_analytic: bool = True, Bz_analytic: bool = True)
Bases:
CoilGroupA CoilGroup where all coils have the same current
- Parameters:
coils (bluemira.equilibria.coils._coil.Coil | CoilGroup) – coils in circuit
current (float | None) – The current value, if not provided the first coil current is used
psi_analytic (bool)
Bx_analytic (bool)
Bz_analytic (bool)
- __slots__ = ('_Bx_analytic', '_Bz_analytic', '_coils', '_pad_size', '_psi_analytic')
- current
Get coil currents
- _get_current()
- property primary_group: bluemira.equilibria.coils._coil.Coil | CoilGroup
Get the first coil or group in the circuit as the ‘primary_group’
- Return type:
- add_coil(*coils: bluemira.equilibria.coils._coil.Coil | CoilGroup)
Add coil to circuit forcing the same current
- Parameters:
- class bluemira.equilibria.coils._grouping.SymmetricCircuit(*coils: bluemira.equilibria.coils._coil.Coil | CoilGroup, psi_analytic: bool = False, Bx_analytic: bool = True, Bz_analytic: bool = True)
Bases:
CircuitA Circuit with positional symmetry
- Parameters:
coils (bluemira.equilibria.coils._coil.Coil | CoilGroup) – 2 coil or coil group objects to symmetrise in a circuit
psi_analytic (bool)
Bx_analytic (bool)
Bz_analytic (bool)
Notes
Although two groups can be defined any movement of the coils is achieved by offsets to the mean position of the coilgroups.
Currently only symmetric about z = 0 see gh issue #210
- __slots__ = ('_symmetry_line', '_shift', 'sym_mat', '_Bx_analytic', '_Bz_analytic', '_coils', '_pad_size',...
- property symmetric_group: bluemira.equilibria.coils._coil.Coil | CoilGroup
Get the second coil or group as the ‘symmetric_group’
- Return type:
- modify_symmetry(symmetry_line: numpy.ndarray)
Create a unit vector for the symmetry of the circuit
- Parameters:
symmetry_line (numpy.ndarray) – two points making a symmetry line [[float, float], [float, float]]
- _symmetry_matrix()
Symmetry matrix
\[\begin{split}\frac{1}{1 + m} \left[ {\begin{array}{cc} 1 - m^2 & 2m \\ 2m & -(1 - m^2) \\ \end{array} } \right]\end{split}\]
- _symmetrise() numpy.ndarray
Calculate the change in position to the symmetric coil, twice the distance to the line of symmetry.
- Returns:
The change in position
- Return type:
numpy.ndarray
- remove_coil(*coil_name: str, _top_level: bool = True) list[str] | None
Remove coil(s) from CoilSet
- Parameters:
coil_name (str) – coil(s) to remove
_top_level (bool) – FOR INTERNAL USE, flags if at top level of nested coilgroup stack
- Returns:
Removed coil names, if not at top level of nested stack
- Raises:
ValueError – Cannot remove coils from a SymmetricCircuit with nested CoilGroups
- Return type:
list[str] | None
- _get_primary_group_x_centre() numpy.float64
Get the x centre of the first coil group
- Return type:
numpy.float64
- _get_primary_group_z_centre() numpy.float64
Get the z centre of the first coil group
- Return type:
numpy.float64
- _get_symmetric_group_x_centre() numpy.float64
Get the x centre of the first coil group
- Return type:
numpy.float64
- _get_symmetric_group_z_centre() numpy.float64
Get the z centre of the first coil group
- Return type:
numpy.float64
- _get_group_centre() numpy.ndarray
Get the centre of the first coil group
- Return type:
numpy.ndarray
- class bluemira.equilibria.coils._grouping.CoilSetOptimisationState
State of the optimisation of a CoilSet
- Parameters:
currents – The current values of the coils
xs – The x positions of the coils
zs – The z positions of the coils
- currents: numpy.ndarray
- xs: numpy.ndarray
- zs: numpy.ndarray
- __post_init__()
- property positions: numpy.ndarray
Get the positions as a (2, N) array
- Return type:
numpy.ndarray
- property positions_flat: numpy.ndarray
Get the positions as an array with xs and zs concatenated (xs then zs)
- Return type:
numpy.ndarray
- class bluemira.equilibria.coils._grouping.CoilSet(*coils: bluemira.equilibria.coils._coil.Coil | CoilGroup, control_names: list | bool | None = None, psi_analytic: bool = False, Bx_analytic: bool = True, Bz_analytic: bool = True)
Bases:
bluemira.equilibria.coils._field.CoilSetFieldsMixin,CoilGroupCoilSet is a CoilGroup with the concept of control coils
A CoilSet will return the total volume and area of the coils and the respective psi or field calculations can optionally sum over the coils or only sum over the control coils.
By default all coils are controlled
- Parameters:
coils (bluemira.equilibria.coils._coil.Coil | CoilGroup) – The coils to be added to the set
control_names (list | bool | None) – List of coil names to be controlled
psi_analytic (bool)
Bx_analytic (bool)
Bz_analytic (bool)
- __slots__ = ('_control', '_control_ind', '_Bx_analytic', '_Bz_analytic', '_coils', '_pad_size', '_psi_analytic')
- property control: list[str]
Get control coil names
- Return type:
list[str]
- remove_coil(*coil_name: str, _top_level: bool = True) list[str] | None
Remove coil(s) from CoilSet
- Parameters:
coil_name (str) – coil(s) to remove
_top_level (bool) – FOR INTERNAL USE, flags if at top level of nested coilgroup stack
- Returns:
Removed coil names, if not at top level of nested stack
- Return type:
list[str] | None
- property n_control: float
Number of coils being actively controlled
- Return type:
float
- property area: float
Cross sectional area of CoilSet
- Return type:
float
- property volume: float
Volume of Coilset
- Return type:
float
- _sum(output: numpy.ndarray, *, sum_coils: bool = False, control: bool = False) numpy.ndarray
Get responses of coils optionally only control and/or sum over the responses
- Parameters:
output (numpy.ndarray) – Output of calculation
sum_coils (bool) – sum over coils
control (bool) – operations on control coils only
- Returns:
Summed response output
- Return type:
numpy.ndarray
- get_coiltype(*ctype: str | bluemira.base.constants.CoilType) CoilSet | None
Get coils by coils type
- Parameters:
ctype (str | bluemira.base.constants.CoilType)
- Return type:
CoilSet | None
- classmethod from_group_vecs(eqdsk: eqdsk.EQDSKInterface, control_coiltypes=(CoilType.PF, CoilType.CS)) CoilGroup
Create CoilSet from eqdsk group vectors.
Automatically sets all coils that are not implicitly passive to control coils
- Parameters:
eqdsk (eqdsk.EQDSKInterface)
- Return type:
- get_optimisation_state(position_coil_names: list[str] | None = None, current_scale: float = 1.0) CoilSetOptimisationState
Get the state of the CoilSet for optimisation. If control coils are set then this is accounted for.
- Parameters:
position_coil_names (list[str] | None) – The names of the coils to get the positions of
current_scale (float) – The scale of the currents
- Returns:
The state of the CoilSet for optimisation
- Return type:
- set_optimisation_state(opt_currents: numpy.ndarray | None = None, coil_position_map: dict[str, numpy.ndarray] | None = None, current_scale: float = 1.0)
Set the state of the CoilSet, post optimisation. If control coils are set then this is accounted for.
Used in conjunction with get_optimisation_state.
- Parameters:
opt_currents (numpy.ndarray | None) – The optimisation currents
coil_position_map (dict[str, numpy.ndarray] | None) – The map of coil names to positions: [x, z]
current_scale (float) – The scale of the currents
- property n_current_optimisable_coils: int
Get the number of all current optimisable coils. If control coils are set then this is accounted for.
This will only count the primary coil in the case of a SymmetricCircuit pair or coils.
- Return type:
int
- property current_optimisable_coil_names: list[str]
Get the names of all current optimisable coils. If control coils are set then this is accounted for.
This will be the primary coil in the case of a SymmetricCircuit pair or coils.
- Return type:
list[str]
- property all_current_optimisable_coils: list[bluemira.equilibria.coils._coil.Coil]
Get a list of all coils that can be current optimised. If control coils are set then this is accounted for.
- Return type:
- get_current_optimisable_coils(coil_names: list[str] | None = None) CoilSet
Get a coils that can be current optimised. If control coils are set then this is accounted for.
If coil_names is given, only the coils with those names are returned. Names in coil_names must be a subset of current optimisable coils.
- Parameters:
coil_names (list[str] | None) – The names of the coils to get. If None, all current optimisable coils are returned.
- Raises:
ValueError – If a name in coil_names in not in all_current_optimisable_coils.
- Return type:
- property _opt_currents_inds: list[int]
Get the indices of the coils that can be optimised. If control coils are set then this is accounted for.
These indices are used to extract the optimisable currents from the CoilSet and are based on the index of the coils in the name array.
- Return type:
list[int]
- property _contains_circuits: bool
A simple check to see if the CoilSet contains any Circuits.
- Return type:
bool
- property _opt_currents_expand_mat: numpy.ndarray
Get the optimisation currents expansion matrix.
This matrix is used to convert the optimisable currents to the full set of currents in the CoilSet.
- Raises:
ValueError – Number of optimisable coils not equal number of groups/coils
- Return type:
numpy.ndarray
- property _opt_currents: numpy.ndarray
Get the currents for the optimisable coils. If control coils are set then this is accounted for.
- Return type:
numpy.ndarray
- property n_position_optimisable_coils: int
Get the number of coils that can be position optimised. If control coils are set then this is accounted for.
This will only count the primary coil in the case of a SymmetricCircuit pair or coils.
- Return type:
int
- property position_optimisable_coil_names: list[str]
Get the names of the coils that can be position optimised. If control coils are set then this is accounted for.
This will be the primary coil in the case of a SymmetricCircuit pair or coils.
- Return type:
list[str]
- property all_position_optimisable_coils: list[bluemira.equilibria.coils._coil.Coil]
Get the names of all coils that can be position optimised. If control coils are set then this is accounted for.
- Return type:
- get_position_optimisable_coils(coil_names: list[str] | None = None) CoilSet
Get the coils that can be position optimised. If control coils are set then this is accounted for.
- Parameters:
coil_names (list[str] | None) – The names of the coils to get the positions of. If None, all position optimisable coils are returned.
- Raises:
ValueError – Coil’s position not optimisable
- Return type:
- _get_opt_positions(position_coil_names: list[str] | None = None) tuple[numpy.ndarray, numpy.ndarray]
Get the positions of the position optimisable coils.
- Parameters:
position_coil_names (list[str] | None) – The names of the coils to get the positions of. If None, all position optimisable coils are returned.
- Returns:
The x coordinates
The z coordinates
- Return type:
tuple[numpy.ndarray, numpy.ndarray]
- _set_opt_positions(coil_position_map: dict[str, numpy.ndarray]) None
Set the positions of the position optimisable coils.
- Parameters:
coil_position_map (dict[str, numpy.ndarray])
- Return type:
None