In [1]:
import oommfc as oc
import discretisedfield as df
%matplotlib inline
In this tutorial we show how spin transfer torque (STT) can be included in micromagnetic simulations. To illustrate that, we will try to move a domain wall pair using spin-polarised current.
Let us simulate a two-dimensional sample with length $L = 500 \,\text{nm}$, width $w = 20 \,\text{nm}$ and discretisation cell $(2.5 \,\text{nm}, 2.5 \,\text{nm}, 2.5 \,\text{nm})$. The material parameters are:
In [2]:
# Definition of parameters
L = 500e-9 # sample length (m)
w = 20e-9 # sample width (m)
d = 2.5e-9 # discretisation cell size (m)
Ms = 5.8e5 # saturation magnetisation (A/m)
A = 15e-12 # exchange energy constant (J/)
D = 3e-3 # Dzyaloshinkii-Moriya energy constant (J/m**2)
K = 0.5e6 # uniaxial anisotropy constant (J/m**3)
u = (0, 0, 1) # easy axis
gamma = 2.211e5 # gyromagnetic ratio (m/As)
alpha = 0.3 # Gilbert damping
# Mesh definition
p1 = (0, 0, 0)
p2 = (L, w, d)
cell = (d, d, d)
mesh = oc.Mesh(p1=p1, p2=p2, cell=cell)
# Micromagnetic system definition
system = oc.System(name="domain_wall_pair")
system.hamiltonian = oc.Exchange(A=A) + \
oc.DMI(D=D, kind="interfacial") + \
oc.UniaxialAnisotropy(K=K, u=u)
system.dynamics = oc.Precession(gamma=gamma) + oc.Damping(alpha=alpha)
Because we want to move a DW pair, we need to initialise the magnetisation in an appropriate way before we relax the system.
In [3]:
def m_value(pos):
x, y, z = pos
if 20e-9 < x < 40e-9:
return (0, 1e-8, -1)
else:
return (0, 1e-8, 1)
# We have added the y-component of 1e-8 to the magnetisation to be able to
# plot the vector field. This will not be necessary in the long run.
system.m = df.Field(mesh, value=m_value, norm=Ms)
system.m.plot_slice("z", 0);
Now, we can relax the magnetisation.
In [4]:
md = oc.MinDriver()
md.drive(system)
system.m.plot_slice("z", 0);
Now we can add the STT term to the dynamics equation.
In [5]:
ux = 400 # velocity in x direction (m/s)
beta = 0.5 # non-adiabatic STT parameter
system.dynamics += oc.STT(u=(ux, 0, 0), beta=beta) # please notice the use of `+=` operator
And drive the system for half a nano second:
In [6]:
td = oc.TimeDriver()
td.drive(system, t=0.5e-9, n=100)
system.m.plot_slice("z", 0);
We see that the DW pair has moved to the positive $x$ direction.
In [7]:
# Definition of parameters
L = 500e-9 # sample length (m)
w = 20e-9 # sample width (m)
d = 2.5e-9 # discretisation cell size (m)
Ms = 5.8e5 # saturation magnetisation (A/m)
A = 15e-12 # exchange energy constant (J/)
D = 3e-3 # Dzyaloshinkii-Moriya energy constant (J/m**2)
K = 0.5e6 # uniaxial anisotropy constant (J/m**3)
u = (0, 0, 1) # easy axis
gamma = 2.211e5 # gyromagnetic ratio (m/As)
alpha = 0.3 # Gilbert damping
# Mesh definition
p1 = (0, 0, 0)
p2 = (L, w, d)
cell = (d, d, d)
mesh = oc.Mesh(p1=p1, p2=p2, cell=cell)
# Micromagnetic system definition
system = oc.System(name="domain_wall")
system.hamiltonian = oc.Exchange(A=A) + \
oc.DMI(D=D, kind="interfacial") + \
oc.UniaxialAnisotropy(K=K, u=u)
system.dynamics = oc.Precession(gamma=gamma) + oc.Damping(alpha=alpha)
def m_value(pos):
x, y, z = pos
if 20e-9 < x < 40e-9:
return (0, 1e-8, -1)
else:
return (0, 1e-8, 1)
# We have added the y-component of 1e-8 to the magnetisation to be able to
# plot the vector field. This will not be necessary in the long run.
system.m = df.Field(mesh, value=m_value, norm=Ms)
system.m.plot_slice("z", 0);
In [8]:
md = oc.MinDriver()
md.drive(system)
system.m.plot_slice("z", 0);
In [9]:
ux = 400 # velocity in x direction (m/s)
beta = 0.5 # non-adiabatic STT parameter
system.dynamics += oc.STT(u=(ux, 0, 0), beta=beta)
td = oc.TimeDriver()
td.drive(system, t=0.5e-9, n=100)
system.m.plot_slice("z", 0);