Fe film with cubic anisotropy, angular dependent FMR#

This notebook can be used to compute the dispersion of films with cubic anisotropy. As an example, we choose Fe material parameters for a 20 nm thick film and compute the FMR frequency for anisotropy axes of two different orientations, in-plane and out-of-plane. Note that the notebook might run for several minutes, depending on the computer/notebook computational capabilities. We also included an analytical derivation of the resonance frequency from the free energy according to Ref. 1. The analytical expression of the resonance freqeuncy is given for both the in-plane and out-of-plane field sweep.

NOTE: to run this notebook you need to install the sympy python package by the pip install sympy command in your python virtual environment.

[1]:
import tetrax as tx
import numpy as np
from scipy.constants import mu_0

fe_film = tx.Sample(
    tx.geometries.layer.monolayer(thickness=20, cell_size=1),
    name = "Fe_film"
)

Setting material parameters#

First, we set the material parameters to iron with cubic anisotropy. When setting the anisotropy axes, only the first and the second one need to be given while the third one is automatically calculated (as the cross product of the first two).

[2]:
Ms_ = 1750e3 # A/m
Aex_ = 21e-12 # J/m
gamma_ =  1.838e11 # rad/Ts
K4_ = 48000.0 # in FMR papers might appear as K4, therefore the usage to draw the attention for the equivalence

fe_film.material["Msat"] = Ms_
fe_film.material["Aex"] = Aex_
fe_film.material["gamma"] = gamma_


fe_film.material["Kc1"] = K4_
fe_film.material["e_c1"] = (1,0,0)
fe_film.material["e_c2"] = (0,1,0)

fe_film.material

[2]:

SampleMaterial (Sample.material) of 'Fe_film'

name average description
Msat 1750000.0 A/m saturation magnetization
Aex 2.0999999999999992e-11 J/mexchange stiffness
gamma 183800000000.0 radHz/T gyromagnetic ratio
alpha 0.008 (is_global) Gilbert damping
Ku1 0.0 J/m^3 first-order unaxial-anistropy constant
e_u [0. 0. 1.] uniaxial anistropy direction
Dbulk 0 (is_global) bulk DMI constant
Didmi 0 (is_global) interfacial DMI constant
e_d [0. 1. 0.] interfacial DMI direction
Kc1 48000.0 J/m^3 first-order cubic-anistropy constant
e_c1 [1. 0. 0.] first cubic anistropy direction
e_c2 [0. 1. 0.] second cubic anistropy direction
e_c3 [0. 0. 1.] third cubic anistropy direction
Hint: Access each parameter using material['name'].

We could have also used the template material provided with TetraX.

fe_film.material = tx.materials.iron

Angular dependence of the cubic anisotropy energy#

The angular dependence of the cubic anisotropy is compared to the analytical solution using macrospin approximation.

The analytics will be performed with the sympy package.

[3]:
from sympy import *

# We define the sybmolic variables for the analytics
theta, phi, K4 = symbols("theta phi K4", positive=True, real=True)

# The cubic anisotropy energy in spherical coordinates is:

Fcub = 2*K4*sin(theta)**2*(cos(theta)**2 + sin(theta)**2*sin(2*phi)**2/4)
# with theta and phi being the out-of-plane and i-plane angles and K4 the anisotropy energy.
# for in-plane angular dependence the theta = pi/2

ecub = Fcub.subs(theta,pi/2)

ecub
[3]:
$\displaystyle \frac{K_{4} \sin^{2}{\left(2 \phi \right)}}{2}$

We compare the TetraX results with the analytics:

[4]:
fe_film.material["e_c1"] = (1,0,0)
fe_film.material["e_c2"] = (0,0,1)

ecubic = []

phis = np.linspace(-95,95,191)

for p in phis:
    fe_film.mag = tx.vectorfields.homogeneous(fe_film.xyz, p, 0)
    ecubic.append(fe_film.average(fe_film.get_energy_density("cubic_anisotropy")))

from plotly import graph_objects as go
import plotly.express as px

cmap = px.colors.sequential.Plasma
fig = go.Figure()

colors = ["#000E86","#C81C89"]

fig.add_trace(
            go.Scatter(
                x=phis,
                y=K4_/2*(np.sin(2*phis/180*np.pi)**2),
                mode="lines",
                name="Macrospin, theory",
                legendgroup=1,
                line = {"color": colors[0]},
            )
        )

fig.add_trace(
            go.Scatter(
                x=phis,
                y=np.array(ecubic),
                mode="lines",
                name="TetraX",
                legendgroup=2,
                line = {"dash": "dash", "color": colors[1]},
            )
        )

fig.update_xaxes(title_text="In-plane angle <i>ø<i> (deg)", exponentformat="power")
fig.update_yaxes(title_text="Cubic anisotropy energy density (J/m^3)", exponentformat="power")

fig.update_layout(
        template="simple_white",
        height=600,
        width=600,
        hoverlabel={"bordercolor": "rgba(255,255,255,1)"},
    )
fig.show(renderer="notebook") # remove the renderer argument when running on your computer

Angular dependence of the ferromagnetic resonance mode#

In-plane:#

[5]:
# First for the (100) cubic anisotropy axes azimuthal field sweep
Bext_IP = 350e-3 # mT in-plane field

phis = np.linspace(-95,95,191)

fe_film.material["e_c1"] = (1,0,0)
fe_film.material["e_c2"] = (0,1,0)

f0_inplane = []

for p in phis:
    fe_film.mag = tx.vectorfields.homogeneous(fe_film.xyz, p, 0)
    fe_film.external_field = Bext_IP*tx.vectorfields.homogeneous(fe_film.xyz, p, 0)

    spectrum = tx.experiments.eigenmodes(fe_film, num_cpus=-1,num_modes=2, k=0, save_mode_profiles=False, verbose=False)
    f0_inplane.append(spectrum.frequencies(0,0,0))

Plotting the in-plane angular dependence of the FMR (k=0) resonance#

[6]:
from plotly import graph_objects as go

fig = go.Figure()

fig.add_trace(
                go.Scatter(
                    x=phis,
                    y=np.array(f0_inplane)*1e-9,
                    mode="lines",
                    name="[100], [010] - in-plane FMR",
                )
            )

fig.update_xaxes(title_text="In-plane angle <i>ø</i> (deg)")
fig.update_yaxes(title_text="Frequency <i>f</i> (GHz)")

fig.update_layout(
        template="simple_white",
        height=600,
        width=600,
        hoverlabel={"bordercolor": "rgba(255,255,255,1)"},
    )
fig.show(renderer="notebook") # remove the renderer argument when running on your computer