Skip to content

Commit f9b39ef

Browse files
author
davidcorteso
committed
Started C code for the calculation of skyrmion number using the formalism of Berg and Luscher based on spherical triangles formed by three neighbouring spins
1 parent 9a39415 commit f9b39ef

File tree

4 files changed

+93
-9
lines changed

4 files changed

+93
-9
lines changed

fidimag/atomistic/lib/clib.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ void normalise(double *m, int *pins, int n);
7878
double skyrmion_number(double *spin, double *charge,
7979
int nx, int ny, int nz, int *ngbs);
8080

81+
double skyrmion_number_BergLuscher(double *spin, double *charge,
82+
int nx, int ny, int nz, int *ngbs);
83+
8184
void compute_guiding_center(double *spin, int nx, int ny, int nz, double *res);
8285

8386
void compute_px_py_c(double *spin, int nx, int ny, int nz,

fidimag/atomistic/lib/clib.pyx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ cdef extern from "clib.h":
1212
double skyrmion_number(double *spin, double *charge,
1313
int nx, int ny, int nz, int *ngbs)
1414

15+
16+
double skyrmion_number_BergLuscher(double *spin, double *charge,
17+
int nx, int ny, int nz, int *ngbs)
18+
1519
void compute_guiding_center(double *spin, int nx, int ny, int nz,
1620
double *res)
1721

@@ -83,6 +87,15 @@ def compute_skyrmion_number(np.ndarray[double, ndim=1, mode="c"] spin,
8387

8488
return skyrmion_number(&spin[0], &charge[0], nx, ny, nz, &ngbs[0,0])
8589

90+
91+
def compute_skyrmion_number_BergLuscher(np.ndarray[double, ndim=1, mode="c"] spin,
92+
np.ndarray[double, ndim=1, mode="c"] charge,
93+
nx, ny, nz,
94+
np.ndarray[int, ndim=2, mode="c"] ngbs
95+
):
96+
97+
return skyrmion_number_BergLuscher(&spin[0], &charge[0], nx, ny, nz, &ngbs[0,0])
98+
8699
def compute_RxRy(np.ndarray[double, ndim=1, mode="c"] spin,
87100
nx, ny, nz):
88101

fidimag/atomistic/lib/util.c

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include "clib.h"
2+
#include "math.h"
3+
#include "complex.h"
24

35
//compute the S \cdot (S_i \times S_j)
46
inline double volume(double S[3], double Si[3], double Sj[3]) {
@@ -17,7 +19,7 @@ double skyrmion_number(double *spin, double *charge,
1719
*
1820
* The *spin array is the vector field for a two dimensional
1921
* lattice with dimensions nx * ny
20-
* (we can take a slice of a bulk from Python and pass it here,
22+
* (we can take a slice of a bulk from Python and pass it here,
2123
* remember to do the ame for the neighbours matrix)
2224
* The array follows the order:
2325
* [Sx0 Sy0 Sz0 Sx1 Sy1 Sz1 ... ]
@@ -50,17 +52,17 @@ double skyrmion_number(double *spin, double *charge,
5052
*
5153
* Then, we use the follwing expression:
5254
*
53-
* Q = S_i \dot ( S_{i+1} \times S_{j+1} )
55+
* Q = S_i \dot ( S_{i+1} \times S_{j+1} )
5456
* + S_i \dot ( S_{i-1} \times S_{j-1} )
5557
*
5658
* This expression is based on the publication PRL 108, 017601 (2012)
5759
* where Q is called "finite spin chirality". The idea comes from
5860
* discrete chiral quantities in Hall effect studies. For example, at
5961
* the end of page 3 in Rep. Prog. Phys. 78 (2015) 052502, it
6062
* is argued:
61-
* scalar chirality (...) , which measures the volume enclosed
63+
* scalar chirality (...) , which measures the volume enclosed
6264
* by the three spins of the elementary triangle and, similarly to
63-
* (the vector chirlity) is sensitive to the sense of spin's
65+
* (the vector chirlity) is sensitive to the sense of spin's
6466
* rotation in the x–y plane
6567
*
6668
* Hence we are taking the triangles formed by (i, i+1, j+1)
@@ -72,12 +74,12 @@ double skyrmion_number(double *spin, double *charge,
7274
*
7375
* Recently, other ways to calculate a discrete skyrmion number have
7476
* been proposed: http://arxiv.org/pdf/1601.08212.pdf
75-
* Phys. Rev. B 93, 024417
76-
*
77+
* Phys. Rev. B 93, 024417
78+
*
7779
* also based on using three spins using triangles. This could be
78-
* useful for applying to a hexagonal lattice in the future.
80+
* useful for applying to a hexagonal lattice in the future.
7981
*
80-
*/
82+
*/
8183

8284
int i, j;
8385
int index, id;
@@ -91,7 +93,7 @@ double skyrmion_number(double *spin, double *charge,
9193
for (i = 0; i < nxy; i++) {
9294
index = 3 * i;
9395

94-
/* The starting index of the nearest neighbours for the
96+
/* The starting index of the nearest neighbours for the
9597
* i-th spin */
9698
int id_nn = 6 * i;
9799

@@ -156,6 +158,64 @@ double skyrmion_number(double *spin, double *charge,
156158

157159
}
158160

161+
double dot(double *a, double *b){
162+
double dp = 0;
163+
int i;
164+
165+
for(i = 0; i< 3; i++) dp += a[i] * b[i];
166+
return dp;
167+
}
168+
169+
double compute_BergLuscher_angle(double *s1, double *s2, double *s3){
170+
double rho;
171+
double complex exp;
172+
double crossp[3];
173+
174+
crossp[0] = s2[1] * s3[2] - s2[2] * s3[1];
175+
crossp[1] = s2[2] * s3[0] - s2[0] * s3[2];
176+
crossp[2] = s2[0] * s3[1] - s2[1] * s3[0];
177+
178+
rho = sqrt(2 * (1 + dot(&s1[0], &s2[0]))
179+
* (1 + dot(&s2[0], &s3[0]))
180+
* (1 + dot(&s3[0], &s1[0]))
181+
);
182+
183+
exp = (1 + dot(&s1[0], &s2[0])
184+
+ dot(&s2[0], &s3[0])
185+
+ dot(&s3[0], &s1[0])
186+
+ I * dot(&s1[0], &crossp[0])
187+
) / rho;
188+
189+
return 2 * cimagl(clog(exp)) / (4 * WIDE_PI);
190+
191+
}
192+
193+
double skyrmion_number_BergLuscher(double *spin, double *charge,
194+
int nx, int ny, int nz, int *ngbs) {
195+
196+
int n = nx * ny * nz;
197+
int i, spin_index, nn_index;
198+
double total_sum = 0;
199+
200+
for(i = 0; i < n; i++){
201+
202+
spin_index = 3 * i;
203+
nn_index = 6 * ngbs[i];
204+
205+
charge[i] = compute_BergLuscher_angle(&spin[spin_index],
206+
&spin[nn_index + 0],
207+
&spin[nn_index + 2]
208+
);
209+
charge[i] += compute_BergLuscher_angle(&spin[spin_index],
210+
&spin[nn_index + 1],
211+
&spin[nn_index + 3]
212+
);
213+
total_sum += charge[i];
214+
}
215+
216+
return total_sum;
217+
}
218+
159219
//compute the first derivative respect to x and for the whole mesh
160220
//assume 2d pbc is used
161221
void compute_px_py_c(double *spin, int nx, int ny, int nz, double *px, double *py){

fidimag/atomistic/llg.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,14 @@ def skyrmion_number(self):
297297
self.spin, self._skx_number, nx, ny, nz, self.mesh.neighbours)
298298
return number
299299

300+
def skyrmion_number_BergLuscher(self):
301+
nx = self.mesh.nx
302+
ny = self.mesh.ny
303+
nz = self.mesh.nz
304+
number = clib.compute_skyrmion_number_BergLuscher(
305+
self.spin, self._skx_number, nx, ny, nz, self.mesh.neighbours)
306+
return number
307+
300308
def spin_at(self, i, j, k):
301309
"""
302310
Returns the spin components of the spin at

0 commit comments

Comments
 (0)