Submodule: mfs.helpers¶
Assistance functions
Overview¶
Rotation matricies
|
Calculcate the rotation matrix to rotate around the Z-axis by angle theta (radians) |
Calculcate the rotation matrix to rotate around the X-axis by angle phi (radians) |
|
|
Rotate the 3-element vector |
|
Rotate the 3-element array |
Display magnetic field
|
Plot the magnitude of the B-field along a 1D axis |
|
Produce a 2D quiver plot of the vector B-field arising from a set of magnets |
|
Print the value of the B-field gradient along the x and y axes around centre in G/cm |
Detailed Documentation¶
-
mfs.helpers.evaluate_axis_projection(projection)¶ Interpret a 2D projection request
Interprets a string containing the unique letters ‘xyz’ into indicies for reading values out of an array and plotting a projection. The first letter will go on the graph’s X-axis, the 2nd letter on the graph’s Y axis.
For example, ‘zyx’ or ‘zy’ will result in projecting the simulation’s Z-axis onto the horizontal axis of a 2D graph (and label it accordingly), and the simulation’s Y-axis onto the vertical axis of the 2D graph.
- Parameters
- projection: str
Desired projection order
- Returns
- axOnePos: int
The index of the simulation axis that will be placed on the graph’s first (x) axis. For example, if the string was ‘zyx’, this will have the value 2
- axTwoPos: int
The index of the simulation axis that will be placed on the graph’s second (y) axis. For example, if the string was ‘zyx’, this will have the value 1
- axThreePos: int
The index of the simulation axis that will be placed on the graph’s third (z) axis. For example, if the string was ‘zyx’, this will have the value 0
-
mfs.helpers.plot_scalar_B_field(magnets, axes, centre, limit, projection, points)¶ Plot the magnitude of the B-field along a 1D axis
Axis must be parallel to one of the global cardinal dimensions.
- Parameters
- magnets: magnet or list of magnets
Group of magnets over which to calculate
- axes: matplotlib.Axes
axes on which to display the plot. Produced by, e.g., fig, axes = plt.subplots()
- centre: 3-element array
(x, y, z) in global frame
- limit: float
+- limit of the axis along which to calculate field. The axis goes from (centre-lim) to (centre+lim)
- projection: str
Which cardinal axis is your axis parallel to
- points: Number of points at which to calculate B-field.
- Returns
- np.ndarray
Axis of locations along projection at which values were calculated
- np.ndarray
Values of magnitude of B-field along axis
-
mfs.helpers.plot_vector_B_field(magnets, axes, centre, limit, projection, points=50, threads=1)¶ Produce a 2D quiver plot of the vector B-field arising from a set of magnets
Plot a grid of arrows indicating the direction and magnitude of the vector B-field. The values are calculated in a flat plane in the global frame, determined by
centre,projection, andlimit.The grid is
points * pointsin size, covering the areacentre-limittocentre+limitFor large numbers of magnets, multiprocessing is recommended to speed up the calculations. Additional processes can be spawned with the
threadsargument. Particularly recommended with spatially distributed CoilPairs.- Parameters
- magnets: mfs.Magnet or list of mfs.Magnet
All magnet sources to include in the calculation. Should be descendents of mfs.Magnet
- axes: matplotlib.Axes
Matplotlib axes objects on which to display the resulting figure
- centre: np.ndarray
Origin of the grid over which the B field is calculated: r=(x, y, z)
- limit: float
half-width of the grid over which B-field is calculated The total grid is calculated as (r-limit, r+limit)
- projection: str
Projection over which to evaluate the B-field, see mfs.helpers.evaluate_axis_projection
- points: int
Number of points along each edge of the grid. Computational complexity scales as O(points^2)
- threads: int
Number of concurrent processes. Defaults to the number of logical CPUs available. Operates on a single process if given either 0 or 1 For a small number of magnets, single-threading is dramatically faster due to the overhead of spawning new processes.
- Returns
- np.ndarray
points x pointsarray storing thei'thcomponent of the B field at those locations.idetermed as the first element ofprojection- np.ndarray
points x pointsarray storing thej'thcomponent of the B field at those locations.jdetermed as the second element ofprojection
-
mfs.helpers.print_field_gradient(magnets, centre, label='')¶ Print the value of the B-field gradient along the x and y axes around centre in G/cm
-
mfs.helpers.rotate_around_x(phi)¶ Calculcate the rotation matrix to rotate around the X-axis by angle phi (radians)
- Parameters
- phi: float
Rotation angle in radians
- Returns
- np.ndarray
3x3 array. May be multiplied with a 3-element vector to rotate that vector around the X-axis by theta
-
mfs.helpers.rotate_around_z(theta)¶ Calculcate the rotation matrix to rotate around the Z-axis by angle theta (radians)
- Parameters
- theta: float
Rotation angle in radians
- Returns
- np.ndarray
3x3 array. May be multiplied with a 3-element vector to rotate that vector around the Z-axis by theta
-
mfs.helpers.rotate_to_dashed_frame(r, theta, phi)¶ Rotate the 3-element vector
raround the X-axis byphi, and then around the Z-axis bythetathetaandphiare extrinsic angles, i.e. the angles remain relative to the global frame, regardless of how many or what rotations are performed.The order is relevant, consider the following example, in which we rotate the y-unit-vector
(0, 1, 0)first byphi=45°, and second bytheta=90°The first rotation, around X, should give us a diagonal in the YZ plane, i.e.
1/sqrt(2) (0, 1, 1)The second rotation takes that diagonal, and rotates it around Z into the XZ plane, to
1/sqrt(2) (-1, 0, 1)We can process this in two separate, discrete, steps
>>> unit_y = np.array([0,1,0]) >>> stage_1a = rotate_to_dashed_frame(unit_y, theta=0, phi=np.radians(45)) >>> stage_1a array(0, 0.7071, 0.7071 )
>>> stage_2a = rotate_to_dashed_frame(stage_1a, theta=np.radians(90), phi=0) >>> stage_2a array(-0.7071, 0, 0.7071)
We can consider what the outcome would be if the rotation occurred in the reverse order: i.e. the y-unit-vector rotated first by
theta=90°and then byphi=45°The first rotation, around Z, should give us
(-1, 0, 0)The second rotation, around X, should then have no effect at all, because the vector is on the x-axis.
>>> unit_y = np.array([0,1,0]) >>> stage_1b = rotate_to_dashed_frame(unit_y, theta=np.radians(90), phi=0) >>> stage_1b array(-1, 0, 0) >>> stage_2b = rotate_to_dashed_frame(stage_1b, theta=0, phi=np.radians(45)) >>> stage_2b array(-1, 0, 0)
We can verify that thisfunction behaves in the order shown by the first case in two ways
by examining the matrix multiplication implemented
By comparing the outcome to the two examples given
>>> rotate_to_dashed_frame(unit_y, theta=np.radians(90), phi=np.radians(45)) array (-0.7071, 0, 0.7071)
As we can see, the outcome matches the example given first, i.e. X then Y.
- Parameters
- r: array-like
Vector to rotate, must be 3 elements.
- theta: float
Angle (in radians) to rotate around the Z-axis
- phi: float
Angle (in radians) to rotate around the X-axis
- Returns
- np.ndarray
Rotated array
-
mfs.helpers.rotate_to_normal_frame(rDash, theta, phi)¶ Rotate the 3-element array
rDash, that exists in the dashed frame defined by theta and phi, back into the global frame.The inverse transformation to
rotate_to_dashed_frame. The argumentsthetaandphishould be given as the same values used to transform to the dashed frame to begin with - i.e. these are the angles that define the dashed frame, and not the transformation from the dashed frame, per se.>>> unit_y = np.array([0,1,0]) >>> theta = np.radians(30) >>> phi = np.radians(45) >>> unit_y_dash = rotate_to_dashed_frame(unit_y, theta, phi) >>> unit_y_dash np.array( -0.3536, 0.6123, 0.7071)
If we attempt to transform back with the same angles, we get the original vector
>>> rotate_to_normal_frame(unit_y_dash, theta, phi) np.array(0, 1, 0)
If we attempt to rotate back with the opposite angles, we get something else entirely
>>> rotate_to_dashed_frame(unit_y_dash, -theta, -phi) np.array(-0.6124, -0.25, 0.75)
- Parameters
- rDash: array-like
Vector in Dashed frame to transform back to global frame
- theta: float
angle (in radians) that defines the dashed frame rotation around the Z axis
- phi: float
angle (in radians) that defines the dashed frame rotation around the X axis