Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DMI standardproblem #63

Open
wants to merge 12 commits into
base: dev
Choose a base branch
from
99 changes: 99 additions & 0 deletions test/mumax3/test_mumax3_DMI_standardproblem1D.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"""This test is based on the 1D case in
https://iopscience.iop.org/article/10.1088/1367-2630/aaea1c
The magnet lies along the z-direction, because mumax³ is not correct. They ignore
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"mumax3 is not correct" is a very bold statement. I would be more specific and refer to the issue number in its repo instead.

the z-component.
"""

import pytest
import numpy as np
from mumaxplus import Ferromagnet, Grid, World
from mumax3 import Mumax3Simulation

RTOL = 1e-5
DiegoDeGusem marked this conversation as resolved.
Show resolved Hide resolved
def max_relative_error(result, wanted):
err = np.linalg.norm(result - wanted, axis=0)
relerr = err / np.linalg.norm(wanted, axis=0)
return np.max(relerr)

def simulations(openbc, interfacial):
"""This simulates a 1D wire with bulk or interfacial DMI in both
mumax³ and mumax⁺."""

# constants
A = 13e-12
D = 3e-3
Ku = 0.4e6
anisU = (1,0,0)
Ms = 0.86e6

cellsize = (1e-9, 1e-9, 1e-9)
gridsize = (1, 1, 100)
magnetization = (1,0,0)

# mumax⁺ simulation
world = World(cellsize=cellsize)
magnet = Ferromagnet(world, Grid(gridsize))
magnet.enable_demag = False
magnet.enable_openbc = openbc

magnet.msat = Ms
magnet.aex = A
magnet.ku1 = Ku
magnet.anisU = anisU

if interfacial:
DMI = "Dind"
magnet.dmi_tensor.set_interfacial_dmi(D)
else:
DMI = "Dbulk"
magnet.dmi_tensor.set_bulk_dmi(D)

magnet.magnetization = magnetization
magnet.minimize()

# mumax³ simulation
mumax3sim = Mumax3Simulation(
f"""
setcellsize{cellsize}
setgridsize{gridsize}
msat = {Ms}
aex = {A}
Ku1 = {Ku}
anisU = vector{anisU}
{DMI} = {D}
enabledemag = False
openBC = {openbc}

m = Uniform{tuple(magnetization)}
minimize()
saveas(m, "m.ovf")
"""
)

return magnet, mumax3sim


@pytest.mark.mumax3
class TestDMI1D:
"""Compare the results of the simulations by comparing the magnetizations.
"""

def test_closed_inter(self):
magnet, mumax3sim = simulations(False, True)
err = max_relative_error(magnet.magnetization.eval(), mumax3sim.get_field("m"))
assert err < RTOL

def test_closed_bulk(self):
magnet, mumax3sim = simulations(False, False)
err = max_relative_error(magnet.magnetization.eval(), mumax3sim.get_field("m"))
assert err < RTOL

def test_open_inter(self):
magnet, mumax3sim = simulations(True, True)
err = max_relative_error(magnet.magnetization.eval(), mumax3sim.get_field("m"))
assert err < RTOL

def test_open_bulk(self):
magnet, mumax3sim = simulations(True, False)
err = max_relative_error(magnet.magnetization.eval(), mumax3sim.get_field("m"))
assert err < RTOL
101 changes: 101 additions & 0 deletions test/mumax3/test_mumax3_DMI_standardproblem2D.py
DiegoDeGusem marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"""This test is based on the 2D case in
https://iopscience.iop.org/article/10.1088/1367-2630/aaea1c"""

import pytest
import numpy as np
from mumaxplus import Ferromagnet, Grid, World
from mumax3 import Mumax3Simulation
from mumaxplus.util.shape import Cylinder
from mumaxplus.util.config import neelskyrmion


ATOL = 1e-3
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mweh, not super amazing

def max_absolute_error(result, wanted):
err = np.linalg.norm(result - wanted, axis=0)
return np.max(err)

def simulations(openBC):
"""This simulates a 2D circle with interfacial DMI and a Neél skyrmion
in both mumax³ and mumax⁺."""

# constants
A = 13e-12
D = 3e-3
Ku = 0.4e6
anisU = (0,0,1)
Ms = 0.86e6

# charge and polarization of the skyrmion
charge, pol = -1, 1

# diameter and thickness of the skyrmion
diam = 100e-9
thickness = 2e-9
skyrmion_radius = 25e-9

nx, ny, nz = 50, 50, 1
dx, dy, dz = 2e-9, 2e-9, 2e-9

gridsize = (nx, ny, nz)
cellsize = (dx, dy, dz)

# mumax⁺ simulation
world = World(cellsize=cellsize)
geo = Cylinder(diam, thickness).translate((nx*dx-dx)/2, (ny*dy-dy)/2, 0)
magnet = Ferromagnet(world, Grid(gridsize), geometry=geo)

magnet.enable_demag = False
magnet.enable_openbc = openBC

magnet.msat = Ms
magnet.aex = A
magnet.ku1 = Ku
magnet.anisU = anisU

magnet.dmi_tensor.set_interfacial_dmi(D)
magnet.magnetization = neelskyrmion(magnet.center, skyrmion_radius, charge, pol)
magnet.minimize()

# mumax³ simulation
mumax3sim = Mumax3Simulation(
f"""
// Set mesh and disk geometry
SetGridSize{tuple(gridsize)}
SetCellSize{tuple(cellsize)}
SetGeom(Circle({diam}))

Msat = {Ms}
Aex = {A}
Ku1 = {Ku}
anisU = vector{tuple(anisU)}
Dind = {D}
// No Demag:
EnableDemag = false

openBC = {openBC}

// Initial state
m = Neelskyrmion({charge}, {pol})

minimize()
SaveAs(m, "m.ovf")
"""
)

return magnet, mumax3sim


@pytest.mark.mumax3
class TestDMI2D:
"""Compare the results of the simulations by comparing the magnetizations.
"""

def test_closed(self):
magnet, mumax3sim = simulations(False)
err = max_absolute_error(magnet.magnetization.eval(), mumax3sim.get_field("m"))
assert err < ATOL

def test_open(self):
magnet, mumax3sim = simulations(True)
err = max_absolute_error(magnet.magnetization.eval(), mumax3sim.get_field("m"))
assert err < ATOL
107 changes: 107 additions & 0 deletions test/mumax3/test_mumax3_DMI_standardproblem3D.py
DiegoDeGusem marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"""This test is based on the 3D case in
https://iopscience.iop.org/article/10.1088/1367-2630/aaea1c"""

import pytest
import numpy as np
from mumaxplus import Ferromagnet, Grid, World
from mumax3 import Mumax3Simulation
from mumaxplus.util.shape import Cylinder
from mumaxplus.util.config import blochskyrmion


ATOL = 2e-3
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:/
This seems fairly large for something that should be almost exactly the same, no?

def max_absolute_error(result, wanted):
err = np.linalg.norm(result - wanted, axis=0)
return np.max(err)

def simulations(openBC):
"""This simulates a 3D cylinder with bulk DMI and a bloch skyrmion
in both mumax³ and mumax⁺."""

# constants
A = 8.78e-12
D = 1.58e-3
Ms = 0.384e6
Bz = 0.4

# diameter and thickness of the skyrmion
diam, thickness = 183e-9, 21e-9
skyrmion_radius = 36e-9

# charge and polarization of the skyrmion
charge, pol = 1, -1

nx, ny, nz = 183, 183, 21
dx, dy, dz = 1e-9, 1e-9, 1e-9

gridsize = (nx, ny, nz)
cellsize = (dx, dy, dz)

# mumax⁺ simulation
world = World(cellsize=cellsize)
geo = Cylinder(diam, thickness).translate((nx*dx-dx)/2, (ny*dy-dy)/2, (nz*dz-dz)/2)
magnet = Ferromagnet(world, Grid(gridsize), geometry=geo)

magnet.enable_demag = False
magnet.enable_openbc = openBC
magnet.msat = Ms
magnet.aex = A
magnet.dmi_tensor.set_bulk_dmi(D)

magnet.bias_magnetic_field = (0,0,Bz)

magnet.magnetization = blochskyrmion(magnet.center, skyrmion_radius, charge, pol)

magnet.minimize()

# mumax³ simulation
mumax3sim = Mumax3Simulation(
f"""
lx := 183e-9
ly := 183e-9
lz := 21e-9

SetGridSize{tuple(gridsize)}
SetCellSize{tuple(cellsize)}

// Define the cylinder
SetGeom(Circle({diam}))

Msat = {Ms}
Aex = {A}
Dbulk = {D}

// External field in T
B_ext = vector(0, 0, {Bz})

// No Demag
EnableDemag = false

openBC = {openBC}

m = BlochSkyrmion({charge}, {pol})

// Relax with conjugate gradient:
minimize();
SaveAs(m, "m")
"""
)

return magnet, mumax3sim


@pytest.mark.mumax3
@pytest.mark.slow
DiegoDeGusem marked this conversation as resolved.
Show resolved Hide resolved
class TestDMI3D:
"""Compare the results of the simulations by comparing the magnetizations.
"""

def test_closed(self):
magnet, mumax3sim = simulations(False)
err = max_absolute_error(magnet.magnetization.eval(), mumax3sim.get_field("m"))
assert err < ATOL

def test_open(self):
magnet, mumax3sim = simulations(True)
err = max_absolute_error(magnet.magnetization.eval(), mumax3sim.get_field("m"))
assert err < ATOL
Loading