Skip to content

Commit fcd9b8b

Browse files
committed
2 parents fc86e45 + 9271749 commit fcd9b8b

File tree

1 file changed

+86
-10
lines changed

1 file changed

+86
-10
lines changed

fidimag/atomistic/lib/util.c

Lines changed: 86 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,77 @@ inline double volume(double S[3], double Si[3], double Sj[3]) {
88
return tx + ty + tz;
99
}
1010

11-
// C = S_i \dot (S_{i+1} \times S_{j+1}) + S_i \dot (S_{i-1} \times S_{j-1})
1211
double skyrmion_number(double *spin, double *charge,
1312
int nx, int ny, int nz, int *ngbs) {
1413

14+
/* Calculation of the "Skyrmion number" Q for a two dimensional discrete
15+
* spin lattice in the x-y plane (also known
16+
* as finite spin chirality)
17+
*
18+
* The *spin array is the vector field for a two dimensional
19+
* lattice with dimensions nx * ny
20+
* (we can take a slice of a bulk from Python and pass it here,
21+
* remember to do the ame for the neighbours matrix)
22+
* The array follows the order:
23+
* [Sx0 Sy0 Sz0 Sx1 Sy1 Sz1 ... ]
24+
*
25+
* Charge is a scalar field array used to store the spin chirality /
26+
* skyrmion number density (Q value per lattice site)
27+
*
28+
* *ngbs is the array with the neighbours information for every
29+
* lattice site. The array is like:
30+
* [ 0-x, 0+x, 0-y, 0+y, 0-z, 0+z, 1-x, 1+x, 1-y, ... ]
31+
* i=0 i=1 ...
32+
*
33+
* where 0-y is the index of the neighbour of the 0th spin,
34+
* in the -y direction, for example
35+
*
36+
*
37+
* THEORY:
38+
*
39+
* Referring to the i-th site of a
40+
* square lattice, we refer to the x direction for the i-th neighbours
41+
* and to the y direction for the j-th neighbours, as here:
42+
*
43+
* X (j + 1)
44+
* |
45+
* (i) |
46+
* (i - 1) X------O------X (i + 1)
47+
* |
48+
* |
49+
* X (j - 1)
50+
*
51+
* Then, we use the follwing expression:
52+
*
53+
* Q = S_i \dot ( S_{i+1} \times S_{j+1} )
54+
* + S_i \dot ( S_{i-1} \times S_{j-1} )
55+
*
56+
* This expression is based on the publication PRL 108, 017601 (2012)
57+
* where Q is called "finite spin chirality". The idea comes from
58+
* discrete chiral quantities in Hall effect studies. For example, at
59+
* the end of page 3 in Rep. Prog. Phys. 78 (2015) 052502, it
60+
* is argued:
61+
* scalar chirality (...) , which measures the volume enclosed
62+
* by the three spins of the elementary triangle and, similarly to
63+
* (the vector chirlity) is sensitive to the sense of spin's
64+
* rotation in the x–y plane
65+
*
66+
* Hence we are taking the triangles formed by (i, i+1, j+1)
67+
* and (i, i-1, j-1) whose total area covers a unit cell,
68+
* and ommit the other two triangles (bottom right and top left)
69+
* When we sum this quantity across the whole lattice we cover every
70+
* triangle. The final quantity will be scaled by 8 PI
71+
* to match +-1 for a full skyrmion configuration
72+
*
73+
* Recently, other ways to calculate a discrete skyrmion number have
74+
* been proposed: http://arxiv.org/pdf/1601.08212.pdf
75+
* Phys. Rev. B 93, 024417
76+
*
77+
* also based on using three spins using triangles. This could be
78+
* useful for applying to a hexagonal lattice in the future.
79+
*
80+
*/
81+
1582
int i, j;
1683
int index, id;
1784

@@ -24,7 +91,9 @@ double skyrmion_number(double *spin, double *charge,
2491
for (i = 0; i < nxy; i++) {
2592
index = 3 * i;
2693

27-
int idv = 6 * i;
94+
/* The starting index of the nearest neighbours for the
95+
* i-th spin */
96+
int id_nn = 6 * i;
2897

2998
S[0] = spin[index];
3099
S[1] = spin[index + 1];
@@ -34,45 +103,52 @@ double skyrmion_number(double *spin, double *charge,
34103
S_j[0] = S_j[1] = S_j[2] = 0;
35104

36105
// neighbour at -x
37-
if (ngbs[idv] > 0) {
38-
id = 3 * ngbs[idv];
106+
// Remember that the index is -1 for sites without material
107+
if (ngbs[id_nn] > 0) {
108+
id = 3 * ngbs[id_nn];
39109
S_i[0] = spin[id];
40110
S_i[1] = spin[id + 1];
41111
S_i[2] = spin[id + 2];
42112
}
43113

44114
// neighbour at -y
45-
if (ngbs[idv + 2] > 0) {
46-
id = 3 * ngbs[idv + 2];
115+
if (ngbs[id_nn + 2] > 0) {
116+
id = 3 * ngbs[id_nn + 2];
47117
S_j[0] = spin[id];
48118
S_j[1] = spin[id + 1];
49119
S_j[2] = spin[id + 2];
50120
}
51121

122+
// The S_i \dot ( S_{i+1} \times S_{j+1} )
52123
charge[i] = volume(S, S_i, S_j);
53124

54125
S_i[0] = S_i[1] = S_i[2] = 0;
55126
S_j[0] = S_j[1] = S_j[2] = 0;
56127

57128
// neighbour at +x
58-
if (ngbs[idv + 1] > 0) {
59-
id = 3 * ngbs[idv + 1];
129+
if (ngbs[id_nn + 1] > 0) {
130+
id = 3 * ngbs[id_nn + 1];
60131
S_i[0] = spin[id];
61132
S_i[1] = spin[id + 1];
62133
S_i[2] = spin[id + 2];
63134
}
64135

65136
// neighbour at +y
66-
if (ngbs[idv + 3] > 0) {
67-
id = 3 * ngbs[idv + 3];
137+
if (ngbs[id_nn + 3] > 0) {
138+
id = 3 * ngbs[id_nn + 3];
68139
S_j[0] = spin[id];
69140
S_j[1] = spin[id + 1];
70141
S_j[2] = spin[id + 2];
71142
}
72143

144+
// The S_i \dot ( S_{i-1} \times S_{j-1} )
73145
charge[i] += volume(S, S_i, S_j);
146+
147+
/* Scale the chirality quantity */
74148
charge[i] /= (8 * WIDE_PI);
75149

150+
/* We use the sum to output the total spin chirality
151+
* or skyrmion number */
76152
sum += charge[i];
77153
}
78154

0 commit comments

Comments
 (0)