Magneto-optical Kerr Effect (MOKE) microscopy is an optical technique that can be used to image the magnetisation structures of samples. This technique uses the change in polarisation in light through a magnetic media in order to detect the magnetisation.
The current version of MOKE microscopy is under development and currently the angle of incidence is approximated to be the same throughout the sample. This is not correct but allows roughly behaviour to be seen and we are looking to correct this in future releases. Please feel free to contact us or raise an issue if you have any comments on this technique.
In mag2exp
the coordinate system is defined with the beam in the yz
plane with θ defined as the angle between the beam direction and the z
direction.
A micromagnetic simulation can be set up using Ubermag
to obtain a 3-dimensional magntic structure.
%matplotlib inline
import oommfc as oc
import discretisedfield as df
import micromagneticmodel as mm
import numpy as np
import ubermagutil.units as uu
np.random.seed(1)
region = df.Region(p1=(-150e-9, -150e-9, 0), p2=(150e-9, 150e-9, 20e-9))
mesh = df.Mesh(region=region, cell=(5e-9, 5e-9, 5e-9))
system = mm.System(name='Box2')
system.energy = (mm.Exchange(A=1.6e-11)
+ mm.DMI(D=4e-3, crystalclass='T')
+ mm.UniaxialAnisotropy(K=0.51e6, u=(0, 0, 1))
+ mm.Demag()
+ mm.Zeeman(H=(0, 0, 2e5)))
Ms = 1.1e6 # A/m
def m_fun(pos):
return 2 * np.random.rand(3) - 1
# create system with above geometry and initial magnetisation
system.m = df.Field(mesh, dim=3, value=m_fun, norm=Ms)
Plot the initial magnetisation:
system.m.plane('z').mpl()
Relax the system and plot its magnetisation.
# NBVAL_IGNORE_OUTPUT
# minimize the energy
md = oc.MinDriver()
md.drive(system)
# Plot relaxed configuration: vectors in z-plane
system.m.plane('z').mpl()
Running OOMMF (DockerOOMMFRunner) [2021/09/28 11:32]... (20.9 s)
From the magnetisation, we can compute the MOKE related quantities.
Calculation of the magneto-optical Kerr effect is based off an incident wave Ei described by Ei=(EisEip),
i.e. Ei=(10),
is p polarised,
and Ei=(11j),
The reflected wave can be obtained by multiplication by the reflection matrix (ErsErp)=(rssrsprpsrpp)(EisEip)
These matrices can be obtained from the 4-by-4 product matrix M which can be descried as four 2-by-2 matrices using M=(GHIJ),G−1=(tsstsptpstpp),I−1=(rssrsprpsrpp).
The product matrix M is calculated based of the the system being studied by dividing the system up into layers of magnetisation in the z direction. Each of these layers have a thickness and boundaries, in order to describe this we can use the boundary matrix of the jth layer Aj and the propagation matrix of the layer Dj. This leads to a description of a single layer as AjDjA−1j. Aj and Dj are both 4-by-4 matrices.
If we assume are material is surrounded by free space, the whole system can thus be described by the product matrix M withe the following form M=A−1f∏jAjDjA−1jAf,
The boundary matrix can be written as Aj=(1010iQα2yi2(my1+α2ziαyiαzi−mz)αzi−iQα2yi2(my1+α2ziαyiαzi+mz)−αzi−injQ2(myαyi+mzαzi)−nj−injQ2(myαyi−mzαzi)−njnjαzj−injQ2(myαyiαzi−mz)−njαzjinjQ2(myαyiαzi+mz))
The propagation matrix can be written as Dj=(UcosδiUsinδi00−UsinδiUcosδi0000U−1cosδrU−1sinδr00−U−1sinδrU−1cosδr)
where
U=exp(−i2πnjαzjdjλ)δi=−πnjQdjgiλαzjδr=−πnjQdjgrλαzjgi=mzαzj+myαyjgr=mzαzj−myαyjwhere αyi=sinθj,αzi=cosθj, θj is the complex refractive angle, Q is the Voight parameter, nj is the refractive index, and dj is the thickness of the jth layer. The angle is measure with respect to the z axis and is calculated using Snell's law. mx, my and mz are the normalized magnetisation. λ is the wavelength of light.
Please be aware that the current version of MOKE is still under development and does not deal with the refractive index correctly
The function mag2exp.moke.e_field
is used to calculate the relected or transmitted electric field based on an incident field E_i
.
import mag2exp
E_i = [1, 0]
theta = 0
n_0 = 2
Q = 1
wavelength = 600e-9 # Meters
E_r = mag2exp.moke.e_field(system.m, theta, n_0, Q, wavelength, E_i, mode='reflection')
c:\users\samjr_ym2i32\onedrive - university of warwick\ubermag_pd\ubermag_dev\mag2exp\mag2exp\moke.py:486: UserWarning: This technique is currently under development so results may not be accurate. Please see the documentation for further details. warnings.warn('This technique is currently under development so results'
The reflected field is discretisedfield
objects with components s
and p
for each of the linear polarisations. These can be accessed using
E_r.s
Field(mesh=Mesh(region=Region(p1=(-1.5e-07, -1.5e-07, 7.500000000000001e-09), p2=(1.5e-07, 1.5e-07, 1.25e-08)), n=(60, 60, 1), bc='', subregions={}, attributes={'unit': 'm', 'fourierspace': False, 'isplane': True, 'planeaxis': 2, 'point': 1e-08, 'axis1': 0, 'axis2': 1}), dim=1)
The intensity of the MOKE image is IK=|Ers|2+|Erp|2.
mag2exp.moke.intensity
can be used to calculate this quantity.
intensity = mag2exp.moke.intensity(system.m, theta, n_0, Q, wavelength,
E_i, mode='reflection')
c:\users\samjr_ym2i32\onedrive - university of warwick\ubermag_pd\ubermag_dev\mag2exp\mag2exp\moke.py:486: UserWarning: This technique is currently under development so results may not be accurate. Please see the documentation for further details. warnings.warn('This technique is currently under development so results'
As the intensity
is a discretisedfield
object, the built in plotting functions can be used to view it.
intensity.mpl.scalar(interpolation='spline16', cmap='gray')
Similarly the transmitted intensity can be calculated.
intensity = mag2exp.moke.intensity(system.m, theta, n_0, Q, wavelength, E_i, mode='transmission')
intensity.mpl.scalar(interpolation='spline16', cmap='gray')
c:\users\samjr_ym2i32\onedrive - university of warwick\ubermag_pd\ubermag_dev\mag2exp\mag2exp\moke.py:486: UserWarning: This technique is currently under development so results may not be accurate. Please see the documentation for further details. warnings.warn('This technique is currently under development so results'
This can also be done for circularly polarised light.
E_i = [1, 1j]
intensity = mag2exp.moke.intensity(system.m, theta, n_0, Q, wavelength, E_i, mode='reflection')
intensity.mpl.scalar(interpolation='spline16', cmap='gray')
c:\users\samjr_ym2i32\onedrive - university of warwick\ubermag_pd\ubermag_dev\mag2exp\mag2exp\moke.py:486: UserWarning: This technique is currently under development so results may not be accurate. Please see the documentation for further details. warnings.warn('This technique is currently under development so results'
Incident at an angle
theta = np.pi/4
intensity = mag2exp.moke.intensity(system.m, theta, n_0, Q, wavelength, E_i, mode='reflection')
intensity.mpl.scalar(interpolation='spline16')
c:\users\samjr_ym2i32\onedrive - university of warwick\ubermag_pd\ubermag_dev\mag2exp\mag2exp\moke.py:486: UserWarning: This technique is currently under development so results may not be accurate. Please see the documentation for further details. warnings.warn('This technique is currently under development so results'
The Kerr angle of the reflected light can be obtained using Φs=ϕ′s+iϕ″s=rpsrssΦp=ϕ′p+iϕ″p=−Real(rsprpp)+Imag(rsprpp)i
The function mag2exp.moke.kerr_angle
enables the rotation and ellipticity to be obtained.
theta = 0
kerr_angle = mag2exp.moke.kerr_angle(system.m, theta, n_0, Q, wavelength)
c:\users\samjr_ym2i32\onedrive - university of warwick\ubermag_pd\ubermag_dev\mag2exp\mag2exp\moke.py:368: UserWarning: This technique is currently under development so results may not be accurate. Please see the documentation for further details. warnings.warn('This technique is currently under development so results'
The s polarisation Kerr rotation
kerr_angle.s.real.mpl.scalar(interpolation='spline16')
The s polarisation ellipticity
kerr_angle.s.imag.mpl.scalar(interpolation='spline16')
The p polarisation Kerr rotation
kerr_angle.p.real.mpl.scalar(interpolation='spline16')
The p polarisation ellipticity
kerr_angle.p.imag.mpl.scalar(interpolation='spline16')
Often experiments can be limited by their resolution. In order to take this into account when computing images the kerr_angle
, e_field
, and intensity
functions has the ability to convolute the output with a 2-dimensional Gaussian to view different spatial resolutions. A value for the Full Width Half Maximum (FWHM) of the Gaussian can be specified (in meters) for each dimension. For example a convolution of a 2 dimensional Gaussian with the intensity image is shown below.
intensity = mag2exp.moke.intensity(system.m, theta, n_0, Q, wavelength, E_i, mode='reflection', fwhm=(25e-9, 25e-9))
intensity.mpl.scalar(interpolation='spline16')
c:\users\samjr_ym2i32\onedrive - university of warwick\ubermag_pd\ubermag_dev\mag2exp\mag2exp\moke.py:486: UserWarning: This technique is currently under development so results may not be accurate. Please see the documentation for further details. warnings.warn('This technique is currently under development so results'