11from __future__ import print_function
22from fidimag .atomistic import Sim
33from fidimag .common import CuboidMesh
4+ from fidimag .atomistic .hexagonal_mesh import HexagonalMesh
45from fidimag .atomistic import DMI
56from fidimag .atomistic import UniformExchange
67from fidimag .atomistic import Zeeman
8+ from fidimag .atomistic import Anisotropy
79
810from fidimag .micro import DMI as microDMI
911from fidimag .micro import UniaxialAnisotropy as microUniaxialAnisotropy
1012from fidimag .micro import UniformExchange as microUniformExchange
1113from fidimag .micro import Zeeman as microZeeman
1214from fidimag .micro import Sim as microSim
1315
16+ import fidimag .common .constant as const
17+
18+ import numpy as np
19+
1420
1521def 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+
3050def 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
85183def test_skx_num_micromagnetic ():
86184 """
@@ -145,4 +243,5 @@ def test_skx_num_micromagnetic():
145243if __name__ == '__main__' :
146244
147245 test_skx_num_atomistic ()
246+ test_skx_num_atomistic_hexagonal ()
148247 test_skx_num_micromagnetic ()
0 commit comments