MIME-VER-110 — Permanent-Magnet Field vs Analytical#
Date: 2026-04-30
Node under test: mime.nodes.actuation.permanent_magnet.PermanentMagnetNode
Algorithm ID: MIME-NODE-101
Benchmark type: Analytical (Mode 2 independent)
Test file: tests/verification/test_permanent_magnet.py::test_ver110_dipole_field_far_field
Acceptance: $|B_{\text{node}} - B_{\text{analytic}}| / |B_{\text{analytic}}| < 10^{-4}$
Goal#
Verify that each of the three field models (point_dipole,
current_loop, coulombian_poles) returns the B field at a target
point in agreement with its own analytical reference, in the far-field
regime $r/R_{\text{magnet}} \in {10, 20, 50}$.
This benchmark validates the value output of the node. The companion benchmarks MIME-VER-111 and MIME-VER-112 cover the gradient and the Earth-field superposition respectively.
Configuration#
Parameter |
Value |
|---|---|
|
$1.0$ A·m² |
|
$10^{-3}$ m |
|
$2 \times 10^{-3}$ m |
|
$(0,0,1)$ |
|
$(0,0,0)$ — magnet-only check |
Magnet pose |
identity quaternion at origin |
Target points |
$(0,0,z)$ with $z \in {10, 20, 50},R_{\text{magnet}}$ |
JAX precision |
x64 (enabled at module load) |
Analytical references (numpy, double precision)#
Point dipole (any displacement $\mathbf{r}$):
$$ \mathbf{B}_{\text{dipole}} = \frac{\mu_0}{4\pi} \cdot \frac{3(\mathbf{m}\cdot\hat{\mathbf{r}})\hat{\mathbf{r}} - \mathbf{m}}{r^3}. $$
Current loop, on-axis:
$$ B_z = \frac{\mu_0 I R^2}{2(R^2+z^2)^{3/2}},\quad I_{\text{eff}} = \frac{|\mathbf{m}|}{\pi R^2}. $$
Coulombian poles, on-axis ($M = |\mathbf{m}| / (\pi R^2 L)$):
$$ B_z = \frac{\mu_0 M}{2}\left[ \frac{z+L/2}{\sqrt{R^2+(z+L/2)^2}}
\frac{z-L/2}{\sqrt{R^2+(z-L/2)^2}} \right]. $$
Method#
Construct
PermanentMagnetNodewith the model under test andearth_field_world_t = (0, 0, 0).Call
update(state, boundary_inputs, dt)with the magnet pose and target. Readstate["field_vector"].Compute the analytical reference in float64 numpy.
Compare per-point: $|B_{\text{node}} - B_{\text{ref}}| / |B_{\text{ref}}| < 10^{-4}$.
A second test (test_ver110_dipole_field_off_axis) checks the
point_dipole model at three off-axis configurations
($r \in {(3,0,5), (3,4,5), (0,50,0)}$ mm) — these are 3D
configurations where coordinate-frame errors would manifest as
cross-component leakage.
Results#
Model |
$z = 10,R$ |
$z = 20,R$ |
$z = 50,R$ |
|---|---|---|---|
|
$< 10^{-4}$ |
$< 10^{-4}$ |
$< 10^{-4}$ |
|
$< 10^{-4}$ |
$< 10^{-4}$ |
$< 10^{-4}$ |
|
$< 10^{-4}$ |
$< 10^{-4}$ |
$< 10^{-4}$ |
Off-axis (point_dipole only):
Target $(x,y,z)$ mm |
Relative error |
|---|---|
$(3, 0, 5)$ |
$< 10^{-4}$ |
$(3, 4, 5)$ |
$< 10^{-4}$ |
$(0, 50, 0)$ |
$< 10^{-4}$ |
All eight configurations pass the $10^{-4}$ acceptance threshold.
Verdict: PASS#
The three field models match their analytical references to better than $10^{-4}$ relative error in the far field, on-axis. The point-dipole model also matches off-axis to the same tolerance. The v1 implementation is faithful in its declared validity envelope.