@@ -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})
1211double 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