Skip to content

Commit b9ced35

Browse files
author
davidcorteso
committed
Simplified micro DMI calculation. Added D_2d DMI
Merged C functions to calculate DMIs into a general function that only requires the specification of the DM vectors. These vectors are obtained when discretising Lifshitz invariants into the finite differences approximation (important to not confuse these DM vectors with the atomistic DM tensor). Simplifying the DMI function allows to add new terms. In this commit we added DMI for D_2d materials specified in one of Bogdanov's original papers. The corresponding DMI has been recently found in Heusler alloys.
1 parent a7a6123 commit b9ced35

File tree

5 files changed

+292
-337
lines changed

5 files changed

+292
-337
lines changed

fidimag/micro/dmi.py

Lines changed: 67 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ class DMI(Energy):
3939
neighbouring sites in the xy plane and not between
4040
layers in the z direction.
4141
42+
D_2d :: The energy density of this DMI is
43+
44+
w = D * ( L_{xz}^{(y)} + L_{yz}^{(x)} )
45+
46+
where L are Lifshitz invariants. This DMI is for
47+
materials with symmetry class D_{2d}. Structures
48+
known as anti-skyrmions are stabilised with this
49+
DMI type
50+
4251
ARGUMENTS: ----------------------------------------------------------------
4352
4453
D :: DMI vector norm which can be specified as an int, float, (X * n)
@@ -55,12 +64,12 @@ class DMI(Energy):
5564
5665
(X * n) array: Manually specify the DMI vector norm for every NN
5766
at every mesh node. The bulk DMI considers the 6 NNs from every
58-
node an interfacial DMI is D so it only considers 4 NNs from the
59-
xy plane.
67+
node and interfacial and D_2d DMI are 2D so they only consider 4
68+
NNs from the xy plane.
6069
6170
OPTIONAL ARGUMENTS: -------------------------------------------------------
6271
63-
dmi_type :: 'bulk' or 'interfacial'
72+
dmi_type :: 'bulk' or 'interfacial' or 'D_2d'
6473
name :: Interaction name
6574
6675
"""
@@ -73,26 +82,31 @@ def __init__(self, D, name='DMI', dmi_type='bulk'):
7382
self.jac = True
7483
self.dmi_type = dmi_type
7584

85+
# Number of NNs for the calculation of the corresponding DMI
86+
# Interfacial or D_2d are 2D so we use 4 ngbs
7687
if self.dmi_type == 'bulk':
77-
self.NN = 6
88+
self.n_dmi_ngbs = 6
7889
elif self.dmi_type == 'interfacial':
79-
self.NN = 4
90+
self.n_dmi_ngbs = 4
91+
elif self.dmi_type == 'D_2d':
92+
self.n_dmi_ngbs = 4
8093

8194
def setup(self, mesh, spin, Ms):
8295
super(DMI, self).setup(mesh, spin, Ms)
8396

8497
# We will allow to completely specify the DMI vectors according to the
85-
# NNs of every lattice site, thus we need a matrix of NN * n entries
86-
self.Ds = np.zeros(self.NN * self.n, dtype=np.float)
98+
# NNs of every lattice site, thus we need a matrix of n_dmi_ngbs * n entries
99+
self.Ds = np.zeros(self.n_dmi_ngbs * self.n, dtype=np.float)
87100

88-
if isinstance(self.D, np.ndarray) and len(self.D) == self.NN * self.n:
101+
if isinstance(self.D, np.ndarray) and len(self.D) == self.n_dmi_ngbs * self.n:
89102
self.Ds = self.D.astype('float')
90-
# If we do not pass a (NN * n) array, we just create a scalar field as
91-
# usual and then repeat the entries NN times so every neighbour will
92-
# have the same DMI per lattice site (can vary spatially)
103+
# If we do not pass a (n_dmi_ngbs * n) array, we just create a scalar
104+
# field as usual and then repeat the entries NN times so every
105+
# neighbour will have the same DMI per lattice site (can vary
106+
# spatially)
93107
else:
94108
D_array = helper.init_scalar(self.D, self.mesh)
95-
self.Ds = np.repeat(D_array, self.NN)
109+
self.Ds = np.repeat(D_array, self.n_dmi_ngbs)
96110

97111
# This is from the original code:
98112
# self.Ds[:] = helper.init_scalar(self.D, self.mesh)
@@ -104,32 +118,49 @@ def compute_field(self, t=0, spin=None):
104118
m = self.spin
105119

106120
if self.dmi_type == 'bulk':
107-
micro_clib.compute_dmi_field_bulk(m,
108-
self.field,
109-
self.energy,
110-
self.Ms_inv,
111-
self.Ds,
112-
self.dx,
113-
self.dy,
114-
self.dz,
115-
self.n,
116-
self.neighbours
117-
)
121+
dmi_vector = np.array([-1., 0, 0,
122+
1., 0, 0,
123+
0, -1., 0,
124+
0, 1., 0,
125+
0, 0, -1.,
126+
0, 0, 1.
127+
])
118128

119129
elif self.dmi_type == 'interfacial':
120-
micro_clib.compute_dmi_field_interfacial(m,
121-
self.field,
122-
self.energy,
123-
self.Ms_inv,
124-
self.Ds,
125-
self.dx,
126-
self.dy,
127-
self.dz,
128-
self.n,
129-
self.neighbours
130-
)
130+
dmi_vector = np.array([0, -1., 0, # -x
131+
0, 1., 0, # +x
132+
1., 0, 0, # -y
133+
-1., 0, 0, # +y
134+
0, 0, 0, # -z
135+
0, 0, 0 # +z
136+
])
137+
138+
elif self.dmi_type == 'D_2d':
139+
dmi_vector = np.array([0, 1., 0, # -x
140+
0, -1., 0, # +x
141+
1., 0, 0, # -y
142+
-1., 0, 0, # +y
143+
0, 0, 0, # -z
144+
0, 0, 0 # +z
145+
])
131146
else:
132147
raise Exception(
133-
"Unsupported DMI type: {}, avaiable options: 'bulk', 'interfacial'.".format(self.dmi_type))
134-
148+
"Unsupported DMI type: {}, " +
149+
"available options: ".format(self.dmi_type) +
150+
"'bulk', 'interfacial', 'D_2d'."
151+
)
152+
153+
micro_clib.compute_dmi_field(m,
154+
self.field,
155+
self.energy,
156+
self.Ms_inv,
157+
self.Ds,
158+
dmi_vector,
159+
self.n_dmi_ngbs,
160+
self.dx,
161+
self.dy,
162+
self.dz,
163+
self.n,
164+
self.neighbours
165+
)
135166
return self.field

0 commit comments

Comments
 (0)