Welcome to fidimag’s documentation!¶
Contents:
How to install¶
Install prerequisites¶
On Ubuntu systems, we need to run the following commands:
# required to compile fidimag
apt-get install cython python-numpy
# required for tests and running it
apt-get install python-pytest python-pyvtk ipython python-matplotlib mayavi2
These are available in the script bin/install-ubuntu-packages.sh for convenience.
Install external libraries (FFTW and Sundials)¶
Run the install.sh by using
bash install.sh
in the fidimag/bin folder.
Add the fidimag to python path¶
Add the following to your .bashrc file:
export PYTHONPATH=/path/to/fidimag:$PYTHONPATH
for example, suppose fidimag is in the directory of ~/work, then:
export PYTHONPATH=~/work/fidimag:$PYTHONPATH
Add the library path to LD_LIBRARY_PATH¶
By default, the libraries are installed in fidimag/local, so in order to run fidimag we need to include the libs path in LD_LIBRARY_PATH, so please add the following to your .bashrc file:
export LD_LIBRARY_PATH=/path/to/fidimag/local/lib:$LD_LIBRARY_PATH
for instance:
export LD_LIBRARY_PATH=~/work/fidimag/local/lib:$LD_LIBRARY_PATH
Adding OOMMF path to the system¶
For the tests that call OOMMF (in micro/tests), we need to tell the system where to
find it. The way it is currently set up (in util/oommf.py), we need to
find our oommf.tcl
file, and add the path to it to .bashrc
in this way:
export OOMMF_PATH=/opt/oommf/oommf-1.2a5bis
Installing on Iridis¶
Few additional notes for installing on iridis.
Loading Modules¶
Need to load the hg and numpy modules. This can be done by
module load hg numpy
These modules will only be loaded for your current session on iridis. To have the modules automatically loaded at login, you can add them to the module initlist by
module initadd hg numpy
Installing PyTest and PyVTK¶
py.test and PyVTK need to be installed locally (at /home/$USER/.local/bin/) by
pip install --user pytest pyvtk
The following path needs to be added to the .bashrc file
export PATH=~/.local/bin:$PATH
Cloning Repository¶
Can only be done with ssh keys.
Quick test¶
Go to the fidimag/tests folder and type “py.test”, a similar result is expected
============================= test session starts ==============================
platform linux2 -- Python 2.7.5 -- pytest-2.4.2
collected 20 items
test_anis.py .
test_demag.py ..
test_dmi.py ..
test_energy.py .
test_exch.py ....
test_mesh.py ..
test_sim.py .......
test_stt.py .
========================== 20 passed in 2.31 seconds ===========================
How to set up a virtual machine via vagrant¶
install vagrant on your host machine
run:
vagrant init ubuntu/trusty64
to set up a basic linux machine.
run:
vagrant up
to start the machine.
ssh into the machine with X-forwarding:
vagrant ssh -- -X
Then within the virtual machine:
aptitude install git
git clone https://github.com/fangohr/fidimag.git
cd fidimag/bin
sudo sh install-ubuntu-packages.sh
sh install.sh
cd ..
make
To run the tests:
cd /home/vagrant/fidimag/tests
py.test
Notes:
- some tests will fail as OOMMF is not installed
- it seems that we need an active X server, on OS X, one may need to install XQuartz before the tests can pass (even ‘import fidimag’ failed without a working X server).
Core equations¶
Landau-Lifshitz-Gilbert (LLG) equation¶
The dynamic of magnetic moment \(\vec{\mu}_i\) is governed by LLG equation,
where \(\vec{S}_i\) is the unit vector of magnetic moment,
and \(\vec{\mu}_s = |\vec{\mu}_i|\), the effective field \(\vec{H}_i\) is defined as
Interactions¶
In the level of atomic moments, \(\vec{\mu}_s\), originated from the angular momentum of electrons in atoms, could be employed as the base unit in simulations. There are several typical interactions between magnetic moments. The total Hamiltonian is the summation of them.
Exchange interaction¶
The classical Heisenberg Hamiltonian with the nearest-neighbor exchange interaction,
where the summation is taken only once for each pair, so the effective field is
In the continuum limit the exchange energy could be written,
so the corresponding effective field is
Once we implemented the Heisenberg exchange interaction, the effective field in the continuum case can be computed by the same codes with
Note that we needs the factor of \(\mu_0\) to convert the units from T to A/m.
Anisotropy¶
The Hamiltonian for uniaxial anisotropy with easy axis in x direction is expressed as,
and the corresponding field is
UniaxialAnisotropy¶
The UniaxialAnisotropy energy of the magnetic system is defined as
the the effective field is,
Dipolar interaction¶
The Hamiltonian for dipolar interaction is,
Dzyaloshinskii-Moriya interaction (DMI)¶
DMI is an antisymmetric, anisotropic exchange coupling beteen spins (magnetic moments),
Note that \(\vec{a}\cdot(\vec{b}\times\vec{c})=(\vec{a}\times\vec{b})\cdot\vec{c}\), the effective field can be computed by
For bulk materials \(\vec{D}_{ij} = D \vec{r}_{ij}\) and for interfacial DMI one has \(\vec{D}_{ij} = D \vec{r}_{ij} \times \vec{e}_z\), in both cases the vector \(\vec{D}_{ij}\) such that \(\vec{D}_{ij}=-\vec{D}_{ji}\).
In the continuum limit the bulk DMI energy could be written,
where \(D_a = -D/a^2\) and the effective field is
For the interfacial case, the effective field thus becomes,
Compared with the effective field [PRB 88 184422]
we have \(D_a = D/a^2\), note that there is no negative sign for the interfacial case.
Zeeman energy¶
The zeeman energy is,
Basically, we will follow the above equations to write codes.
Extended equations¶
Stochastic LLG equation¶
The implemented equation including the thermal fluctuation effects is
where \(\vec{\xi}\) is the thermal fluctuation field and is assumed to have the following properties,
and
Spin transfer torque (Zhang-Li model)¶
The extended equation with current is,
Where
and \(\mu_B=|e|\hbar/(2m)\) is the Bohr magneton. Notice that \(\partial_x \vec{m} \cdot \vec{m}=0\) so \(u_0 (\vec{j}_s \cdot \nabla) \vec{m}= - u_0 \vec{m}\times[\vec{m}\times (\vec{j}_s \cdot \nabla)\vec{m}]\). Besides, we can change the equation to atomistic one by introducing \(\vec{s}=-\vec{S}\) where \(\vec{S}\) is the local spin such that
so \(u_0=p a^3/(2|e|s)\), furthermore,
However, we perfer the normalised equaiton here, after changing it to LL form, we obtain,
although in principle \(\partial_x \vec{m}\) is always perpendicular to \(\vec{m}\), it’s better to take an extra step to remove its longitudinal component, therefore, the real equation written in codes is,
where \(\vec{\tau}=(\vec{j}_s \cdot \nabla)\vec{m}\) is the effective torque generated by current.
Nonlocal spin transfer torque (full version of Zhang-li model)¶
The LLG equation with STT is given by,
where \(\vec{T}\) is the spin transfer torque. In the local form the STT is given by,
And in general case, the spin transfer torque could be computed by,
where \(\tau_{sd}\) is the s-d exchange time and \(\delta \vec{m}\) is the nonequilibrium spin density governed by
By changing the LLG equation to LL form, we obtain,
i.e.,
Spin transfer torque (Slonczewski type)¶
We consider the LLG equation with a Slonczewski-type extension [PRB 91 064423 (2015)],
where \(\vec{p}\) is the unit vector in the direction of the spin polarization. Similar to the Zhang-Li case, the implemented equation in the code is,
where \(\vec{p}_\perp=\vec{p}-(\vec{m}\cdot\vec{p})\vec{m}\).
Developing notes¶
Data structure¶
The first thing we may want to know is that how we label each spin in space, which can be peered from the index method in Mesh class
def index(self, i, j, k):
idx = i*self.nyz + j*self.nz + k
return idx
So we label the cells along z axis first then along y axis and the last is x, therefore we using the following code to loop all cells
for (i = 0; i < nx; i++) {
for (j = 0; j < ny; j++) {
for (k = 0; k < nz; k++) {
index = nyz * i + nz * j + k;
//do something ...
}
}
}
Units¶
We try to follow the SI units in the whole development, for example the gyromagnetic ratio \(\gamma\) is 1.76e11 rad/(s T). Because we use the sampe code to compute the exchange field and DMI field for both the atomic moments and the continuum case, so we need to take care of the relation between the two. For example, the saturated magnetization \(M_s\) can be computed by
Exchange and DMI energy¶
Although we can compute the total energy according to the direct definitions, however, we also can compute them using the corresponding effective fields, the energy density is
where
and thus the total energy is
\[\mathcal{H} = \frac{1}{2}\sum_i \mathcal{H}_i\]
Anisotropy and external field energy¶
We compute them directly from the direct definitions.
Fidimag: A Basic Simulation¶
TODO: - [x] imports - [x] Meshes (+ parameters) - [] Material parameters - [] simulation object - [] adding energies - [] setting magnetisation - [] saving data - [] relax simulation - [] viewing data
This notebook is a guide to the essential commands required to write and run basic Fidimag simulations.
The first step is to import Fidimag. Numpy and Matplotlib are also imported for later use, to demonstrate visualising simulations results.
In [1]:
import fidimag
from fidimag.common import CuboidMesh
import numpy as np
import matplotlib.pyplot as plt
Meshes¶
Mesh Cell
+------------+
+-----+-----+-----+-----+-----+-----+ / /|
/ / / / / / /| / / |
+-----+-----+-----+-----+-----+-----+ | / / | dz
/ / / / / / /| + +------------+ |
+-----+-----+-----+-----+-----+-----+ |/ -----> | | |
/ / / / / / /| + | | +
+-----+-----+-----+-----+-----+-----+ |/ | | /
| | | | | | | + | | / dy
| | | | | | |/ | |/
+-----+-----+-----+-----+-----+-----+ +------------+
dx
We need to create a mesh. Meshes are created by specifying the dimensions of the finite difference cells, (dx, dy, dz) and the number of cells in each direction, (nx, ny, nz).
The cell dimensions are defined by dimensionless units. The dimensions of the mesh/cells are integrated by the parameter, unit_length.
In the the following example, the (cuboid) mesh consists of 6x3x1 cells (nx=6, ny=3 and nz=1), with each cell comprising of the dimensions, dx=3, dy=3 and dz=4. The unit_length = 1e-9 (nm).
Thus, the total size of the mesh is 18nm x 9nm x 4nm.
In [2]:
nx, ny, nz = 6, 3, 1
dx, dy, dz = 3, 3, 4 #nm
unit_length = 1e-9 # define the unit length of the dx units to nm.
mesh = CuboidMesh(nx=nx, ny=ny, nz=nz, dx=dx, dy=dy, dz=dz, unit_length=unit_length)
In [3]:
nx
Out[3]:
6
In [ ]: