Expand description
§Magba
Magba is a performant analytical magnetic computation library for Rust.
In Magba, the sources submodule provides structs such as CylinderMagnet and Dipole. These objects can compute magnetic fields and transform. The sources can be grouped into source collections. This is the recommended way to interact with the API.
The submodule fields can be accessed to directly compute the fields. All physical quantities are assumed to be in SI units. The submodule conversion provides functions to conveniently convert between physical quantities.
The source code is available on GitHub.
§Features
- Compute magnetic fields analytically for various source geometries.
- Create magnetic sources and group them as source collections.
- Move and rotate objects in 3D space.
- Increase performance using parallelization with Rayon.
- Support calculation with f32 and f64.
- Python bindings available via Pymagba
§Installation
To install Magba using cargo
, simply run in your command line:
>> cargo add magba
By default, Magba installs with all stable features enabled. To install only the specified feature flags, use:
>> cargo add magba --no-default-features --features sources,parallel
The available feature flags are:
default
: Enablesources
andparallel
.transform
: Enable spatial transformation functionalities.sources
: Magnetic source structs and collections. Also enabletransform
.parallel
: Enable parallelization with Rayon for performance.unstable
: Enable unstable features. These features may change any time.
§Sources and Collections
The magnetic sources are located in the sources submodule. The parameters of the sources
can be accessed and modified using getters and setters, such as position()
and set_position()
.
The sources can be grouped as source collections. For performance, there are two types of source collections, the SourceCollection and MultiSourceCollection. SourceCollection is faster, as it is stack-allocated. However, it can only hold the same type of Source. Meanwhile, MultiSourceCollection is slower due to heap allocation but can holdheterogenous source types encapsulated in Box.
§Defining Sources and Grouping as MultiSourceCollection
use magba::*;
use nalgebra::*;
let cylinder = Box::new(CylinderMagnet::default());
let cuboid = Box::new(CuboidMagnet::new(
Point3::new(1.0, 0.0, 0.0), // position (m)
UnitQuaternion::identity(), // orientation
Vector3::z(), // polarization (T)
Vector3::new(0.1, 0.2, 0.3), // dimensions (m)
));
let mut collection = MultiSourceCollection::from_sources(vec![cylinder, cuboid]);
collection.add(Box::new(Dipole::default()));
§Stack-allocated Collection
use magba::*;
use nalgebra::*;
use std::f64::consts::PI;
let magnet1 = CylinderMagnet::new(
Point3::new(0.0, 0.0, 1.0), // position (m)
UnitQuaternion::identity(), // orientation
Vector3::z(), // polarization (T)
0.1, // radius (m)
0.2, // height (m)
);
let mut magnet2 = magnet1.clone();
magnet2.rotate_anchor(
&UnitQuaternion::from_scaled_axis(Vector3::new(PI, 0.0, 0.0)),
&Point3::origin(),
);
let collection = SourceCollection::from_sources(vec![magnet1, magnet2]);
§Field Computation
The methods like Field::get_B are available for all Source and types that implement Field, including SourceCollection and MultiSourceCollection.
use magba::*;
use magba::util::*;
use nalgebra::*;
// A unit cylinder magnet (pol=(0,0,1), r=1, h=1) at (0,0,0), q=(0,0,0,1)
let mut magnet = CylinderMagnet::default();
// Observer positions
let points = [
Point3::new(0.0, 0.0, 0.020),
Point3::new(0.0, 0.0, 0.025),
Point3::new(0.0, 0.0, 0.030),
];
// Compute the magnetic field
let b_fields = magnet.get_B(&points);
let expected = [
Vector3::new(0.0, 0.0, 0.4470419021133804),
Vector3::new(0.0, 0.0, 0.446945356779104),
Vector3::new(0.0, 0.0, 0.44682738840312125),
];
b_fields.iter().zip(expected).for_each(|(b, b_ref)| {assert_close_vector_elem!(b, &b_ref, 1e-12);});
use magba::conversion::*;
let h_field = Bs_to_Hs(&b_fields);
§Move and Rotate Objects
The transformation functionalities are implemented for all Source and types with Transform trait. The available methods are:
- Transform::position and Transform::set_position
- Transform::orientation and Transform::set_orientation
- Transform::translate
- Transform::rotate and Transform::rotate_anchor
use magba::*;
use nalgebra::*;
use std::f64::consts::PI;
// Define mutable object to allow transformations.
let mut magnet = CylinderMagnet::new(
Point3::origin(),
UnitQuaternion::identity(),
Vector3::new(0.0, 0.0, 0.9),
0.005,
0.020,
);
// Computing the magnetic field
let points = [Point3::new(0.0, 0.0, 0.05)];
let b = magnet.get_B(&points)[0];
let expected = Vector3::new(0.0, 0.0, 0.0019205466890453442);
assert_close_vector_elem!(&b, &expected, 1e-12);
// Moving the magnet
magnet.translate(&Translation3::new(0.0, 0.0, 0.01));
let b = magnet.get_B(&points)[0];
let expected = Vector3::new(0.0, 0.0, 0.0038894698700304275);
assert_close_vector_elem!(&b, &expected, 1e-12);
magnet.set_position(Point3::new(0.0, 0.0, 0.02));
let b = magnet.get_B(&points)[0];
let expected = Vector3::new(0.0, 0.0, 0.00996091945575112);
assert_close_vector_elem!(&b, &expected, 1e-12);
// Rotating the magnet
magnet.rotate(&UnitQuaternion::from_scaled_axis(Vector3::new(PI / 4.0, 0.0, 0.0)));
let b = magnet.get_B(&points)[0];
let expected = Vector3::new(3.9407500527173422e-19, 0.0035238379945531874, 0.005577663229073966);
assert_close_vector_elem!(&b, &expected, 1e-12);
magnet.set_orientation(UnitQuaternion::from_scaled_axis(Vector3::new(PI / 2.0, 0.0, 0.0)));
let b = magnet.get_B(&points)[0];
let expected = Vector3::new(6.086025172136602e-35, 0.003642460886175623, 0.0);
assert_close_vector_elem!(&b, &expected, 1e-12);
§Direct Field Calculation
If you only need to access the field functions, you can use the fields submodule and disable
the sources
feature by running cargo add magba --no-default-features --features parallel
.
The core field computation functions, such as computation in local frame, are available under
the unstable
feature flag.
use magba::*;
use magba::fields;
use nalgebra::*;
// Compute the magnetic field of a cylinder magnet.
let b = fields::cylinder_B(
&[Point3::new(1.0, -1.0, 0.0)], // observer positions (m)
&Point::origin(), // magnet position (m)
&UnitQuaternion::identity(), // magnet orientation
&Vector3::new(1.0, 2.0, 3.0), // polarization (T)
1.0, // radius (m)
2.0, // height (m)
)[0]; // Extract the element since the field function returns a vec of Vector3.
let expected = Vector3::new(-0.3684605662842379, -0.10171405289381347, -0.330064920993222);
assert_close_vector_elem!(&b, &expected, 1e-12);
§Acknowledgment
Most of the field computation used in Magba is based on MagpyLib. We would like to thank MagpyLib contributors their hard work and contributions to the scientific community.
Modules§
- constants
- Physical constants used in magnetic field calculations.
- conversion
- Conversion tools for magnetic field-related quantities.
- fields
- Analytical computation of magnetic fields for various source geometries.
- geometry
- Geometric utilities for 3D transformations and coordinate conversions.
- sources
- Magnetic source traits and structs.
- util
- Utilities for Magba.
Macros§
- assert_
close_ vector_ elem - Panics if the elements of two vectors are not close.
Structs§
- Cuboid
Magnet - Uniformly magnetized cylindrical magnet in 3D space.
- Cylinder
Magnet - Uniformly magnetized cylindrical magnet in 3D space.
- Dipole
- Magnetic dipole in 3D space.
- Multi
Source Collection - Heap-allocated collection of multiple source types.
- Source
Collection - Stack-allocated collection of a single source type.
Traits§
- Field
- Trait shared by objects that generate magnetic field.
- Float
- Generic trait for floating point numbers compatible with all Magba implementations.
- Source
- Trait shared by magnetic sources.
- Transform
- Trait for transforming objects in 3D Cartesian CS with methods for translation, rotation, and rotation with anchor.