llg3d.element

Define the chemical elements.

Module Attributes

k_B

Boltzmann constant \([J.K^{-1}]\)

mu_0

Vacuum permeability \([H.m^{-1}]\)

gamma

Gyromagnetic ratio \([rad.s^{-1}.T^{-1}]\)

Functions

get_element_class(element_name)

Get the class of the chemical element by its name.

Classes

Cobalt(T, H_ext, g, dt[, dtype])

Cobalt element.

Element(T, H_ext, g, dt[, dtype])

Abstract class for chemical elements.

Iron(T, H_ext, g, dt[, dtype])

Iron element.

Nickel(T, H_ext, g, dt[, dtype])

Nickel element.

k_B = 1.38e-23

Boltzmann constant \([J.K^{-1}]\)

mu_0 = 1.2566370614359173e-06

Vacuum permeability \([H.m^{-1}]\)

gamma = 176000000000.0

Gyromagnetic ratio \([rad.s^{-1}.T^{-1}]\)

class Element(T, H_ext, g, dt, dtype=None)[source]

Bases: ABC

Abstract class for chemical elements.

Parameters:
  • T (float) – Temperature in Kelvin

  • H_ext (float) – External magnetic field strength

  • g (Grid) – Grid object representing the simulation grid

  • dt (float) – Time step for the simulation

  • dtype (dtype | None) – Optional numpy dtype to cast scalar coefficients to

A: float = 0.0

Exchange constant \([J.m^{-1}]\)

K: float = 0.0

Anisotropy constant \([J.m^{-3}]\)

lambda_G: float = 0.0

Damping parameter \([1]\)

M_s: float = 0.0

Saturation magnetization \([A.m^{-1}]\)

a_eff: float = 0.0

Effective lattice constant \([m]\)

anisotropy: Literal['uniaxial', 'cubic']

Type of anisotropy

gamma_0

Rescaled gyromagnetic ratio [mA^-1.s^-1]

d_0

Domain wall width [m]

_cast_to_dtype(dtype)[source]

Cast all float attributes of the instance to the specified numpy dtype.

Parameters:

dtype (dtype) – The numpy dtype to cast to (e.g., np.float32, np.float64)

static _omega_c_heun(lambda_G)[source]

Maximum stable dimensionless frequency for the Heun scheme.

Linearised LLG. Small transverse fluctuations around the ground state satisfy \(\dot\psi_k = (-\lambda_G + i)\,\omega_k\,\psi_k\), where \(\omega_k > 0\) are the spin-wave frequencies and \(\lambda_G > 0\) provides damping.

Heun amplification factor. One Heun step maps \(\psi \mapsto R(z)\,\psi\) with

\[R(z) = 1 + z + \tfrac{z^2}{2}, \qquad z = (-\lambda_G + i)\,\Omega, \quad \Omega = \omega_k\,dt.\]

Stability requires \(|R(z)| \leq 1\) for all modes.

Stability boundary. Writing \(z = (-\lambda_G + i)\Omega\) and expanding:

\[|R(z)|^2 = \underbrace{\Bigl(1 - \lambda_G\Omega + \tfrac{\lambda_G^2-1}{2}\Omega^2\Bigr)^2}_{\text{Re}^2} + \underbrace{\Omega^2\bigl(1 - \lambda_G\Omega\bigr)^2}_{\text{Im}^2}\]

After collecting powers of \(\Omega\) and using \((\lambda_G^2-1)^2 + 4\lambda_G^2 = (\lambda_G^2+1)^2\):

\[|R(z)|^2 = 1 - 2\lambda_G\,\Omega + 2\lambda_G^2\,\Omega^2 - \lambda_G(\lambda_G^2+1)\,\Omega^3 + \frac{(\lambda_G^2+1)^2}{4}\,\Omega^4.\]

Setting \(|R|^2 = 1\) and factoring the trivial root \(\Omega = 0\), the non-trivial stability boundary is the cubic

\[\frac{(\lambda_G^2+1)^2}{4}\,\Omega^3 - \lambda_G(\lambda_G^2+1)\,\Omega^2 + 2\lambda_G^2\,\Omega - 2\lambda_G = 0.\]

\(\Omega_c\) is the largest positive real root, found via numpy.roots() (companion-matrix eigenvalues).

Note

For \(\lambda_G = 0\) (no damping) the cubic has no positive real root: the Heun scheme is unconditionally unstable for pure precession, as expected for any explicit method on a purely imaginary spectrum.

Parameters:

lambda_G (float) – Gilbert damping parameter.

Returns:

Critical frequency \(\Omega_c(\lambda_G)\).

Return type:

float

check_numerical_parameters()[source]

Check CFL stability and spatial resolution; log warnings if violated.

Two conditions are checked:

CFL stability\(12 \times \text{CFL} \leq \Omega_c(\lambda_G)\), where the factor 12 is the maximum eigenvalue of the 3-D discrete Laplacian (normalised by \(1/\Delta x^2\)).

Spatial resolution — two severity levels based on \(r = \Delta x / \ell_{\rm ex}\) with \(\ell_{\rm ex}\) the exchange length defined as \(\ell_{\rm ex} = \sqrt{A/|K|}\):

  • \(r > \tfrac{1}{2}\): Nyquist limit exceeded. \(\ell_{\rm ex}\) is sampled by fewer than 2 cells. The discrete exchange interaction is qualitatively wrong.

  • \(\tfrac{1}{5} < r \leq \tfrac{1}{2}\): precision warning. The finite-difference truncation error on the exchange energy is \(O(r^2)\), already reaching ~4 % at \(r = \tfrac{1}{5}\).

Return type:

None

get_CFL()[source]

Returns the dimensionless CFL (Fourier) number for the exchange term.

\[CFL = \frac{dt \cdot 2 \gamma A}{M_s \Delta x^2}\]

This is the analogue of the Fourier number for the heat equation, with effective diffusivity \(D = 2\gamma A / M_s\).

For the Heun scheme, the stability condition in 3D is:

\[12 \times CFL \leq \Omega_c(\lambda_G) \approx 1.72 \quad (\lambda_G = 0.5)\]

i.e. \(CFL \lesssim 0.14\) in 3D (the factor 12 comes from the maximum eigenvalue \(12/\Delta x^2\) of the 3D discrete Laplacian).

Returns:

The CFL value

Return type:

float

to_dict()[source]

Export element parameters to a dictionary for JAX JIT compatibility.

Returns:

Dictionary containing element parameters needed for computations

Return type:

dict

compute_H_anisotropy(m, H_aniso)[source]

Compute the anisotropy field.

For uniaxial anisotropy:

\[\boldsymbol{H}_{\text{ani, uniaxial}}=\frac{2K}{\mu_0M_s}(\boldsymbol{e}_x \cdot\boldsymbol{m})\boldsymbol{e}_x,\label{uniaxial}\]

For cubic anisotropy:

\[\boldsymbol{H}_{\text{ani, cubic}}=-\frac{2K}{\mu_0M_s}\sum_{(i,j,k)\in I} \left((\boldsymbol{e}_j\cdot\boldsymbol{m})^2+(\boldsymbol{e}_k\cdot \boldsymbol{m})^2+(\boldsymbol{e}_j\cdot\boldsymbol{m})^2(\boldsymbol{e}_k \cdot\boldsymbol{m})^2\right)(\boldsymbol{e}_i\cdot\boldsymbol{m})\boldsymbol{e}_i,\label{cubic}\]
Parameters:
  • m (ndarray) – Magnetization array (shape (3, nx, ny, nz)).

  • H_aniso (ndarray) – Pre-allocated output array (shape (3, nx, ny, nz)).

Raises:

ValueError – If the anisotropy type is unknown

class Cobalt(T, H_ext, g, dt, dtype=None)[source]

Bases: Element

Cobalt element.

Parameters:
  • T (float)

  • H_ext (float)

  • g (Grid)

  • dt (float)

  • dtype (dtype | None)

A: float = 3e-11

Exchange constant \([J.m^{-1}]\)

K: float = 520000.0

Anisotropy constant \([J.m^{-3}]\)

lambda_G: float = 0.5

Damping parameter \([1]\)

M_s: float = 1400000.0

Saturation magnetization \([A.m^{-1}]\)

a_eff: float = 2.5e-10

Effective lattice constant \([m]\)

anisotropy: Literal['uniaxial', 'cubic'] = 'uniaxial'

Type of anisotropy (e.g., “uniaxial”, “cubic”)

class Iron(T, H_ext, g, dt, dtype=None)[source]

Bases: Element

Iron element.

Parameters:
  • T (float)

  • H_ext (float)

  • g (Grid)

  • dt (float)

  • dtype (dtype | None)

A: float = 2.1e-11

Exchange constant \([J.m^{-1}]\)

K: float = 48000.0

Anisotropy constant \([J.m^{-3}]\)

lambda_G: float = 0.5

Damping parameter \([1]\)

M_s: float = 1700000.0

Saturation magnetization \([A.m^{-1}]\)

a_eff: float = 2.86e-10

Effective lattice constant \([m]\)

anisotropy: Literal['uniaxial', 'cubic'] = 'cubic'

Type of anisotropy (e.g., “uniaxial”, “cubic”)

class Nickel(T, H_ext, g, dt, dtype=None)[source]

Bases: Element

Nickel element.

Parameters:
  • T (float)

  • H_ext (float)

  • g (Grid)

  • dt (float)

  • dtype (dtype | None)

A: float = 9e-12

Exchange constant \([J.m^{-1}]\)

K: float = -5700.0

Anisotropy constant \([J.m^{-3}]\)

lambda_G: float = 0.5

Damping parameter \([1]\)

M_s: float = 490000.0

Saturation magnetization \([A.m^{-1}]\)

a_eff: float = 3.45e-10

Effective lattice constant \([m]\)

anisotropy: Literal['uniaxial', 'cubic'] = 'cubic'

Type of anisotropy (e.g., “uniaxial”, “cubic”)

get_element_class(element_name)[source]

Get the class of the chemical element by its name.

Example

>>> cls = get_element_class("Cobalt")
>>> cls.__name__
'Cobalt'
Parameters:

element_name (str) – The name of the element

Returns:

The class of the element

Raises:

ValueError – If the element is not found

Return type:

type[Element]