#!/usr/bin/env python # coding: utf-8 # # Periodic boundary conditions # # In this tutorial, we compute and relax a skyrmion in an interfacial-DMI (Cnv) material in a part of an infinitely large thin film. # In[1]: import oommfc as mc import discretisedfield as df import micromagneticmodel as mm # We define mesh in cuboid through corner points `p1` and `p2`, and discretisation cell size `cell`. # In[2]: region = df.Region(p1=(-50e-9, -50e-9, 0), p2=(50e-9, 50e-9, 10e-9)) mesh = df.Mesh(region=region, cell=(5e-9, 5e-9, 5e-9), bc="xy") # Here `bc="xy"` means that we have periodic boundary conditions along the `x` and `y` directions. The mesh we defined is: # In[3]: mesh.mpl() # Now, we can define the system object by first setting up the Hamiltonian: # In[4]: system = mm.System(name="skyrmion") system.energy = ( mm.Exchange(A=1.6e-11) + mm.DMI(D=4e-3, crystalclass="Cnv_z") + mm.UniaxialAnisotropy(K=0.2e6, u=(0, 0, 1)) + mm.Zeeman(H=(0, 0, 1e5)) ) system.energy # Now, we need to define a function to define the initial magnetisation which is going to relax to skyrmion. # In[5]: def m_init(pos): """Function to set initial magnetisation direction: -z inside cylinder (r=10nm), +z outside cylinder. y-component to break symmetry. """ x, y, z = pos if (x**2 + y**2) ** 0.5 < 10e-9: return (0, 0, -1) else: return (0, 0, 1) system.m = df.Field(mesh, nvdim=3, value=m_init, norm=1.1e6) # The initial magnetsation is: # In[6]: system.m.sel("z").mpl() # Finally we can minimise the energy and plot the magnetisation. # In[7]: # minimize the energy md = mc.MinDriver() md.drive(system) # Plot relaxed configuration: vectors in z-plane system.m.sel("z").mpl() # In[8]: # Plot z-component only: system.m.z.sel("z").mpl() # Finally we can sample and plot the magnetisation along the line: # In[9]: system.m.z.line(p1=(-49e-9, 0, 0), p2=(49e-9, 0, 0), n=20).mpl() # Finally let us compute the skyrmion number # # $$S = \frac{1}{4\pi}\int\mathbf{m}\cdot\left(\frac{\partial \mathbf{m}}{\partial x} \times \frac{\partial \mathbf{m}}{\partial y}\right)dxdy$$ # In[10]: import math m = system.m.orientation.sel("z") 1 / (4 * math.pi) * (m.dot(m.diff("x").cross(m.diff("y")))).integrate() # In[11]: import discretisedfield.tools as dft dft.topological_charge(system.m.sel("z")) # In[12]: dft.topological_charge(system.m.sel("z"), method="berg-luescher")