beamtracer.field_map
Gridded external fields read from and written to xarray/netCDF field maps.
A field map holds b_field_<i> (T) and/or e_field_<i> (V/m) on node coordinates
x, y, z (m): magnet and coil maps, or fields computed offline on fitted
meshes (NGSolve, FEniCSx). FieldMap reads and writes one, checks it with
validate_field_map and interpolates it multilinearly to any position. It gives
beamtracer.model.BeamOpticsan imposed E and/or B, added to the solved field and the solenoids (field_map: {file: magnets.nc}in its configuration,beamtracer.config.FieldMapParams);beamtracer.beamline.FieldRegionitselectricandmagneticfields (FieldRegion(..., magnetic=FieldMap.read("stray.nc"))).
The format is shared. It is the field-map layout of the max-models output format,
Conventions = "max-models-field-map-1.0", whose specification and reference
validator live in picnic (picnic.input_output.output_format: the module docstring
and validate_field_map; picnic reads and writes maps with
picnic.parameters.field_map.FieldMap). beamtracer does not depend on picnic, so
this module implements the same layout and the same checks, and a map written by
either code is read by the other. A shared home for the specification and the
validator (a module of an existing package or a small interfaces package) is still
to be decided; until then, a change to the layout is made in both places.
The layout:
- dims an ordered subset of
(x, y, z), each with an increasing coordinate inm; a map may have fewer dims than the positions it is evaluated at and is then uniform along the others (a 1D profileB_z(x)in a 3D region); - variables
b_field_<i>(units = "T") and/ore_field_<i>(units = "V/m"),<i>inx, y, z, each on all the map’s dims in that order; - attributes
Conventions(FIELD_MAP_FORMAT),frame("cartesian", or"cylindrical"for the axisymmetric(x, r)plane:xaxial,ythe radius, and here thezcomponent the azimuthal one,x, r, thetaright-handed), optionallyframe_axes(the dims in the device frame of the spokes3d conventions, seeparse_frame_axes) andsource(what produced it).
Outside the map the field is that of the nearest boundary node (outside="clip"),
zero ("zero") or an error ("error")::
field_map = FieldMap.from_function( lambda p: np.stack([0 * p[:, 0], 0 * p[:, 0], 0.01 * np.exp(-p[:, 0] ** 2 / 1e-4)], 1), {"x": np.linspace(0, 0.05, 101)}, kind="magnetic", source="analytic",)field_map.write("magnets.nc")Attributes
| Name | Description |
|---|---|
FIELD_MAP_FORMAT | No description. |
FRAMES | No description. |
Classes
| Name | Description |
|---|---|
FieldMap | A gridded external field in the shared field-map layout, interpolated to positions. |
FieldMapError | A dataset does not follow the field-map layout. |
Functions
| Name | Description |
|---|---|
parse_frame_axes | Parse a frame_axes attribute such as "x=z y=-s z=r". |
validate_field_map | What ds gets wrong against the field-map layout (picnic's checks). |
FIELD_MAP_FORMATattributemodule attribute#
FIELD_MAP_FORMAT = 'max-models-field-map-1.0'FRAMESattributemodule attribute#
FRAMES = ('cartesian', 'cylindrical')FieldMapclass#
class FieldMap(dataset: xr.Dataset, path: str | Path | None = None, outside: str = 'clip')A gridded external field in the shared field-map layout, interpolated to positions.
Attributes
| Name | Description |
|---|---|
dataset | The map, checked with validate_field_map. |
path | The file it was read from or written to, if any. |
outside | What the field is outside the map: "clip" (the nearest boundary
node’s), "zero" or "error". |
dims | The map’s dims, an ordered subset of ("x", "y", "z"). |
Numerics
multilinear
outside
Order of accuracy: 2.
Assumptions:
- each component on the nodes of a tensor-product mesh of increasing (not necessarily uniform) coordinates
- a map with fewer dims than the positions is uniform along the missing axes
- the order is in the node spacing, for a smooth field
datasetattributeinstance attribute#
dataset = datasetdimsattributeinstance attribute#
dims = tuple((dim for dim in AXES if dim in dataset.dims))outsideattributeinstance attribute#
outside = outsidepathattributeinstance attribute#
path = None if path is None else Path(path)componentsmethod#
def components(kind: str) -> tuple[str, ...]The names of the components of kind in the map, e.g. ("b_field_z",).
Parameters
| Name | Type | Description |
|---|---|---|
kind | str | "magnetic" or "electric". |
electric_fieldmethod#
def electric_field(positions: Any) -> np.ndarrayE (V/m) at positions (N, ndim), as (N, ndim).
evaluatemethod#
def evaluate(coordinates: tuple[Any, ...], kind: str = 'magnetic') -> np.ndarrayThe field on a mesh, (*mesh, num_components).
fieldmethod#
def field(kind: str, positions: Any, num_components: int) -> np.ndarrayThe field of kind at positions, num_components of it.
Parameters
Returns
np.ndarray(N, num_components)in T or V/m.
from_arraysmethodclassmethod#
def from_arrays(coordinates: Mapping[str, Any], components: Mapping[str, Any], frame: str = 'cartesian', frame_axes: str | None = None, source: str = '', outside: str = 'clip') -> FieldMapBuild a map from node coordinates and component arrays.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
coordinates | Mapping[str, Any] | required | {"x": nodes, ...} in m, increasing. |
components | Mapping[str, Any] | required | {"b_field_z": values, ...} (T or V/m), each of the shape of
the mesh of coordinates (in the order x, y, z). |
frame | str | 'cartesian' | The frame attribute. |
frame_axes | str | None | None | The frame_axes attribute, if any. |
source | str | '' | What produced the map (a script, a solver and its mesh, a measurement). |
outside | str | 'clip' | See FieldMap. |
from_functionmethodclassmethod#
def from_function(function: Callable[[np.ndarray], np.ndarray], coordinates: Mapping[str, Any], kind: str = 'magnetic', **kwargs: Any) -> FieldMapSample a field function on the mesh of coordinates.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
function | Callable[[np.ndarray], np.ndarray] | required | The field at positions (N, ndim) (m), as
(N, num_components), the components x, y, ... (beyond the third
ignored). |
coordinates | Mapping[str, Any] | required | {"x": nodes, ...} in m. |
kind | str | 'magnetic' | "magnetic" (b_field_*) or "electric" (e_field_*). |
**kwargs | Any | {} | Passed to from_arrays. |
magnetic_fieldmethod#
def magnetic_field(positions: Any) -> np.ndarrayB (T) at positions (N, ndim), as (N, 3).
plane_functionmethod#
def plane_function(kind: str) -> Callable[[np.ndarray, np.ndarray], tuple[np.ndarray, ...]]The field of kind as F(x, y) -> (F_x, F_y, F_z) on a 2D plane.
The form of beamtracer.solver.BeamTracer’s imposed fields: (x, y)
planar, or (x, r) -> (F_x, F_r, F_theta) in a "cylindrical" map.
points_functionmethod#
def points_function(kind: str) -> Callable[[np.ndarray], np.ndarray]The field of kind as F(points), (3, N) at (3, N) points.
The form of beamtracer.beamline.FieldRegion’s fields, in a
"cartesian" map.
readmethodclassmethod#
def read(path: str | Path, outside: str = 'clip') -> FieldMapRead a field map from a netCDF file (loaded into memory).
writemethod#
def write(path: str | Path, **kwargs: Any) -> PathWrite the map to the netCDF file path and remember it there.
FieldMapErrorclass#
class FieldMapError(ValueError)Bases: ValueError
A dataset does not follow the field-map layout.
parse_frame_axesfunction#
def parse_frame_axes(text: str) -> dict[str, tuple[int, str]]Parse a frame_axes attribute such as "x=z y=-s z=r".
Space-separated <dim>=[-]<device axis> items; the device axes are r,
theta (or s, the arc length along it) and z of the spokes3d
conventions (z normal to the target into the plasma).
Parameters
| Name | Type | Description |
|---|---|---|
text | str | The attribute. |
Raises
FieldMapError- On a malformed item, a repeated dim or axis, or three mapped axes that are not right-handed.
validate_field_mapfunction#
def validate_field_map(ds: xr.Dataset) -> list[str]What ds gets wrong against the field-map layout (picnic’s checks).
Parameters
| Name | Type | Description |
|---|---|---|
ds | xr.Dataset | A field map: b_field_<i> and/or e_field_<i> on (x[, y[, z]]). |