#!/usr/bin/env python # coding: utf-8 # # Tutorial: Magneto-optical Kerr Effect # 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.** # ## MOKE reference frame # In `mag2exp` the coordinate system is defined with the beam in the `yz` plane with $\theta$ defined as the angle between the beam direction and the `z` direction. # # # ## The micromagnetic simulation # A micromagnetic simulation can be set up using Ubermag to obtain a 3-dimensional magntic structure. # In[1]: get_ipython().run_line_magic('matplotlib', 'inline') import discretisedfield as df import micromagneticmodel as mm import numpy as np import oommfc as oc 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, nvdim=3, value=m_fun, norm=Ms) # Plot the initial magnetisation: # In[2]: system.m.sel("z").mpl() # Relax the system and plot its magnetisation. # In[3]: # NBVAL_IGNORE_OUTPUT # minimize the energy md = oc.MinDriver() md.drive(system) # Plot relaxed configuration: vectors in z-plane system.m.sel("z").mpl() # From the magnetisation, we can compute the MOKE related quantities. # ## Computing MOKE # # Calculation of the magneto-optical Kerr effect is based off an # incident wave $E^i$ described by # \begin{equation} # E^i = # \begin{pmatrix} # E^i_s \\ E^i_p # \end{pmatrix}, # \end{equation} # where $E^i_s$ and $E^i_p$ are the electric field components of incident linear # s and p polarisation modes. # # i.e. # \begin{equation} # E^i = # \begin{pmatrix} # 1 \\ 0 # \end{pmatrix}, # \end{equation} # is s polarised, # # \begin{equation} # E^i = # \begin{pmatrix} # 0 \\ 1 # \end{pmatrix}, # \end{equation} # is p polarised, # # and # \begin{equation} # E^i = # \begin{pmatrix} # 1 \\ 1j # \end{pmatrix}, # \end{equation} # is circularly polarised. # # The reflected wave can be obtained by multiplication by the reflection matrix # \begin{equation} # \begin{pmatrix} E^r_s \\ E^r_p \end{pmatrix} = # \begin{pmatrix} r_{ss} & r_{sp} \\ r_{ps} & r_{pp} \end{pmatrix} # \begin{pmatrix} E^i_s \\ E^i_p \end{pmatrix} # \end{equation}. # Similarly, the transmitted wave can be obtained by multiplication by the reflection matrix # \begin{equation} # \begin{pmatrix} E^r_s \\ E^r_p \end{pmatrix} = # \begin{pmatrix} t_{ss} & t_{sp} \\ t_{ps} & t_{pp} \end{pmatrix} # \begin{pmatrix} E^i_s \\ E^i_p \end{pmatrix} # \end{equation}. # # These matrices can be obtained from the 4-by-4 product matrix $M$ which can be descried as four 2-by-2 matrices using # \begin{align} # M &= \begin{pmatrix} G & H \\ I & J \end{pmatrix}, \\ # G^{-1} &= \begin{pmatrix} t_{ss} & t_{sp} \\ t_{ps} & t_{pp} \end{pmatrix},\\ # I^{-1} &= \begin{pmatrix} r_{ss} & r_{sp} \\ r_{ps} & r_{pp} \end{pmatrix}. # \end{align} # # 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 $j$th layer $A_j$ and the propagation matrix of the layer $D_{j}$. # This leads to a description of a single layer as $A_j D_j A^{-1}_j$. # $A_{j}$ and $D_{j}$ 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 # \begin{equation} # M = A_f^{-1} \prod_{j} A_{j} D_j A_j^{-1} A_f, # \end{equation} # where $A_j$ is the boundary matrix for the $j$th layer, # $D_j$ is the propagation matrix for the $j$th layer, # and $A_f$ is the boundary layer matrix for free space. # # The boundary matrix can be written as # \begin{equation} # A_{j} = # \begin{pmatrix} # 1 & 0 & 1 & 0 \\ # \frac{iQ\alpha^2_{yi}}{2} \left(m_y \frac{1+\alpha^2_{zi}} # {\alpha_{yi}\alpha_{zi}} - m_z\right) & \alpha_{zi} & # -\frac{iQ\alpha^2_{yi}}{2} \left(m_y \frac{1+\alpha^2_{zi}} # {\alpha_{yi}\alpha_{zi}} + m_z\right) & -\alpha_{zi} \\ # -\frac{in_jQ}{2} \left(m_y \alpha_{yi} + m_z \alpha_{zi} \right) & # -n_j & # -\frac{in_jQ}{2} \left(m_y \alpha_{yi} - m_z \alpha_{zi} \right) & # -n_j \\ # n_j\alpha_{zj} & -\frac{in_jQ}{2} \left(m_y \frac{\alpha_{yi}} # {\alpha_{zi}} - m_z \right) & -n_j \alpha_{zj} & # \frac{in_jQ}{2} \left(m_y \frac{\alpha_{yi}} # {\alpha_{zi}} + m_z \right) # \end{pmatrix} # \end{equation} # where $\alpha_{yi}=\sin\theta_j, \alpha_{zi}=\cos\theta_j$, # $\theta_j$ is the complex refractive angle, $Q$ is the Voight # parameter and $n_j$ is the refractive index of the $j$th layer. # The angle is measure with respect to the $z$ axis and is calculated # using Snell's law. # $m_x$, $m_y$ and # $m_z$ are the normalized magnetisation. # # The propagation matrix can be written as # \begin{equation} # D_{j} = # \begin{pmatrix} # U\cos\delta^i & U\sin\delta^i & 0 & 0 \\ # -U\sin\delta^i & U\cos\delta^i & 0 & 0 \\ # 0 & 0 & U^{-1}\cos\delta^r & U^{-1}\sin\delta^r \\ # 0 & 0 & -U^{-1}\sin\delta^r & U^{-1}\cos\delta^r # \end{pmatrix} # \end{equation} # # where # # \begin{align} # U &= \exp\left(\frac{-i2\pi n_j \alpha_{zj} d_j}{\lambda} \right)\\ # \delta^i &= -\frac{\pi n_j Q d_j g^i}{\lambda \alpha_{zj}} \\ # \delta^r &= -\frac{\pi n_j Q d_j g^r}{\lambda \alpha_{zj}} \\ # g^i &= m_z \alpha_{zj} + m_y \alpha_{yj} \\ # g^r &= m_z \alpha_{zj} - m_y \alpha_{yj} # \end{align} # # where $\alpha_{yi}=\sin\theta_j, \alpha_{zi}=\cos\theta_j$, # $\theta_j$ is the complex refractive angle, $Q$ is the Voight # parameter, $n_j$ is the refractive index, and $d_j$ # is the thickness of the $j$th layer. # The angle is measure with respect to the $z$ axis and is calculated # using Snell's law. # $m_x$, $m_y$ and # $m_z$ are the normalized magnetisation. # $\lambda$ 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`. # In[4]: import mag2exp # In[5]: 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") # The reflected field is `discretisedfield` objects with components `s` and `p` for each of the linear polarisations. These can be accessed using # In[6]: E_r.s # The intensity of the MOKE image is # \begin{equation} # I_K = \lvert E^r_s \rvert ^2 + \lvert E^r_p \rvert ^2. # \end{equation} # The function `mag2exp.moke.intensity` can be used to calculate this quantity. # In[7]: intensity = mag2exp.moke.intensity( system.m, theta, n_0, Q, wavelength, E_i, mode="reflection" ) # As the `intensity` is a `discretisedfield` object, the built in plotting functions can be used to view it. # In[8]: intensity.mpl.scalar(interpolation="spline16", cmap="gray") # Similarly the transmitted intensity can be calculated. # In[9]: intensity = mag2exp.moke.intensity( system.m, theta, n_0, Q, wavelength, E_i, mode="transmission" ) intensity.mpl.scalar(interpolation="spline16", cmap="gray") # This can also be done for circularly polarised light. # In[10]: 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") # Incident at an angle # In[11]: theta = np.pi / 4 intensity = mag2exp.moke.intensity( system.m, theta, n_0, Q, wavelength, E_i, mode="reflection" ) intensity.mpl.scalar(interpolation="spline16") # The Kerr angle of the reflected light can be obtained using # \begin{align} # \Phi_s &= \phi_s' + i \phi_s'' \\ # &= \frac{r_{ps}}{r_{ss}} \\ # \Phi_p &= \phi_p' + i \phi_p'' \\ # &= -\text{Real}\left(\frac{r_{sp}}{r_{pp}}\right) + \text{Imag}\left(\frac{r_{sp}}{r_{pp}}\right) i # \end{align} # where $\phi'$ is the Kerr rotation and # $\phi''$ is the ellipticity for the s and p polarisations. # # The function `mag2exp.moke.kerr_angle` enables the rotation and ellipticity to be obtained. # In[12]: theta = 0 kerr_angle = mag2exp.moke.kerr_angle(system.m, theta, n_0, Q, wavelength) # The s polarisation Kerr rotation # In[13]: kerr_angle.s.real.mpl.scalar(interpolation="spline16") # The s polarisation ellipticity # In[14]: kerr_angle.s.imag.mpl.scalar(interpolation="spline16") # The p polarisation Kerr rotation # In[15]: kerr_angle.p.real.mpl.scalar(interpolation="spline16") # The p polarisation ellipticity # In[16]: 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. # In[17]: 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")