Field Computation (B, H, J, M)#
The following is a detailed technical documentation of Magpylib field computation. The tutorial Field Computation (B, H, J, M) shows good practices and illustrative examples.
Object-oriented Interface#
The object-oriented interface relies on the idea that sources of the magnetic field and observers thereof are created as Python objects which can be manipulated at will, and called for field computation. This is done via four top-level functions getB(), getH(), getJ() and, getM(),
B = magpylib.getB(sources, observers, squeeze=True, pixel_agg=None, output="ndarray")
H = magpylib.getH(sources, observers, squeeze=True, pixel_agg=None, output="ndarray")
J = magpylib.getJ(sources, observers, squeeze=True, pixel_agg=None, output="ndarray")
M = magpylib.getM(sources, observers, squeeze=True, pixel_agg=None, output="ndarray")
that compute the respective fields B (B-field), H (H-field), J (polarization) or M (magnetization) generated by sources as seen by the observers in their local coordinates. sources can be any Magpylib source object (e.g. magnets) or a flat list thereof. observers can be an array of position vectors with shape (o1, o2, …, 3), any Magpylib observer object (e.g. sensors), or a flat list thereof. The following code shows a minimal example for Magpylib field computation.
import magpylib as magpy
# Define source and observer objects
loop = magpy.current.Circle(current=1, diameter=0.001)
sens = magpy.Sensor()
# Compute field
B = magpy.getB(loop, sens)
print(B)
# --> [0. 0. 0.00125664]
For quick access, the functions getBHJM are also methods of all Magpylib objects, such that the sources or observers input is the object itself. The above example can be continued as
# Call getB as method of loop
B = loop.getB(sens)
# Call getB as method of loop
B = sens.getB(loop)
with the same result for B.
By default, getB() returns the B-field in units (T), getH() the H-field in units (A/m), getJ() the magnetic polarization in (T) and, getM() the magnetization in (A/m), assuming that all inputs are given in SI units as described in the docstrings.
Hint
In reality, getB() is proportional to the polarization input and therefore returns the same unit. For example, with polarization input in mT, getB() will return mT as well. At the same time when the magnetization input is in (kA/m), then getH() returns (kA/m) as well. The B/H-field outputs are related to a M/J-inputs via a factor of \(µ_0\).
The output of a field computation magpy.getB(sources, observers) is by default a NumPy array of shape (s, p, o, o1, o2, …, 3) where s is the number of input sources, p the (maximal) object path length, o the number of observers, o1, o2, … the sensor pixel shape or the shape of the observer position array input and 3 the three magnetic field components \((B_x, B_y, B_z)\).
squeeze: IfTrue(default) all axes of length 1 in the output (e.g. only a single source) are squeezed.pixel_agg: Select a compatible NumPy aggregator function (e.g.'min','mean') that is applied to the output. For example, withpixel_agg='mean'the mean field of all observer points is returned. With this option it is possible to supplygetBHJMwith multiple observers that have different pixel shapes.output: Change the output format. Options are'ndarray'(default, returns a NumPy ndarray) and'dataframe'(returns a 2D-table Pandas DataFrame).
Note
Magpylib collects all inputs (object parameters), and vectorizes them for the computation which reduces the computation time dramatically for large inputs.
Try to make all field computations with as few calls to getBHJM as possible. Avoid Python loops at all costs!
Functional Interface#
Users can bypass the object-oriented interface and compute fields for i parameter sets via the functional interface—functions provided in the magpylib.func subpackage. These functions offer field computation, including source position and orientation.
Inputs may be scalars or array-like of length i. Scalar inputs are automatically tiled to length i, creating i computation instances. The field is returned with shape (i, 3); when squeeze=True and i=1, the shape is (3,).
For all functions, set field to 'B' or 'H'. The common defaults are positions=(0, 0, 0), orientations=None, and squeeze=True.
The following functions, with their specific parameters (see individual docstrings), make up the subpackage:
circle_field(field, observers, diameters, currents)polyline_field(field, observers, segments_start, segments_end, currents)cuboid_field(field, observers, dimensions, polarizations)cylinder_field(field, observers, dimensions, polarizations)cylinder_segment_field(field, observers, dimensions, polarizations)sphere_field(field, observers, diameters, polarizations)tetrahedron_field(field, observers, vertices, polarizations)dipole_field(field, observers, moments)triangle_charge_field(field, observers, vertices, polarizations)triangle_current_field(field, observers, vertices, current_densities)
The following code demonstrates the functional interface.
import numpy as np
from magpylib.func import cuboid_field
# All inputs and outputs in SI units
# Compute the cuboid field for 3 input instances
i = 3 # number of instances
B = cuboid_field(
field="B",
observers=np.linspace((0, 0, 1), (0, 0, 3), i),
dimensions=np.linspace((1, 1, 1), (3, 3, 3), 3, i),
polarizations=(0, 0, 1),
)
print(B.round(3))
# [[0. 0. 0.135]
# [0. 0. 0.135]
# [0. 0. 0.135]]
This example demonstrates the scale invariance
Note
The functional interface is potentially faster than the object oriented one if users generate the input arrays efficiently with NumPy (e.g. np.arange, np.linspace, np.tile, np.repeat, …).
Core Interface#
At the heart of Magpylib lies a set of core functions that are our implementations of analytical field expressions found in the literature, see Physics and Computation. Direct access to these functions is given through the magpylib.core subpackage which includes,
magnet_cuboid_Bfield(observers, dimensions, polarizations)magnet_cylinder_axial_Bfield(z0, r, z)magnet_cylinder_diametral_Hfield(z0, r, z, phi)magnet_cylinder_segment_Hfield(observers, dimensions, magnetizations)magnet_sphere_Bfield(observers, diameters, polarizations)current_circle_Hfield(r0, r, z, i0)current_polyline_Hfield(observers, segments_start, segments_end, currents)current_sheet_Hfield(observers, vertices, current_densities)dipole_Hfield(observers, moments)triangle_Bfield(observers, vertices, polarizations)
All inputs must be NumPy ndarrays of shape (i, x). Details can be found in the respective function docstrings. The following example demonstrates the core interface.
import numpy as np
import magpylib as magpy
# All inputs and outputs in SI units
# Prepare input
z0 = np.array([1, 1])
r = np.array([1, 1])
z = np.array([2, 2])
# Compute field with core functions
B = magpy.core.magnet_cylinder_axial_Bfield(z0=z0, r=r, z=z).T
print(B)
# --> [[0.05561469 0. 0.06690167]
# [0.05561469 0. 0.06690167]]
Computation Workflow (B, H, J, M)#
The Magpylib field computation internal workflow and different approaches of the three interfaces is outlined in the following sketch.
Magpylib computational flow chart.#