# Micromagnetic standard problem 4¶

**Authors**: Marijan Beg, Ryan A. Pepper, and Hans Fangohr

**Date**: 12 December 2016

## Problem specification¶

The sample is a thin film cuboid with dimensions:

- length \(l_{x} = 500 \,\text{nm}\),
- width \(l_{y} = 125 \,\text{nm}\), and
- thickness \(l_{z} = 3 \,\text{nm}\).

The material parameters (similar to permalloy) are:

- exchange energy constant \(A = 1.3 \times 10^{-11} \,\text{J/m}\),
- magnetisation saturation \(M_\text{s} = 8 \times 10^{5} \,\text{A/m}\).

Magnetisation dynamics are governed by the Landau-Lifshitz-Gilbert equation

where \(\gamma_{0} = 2.211 \times 10^{5} \,\text{m}\,\text{A}^{-1}\,\text{s}^{-1}\) and Gilbert damping \(\alpha=0.02\).

In the standard problem 4, the system is first relaxed at zero external magnetic field and then, starting from the obtained equlibrium configuration, the magnetisation dynamics are simulated for two external magnetic fields \(\mathbf{B}_{1} = (-24.6, 4.3, 0.0) \,\text{mT}\) and \(\mathbf{B}_{2} = (-35.5, -6.3, 0.0) \,\text{mT}\).

More detailed specification of Standard problem 4 can be found in Ref. 1.

## Simulation¶

In the first step, we import the required `discretisedfield`

and
`oommfc`

modules.

```
In [1]:
```

```
%matplotlib notebook
import discretisedfield as df
import oommfc as oc
```

```
/usr/local/lib/python3.5/dist-packages/matplotlib/__init__.py:1405: UserWarning:
This call to matplotlib.use() has no effect because the backend has already
been chosen; matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.
warnings.warn(_use_error_msg)
```

Now, we can set all required geometry and material parameters.

```
In [2]:
```

```
# Geometry
lx = 500e-9 # x dimension of the sample(m)
ly = 125e-9 # y dimension of the sample (m)
lz = 3e-9 # sample thickness (m)
# Material (permalloy) parameters
Ms = 8e5 # saturation magnetisation (A/m)
A = 1.3e-11 # exchange energy constant (J/m)
# Dynamics (LLG equation) parameters
gamma = 2.211e5 # gyromagnetic ratio (m/As)
alpha = 0.02 # Gilbert damping
```

## First stage¶

In the first stage, we need to relax the system at zero external magnetic field.

We choose `stdprob4`

to be the name of the system. This name will be
used to name all output files created by OOMMF.

```
In [3]:
```

```
system = oc.System(name='stdprob4')
```

In order to completely define the micromagnetic system, we need to provide:

- hamiltonian \(\mathcal{H}\)
- dynamics \(\text{d}\mathbf{m}/\text{d}t\)
- magnetisation \(\mathbf{m}\)

The mesh is created by providing two points `p1`

and `p2`

between
which the mesh domain spans and the size of a discretisation cell. We
choose the discretisation to be \((5, 5, 3) \,\text{nm}\).

```
In [4]:
```

```
cell = (5e-9, 5e-9, 3e-9) # mesh discretisation (m)
mesh = oc.Mesh(p1=(0, 0, 0), p2=(lx, ly, lz), cell=cell) # Create a mesh object.
```

We can visualise the mesh domain and a discretisation cell:

```
In [5]:
```

```
%matplotlib inline
mesh
```

**Hamiltonian:** In the second step, we define the system’s Hamiltonian.
In this standard problem, the Hamiltonian contains only exchange and
demagnetisation energy terms. Please note that in the first simulation
stage, there is no applied external magnetic field. Therefore, we do not
add Zeeman energy term to the Hamiltonian.

```
In [6]:
```

```
system.hamiltonian = oc.Exchange(A) + oc.Demag()
```

We can check what is the continuous model of system’s Hamiltonian.

```
In [7]:
```

```
system.hamiltonian
```

```
Out[7]:
```

**Dynamics:** Similarly, the system’s dynamics is defined by providing
precession and damping terms (LLG equation).

```
In [8]:
```

```
system.dynamics = oc.Precession(gamma) + oc.Damping(alpha)
system.dynamics # check the dynamics equation
```

```
Out[8]:
```

**Magnetisation:** Finally, we have to provide the magnetisation
configuration that is going to be relaxed subsequently. We choose the
uniform configuration in \((1, 0.25, 0.1)\) direction, and as norm
(magnitude) we set the magnetisation saturation \(M_\text{s}\). In
order to create the magnetisation configuration, we create a `Field`

object from the `discretisedfield`

module.

```
In [9]:
```

```
system.m = df.Field(mesh, value=(1, 0.25, 0.1), norm=Ms)
```

Now, the system is fully defined.

**Energy minimisation:** The system (its magnetisation) is evolved using
a particular driver. In the first stage, we need to relax the system -
minimise its energy. Therefore, we create `MinDriver`

object and drive
the system using its `drive`

method.

```
In [10]:
```

```
md = oc.MinDriver() # create energy minimisation driver
md.drive(system) # minimise the system's energy
```

```
2017/5/19 16:32: Calling OOMMF (stdprob4/stdprob4.mif) ... [0.9s]
```

The system is now relaxed. We can now obtain some data characteristic to the magnetisation field.

```
In [11]:
```

```
print('The average magnetisation is {}.'.format(system.m.average))
print('The magnetisation at the mesh centre {} is {}.'.format(
system.m.mesh.centre, system.m(system.m.mesh.centre)))
```

```
The average magnetisation is (773766.18071923021, 99856.83005410152, -0.00013819450830563856).
The magnetisation at the mesh centre (2.5e-07, 6.25e-08, 1.5e-09) is (799979.27390588203, -5758.5866589173402, 0.00083768562023152002).
```

We can also plot the magnetisation along the diagonal (i.e. from one
corner of the simulation `(0, 0, 0)`

to the other `(lx, ly, lz)`

):

```
In [12]:
```

```
fig = system.m.plot_line_intersection((0, 0, 0), (lx, ly, lz))
fig
```

```
Out[12]:
```

## Second stage: field \(\mathbf{B}_{1}\)¶

In the second stage, we need to apply an external magnetic field \(\mathbf{B}_{1} = (-24.6, 4.3, 0.0) \,\text{mT}\) to the system. In other words, we have to add Zeeman energy term to the Hamiltonian.

```
In [13]:
```

```
# Add Zeeman energy term to the Hamiltonian
H1 = (-24.6e-3/oc.mu0, 4.3e-3/oc.mu0, 0.0)
system.hamiltonian += oc.Zeeman(H1)
```

If we now inspect the Hamiltonian, we see that an additional Zeeman term is added.

```
In [14]:
```

```
system.hamiltonian
```

```
Out[14]:
```

Finally, we can run the simulation using `TimeDriver`

this time. We
run the magnetisation evolution for \(t=1 \,\text{ns}\), during
which we save the system’s state \(n=200\) times.

```
In [15]:
```

```
t = 1e-9 # simulation time (s)
n = 200 # number of data saving steps
td = oc.TimeDriver() # create time driver
td.drive(system, t=t, n=n) # drive the system
```

```
2017/5/19 16:32: Calling OOMMF (stdprob4/stdprob4.mif) ... [4.1s]
```

### Postprocessing¶

When we drove the system using the `TimeDriver`

, we specified that we
want to save the magnetisation configuration \(n=200\) times. A
detailed table of all computed parameters from the last simulation can
be shown from the datatable (`system.dt`

), which is a `pandas`

dataframe [2].

For instance, if we want to show the last 10 rows in the table, we run:

```
In [16]:
```

```
system.dt.tail()
```

```
Out[16]:
```

E | Ecount | max_dm/dt | dE/dt | deltaE | E_Exchange | max_spin_angle | stage_max_spin_angle | run_max_spin_angle | E_Demag | E_Zeeman | iteration | stage_iteration | stage | mx | my | mz | last_time_step | t | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|

195 | -2.676341e-18 | 3736.0 | 1161.789499 | -1.697396e-09 | -2.288007e-21 | 9.548592e-20 | 3.912405 | 4.282757 | 29.615654 | 8.530166e-19 | -3.624844e-18 | 784.0 | 3.0 | 195.0 | -0.984260 | -0.010971 | 0.033987 | 1.380277e-12 | 9.800000e-10 |

196 | -2.685463e-18 | 3755.0 | 1258.464642 | -1.935261e-09 | -2.633436e-21 | 8.637493e-20 | 4.154967 | 4.154967 | 29.615654 | 8.844370e-19 | -3.656275e-18 | 788.0 | 3.0 | 196.0 | -0.987086 | 0.021592 | 0.039286 | 1.380129e-12 | 9.850000e-10 |

197 | -2.695498e-18 | 3774.0 | 1383.455594 | -2.057825e-09 | -2.825730e-21 | 8.039799e-20 | 4.725952 | 4.725952 | 29.615654 | 9.074607e-19 | -3.683357e-18 | 792.0 | 3.0 | 197.0 | -0.988092 | 0.057824 | 0.042604 | 1.379733e-12 | 9.900000e-10 |

198 | -2.705827e-18 | 3793.0 | 1352.455179 | -2.053206e-09 | -2.841915e-21 | 7.586056e-20 | 4.668692 | 4.775022 | 29.615654 | 9.220444e-19 | -3.703732e-18 | 796.0 | 3.0 | 198.0 | -0.986964 | 0.095870 | 0.043794 | 1.379110e-12 | 9.950000e-10 |

199 | -2.715833e-18 | 3812.0 | 1192.662101 | -1.931679e-09 | -2.693402e-21 | 7.141346e-20 | 4.352088 | 4.668692 | 29.615654 | 9.291427e-19 | -3.716389e-18 | 800.0 | 3.0 | 199.0 | -0.983765 | 0.133793 | 0.042832 | 1.378274e-12 | 1.000000e-09 |

Finally, we want to plot the average magnetisation configuration `my`

as a function of time `t`

:

```
In [17]:
```

```
myplot = system.dt.plot("t", "my")
```

```
In [18]:
```

```
system.m.plot_slice(z=0);
```

## References¶

[1] µMAG Site Directory: http://www.ctcms.nist.gov/~rdm/mumag.org.html

[2] Pandas: http://pandas.pydata.org/