Transversal hysteresis of rectangular waveguide#
In this notebook, we calculate a hysteresis loop with the static field applied along the transversal/width (here: \(x\)) direction of a rectangular waveguide.
First, we create the sample and set the material parameters to permalloy.
[1]:
import tetrax as tx
import numpy as np
sample = tx.Sample(
tx.geometries.waveguide.rectangular(
width=500,
thickness=20,
cell_size_width=5,
cell_size_thickness=5
),
name="hysteresis_rect_WG_500nmx20nm"
)
sample.material = tx.materials.permalloy
Equilibrium in a field loop#
First, we construct a field range from -300 to 300 mT in both directions. For each value of the external field, we relax the system to its equilibrium and obtain the average magnetization in the cross-section of the waveguide using the average() method of the sample. Since energy minimization using the relax() function is not the most reliable and tends to fail some points, we use dynamic relaxation using relax_dynamic() in these situations to minimize the total torque in the system
instead. Note that the following cell can take a while depending on the number of field steps and the size of the used mesh.
[2]:
static_field_range = np.concatenate((np.linspace(-.3, .3 , 70), np.linspace(.3, -.3 , 70))) # in Tesla
average_magnetization = []
sample.mag = tx.vectorfields.homogeneous(sample.xyz, 60.0, 0.0)
for i, B in enumerate(static_field_range):
# We reinitialize the sample magnetization at an oblique angle at each field step.
sample.external_field = (B, 0, 0.005)
# In general, we use energy minimization to calculate the equilibrium state.
relaxation = tx.experiments.relax(
sample,
verbose=False, # surpress verbose console output
set_initial_on_failure=False, # store last step even on failure
tolerance=1e-12,
)
# Should energy minimization fail to achieve the desired accuracy, we
# Continue with dynamic relaxation (based on the overdamped LLG).
if not relaxation.was_success:
print("Relaxing with LLG ... ", end="\r")
tx.experiments.relax_dynamic(
sample,
verbose=False,
tolerance=1e-10
)
# storing the average magnetization in a list
average_magnetization.append(sample.average(sample.mag))
print(f"B = {int(B*1e3)} mT ({(i+1)/len(static_field_range)*100:.1f}%) done.", end="\r")
B = -300 mT (100.0%) done. (s), dm/dt = 18471.97532071007 [Hz], <mag.x> = -1.00, <mag.y> = 0.00, <mag.z> = 0.033
Plotting the results#
We can plot the obtained average magnetization as a function of the applied field using plotly.
[3]:
from plotly import graph_objects as go
fig = go.Figure()
fig.add_trace(
go.Scatter(
x=static_field_range*1e3,
y=np.asarray(average_magnetization)[:, 0],
mode="lines",
line = dict(color="#86337A"),
name = "<i>m</i><sub>x</sub>",
)
)
fig.add_trace(
go.Scatter(
x=static_field_range*1e3,
y=np.asarray(average_magnetization)[:, 1],
mode="lines",
line = dict(color="#D16F6B"),
name = "<i>m</i><sub>y</sub>",
)
)
fig.add_trace(
go.Scatter(
x=static_field_range*1e3,
y=np.asarray(average_magnetization)[:, 2],
mode="lines",
line = dict(color="#EAB44F"),
name = "<i>m</i><sub>z</sub>",
)
)
fig.update_xaxes(title_text="External field <i>B</i><sub>x</sub> (mT)", exponentformat="power")
fig.update_yaxes(title_text="Normalized magnetization", 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.