Getting started 00: First Ubermag notebook

Interactive online tutorial: Binder

The goal of this tutorial is to familiarise users with basics of running Ubermag simulations in Jupyter notebook. The only thing you need to know for this tutorial is how to execute individual cells: this is done by pressing Shift + Return (Return = Enter).

Simple Ubermag simulation

Before we specify and run the simulation, we have to import Ubermag modules we intend to use. Because we are going to run OOMMF simulations, we will import oommfc and for creating finite diference fields, we are going to import discretisedfield.

In [1]:
import oommfc as oc
import discretisedfield as df
import micromagneticmodel as mm

# The following line enables plotting inside the notebook.
%matplotlib inline

System

The object on which different drivers act on in Ubermag is oommfc.System. In order to define the micromagnetic system we intend to simulate, we have to specify:

  1. Hamiltonian,
  2. Dynamics equation,
  3. Magnetisation configuration.
In [2]:
system = mm.System(name='first_ubermag_simulation')

Hamiltonian

The Hamiltonian for the first Ubermag simulaton is very simple and contains only:

  1. exchange,
  2. demagnetisation,
  3. Zeeman energy terms.

We will apply an external magnetic field in the $x$-direction for the purpose of this demonstration:

In [3]:
A = 1e-12  # exchange energy constant (J/m)
H = (5e6, 0, 0)  # external magnetic field in the x-direction (A/m)
system.energy = mm.Exchange(A=A) + mm.Demag() + mm.Zeeman(H=H)

Dynamics equation

The dynamics equation contains only precession and damping terms:

In [4]:
gamma0 = 2.211e5  # gyrotropic ratio parameter (m/As)
alpha = 0.2  # Gilbert damping
system.dynamics = mm.Precession(gamma0=gamma0) + mm.Damping(alpha=alpha)

Initial magnetisation

We initialise the system in positive $y$-direction, i.e. (0, 1, 0), which is different from the equlibrium state we expect for the external Zeeman field applied in $x$ direction:

In [5]:
L = 100e-9  # cubic sample edge length (m)
d = 5e-9  # discretisation cell size (m)
mesh = df.Mesh(p1=(0, 0, 0), p2=(L, L, L), cell=(d, d, d))

Ms = 8e6  # saturation magnetisation (A/m)
system.m = df.Field(mesh, dim=3, value=(0, 1, 0), norm=Ms)

Inspect the properties of the system

We can check the characteristics of the system we defined by asking objects to represent themselves:

In [6]:
mesh.k3d()
In [7]:
system.energy
Out[7]:
$A \left[ (\nabla \mathbf{m}_\text{x})^{2} + (\nabla \mathbf{m}_\text{y})^{2} + (\nabla \mathbf{m}_\text{z})^{2} \right]-\frac{1}{2}\mu_{0}M_\text{s}\mathbf{m} \cdot \mathbf{H}_\text{d}-\mu_{0}M_\text{s} \mathbf{m} \cdot \mathbf{H}$
In [8]:
system.dynamics
Out[8]:
$-\frac{\gamma_{0}}{1 + \alpha^{2}} \mathbf{m} \times \mathbf{H}_\text{eff}-\frac{\gamma_{0} \alpha}{1 + \alpha^{2}} \mathbf{m} \times (\mathbf{m} \times \mathbf{H}_\text{eff})$

We can also visualise the current magnetisation field (using MatPlotLib=mpl):

In [9]:
system.m.plane('z').mpl()

And we can visualise the same data using k3d_vectors - this is more suitable for interactive exploration:

In [10]:
system.m.plane('z').k3d_vector(head_size=20)

Driving the system

After the system object is created, we can minimise its energy (relax it) using the Minimisation Driver (MinDriver).

In [11]:
md = oc.MinDriver()
md.drive(system)
Running OOMMF (ExeOOMMFRunner) [2020/06/12 00:33]... (1.8 s)

The system is now relaxed, and we can plot its slice and compute its average magnetisation.

In [12]:
system.m.plane('z').mpl()
In [13]:
system.m.plane('z').k3d_vector(color_field=system.m.z, head_size=20)
In [14]:
system.m.average
Out[14]:
(7850881.329363451, -0.00035205061599845067, -2.2642780095338822e-11)

We can see that the magnetisation is aligned along the $x$-direction, as expected having in mind we applied the external magnetic field in that direction.