Stoner-Wohlfarth Particle#

We are simulating the hard-axis loop of a Stoner-Wohlfarth particle with uniaxial anisotorpy with \(K\) = 100 kJ/m\(^3\).

Simulation#

Import libraries#

[1]:
import matplotlib.pyplot as plt
import numpy as np
from scipy import constants

import neuralmag as nm
2025-05-12 23:32:23 NeuralMag:INFO [NeuralMag] Version 0.9.1

Initialize state, mesh and material parameters#

In order to simulate a Stoner-Wohlfarth particle, we setup a small 2 x 2 x 2 cell mesh whose size is well below the single-domain limit. As material parameters we choose the saturation magnetization \(M_s\) and the exchange constant \(A\) equal to those of Permalloy, but we add a uniaxial anisotropy in z-axis with anisotropy constant \(K\) = 100 kJ/m\(^3\) with a slight tilt into the x-direction in order to avoid an unstable equilibrium at saturation.

[2]:
mesh = nm.Mesh((2, 2, 2), (5e-9, 5e-9, 5e-9))
state = nm.State(mesh)

state.material.Ms = 8e5
state.material.A = 1.3e-11
state.material.Ku = 1e5
state.material.Ku_axis = [0.01, 0, 1]
state.material.alpha = 1.0
2025-05-12 23:32:23 NeuralMag:INFO [Mesh] 3D, 2 x 2 x 2 (size = 5e-09 x 5e-09 x 5e-09)
2025-05-12 23:32:24 NeuralMag:INFO [NeuralMag] Backend set to 'jax'.
2025-05-12 23:32:24 NeuralMag:INFO [NeuralMag] Set default device to 'TFRT_CPU_0'.
2025-05-12 23:32:24 NeuralMag:INFO [NeuralMag] Set default dtype to 'float32'.
2025-05-12 23:32:24 NeuralMag:INFO [State] Running on device: TFRT_CPU_0 (dtype = float32, backend = jax)

Initialize initial magnetization#

[3]:
state.m = nm.VectorFunction(state).fill((-1, 0, 0))

Register effective field#

We register an effective field comprised of an exchange field, an uniaxial anisotropy and en external field the sweeps from \((-1.5 H_c, 0, 0)\) to \((+1.5 H_c, 0, 0)\) within 20 ns with \(H_c\) being the the coercive field of the particle.

[4]:
nm.ExchangeField().register(state, "exchange")
nm.UniaxialAnisotropyField().register(state, "aniso")
Hc = 2 * 1e5 / (constants.mu_0 * 8e5)
nm.ExternalField(lambda t: state.tensor([1.5 * (t - 10e-9) / 10e-9 * Hc, 0, 0])).register(state, "external")
nm.TotalField("exchange", "aniso", "external").register(state)
2025-05-12 23:32:24 NeuralMag:INFO [ExchangeField] Register state methods (field: 'h_exchange', energy: 'E_exchange')
2025-05-12 23:32:24 NeuralMag:INFO [UniaxialAnisotropyField] Register state methods (field: 'h_aniso', energy: 'E_aniso')
2025-05-12 23:32:24 NeuralMag:INFO [ExternalField] Register state methods (field: 'h_external', energy: 'E_external')
2025-05-12 23:32:24 NeuralMag:INFO [TotalField] Register state methods (field: 'h', energy: 'E')

Perform time integration#

[5]:
llg = nm.LLGSolver(state)
logger = nm.Logger(
    "stoner-wohlfarth-hysteresis",
    ["t", "h_external", "m", "E"],
    ["m"],
    fields_every=100,
)
while state.t < 20e-9:
    logger.log(state)
    llg.step(2e-10)
2025-05-12 23:32:24 NeuralMag:INFO [LLGSolverJAX] Initialize RHS function
2025-05-12 23:32:28 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 0s
2025-05-12 23:32:44 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 2e-10s
2025-05-12 23:32:44 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 4e-10s
2025-05-12 23:32:44 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 6e-10s
2025-05-12 23:32:44 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 8e-10s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.2e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.4e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.6e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.8e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 2e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 2.2e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 2.4e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 2.6e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 2.8e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 3e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 3.2e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 3.4e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 3.6e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 3.8e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 4e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 4.2e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 4.4e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 4.6e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 4.8e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 5e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 5.2e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 5.4e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 5.6e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 5.8e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 6e-09s
2025-05-12 23:32:45 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 6.2e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 6.4e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 6.6e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 6.8e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 7e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 7.2e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 7.4e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 7.6e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 7.8e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 8e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 8.2e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 8.4e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 8.6e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 8.8e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 9e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 9.2e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 9.4e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 9.6e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 9.8e-09s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1e-08s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.02e-08s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.04e-08s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.06e-08s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.08e-08s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.1e-08s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.12e-08s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.14e-08s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.16e-08s
2025-05-12 23:32:46 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.18e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.2e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.22e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.24e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.26e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.28e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.3e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.32e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.34e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.36e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.38e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.4e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.42e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.44e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.46e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.48e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.5e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.52e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.54e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.56e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.58e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.6e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.62e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.64e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.66e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.68e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.7e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.72e-08s
2025-05-12 23:32:47 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.74e-08s
2025-05-12 23:32:48 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.76e-08s
2025-05-12 23:32:48 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.78e-08s
2025-05-12 23:32:48 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.8e-08s
2025-05-12 23:32:48 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.82e-08s
2025-05-12 23:32:48 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.84e-08s
2025-05-12 23:32:48 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.86e-08s
2025-05-12 23:32:48 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.88e-08s
2025-05-12 23:32:48 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.9e-08s
2025-05-12 23:32:48 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.92e-08s
2025-05-12 23:32:48 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.94e-08s
2025-05-12 23:32:48 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.96e-08s
2025-05-12 23:32:48 NeuralMag:INFO [LLGSolverJAX] Step: dt = 2e-10s, t = 1.98e-08s

Plot the result#

[6]:
data = np.loadtxt("stoner-wohlfarth-hysteresis/log.dat")
plt.plot(data[:, 1], data[:, 4])
plt.xlabel("H_x [A/m]")
plt.ylabel("m_x")
plt.show()
../_images/examples_stoner-wohlfarth-hysteresis_11_0.png