EM-App User Guide & Reference
User Guide
1. Getting Started
To simulate a magnetic field, define a coil and a set of points:
from em_app.sources import RingCoil
from em_app.solvers import calculate_b_field
import numpy as np
# Define a coil
coil = RingCoil(current=1.0, radius=0.5, center_point=[0,0,0], axis_direction=[0,0,1])
# Define points (N, 3) array
points = np.random.rand(100, 3)
# Calculate B-field
# Returns a VectorField object (SoA optimized)
b_field = calculate_b_field(coil, points)
Note
Performance Optimization (SoA): As of v0.2.0, this function returns a VectorField using a Structure of Arrays (SoA) memory layout.
The components (Bx, By, Bz) are stored as contiguous numpy arrays rather than lists of vector objects.
This significantly improves memory locality and SIMD vectorization performance.
2. High-Performance Backends
EM-App uses sandalwood for accelerated computation. The solver automatically selects the best kernel (“Hybrid Dispatch”):
Discrete Mode (Fast Path): If you use standard numerical inputs (float arrays) and use_mtf_for_segments=False (default), the solver uses a raw Fortran kernel (~100x speedup). This is ideal for field mapping and particle tracking where derivatives are not needed.
Parametric Mode (DA Mode): If you pass sandalwood.mtf objects or enable use_mtf_for_segments=True in the Coil geometry, the solver uses Differential Algebra. This computes high-order derivatives and Taylor maps but is computationally more expensive.
3. Memory Management
When running large parametric simulations (DA mode), COSY requires explicit memory management to avoid exhausting the static Fortran memory pool. Use CosyScope to prevent stack overflows:
from sandalwood.backends.cosy_scope import CosyScope
# Frees DA memory after block exits
with CosyScope():
b_field = calculate_b_field(coil, points)
Module Reference
em_app.plotting module
This module contains functions for plotting magnetic field data.
- em_app.plotting.plot_1d_field(coil_instance, field_component: str, axis: str = 'x', start_point: ndarray | None = None, end_point: ndarray | None = None, num_points: int = 100, plot_type: str = 'line', log_scale: bool = False, ax=None, title: str = '', xlabel: str = '', ylabel: str = '', **kwargs)[source]
Plots a vector field component along a 1D line.
- em_app.plotting.plot_2d_field(coil_instance, field_component: str = 'norm', plane: str = 'xy', center: ndarray | None = None, normal: ndarray | None = None, size_a: float | None = None, size_b: float | None = None, num_points_a: int = 50, num_points_b: int = 50, plot_type: str = 'heatmap', ax=None, title: str = '', offset_from_center: float = 0.0, **kwargs)[source]
Plots a vector field on a 2D plane.
- Parameters:
coil_instance – The coil object to calculate the field from.
field_component (str) – Component to plot (‘x’, ‘y’, ‘z’, or ‘norm’).
plane (str) – Plane to plot on (‘xy’, ‘yz’, or ‘xz’).
center (np.ndarray, optional) – Center point of the plot. Defaults to coil center.
normal (np.ndarray, optional) – Normal vector for custom plane.
size_a (float, optional) – Size along the first axis of the plane.
size_b (float, optional) – Size along the second axis of the plane.
num_points_a (int) – Grid points along first axis.
num_points_b (int) – Grid points along second axis.
plot_type (str) – Type of plot (‘heatmap’, ‘quiver’, ‘streamline’).
ax (matplotlib.axes.Axes, optional) – Matplotlib axis to plot on.
title (str) – Plot title.
offset_from_center (float) – Offset from the center along the normal.
**kwargs – Additional arguments passed to the plotting function.
- em_app.plotting.plot_field_vectors_3d(coil_instance, num_points_a: int = 10, num_points_b: int = 10, num_points_c: int = 10, title: str = '', ax=None, **kwargs)[source]
Generates a 3D quiver plot of the magnetic field vectors on a grid around the coil.
This method automatically creates a grid of field points based on the coil’s dimensions and then calculates and plots the magnetic field vectors at these points.
- Parameters:
coil_instance (Coil) – An instance of a Coil subclass.
num_points_a (int) – Number of grid points along the x-dimension.
num_points_b (int) – Number of grid points along the y-dimension.
num_points_c (int) – Number of grid points along the z-dimension.
title (str, optional) – The title of the plot. Defaults to an auto-generated title.
ax (matplotlib.axes.Axes3D, optional) – The 3D axis to plot on. If None, a new figure is created.
**kwargs – Additional keyword arguments for the ax.quiver function.
em_app.solvers module
- class em_app.solvers.Backend(value)[source]
Bases:
str,Enum- COSY = 'cosy'
- MPI = 'mpi'
- MPI_COSY = 'mpi_cosy'
- PYTHON = 'python'
- em_app.solvers.calculate_b_field(coil_instance, field_points, backend=Backend.PYTHON)[source]
Calculates the magnetic field generated by a coil at a set of field points using the Biot-Savart law.
- Parameters:
coil_instance (Coil) – An instance of a Coil subclass.
of (field_points (np.ndarray or np.ndarray) – mtf.MultivariateTaylorFunction): The points (x, y, z) where the magnetic field should be calculated. Can be a (M, 3) NumPy array of numbers or MTF objects.
backend (Backend or str, optional) – The backend to use for the calculation. Defaults to Backend.PYTHON.
- Returns:
- A VectorField object containing the field points and the
calculated FieldVector objects.
- Return type:
- em_app.solvers.mpi_biot_savart(element_centers, element_lengths, element_directions, field_points, order=None, backend=Backend.PYTHON)[source]
Parallel Biot-Savart calculation using mpi4py. Returns tuple (Bx, By, Bz).
em_app.sources module
- class em_app.sources.Coil(current, use_mtf_for_segments=True, wire_thickness=0.001)[source]
Bases:
objectBase class for a current-carrying coil.
This class provides a common interface for different coil shapes, storing their properties (like current) and the discretized segments used for numerical calculations.
- get_center_point() ndarray[source]
Calculates the approximate center point of the coil.
- Returns:
A (3,) array representing the center of the coil.
- Return type:
np.ndarray
- get_max_size() ndarray[source]
Calculates the maximum extent of the coil in each dimension.
- Returns:
- A (3,) array of the maximum size of the coil
(width, height, depth).
- Return type:
np.ndarray
- get_segments()[source]
Returns the segments of the coil.
- Returns:
- A tuple containing:
segment_centers (np.ndarray): Array of MTF center points.
segment_lengths (np.ndarray): Array of MTF segment lengths.
segment_directions (np.ndarray): Array of MTF direction vectors.
- Return type:
tuple
- plot(ax=None, color='#B87333', num_interpolation_points=2, wire_thickness=None, show_axis=False)[source]
Plots the coil segments in a 3D matplotlib axis.
If a 3D axis is provided, the coil will be plotted on it. Otherwise, a new figure and a new 3D axis will be created.
- Parameters:
ax (matplotlib.axes.Axes3D) – The 3D axis to plot on. Defaults to None.
color (str) – The color for the plotted segments. Defaults to a copper-like hex code.
num_interpolation_points (int) – The number of points to plot for each segment, including start and end points. This is only used when use_mtf_for_segments is True. Defaults to 2.
wire_thickness (float) – The thickness of the wire to plot. Defaults to the thickness specified at initialization.
show_axis (bool) – Whether to plot the central axis of the coil. Defaults to False.
- class em_app.sources.RectangularCoil(current, p1, p2, p4, num_segments_per_side, use_mtf_for_segments=True, wire_thickness=0.001)[source]
Bases:
CoilRepresents a rectangular current-carrying coil.
- static generate_geometry(p1, p2, p4, num_segments_per_side, use_mtf_for_segments=True, integration_var_index=None)[source]
(PRIVATE) Generates segments for a rectangular coil.
- Parameters:
num_segments_per_side (int) – Segments per side.
use_mtf_for_segments (bool) – Whether to use MTF for segments.
integration_var_index (int, optional) – The index of variable u.
- Returns:
- A tuple containing:
segment_centers (np.ndarray): Array of MTF center points.
segment_lengths (np.ndarray): Array of segment lengths.
segment_directions (np.ndarray): Array of MTF direction vectors.
- Return type:
tuple
- class em_app.sources.RingCoil(current, radius, num_segments, center_point, axis_direction, use_mtf_for_segments=True, wire_thickness=0.001, integration_var_index=None)[source]
Bases:
CoilRepresents a circular current-carrying coil.
- static generate_geometry(ring_radius, num_segments_ring, ring_center_point, ring_axis_direction, use_mtf_for_segments=True, integration_var_index=None)[source]
(PRIVATE) Generates MTF representations for segments of a current ring.
This is a private helper function and should not be used directly.
- Parameters:
ring_radius (float) – Radius of the current ring.
num_segments_ring (int) – Number of segments to discretize the ring into.
ring_center_point (numpy.ndarray) – (3,) array defining the center coordinates (x, y, z) of the ring.
ring_axis_direction (numpy.ndarray) – (3,) array defining the direction vector of the ring’s axis (normal to the plane of the ring).
integration_var_index (int, optional) – The index of variable u.
- Returns:
- A tuple containing:
segment_representations (numpy.ndarray): (N,) array of MTFs or (N, 3) array of segment center points.
element_lengths_ring (numpy.ndarray): (N,) array of lengths of each ring segment (dl).
direction_vectors (numpy.ndarray): (N, 3) array of MTF direction vectors or NumPy direction vectors.
- Return type:
tuple
em_app.vector_fields module
Vector and Vector Field representations.
This module provides classes for representing 3D vectors and vector fields, with support for numerical data and sandalwood Multivariate Taylor Functions (MTFs). It includes classes like Vector, FieldVector, VectorField, and VectorFieldGrid.
- class em_app.vector_fields.FieldVector(x, y, z)[source]
Bases:
VectorRepresents a vector at a point in a field, with components that can be Multivariate Taylor Functions (MTFs).
- curl()[source]
Calculates the curl of the B-field vector.
The curl of the B-field is given by the formula: $nabla times mathbf{B} = (frac{partial B_z}{partial y} - frac{partial B_y}{partial z}) mathbf{i} + (frac{partial B_x}{partial z} - frac{partial B_z}{partial x}) mathbf{j} + (frac{partial B_y}{partial x} - frac{partial B_x}{partial y}) mathbf{k}$
This method uses the derivative method from sandalwood to compute the partial derivatives.
- Returns:
- A new FieldVector object representing the curl of the
field.
- Return type:
- divergence()[source]
Calculates the divergence of the B-field.
The divergence of a vector field is a scalar value given by the formula: $nabla cdot mathbf{B} = frac{partial B_x}{partial x} + frac{partial B_y}{partial y} + frac{partial B_z}{partial z}$
This method uses the derivative method from sandalwood to compute the partial derivatives and then sums the resulting MTF objects.
- Returns:
- A single MTF representing the
scalar divergence of the field.
- Return type:
mtf.MultivariateTaylorFunction
- gradient()[source]
Calculates the Jacobian matrix of the B-field vector.
The gradient of a vector field is a 3x3 matrix where each element is the partial derivative of a component of B with respect to a spatial variable.
- Returns:
A 3x3 array of MTFs representing the Jacobian matrix.
- Return type:
np.ndarray
- class em_app.vector_fields.Vector(*components)[source]
Bases:
objectA generic class to represent a 3D vector. This class handles standard vector operations like addition, subtraction, scalar multiplication/division, dot product, and cross product.
- dot(other)[source]
Calculates the dot product with another Vector object.
- Parameters:
other (Vector) – The Vector object to take the dot product with.
- Returns:
- The scalar result of the
dot product.
- Return type:
mtf.MultivariateTaylorFunction or float
- classmethod from_array_of_vectors(array)[source]
Creates a NumPy array of Vector objects from a 2D NumPy array.
- Parameters:
array (np.ndarray) – A NumPy array of shape (N, 3), where N is the number of vectors.
- Returns:
A NumPy array of Vector objects.
- Return type:
np.ndarray
- is_mtf()[source]
Checks if any of the Vector’s components are MTF objects.
- Returns:
True if any component is an MTF, False otherwise.
- Return type:
bool
- norm()[source]
Calculates the magnitude (L2-norm) of the vector.
- Returns:
The scalar magnitude.
- Return type:
float or mtf.MultivariateTaylorFunction
- to_dataframe(column_names)[source]
Converts the Vector components into a pandas DataFrame.
This method is a helper for creating a clean, tabular representation of the vector, especially when components are MTF objects.
- Parameters:
column_names (list of str) – A list of three strings to be used as the column names for the components.
- Returns:
- A DataFrame representing the vector’s components
and their coefficients if they are MTFs.
- Return type:
pandas.DataFrame
- class em_app.vector_fields.VectorField(vectors, field_points=None)[source]
Bases:
objectA class to store a collection of FieldVector objects, representing a vector field at a set of discrete points in space.
This class can handle both numerical and MTF-based field data.
- get_magnitude()[source]
Calculates and returns the magnitude of each B-vector in the field.
- Returns:
A 1D NumPy array of the magnitudes.
- Return type:
np.ndarray
- quiver(dimension=3, title='Vector Field Quiver Plot', ax=None, **kwargs)[source]
Creates a 3D quiver plot of the vector field.
- Parameters:
title (str, optional) – The title of the plot.
ax (matplotlib.axes.Axes, optional) – An existing 3D Axes object to plot on.
**kwargs – Additional keyword arguments passed to ax.quiver.
- scatter(title='Vector Field Scatter Plot', ax=None, **kwargs)[source]
Creates a 3D scatter plot of the vector field with direction arrows. The color and length of the arrows represent the magnitude of the vectors. This method provides a way to visualize the raw vector field, where arrow lengths are proportional to the vector strength.
- Parameters:
title (str, optional) – The title of the plot.
ax (matplotlib.axes.Axes, optional) – An existing 3D Axes object to plot on.
**kwargs – Additional keyword arguments passed to ax.quiver.
- class em_app.vector_fields.VectorFieldGrid(vectors, field_points, grid_shape, grid_axes)[source]
Bases:
VectorFieldA subclass of VectorField for data on a structured 1D, 2D, or 3D grid.
This class is designed to hold vector field data that is arranged on a structured grid. It stores grid metadata (shape and axes) to allow for easy reshaping of the data for grid-based analysis and plotting.