Skip to content

Commit 6f94498

Browse files
author
davidcorteso
committed
Added tests for the skyrmion number calculations in atomistic simulations using different methods and either Square and Hexagonal meshes. Removed the Skyrmion Number calculation for the Table in the LLg code, since it is meaningless for a hexagonal grid at least we specify the new sk number method
1 parent f7af46d commit 6f94498

File tree

2 files changed

+103
-4
lines changed

2 files changed

+103
-4
lines changed

fidimag/atomistic/llg.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ def __init__(self, mesh, name='unnamed', use_jac=False):
5252
'get': lambda sim: sim.compute_spin_error(),
5353
'header': 'm_error'}
5454

55-
self.saver.entities['skx_num'] = {
56-
'unit': '<>',
57-
'get': lambda sim: sim.skyrmion_number(),
58-
'header': 'skx_num'}
55+
# self.saver.entities['skx_num'] = {
56+
# 'unit': '<>',
57+
# 'get': lambda sim: sim.skyrmion_number(),
58+
# 'header': 'skx_num'}
5959

6060
self.saver.update_entity_order()
6161

tests/test_skyrmion_number.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
from __future__ import print_function
22
from fidimag.atomistic import Sim
33
from fidimag.common import CuboidMesh
4+
from fidimag.atomistic.hexagonal_mesh import HexagonalMesh
45
from fidimag.atomistic import DMI
56
from fidimag.atomistic import UniformExchange
67
from fidimag.atomistic import Zeeman
8+
from fidimag.atomistic import Anisotropy
79

810
from fidimag.micro import DMI as microDMI
911
from fidimag.micro import UniaxialAnisotropy as microUniaxialAnisotropy
1012
from fidimag.micro import UniformExchange as microUniformExchange
1113
from fidimag.micro import Zeeman as microZeeman
1214
from fidimag.micro import Sim as microSim
1315

16+
import fidimag.common.constant as const
17+
18+
import numpy as np
19+
1420

1521
def init_m(pos, x0, y0, r):
1622
x = pos[0]
@@ -27,6 +33,20 @@ def init_m(pos, x0, y0, r):
2733
return m2
2834

2935

36+
def init_m_multiple_sks(pos, r, sk_pos):
37+
# Generate singularities with radius r at the positions in the
38+
# sk_pos list, in order to generate multiple skyrmions after
39+
# relaxation. Example: sk_pos=[(1, 1), (2, 2)]
40+
# x y
41+
x, y = pos[0], pos[1]
42+
43+
for coord in sk_pos:
44+
if (x - coord[0]) ** 2 + (y - coord[1]) ** 2 < r ** 2:
45+
return (0, 0, 1)
46+
47+
return (0, 0, -1)
48+
49+
3050
def test_skx_num_atomistic():
3151
"""
3252
Test the *finite spin chirality* or skyrmion number for
@@ -45,6 +65,10 @@ def test_skx_num_atomistic():
4565
The area of the two triangles cover a unit cell, thus the sum
4666
cover the whole area of the atomic lattice
4767
68+
We also test the Berg and Luscher definition for a topological
69+
charge (see the hexagonal mesh test for details) in a
70+
square lattice.
71+
4872
This test generate a skyrmion pointing down with unrealistic
4973
paremeters.
5074
@@ -79,8 +103,82 @@ def test_skx_num_atomistic():
79103

80104
skn = sim.skyrmion_number()
81105
print('skx_number', skn)
106+
107+
skn_BL = sim.skyrmion_number(method='BergLuscher')
108+
print('skx_number_BergLuscher', skn_BL)
109+
110+
# Test the finite chirality method
82111
assert skn > -1 and skn < -0.99
83112

113+
# Test the Berg-Luscher method
114+
assert np.abs(skn_BL - (-1)) < 1e-4 and np.sign(skn_BL) < 0
115+
116+
117+
def test_skx_num_atomistic_hexagonal():
118+
"""
119+
120+
Test the topological charge or skyrmion number for a discrete spins
121+
simulation in a two dimensional hexagonal lattice, using Berg and Luscher
122+
definition in [Nucl Phys B 190, 412 (1981)] and simplified in [PRB 93,
123+
174403 (2016)], which maps a triangulated lattice (using triangles of
124+
neighbouring spins) area into a unit sphere.
125+
126+
The areas of two triangles per lattice site cover a unit cell, thus the sum
127+
cover the whole area of the atomic lattice
128+
129+
This test generates a skyrmion pointing down and two skyrmions pointing up
130+
in a PdFe sample using magnetic parameters from: PRL 114, 177203 (2015)
131+
132+
"""
133+
134+
mesh = HexagonalMesh(0.2715, 41, 41, periodicity=(True, True))
135+
136+
sim = Sim(mesh, name='skx_number_hexagonal')
137+
sim.set_tols(rtol=1e-6, atol=1e-6)
138+
sim.alpha = 1.0
139+
sim.gamma = 1.0
140+
sim.mu_s = 3 * const.mu_B
141+
142+
sim.set_m(lambda pos: init_m(pos, 16.1, 10, 2))
143+
144+
sim.do_precession = False
145+
146+
J = 5.881 * const.meV
147+
exch = UniformExchange(J)
148+
sim.add(exch)
149+
150+
D = 1.557 * const.meV
151+
dmi = DMI(D, dmi_type='interfacial')
152+
sim.add(dmi)
153+
154+
sim.add(Anisotropy(0.406 * const.meV, axis=[0, 0, 1]))
155+
156+
zeeman = Zeeman([0, 0, 2.5])
157+
sim.add(zeeman)
158+
159+
sim.relax(dt=1e-13, stopping_dmdt=1e-2, max_steps=2000,
160+
save_m_steps=None, save_vtk_steps=100)
161+
162+
skn_single = sim.skyrmion_number(method='BergLuscher')
163+
print('skx_number_hexagonal', skn_single)
164+
165+
# Now we generate two skyrmions pointing up
166+
sim.reset_integrator()
167+
sim.set_m(lambda pos: init_m_multiple_sks(pos, 1,
168+
sk_pos=[(9, 6), (18, 12)]
169+
)
170+
)
171+
sim.get_interaction('Zeeman').update_field([0, 0, -2.5])
172+
sim.relax(dt=1e-13, stopping_dmdt=1e-2, max_steps=2000,
173+
save_m_steps=None, save_vtk_steps=None)
174+
175+
skn_two = sim.skyrmion_number(method='BergLuscher')
176+
print('skx_number_hexagonal', skn_two)
177+
178+
# Check that we get a right sk number
179+
assert np.abs(skn_single - (-1)) < 1e-4 and np.sign(skn_single) < 0
180+
assert np.abs(skn_two - (2)) < 1e-4 and np.sign(skn_two) > 0
181+
84182

85183
def test_skx_num_micromagnetic():
86184
"""
@@ -145,4 +243,5 @@ def test_skx_num_micromagnetic():
145243
if __name__ == '__main__':
146244

147245
test_skx_num_atomistic()
246+
test_skx_num_atomistic_hexagonal()
148247
test_skx_num_micromagnetic()

0 commit comments

Comments
 (0)