Skip to content

Commit 19833c9

Browse files
authored
Merge pull request #42 from computationalmodelling/ENH-017-skyrmion-number
ENH-017-skyrmion-number
2 parents cac61c1 + 9a5d699 commit 19833c9

File tree

5 files changed

+465
-2
lines changed

5 files changed

+465
-2
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ before_install:
1818
- export PATH=/home/travis/miniconda/bin:$PATH
1919

2020
install:
21-
- conda create -q -y -n fidimag-test python=$TRAVIS_PYTHON_VERSION cython matplotlib pytest scipy pytest-cov
21+
- conda create -q -y -n fidimag-test python=$TRAVIS_PYTHON_VERSION cython matplotlib pytest scipy pytest-cov gcc
2222
- source activate fidimag-test
2323
- pip install pyvtk six nbval
2424
# Download and compile FFTW & Sundials locally

fidimag/atomistic/llg.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from fidimag.common.fileio import DataSaver
99
from fidimag.common.save_vtk import SaveVTK
1010
import fidimag.common.constant as const
11+
import fidimag.common.skyrmion_number
1112

1213

1314
class LLG(object):
@@ -17,7 +18,7 @@ def __init__(self, mesh, name='unnamed', use_jac=False):
1718
*Arguments*
1819
name : the Simulation name (used for writing data files, for examples)
1920
"""
20-
21+
self._micromagnetic = False
2122
self.t = 0
2223
self.name = name
2324
self.mesh = mesh
@@ -335,6 +336,9 @@ def skyrmion_number(self, method='FiniteSpinChirality'):
335336

336337
return number
337338

339+
skyrmion_number_slice = fidimag.common.skyrmion_number.skyrmion_number_slice
340+
skyrmion_number_lee = fidimag.common.skyrmion_number.skyrmion_number_lee
341+
338342
def spin_at(self, i, j, k):
339343
"""
340344
Returns the spin components of the spin at

fidimag/common/skyrmion_number.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import fidimag.extensions.clib
2+
import fidimag.extensions.micro_clib
3+
import numpy as np
4+
5+
6+
def skyrmion_number_slice(sim, at=None, zIndex=None):
7+
"""
8+
Returns the skyrmion number calculated on the x-y plane at a specific z
9+
co-ordinate.
10+
11+
The current fidimag skyrmion number function finds the skyrmion number for
12+
the first z co-ordinate in index order (unintentionally?). So the approach
13+
this function uses is to slice the spin array in the simulation object to
14+
only include the x-y plane as previously described.
15+
16+
Arguments:
17+
sim: LLG object with cuboidal mesh.
18+
19+
Optional Arguments:
20+
If neither of these arguments are specified, this function raises a
21+
ValueError.
22+
23+
at: None, "top", "centre", or "bottom" denoting where to slice in
24+
British English. https://en.wikipedia.org/wiki/Strike_It_Lucky
25+
zIndex: Integer (not a float), or None denoting the index at which to
26+
slice. Overrides "at" if not None. Bound by zIndex~[0, sim.mesh.nz-1]
27+
28+
Returns:
29+
skyrmionNumber (a float)
30+
"""
31+
32+
# Deal with inputs.
33+
if zIndex is None:
34+
if at is "bottom":
35+
zIndex = 0
36+
37+
elif at is "centre":
38+
# Find the layer number that corresponds to the centre of the mesh,
39+
# preferring the lower layer in a tie.
40+
zIndex = sim.mesh.nz / 2.
41+
if sim.mesh.nz % 2 == 0:
42+
zIndex -= 0.5
43+
zIndex -= 0.5
44+
45+
elif at is "top":
46+
zIndex = sim.mesh.nz - 1 # Indeces start at 0.
47+
48+
else:
49+
raise ValueError("[skyrmion_number_slice]: Either "
50+
"'at=bottom|centre|top' or 'zIndex'=[integer] "
51+
"must be passed as arguments.")
52+
53+
elif zIndex > sim.mesh.nz - 1 or zIndex < 0:
54+
raise ValueError("[skyrmion_number_slice]: 'zIndex={}' must be an "
55+
"integer between 0 and sim.mesh.nz - 1, which is "
56+
"'{}' for this simulation object."
57+
.format(zIndex, sim.mesh.nz - 1))
58+
59+
# Find the "length" of a slice in terms of the spin array.
60+
xyLength = sim.mesh.nx * sim.mesh.ny * 3 # The 3 represents (x,y,z).
61+
62+
# Obtain slice of spins cleverly. This also works if the domain is flat
63+
# (i.e. nz=1, zIndex=0)
64+
spinSlice = sim.spin[int(xyLength * zIndex):int(xyLength * (zIndex + 1))]
65+
66+
# Compute the skyrmion number for our spin slice.
67+
if sim._micromagnetic is True:
68+
return fidimag.extensions.micro_clib.compute_skyrmion_number(\
69+
spinSlice, sim._skx_number, sim.mesh.nx, sim.mesh.ny,
70+
sim.mesh.nz, sim.mesh.neighbours)
71+
else:
72+
return fidimag.extensions.clib.compute_skyrmion_number(\
73+
spinSlice, sim._skx_number, sim.mesh.nx, sim.mesh.ny,
74+
sim.mesh.nz, sim.mesh.neighbours)
75+
76+
77+
def skyrmion_number_lee(sim):
78+
"""
79+
Returns the skyrmion number calculated from a 3D sample, as defined in:
80+
81+
Lee, M, Kang, W, Onose, Y, et. al (2009) "Unusual Hall effect anomaly in
82+
MnSi under pressure". PRL.
83+
84+
Arguments:
85+
sim: LLG object with cuboidal mesh.
86+
87+
Returns:
88+
skyrmionNumber (a float)
89+
"""
90+
91+
# Find the "length" of a slice in terms of the spin array.
92+
xyLength = sim.mesh.nx * sim.mesh.ny * 3 # The 3 represents (x, y, z).
93+
94+
# Create an array to store skyrmion number values for each z slice.
95+
skyrmionNumbers = np.ndarray(sim.mesh.nz)
96+
97+
# For each slice, compute the skyrmion number.
98+
for zI in range(len(skyrmionNumbers)):
99+
spinSlice = sim.spin[xyLength * zI:xyLength * (zI + 1)]
100+
101+
if sim._micromagnetic is True:
102+
skyrmionNumbers[zI] = fidimag.extensions.micro_clib.compute_skyrmion_number(\
103+
spinSlice, sim._skx_number, sim.mesh.nx,
104+
sim.mesh.ny, sim.mesh.nz,
105+
sim.mesh.neighbours)
106+
else:
107+
skyrmionNumbers[zI] = fidimag.extensions.clib.compute_skyrmion_number(\
108+
spinSlice, sim._skx_number, sim.mesh.nx,
109+
sim.mesh.ny, sim.mesh.nz,
110+
sim.mesh.neighbours)
111+
112+
# Return the average. This is equivalent to the integral in the equation.
113+
return skyrmionNumbers.mean()

0 commit comments

Comments
 (0)