Microcubed
Calculate 3D magnetic stray fields and analytical gradients for uniformly magnetized, axis-aligned cuboids and arrangements. Microcubed provides NumPy and compiled, parallel Rust backends behind the same Python API, plus polygon decomposition and Matplotlib plots.
The field equations follow Ravaud and Lemarquand, Magnetic Field Produced by a Parallelepipedic Magnet of Various and Uniform Polarization. Magnetization is an input; Microcubed does not solve magnetic equilibrium or dynamics.
Installation
Python 3.12 or newer is required. Install the published package with:
python -m pip install microcubed
PyPI wheels contain the compiled Rust backend for supported Linux, macOS, and Windows platforms, so a Rust toolchain is not needed for normal installation. When no matching wheel exists, pip falls back to the source distribution; building that package requires Cargo, rustc, and a platform linker/C compiler.
To install from a checkout:
git clone https://github.com/newton-per-sqm/microcubed.git
cd microcubed
python -m pip install .
The Maturin build includes the Rust extension. At runtime auto selects Rust
when available and otherwise falls back to NumPy. Select a backend explicitly
with microcubed.get_backend("numpy") or microcubed.get_backend("rust").
Use one consistent length unit for size, position, and observation points.
Magnetization is in A/m, Bfield returns T, and dBfield returns T per length
unit. Points are columns in a (3, N) array. Evaluate outside the magnets;
the analytical exterior-field model does not describe their internal field.
Examples
These snippets are generated from the tagged cells in the Jupyter notebooks.
GitHub Actions builds the extension, executes every core notebook, checks numerical
assertions, and uploads executed notebooks and HTML under the examples artifact.
uv sync --locked --extra examples
uv run --locked --extra examples python tools/notebooks.py --check --execute
Open the .ipynb files in a Jupyter-compatible editor using .venv as the
Python environment. Generated HTML is written to build/examples/.
Superposition and field maps
Build a small array by translating one cuboid. The arrangement field is the sum of its members. Sample a plane below the magnets, safely outside all material.
import numpy as np
from microcubed import Arrangement, Magnet
cube = Magnet([80, 80, 40], [0, 0, 0], [0, 0, 8e5])
magnets = [cube.moved_to([x, 0, 0]) for x in (-150, 0, 150)]
array = Arrangement(magnets)
points = np.array([[0, 0, -100], [100, 25, -100]]).T
field = array.Bfield(points)
import matplotlib.pyplot as plt
fig, ax = array.plot_2d(x=(-300, 300, 61), y=(-200, 200, 41), z=-100, component="z")
for index, boundary in enumerate(array.union_boundary("xy")):
ax.plot(*boundary, color="#00ffff", linewidth=2, label="Material boundary" if index == 0 else None)
ax.set(xlabel="x (nm)", ylabel="y (nm)", title="Bz (T) at z = -100 nm", aspect="equal")
ax.legend(loc="upper right", fontsize=8, facecolor="#555555", labelcolor="white", framealpha=0.95)
fig.tight_layout()
plt.show()
Compare NumPy and Rust
Choose backend namespaces explicitly without changing global state. This notebook requires the compiled Rust extension and checks both fields and gradients at exterior points.
import numpy as np
from microcubed import get_backend
points = np.array([[0, 0, -150], [80, 30, -120], [-90, 50, 160]]).T
results = {}
for name in ("numpy", "rust"):
backend = get_backend(name)
magnet = backend.Magnet([100, 80, 40], [0, 0, 0], [2e5, 1e5, 8e5])
results[name] = (magnet.Bfield(points), magnet.dBfield(points))
for reference, compiled in zip(results["numpy"], results["rust"]):
np.testing.assert_allclose(compiled, reference, rtol=1e-9, atol=1e-13)
print("Fields and gradients agree.")
Resolving a polygon boundary
A concave polygon with slanted edges makes rasterization error visible. All lengths
are in nm. delta limits the raster-cell size, not the size of the final cuboids:
merging adjacent occupied cells into larger cuboids preserves the rasterized geometry
exactly. Refining delta improves the staircase approximation along oblique edges.
The previous axis-aligned L-shape could be represented exactly by two large cuboids;
a small cuboid count alone does not imply a coarse approximation.
import numpy as np
from microcubed import cuboidize
polygon = np.array([(0, 0), (120, 15), (95, 65), (55, 45), (35, 115), (-15, 80)])
thickness = 20
magnetization = [0, 0, 8e5]
delta = 0.5
shape = cuboidize(polygon, t=thickness, delta=delta, mag=magnetization)
field = shape.Bfield([50, 50, -60])
print(f"Raster spacing: {delta} nm; merged cuboids: {len(shape)}")
print("Field at (50, 50, -60) nm (T):", field.ravel())
import matplotlib.pyplot as plt
fig, ax = shape.plot_2d(x=(-40, 145, 201), y=(-25, 140, 201), z=-60, component="z")
for index, cuboid in enumerate(shape):
ax.plot(
*cuboid.union_boundary("xy")[0],
color="black",
linewidth=0.3,
alpha=0.35,
label="Projected cuboids" if index == 0 else None,
)
ax.plot(*np.vstack([polygon, polygon[0]]).T, color="#ff9500", linewidth=1.5, label="Input polygon")
for index, boundary in enumerate(shape.union_boundary("xy")):
ax.plot(*boundary, color="#00ffff", linewidth=1.5, label="Union boundary" if index == 0 else None)
ax.set(xlabel="x (nm)", ylabel="y (nm)", title="Bz (T) at z = -60 nm; delta = 0.5 nm", aspect="equal")
ax.legend(loc="upper right", fontsize=7, facecolor="#555555", labelcolor="white", framealpha=0.95)
fig.tight_layout()
plt.show()
Single cuboid
Calculate the field and its analytical gradient outside a uniformly magnetized cube. All lengths here are in nm, magnetization is in A/m, fields are in T, and gradients are in T/nm.
import numpy as np
from microcubed import Magnet
cube = Magnet(size=[100, 100, 100], center=[0, 0, 0], magnetization=[0, 0, 8e5])
points = np.array([[0, 0, -150], [80, 0, -150]]).T
field = cube.Bfield(points) # (3, N): Bx, By, Bz
gradient = cube.dBfield(points) # (3, 3, N): derivative axis, field axis, point
print(field)
import matplotlib.pyplot as plt
fig, ax = cube.plot_2d(x=(-250, 250, 61), y=(-250, 250, 61), z=-150, component="z")
for boundary in cube.union_boundary("xy"):
ax.plot(*boundary, "w-", linewidth=2, label="Material boundary")
ax.set(xlabel="x (nm)", ylabel="y (nm)", title="Bz (T) at z = -150 nm", aspect="equal")
ax.legend(loc="upper right", fontsize=8, facecolor="#555555", labelcolor="white", framealpha=0.95)
fig.tight_layout()
plt.show()
Optional solver comparison
The Ubermag/OOMMF comparison compares
fields and gradients at identical exterior points. Install the comparison
extra and an OOMMF runner to execute it; neither is needed for Microcubed itself.
See the example guide for setup and documentation builds
with comparison results.
Documentation and development
Read the published documentation.
See the user guide sources, backend guide, and
contributing guide for development and validation commands.
Python code lives in src/microcubed/; Rust kernels live in src/rust/.
Microcubed is distributed under the MIT license.
Release files for microcubed 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| microcubed-1.0.0.tar.gz | 314.1 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| microcubed-1.0.0-cp312-abi3-win_amd64.whl | CPython 3.12 | abi3 | Windows x86-64 | Details |
| microcubed-1.0.0-cp312-abi3-manylinux_2_28_x86_64.whl | CPython 3.12 | abi3 | Linux glibc 2.28+ x86-64 | Details |
| microcubed-1.0.0-cp312-abi3-manylinux_2_28_aarch64.whl | CPython 3.12 | abi3 | Linux glibc 2.28+ ARM64 | Details |
| microcubed-1.0.0-cp312-abi3-macosx_11_0_arm64.whl | CPython 3.12 | abi3 | macOS 11.0+ ARM64 | Details |
Total release size: 2.2 MB
Release files / microcubed-1.0.0.tar.gz
| Download URL | microcubed-1.0.0.tar.gz |
|---|---|
| Size | 314.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
aa1eb0d1491bc4d7459c5f4282c7f5abced75c1848adacd737540b1e184b23a7
|
|
BLAKE2b-256 checksum How to use checksums |
27e09dd1b3e626186bd1f93937e08594937380814cada56f2a824ab253c01913
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / microcubed-1.0.0-cp312-abi3-win_amd64.whl
| Download URL | microcubed-1.0.0-cp312-abi3-win_amd64.whl |
|---|---|
| Size | 353.1 kB |
| Tags | CPython 3.12 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
d325816b62692e0b000c0ce1385d4d98a10a807f6c91f8085610511360ab373c
|
|
BLAKE2b-256 checksum How to use checksums |
f977943ed47efdb7c9ca77a26b9b1db27cc70ef3da797451f61dfc3c4d9d7b0f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / microcubed-1.0.0-cp312-abi3-manylinux_2_28_x86_64.whl
| Download URL | microcubed-1.0.0-cp312-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 548.6 kB |
| Tags | CPython 3.12 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
a74bf9c421c4758e89f65f96ab0817eedefe5782d29e11aa58a3bb3015d2e658
|
|
BLAKE2b-256 checksum How to use checksums |
7ad1f00f5b2c5f13ef8f5d68899adc98c4d4600d908055031e43c3d0d55c7738
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / microcubed-1.0.0-cp312-abi3-manylinux_2_28_aarch64.whl
| Download URL | microcubed-1.0.0-cp312-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 535.4 kB |
| Tags | CPython 3.12 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
e82492c593cb3ca60d90819caa7eb8ce6977bdedc2df33cf36fad5f1986eb0cf
|
|
BLAKE2b-256 checksum How to use checksums |
544910e4b4c858fa4c893ae7fc8af05628f84879bfa67cba919cbe6f6be92579
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / microcubed-1.0.0-cp312-abi3-macosx_11_0_arm64.whl
| Download URL | microcubed-1.0.0-cp312-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 471.0 kB |
| Tags | CPython 3.12 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
bee4d0572dff5478d84cfa9dc40b8683440d4f4391e4c7ca5d6bf676f8a36f8e
|
|
BLAKE2b-256 checksum How to use checksums |
d81e03ae58759bb43fd5c962b14d15eb25535aa8e1bd2e016a0c72ab93ee8843
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency log