Micromagnetics in JAX

Simulate magnetic textures — and differentiate through them.

Finite-difference and finite-element solvers behind one interface, FFT and fast-multipole stray fields, float64 on GPU, and automatic differentiation straight through the Landau–Lifshitz–Gilbert equation. Written in Python, fast enough for 216 million cells.

Néel skyrmion · Q = −1
FD + FE

Two backends, one API

The mesh decides the method: create it with jm.fd.make_mesh or jm.fe.make_mesh / jm.fe.from_gmsh, and the same jm.make_demag, jm.make_exchange, … run FFT demag on the grid and fast multipole on the tetrahedral mesh. Only the mesh line differs.

∂/∂p

Differentiable physics

Field terms and whole trajectories are differentiable, so inverse design and parameter fitting become gradient descent instead of guesswork.

curved films

Geometry that follows a surface

Per-element surface normals drive anisotropy and interfacial DMI, so a measured AFM topography becomes a magnetic film with curvature effects included.

multi-GPU

Scales past one card

Domain-decomposed FFT demag across GPUs, agreeing with the single-GPU result to under 1 A/m; 600³ cells on eight GPUs.

Validated, not just fast. muMAG standard problem 4 on both backends, uniform-cube demag to 0.1 % of the analytical value, the Cortés-Ortuño skyrmion problem, and a hard/soft bilayer pinning field within 2 %. The test suite ships with the code.

02 · Run online

Describe a simulation, get a report

Write what you want to simulate, in English or German. An assistant turns it into a jaxmag run: one of the templates below, or a script written for your case (other geometries and materials, several phases, custom observables such as the skyrmion number, extra plots). It rents a GPU, runs the job and returns a PDF report; afterwards it can analyse the stored results on request. Every run keeps its own folder with the exact script, inputs, outputs, report and log (Files panel, one zip).

standard problem 4

Permalloy switching

500 × 125 × 3 nm, field 1 — the reference benchmark every code is measured against.

DMI skyrmion

Skyrmion relaxation

Cortés-Ortuño standard problem: settles at R ≈ 22 nm with Q = −1.

custom

Your own box

Pick the size, material and field, and see where the magnetisation settles.

Your jobs

Only this browser sees your chat, jobs and reports.

Where this runs. Each job rents a GPU on demand from vast.ai and destroys it as soon as the job ends — one job at a time, up to 2.5 M cells and 20 ns. A cold start spends a few minutes on provisioning; a machine that is still warm picks the next job up in seconds.

03 · Meshing service

Turn your geometry into a mesh

Upload a measured topography or an existing mesh and get back a tetrahedral mesh for jaxmag.fe, built with gmsh — with a preview, the element count and the curvature-induced DMI to expect from it.

Drop a geometry or mesh file here — or
.csv / .txt height matrix or x y z list (nm) · .png / .tif height map · .step / .brep / .iges CAD (e.g. from Salome) · .med / .unv / .msh / .vtk / .vtu mesh · .stl surface · .geo script — up to 25 MB and 800k tetrahedra

Then use it locally

# the download contains topo_verts.npy, topo_tets.npy and mesh.msh
import numpy as np
from jaxmag.fe import FEMesh, fix_orientations

v = np.load('topo_verts.npy'); t = np.load('topo_tets.npy').astype('int32')
mesh = FEMesh(v, fix_orientations(v, t), mu0_Ms=4e-7*np.pi*860e3, scale_len=1e-9)

04 · Viewer

Watch the magnetisation move

Every simulation keeps 24 snapshots of the full magnetisation. Play them back, scrub through time, switch between the components and read the topological charge as it changes.

Run a simulation first — finished jobs show up here with their time evolution. The three examples on Run a simulation take a couple of minutes.

05 · Files

Everything you have made here

Reports from your simulations, meshes from your uploads, and the jaxmag source bundle — in one place, scoped to this browser.

06 · Install & use

Get jaxmag running

Install from GitLab, or download the self-contained bundle with vendored dependencies, every example and the documentation.

# from GitLab (pulls jax-ode and jaxfmm automatically)
pip install git+https://gitlab.com/dietersuess1/jaxmag.git

# or from the downloaded bundle, offline
pip install "jax[cuda12]"                       # or plain "jax" for CPU
pip install ./vendor/jax-ode ./vendor/jaxfmm .
python examples/sp4_fd.py                        # muMAG standard problem 4

browse the repository ↗

What the bundle documents

filewhat it covers
README.mdpackage structure and the unified FD/FE API, choosing an integrator
INSTALL.mdsetup online and offline, GPU requirements, how to verify it works
METHODS.mdthe physics and the numerics: field terms, demag splitting, BDF + GMRES, curved films
EXAMPLES.mdevery example script, plus the skyrmion quickstart
TESTING.mdthe test suite and what each test proves

A skyrmion in ten lines

import jaxmag as jm

# the only backend-specific line (jm.fe.make_mesh / jm.fe.from_gmsh for tets + FMM):
mesh   = jm.fd.make_mesh(lx=100e-9, ly=100e-9, lz=2e-9, dx=2e-9)

fields = [jm.make_exchange(mesh, A=13e-12, Ms=860e3),
          jm.make_dmi(mesh, D=3e-3, Ms=860e3),
          jm.make_demag(mesh, Ms=860e3)]

m_sky  = jm.relax(jm.init_m(mesh, (0, 0, 1)), fields)   # Néel skyrmion

07 · Benchmarks

Measured, on real hardware

Pure integration time, measured on the MUSICA cluster (ASC Vienna) on 16–17 October 2026 with the scripts in jaxmag_paper/; setup (demag kernel or FMM tree, JIT compilation) is measured separately and not included, for jaxmag and mumax3 alike (mumax3: marker-file timestamps around run(), its own relaxation excluded). The 600³ cube uses the distributed FFT with the native NCCL all-to-all; the step counts of jaxmag and mumax3 agree within 3 % (stability-limited at 1 nm), so the gain is the single stray-field evaluation per step instead of six.

problembackendhardwaretime
SP4, 1 nm cells (187 500), 1 ns, Dopri5 + demag extrapolationFDH100 / B20013.1 s / 11.0 s
  mumax3 3.12, same grid, same GPUsFDH100 / B20036.4 s / 28.1 s
SP4, 1 nm, 1 ns, Dopri5 without extrapolationFDH100 / B20047.1 s / 33.6 s
SP4, 1 nm, 1 ns, BDF + gmres_approx (2.0 Newton, 92 GMRES per step)FDH100 / B200103 s / 95 s
SP4, 1 nm (252 504 nodes), 1 ns, BDF + gmres_approxFEH100147.6 s
SP4, 1 nm, 1 ns, Dopri5 + demag extrapolationFEH100224.0 s
600³ = 216 M cells, 1 ns, Dopri5 + demag extrapolationFD8× B200 / 4× B20012.2 s / 22.3 s
  mumax3 3.12, same cubeFD1× B200329 s

Cross-code comparison on rented GPUs (vast.ai, 12–13 October 2026)

One right-hand-side evaluation = exchange + full stray field (FFT, no extrapolation) on a 100 × 100 × 100 cube of 2 nm cells (1 M cells); minimum over repeated calls, ms. magnum.np 2.2.0 and neuralmag 1.0.0 measured with M. Steinbauer's timing suite, jaxmag with the same measurement, using the FFT demag path pushed on Oct 13 (pad- and crop-as-you-go, real kernels, no z transform for single-layer meshes). mumax3 3.12 (float32 only) is timed separately, see the note. All seven cards are complete (H100: 203 of 216 suite processes, every mesh covered).

What is timed, and what is not. No setup time enters any number on this page. For magnum.np, neuralmag and jaxmag the suite builds the demag kernel, compiles, and makes a first full RHS call before the clock starts; the figure is then the minimum over 5 GPU-synchronised batches of at least 5 RHS calls (and 0.25 s) each, in 4 to 8 fresh processes per card. For mumax3 the script runs 10 integrator steps first (kernel initialisation, cuFFT plans, autotuning), writes a file, runs 500 RK45 steps, writes a second file; the time between the two file timestamps divided by 500 is the step time, and divided by 6 the time per torque evaluation. mumax3 has no single-evaluation timer, so its number still contains the integrator's own overhead (error estimate, step control) and the write of the second file, about one percent.
GPUmagnum.np
f32 / f64
neuralmag
f32 / f64
jaxmag
f32 / f64
mumax3
f32, per torque eval
B2001.88 / 2.390.99 / 1.640.64 / 1.100.69
H200 NVL2.11 / 3.441.19 / 2.420.93 / 1.670.92
H100 SXM2.26 / 3.751.52 / 2.830.93 / 1.810.93
A100 SXM4 80 GB3.70 / 6.502.34 / 4.481.64 / 3.141.48
RTX PRO 60001.92 / 9.011.58 / 7.811.32 / 5.340.80
L40S3.30 / 14.932.87 / 11.852.27 / 8.521.25
RTX 50902.46 / 8.411.63 / 6.961.16 / 4.810.77

B200, all five large meshes, float32, ms per evaluation:

meshcellsmagnum.npneuralmagjaxmagmumax3
cube 46³97 k1.610.190.130.18
cube 100³1.0 M1.880.990.640.69
cube 144³3.0 M3.972.691.711.84
film 707 × 707 × 21.0 M3.362.510.741.22
monolayer 1000 × 1000 × 11.0 M1.670.570.370.34

A100 SXM4 80 GB, all five large meshes, float32, ms per evaluation (mumax3: per torque evaluation):

meshmumax3magnum.npneuralmagjaxmag
cube 46³0.352.420.310.21
cube 100³1.483.702.341.64
cube 144³4.1511.916.514.51
film 707 × 707 × 22.577.455.672.02
monolayer 1000 × 1000 × 10.742.591.291.17

All meshes, per-step times, memory and dollars per evaluation: slide deck of the campaign.

Why the demag splitting matters. The stray field is not evaluated at every Runge–Kutta stage; it is extrapolated between anchored evaluations. That is where most of the speed-up comes from, and the accuracy is checked against unsplit reference runs in the test suite.

08 · About

Who runs this, and who pays

jaxmag is developed in the Physics of Functional Materials group at the University of Vienna by Dieter Suess and contributors, and released as open source.

compute

Rented per job

Simulations run on a GPU rented on demand from vast.ai and destroyed when the job ends. A typical job costs a few cents.

assistant

Claude API

The chat that turns your description into a simulation runs on the Anthropic Claude API, billed per token.

funding

Paid personally

Both the GPU time and the API tokens are funded by Dieter Suess so this stays free and open for everyone. Please use it fairly.

privacy

Your session is yours

A random id in your browser scopes your chat, jobs, meshes and reports. Nobody else can list or download them; clearing browser data starts a fresh, empty session.