Unit Conversions#
Micromagnetic simulations provide a method of simulating the magnetic structure in real materials. However, in order to do this we need to be able to convert the information we have about the system into the parameters that micromagnetics use.
CGS to SI#
Ubermag
uses SI units for all of the system parameters. Experimentally, material parameters can often be measured in CGS units, SI units, or a mixture of the two. Firstly, we show a convenient way of converting from CGS to SI units and other useful quantities.
To do this, we make use of astropy.units
, a package aimed at the astrophysics community for its unit converting functionality. astropy
is not installed by default. We can install it (e.g. with pip
) directly from the notebook. Generally, you will not install astropy
from inside the notebook (using either pip
or conda
) but for the sake of demonstration we run the command in here.
[1]:
!pip install astropy
Collecting astropy
Downloading astropy-6.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (10 kB)
Requirement already satisfied: numpy>=1.23 in /home/sam/miniconda3/envs/ubermagdev311/lib/python3.11/site-packages (from astropy) (2.0.0)
Collecting pyerfa>=2.0.1.1 (from astropy)
Using cached pyerfa-2.0.1.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.7 kB)
Collecting astropy-iers-data>=0.2024.7.1.0.34.3 (from astropy)
Downloading astropy_iers_data-0.2024.8.5.0.32.23-py3-none-any.whl.metadata (5.1 kB)
Requirement already satisfied: PyYAML>=3.13 in /home/sam/miniconda3/envs/ubermagdev311/lib/python3.11/site-packages (from astropy) (6.0.1)
Requirement already satisfied: packaging>=19.0 in /home/sam/miniconda3/envs/ubermagdev311/lib/python3.11/site-packages (from astropy) (24.1)
Downloading astropy-6.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (10.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 10.2/10.2 MB 49.0 MB/s eta 0:00:0000:010:01
Downloading astropy_iers_data-0.2024.8.5.0.32.23-py3-none-any.whl (1.9 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.9/1.9 MB 70.4 MB/s eta 0:00:00
Using cached pyerfa-2.0.1.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (738 kB)
Installing collected packages: pyerfa, astropy-iers-data, astropy
Successfully installed astropy-6.1.2 astropy-iers-data-0.2024.8.5.0.32.23 pyerfa-2.0.1.4
Now we can import astropy
.
[2]:
import numpy as np
from astropy import units as u
To initalise a value with units, one has to simply multiply the value by the units provided.
[3]:
field = 100 * u.Gauss
field
[3]:
These units remain with the variable throughout operations.
[4]:
field2 = field * 10
field2
[4]:
We can easily convert to SI units by using
[5]:
field2.si
[5]:
Magnetic moment can be expressed using the following CGS units
[6]:
magnetic_moment = 1 * u.erg / u.Gauss
magnetic_moment
[6]:
and simplified using
[7]:
magnetic_moment.si
[7]:
If we wish to detach the numerical value for its units, we can do this using .value
[8]:
magnetic_moment.si.value
[8]:
np.float64(0.001)
Equivalencies#
astropy.units
also enables conversions of units with different equivalencies such as temperature and energy. To use this we can create a variable with the relevant units of temperature and use the to
function to convert to the relevant units with the relevant equivalency.
For example, if an exchange interaction has a temperature of 4.15 K we can calculate the equivalent energy in J.
[9]:
t_k = 4.15 * u.K
t_k.to(u.J, equivalencies=u.temperature_energy())
[9]:
While astropy
handles a variety of units and conversions, it does not currently have an equivalency for magnetic induction and magnetic field strength i.e. B to H . As this is very useful for the magnetism community, we have provided the conversion here.
[10]:
from astropy import constants as const
induction_field = [(u.T, u.A / u.m, lambda x: x / const.mu0, lambda x: const.mu0 * x)]
[11]:
field = 100 * u.Gauss
field.to(u.A / u.m, equivalencies=induction_field)
[11]:
Parameters#
Here we will describe some select methods for relating atomistic parameters, micromagnetic parameters, and experimental results.
NOTE: Different definitions of the exchange Hamiltonian will lead to different conversion factors. Here, we use the atomistic exchange Hamiltonian \begin{equation} {\cal H}_{ex} = -\frac{1}{2}\sum_{i\neq j} J_{ij} {\bf S}_i \cdot {\bf S}_j, \end{equation} where \(\lvert{\bf S}_i \rvert = \lvert {\bf S}_j \rvert = 1\) are the normaised spin vectors, and \(J_{ij}\) is the exchange between the.
Exchange#
Atomistic#
The atomistic exchange \(J\) can be obtained from the Curie temperature \(T_\text{C}\) of a material by using \begin{equation} J = \frac{3k_\text{B}T_\text{C}}{\epsilon z}, \end{equation} where \(k_\text{B}\) is the Boltzmann constant, \(z\) is the number of nearest neighbours, and \(\epsilon\) is a structurally dependent correction factor. The values of this correction factor have been calculated in Table I of Garanin 1996.
[12]:
from scipy import constants
def Tc_to_J(Tc, e, z):
return Tc * 3 * constants.k / (e * z)
For example, a system with a \(T_c\) of 100 K and a fcc cubic structure.
[13]:
Tc = 100
e = 0.808
z = 12
J = Tc_to_J(Tc, e, z)
J
[13]:
4.271810024752475e-22
Micromagnetic#
The micromagnetic exchange correlation constant \(A\) can be related to atomistic exchange using \begin{equation} A = \frac{zJL^2}{12V}, \end{equation} where \(J\) is the Heisenberg exchange, \(z\) is the number of nearest neighbour atoms, and \(L\) is the distance between neighbouring atoms, and \(V\) is the crystal volume per magnetic atom.
[14]:
def J_to_A(J, z, L, V):
return J * L * L * z / (12 * V)
[15]:
L = 6.84e-10
V = 2.24e-28
A = J_to_A(J, z, L, V)
A
[15]:
8.922285495270508e-13
The micromagnetic exchange correlation constant can be obtained directly from \(T_c\) using \begin{equation} A = \frac{k_\text{B}T_\text{C}L^2}{4\epsilon V}. \end{equation}
[16]:
def Tc_to_A(Tc, e, L, V):
return Tc * constants.k * L * L / (4 * e * V)
[17]:
A = Tc_to_A(Tc, e, L, V)
A
[17]:
8.922285495270509e-13
DMI#
Atomistic#
The Dzyaloshinskii–Moriya interaction is given by \begin{equation} {\cal H}_{ex} = -\frac{1}{2}\sum_{i\neq j} {\bf d}_{ij} \cdot \left( {\bf S}_i \times {\bf S}_j \right), \end{equation} where \({\bf d}_{ij}\) is the atomistic DMI vector.
Micromagentic#
The micromagnetic DMI constant \(D\) can be related to atomistic DMI using \begin{equation} D = \frac{zdL}{12V}, \end{equation} where \(d\) is the atomistic DMI, \(z\) is the number of nearest neighbour atoms, and \(L\) is the distance between neighbouring atoms, and \(V\) is the crystal volume per magnetic atom.
[18]:
def d_to_D(d, z, L, V):
return d * L * z / (12 * V)
[19]:
d = 2.01e-23
D = d_to_D(d, z, L, V)
D
[19]:
6.137678571428571e-05
The DMI constants are not easy to measure experimentally, however they can be be calculated from the helical period P using \begin{equation} P = \frac{4\pi A}{|D|}, \end{equation} where \(A\) and \(D\) are the micromagnetic exchange and DMI respectively.
[20]:
def P_to_D(P, A):
return 4 * np.pi * A / P
def D_to_P(D, A):
return 4 * np.pi * A / abs(D)
For a system with a micromagentic exchange of \(6\times 10^{-14}\) Jm \(^{-1}\) and a helical period of 20 nm.
[21]:
A = 6e-14
D = P_to_D(20e-9, A)
D
[21]:
3.7699111843077517e-05
For atomistic simulations, this can be converted into \begin{equation} P = \frac{4\pi J L}{|d|}, \end{equation} where \(J\) is the Heisenberg exchange, \(d\) is the atomistic DMI, and \(L\) is the distance between neighbouring atoms.
Saturation Magnetisation#
Micromagnetics#
The saturation magnetisation is often measured in \(\mu_\text{B}/f.u.\) but is needed in A/m in micromagnetics. A simple conversion can be used \begin{equation} M_s [ \text{A}/ \text{m}]= \frac{\mu_\text{B} M_s[\mu_\text{B}/f.u.]}{V}, \end{equation} where \(M_s[\mu_\text{B}/f.u.]\) is the saturation magnetisation in \(\mu_B\) per formula unit, \(\mu_B\) is the Bohr magneton in J/T, and \(V\) is the volume of the formula unit in m\(^3\).
[22]:
def Ms_muB_to_Am(Ms, V):
return constants.value("Bohr magneton") * Ms / V
[23]:
Ms = Ms_muB_to_Am(0.8, 2.24375e-28)
print(Ms)
33066.10835716991
Atomistic#
In atomistic simulations, the saturation magnetisation \(M_s\) in micromagnetic simulations can be related to the magnetic moment \(\mu\) simply by \begin{equation} \mu = M_s V, \end{equation} where \(V\) is the crystal volume per magnetic atom.
[24]:
def Ms_to_mu(Ms, V):
return Ms * V
[25]:
Ms = 6e5
mu = Ms_to_mu(Ms, V)
mu
[25]:
1.3440000000000002e-22
Anisotropy#
Micromagnetic#
Anisotropy can be measured experimentally in a variety of different ways. The results torque magnetometry, for example, can give correct value for the anisotropy in units of Jm \(^{-3}\).
Atomistic#
Similarly to the saturation magnetisation, the conversion between micromagnetic \(K\) and atomistic anisotropy \(k\) is simply volume weighted \begin{equation} k = K V, \end{equation} where \(V\) is the crystal volume per magnetic atom. This atomistic anisotropy \(k\) can also be calculated from the difference in energy between \(J\) in different directions, i.e. \(J_{\perp} = 6\times 10^{-23}\) J and \(J_{\parallel} = 5 \times 10^{-23}\) J, gives an atomistic anisotropy \(k=1\times 10^{-23}\) J.
[26]:
def K_to_k(K, V):
return Ms * V
[27]:
K = 1.2e6
k = K_to_k(K, V)
k
[27]:
1.3440000000000002e-22
Worked Example#
Here, FeGe will be used as example for how to obtain micromagnetic parameters. FeGe has a cubic crystal structure with four Ge and four Fe atoms per unit cell with a lattice constant of \(a= 4.6995\) Å, and the distance between Fe atoms is 2.881 Å [Wilhelm 2007]. The saturation magnetisation is \(1.07 \mu_\text{B}/f.u.\) [Yamada 2003], and magnetic ordering temperature is 278 K [Lebech 1989]. The helical period of FeGe is \(\sim 70\) nm [Yu 2011].
[28]:
a = 4.6995e-10
L = 2.881e-10
Ms_orig = 1.07
Tc = 278
P = 70e-9
Volume per magnetic atom
[29]:
V = (a**3) / 4
V
[29]:
2.594746713121875e-29
Saturation magnetisation
[30]:
Ms = Ms_muB_to_Am(Ms_orig, V)
Ms
[30]:
382433.88973569183
Exchange
[31]:
e = 0.644
A = Tc_to_A(Tc, e, L, V)
A
[31]:
4.76621650209023e-12
DMI
[32]:
D = P_to_D(P, A)
D
[32]:
0.000855629185622006