Simulating an Anisotropic Grain Structure

[1]:
import fidimag
from scipy.spatial import cKDTree
import numpy as np

Here we set up a simple test system to show how to simulate magnetic grains which have different anisotropy orientations and strengths.

[2]:
A=1.3e-11
Ms=8.6e5
n = 40
d = 5

mesh = fidimag.common.CuboidMesh(nx=n, ny=n, nz=1, dx=d, dy=d, dz=d, unit_length=1e-9, periodicity=(True, True, False))
sim = fidimag.micro.Sim(mesh, name="Grains")
sim.alpha = 1.0
[3]:
# Create positions to be grain centres, and create a cKDTree to
# perform Voronoi Tesselation
np.random.seed(10)
Ngrains = 15
grain_centres = np.random.uniform(0, n*d, (Ngrains, 2))
voronoi_kdtree = cKDTree(grain_centres)

# Define Anisotropy Strength
Ku = 1e6
# Generate random anisotropy axes
axes = np.random.uniform(-1, 1, (Ngrains, 3))
# Weight them towards +z - assume grains oriented along field cooled direction
axes[:, 2] += 1.0
# Normalise
axes /= np.linalg.norm(axes, axis=1)[:, np.newaxis]
# Generate a normal distribution of anisotropy strengths:
strengths = np.random.normal(Ku, Ku*0.2, Ngrains)

# We then use the cKDTree in two functions. We get the x, y position
# of each micromagnetic cell, and query the tree for the region that
# the cell sits in. The functions then return the axis and strength
# at that region index.

def K_axis(pos):
    x, y, z = pos
    _, test_point_regions = voronoi_kdtree.query(np.array([[x, y]]), k=1)
    region = test_point_regions[0]
    return axes[region]

def K_mag(pos):
    x, y, z = pos
    _, test_point_regions = voronoi_kdtree.query(np.array([[x, y]]), k=1)
    region = test_point_regions[0]
    return strengths[region]
[4]:
sim.set_m((0, 0, 1), normalise=True)

sim.set_Ms(Ms)
anisotropy = fidimag.micro.UniaxialAnisotropy(K_mag, K_axis)
sim.add(anisotropy)
sim.add(fidimag.micro.UniformExchange(A))
sim.add(fidimag.micro.Demag(pbc_2d=True))

To check that this looks sensible, we plot the strength of the anisotropy across the whole sample in each direction:

[5]:
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid

strength_x = anisotropy._axis[0::3].reshape(n, n) * anisotropy._Ku.reshape(n, n)
strength_y = anisotropy._axis[1::3].reshape(n, n) * anisotropy._Ku.reshape(n, n)
strength_z = anisotropy._axis[2::3].reshape(n, n) * anisotropy._Ku.reshape(n, n)

maxs = np.max([np.max(np.abs(strength_x)),
               np.max(np.abs(strength_y)),
               np.max(np.abs(strength_z))])



fig = plt.figure(figsize=(5, 3))

grid = ImageGrid(fig, 111,          # as in plt.subplot(111)
                 nrows_ncols=(1,3),
                 axes_pad=0.15,
                 share_all=True,
                 cbar_location="right",
                 cbar_mode="single",
                 cbar_size="7%",
                 cbar_pad=0.15,
                 )

axes = [axis for axis in grid]


axes[0].imshow(strength_x, origin='lower', cmap='RdBu', vmin=-maxs, vmax=maxs, extent=[0, n*d, 0, n*d])
axes[1].imshow(strength_y, origin='lower', cmap='RdBu', vmin=-maxs, vmax=maxs, extent=[0, n*d, 0, n*d])
im = axes[2].imshow(strength_z, origin='lower', cmap='RdBu', vmin=-maxs, vmax=maxs, extent=[0, n*d, 0, n*d])
axes[2].cax.colorbar(im)
axes[2].cax.toggle_label(True)

axes[0].set_title("$K_x$")
axes[1].set_title("$K_y$")
axes[2].set_title("$K_z$")

plt.savefig("Anisotropy.png", dpi=600)

../../_images/user_guide_ipynb_Simulating_an_Anisotropic_Grain_Structure_7_0.png

We can see that we have a granular structure in the anisotropy. We now simply relax the system and plot the magnetisation:

[6]:
sim.relax(dt=1e-12, stopping_dmdt=1.0, max_steps=10000, save_vtk_steps=10, printing=False)
print('Done')
Done
[7]:
fidimag.common.plot(sim, component='z')
../../_images/user_guide_ipynb_Simulating_an_Anisotropic_Grain_Structure_10_0.png

The remanent Magnetisation in the z-direction is then:

[8]:
remanence = np.mean(sim.spin[2::3])*Ms
print(remanence)
521197.7929881685