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

dipole_moment_a_m2

$1.0$ A·m²

magnet_radius_m

$10^{-3}$ m

magnet_length_m

$2 \times 10^{-3}$ m

magnetization_axis_in_body

$(0,0,1)$

earth_field_world_t

$(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#

  1. Construct PermanentMagnetNode with the model under test and earth_field_world_t = (0, 0, 0).

  2. Call update(state, boundary_inputs, dt) with the magnet pose and target. Read state["field_vector"].

  3. Compute the analytical reference in float64 numpy.

  4. 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$

point_dipole

$< 10^{-4}$

$< 10^{-4}$

$< 10^{-4}$

current_loop

$< 10^{-4}$

$< 10^{-4}$

$< 10^{-4}$

coulombian_poles

$< 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.