TB2J 0.8.2.7__py3-none-any.whl → 0.9.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- TB2J/__init__.py +1 -1
- TB2J/abacus/abacus_wrapper.py +1 -2
- TB2J/exchange.py +2 -2
- TB2J/green.py +16 -6
- TB2J/io_merge.py +125 -376
- TB2J/myTB.py +0 -2
- TB2J/rotate_atoms.py +22 -20
- TB2J/rotate_siestaDM.py +36 -0
- TB2J/sisl_wrapper.py +0 -1
- TB2J/spinham/h_matrix.py +68 -0
- TB2J/spinham/obtain_J.py +79 -0
- {TB2J-0.8.2.7.data → TB2J-0.9.0.data}/scripts/TB2J_merge.py +9 -2
- {TB2J-0.8.2.7.data → TB2J-0.9.0.data}/scripts/TB2J_rotate.py +6 -1
- TB2J-0.9.0.data/scripts/TB2J_rotateDM.py +21 -0
- {TB2J-0.8.2.7.dist-info → TB2J-0.9.0.dist-info}/METADATA +1 -1
- {TB2J-0.8.2.7.dist-info → TB2J-0.9.0.dist-info}/RECORD +26 -22
- {TB2J-0.8.2.7.data → TB2J-0.9.0.data}/scripts/TB2J_downfold.py +0 -0
- {TB2J-0.8.2.7.data → TB2J-0.9.0.data}/scripts/TB2J_eigen.py +0 -0
- {TB2J-0.8.2.7.data → TB2J-0.9.0.data}/scripts/TB2J_magnon.py +0 -0
- {TB2J-0.8.2.7.data → TB2J-0.9.0.data}/scripts/TB2J_magnon_dos.py +0 -0
- {TB2J-0.8.2.7.data → TB2J-0.9.0.data}/scripts/abacus2J.py +0 -0
- {TB2J-0.8.2.7.data → TB2J-0.9.0.data}/scripts/siesta2J.py +0 -0
- {TB2J-0.8.2.7.data → TB2J-0.9.0.data}/scripts/wann2J.py +0 -0
- {TB2J-0.8.2.7.dist-info → TB2J-0.9.0.dist-info}/LICENSE +0 -0
- {TB2J-0.8.2.7.dist-info → TB2J-0.9.0.dist-info}/WHEEL +0 -0
- {TB2J-0.8.2.7.dist-info → TB2J-0.9.0.dist-info}/top_level.txt +0 -0
TB2J/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.
|
1
|
+
__version__ = "0.9.0"
|
TB2J/abacus/abacus_wrapper.py
CHANGED
@@ -18,8 +18,7 @@ class AbacusWrapper(AbstractTB):
|
|
18
18
|
def __init__(self, HR, SR, Rlist, nbasis, nspin=1):
|
19
19
|
self.R2kfactor = -2j * np.pi
|
20
20
|
self.is_orthogonal = False
|
21
|
-
self.
|
22
|
-
self._name = "Abacus"
|
21
|
+
self._name = "ABACUS"
|
23
22
|
self.HR = HR
|
24
23
|
self.SR = SR
|
25
24
|
self.Rlist = Rlist
|
TB2J/exchange.py
CHANGED
@@ -240,7 +240,7 @@ or badly localized. Please check the Wannier centers in the Wannier90 output fil
|
|
240
240
|
self.mmats = {}
|
241
241
|
self.orbital_names = {}
|
242
242
|
self.norb_reduced = {}
|
243
|
-
if self.backend_name == "SIESTA":
|
243
|
+
if self.backend_name.upper() == "SIESTA":
|
244
244
|
syms = self.atoms.get_chemical_symbols()
|
245
245
|
for iatom, orbs in self.labels.items():
|
246
246
|
if (self.include_orbs is not None) and syms[iatom] in self.include_orbs:
|
@@ -305,7 +305,7 @@ or badly localized. Please check the Wannier centers in the Wannier90 output fil
|
|
305
305
|
"""
|
306
306
|
sum up the contribution of all the orbitals with same (n,l,m)
|
307
307
|
"""
|
308
|
-
if self.backend_name == "SIESTA":
|
308
|
+
if self.backend_name.upper() == "SIESTA":
|
309
309
|
mmat_i = self.mmats[iatom]
|
310
310
|
mmat_j = self.mmats[jatom]
|
311
311
|
Jorbij = mmat_i.T @ Jorbij @ mmat_j
|
TB2J/green.py
CHANGED
@@ -225,12 +225,22 @@ class TBGreen:
|
|
225
225
|
|
226
226
|
def get_density_matrix(self):
|
227
227
|
rho = np.zeros((self.nbasis, self.nbasis), dtype=complex)
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
228
|
+
if self.is_orthogonal:
|
229
|
+
for ik, _ in enumerate(self.kpts):
|
230
|
+
rho += (
|
231
|
+
(self.get_evecs(ik) * fermi(self.evals[ik], self.efermi))
|
232
|
+
@ self.get_evecs(ik).T.conj()
|
233
|
+
* self.kweights[ik]
|
234
|
+
)
|
235
|
+
else:
|
236
|
+
for ik, _ in enumerate(self.kpts):
|
237
|
+
rho += (
|
238
|
+
(self.get_evecs(ik) * fermi(self.evals[ik], self.efermi))
|
239
|
+
@ self.get_evecs(ik).T.conj()
|
240
|
+
@ self.get_Sk(ik)
|
241
|
+
* self.kweights[ik]
|
242
|
+
)
|
243
|
+
|
234
244
|
return rho
|
235
245
|
|
236
246
|
def get_rho_R(self, Rlist):
|
TB2J/io_merge.py
CHANGED
@@ -1,435 +1,184 @@
|
|
1
1
|
import os
|
2
2
|
import copy
|
3
|
+
import warnings
|
3
4
|
import numpy as np
|
4
|
-
from
|
5
|
+
from itertools import combinations_with_replacement, product
|
5
6
|
from TB2J.io_exchange import SpinIO
|
6
|
-
from TB2J.tensor_rotate import remove_components
|
7
|
-
from TB2J.Jtensor import DMI_to_Jtensor, Jtensor_to_DMI
|
8
|
-
from TB2J.tensor_rotate import Rzx, Rzy, Rzz, Ryz, Rxz
|
9
7
|
|
8
|
+
u0 = np.zeros(3)
|
9
|
+
uy = np.array([0.0, 1.0, 0.0])
|
10
|
+
uz = np.array([0.0, 0.0, 1.0])
|
10
11
|
|
11
|
-
def
|
12
|
-
x = [1, 0, 0]
|
13
|
-
y = [0, 1, 0]
|
14
|
-
z = [0, 0, 1]
|
15
|
-
print(Rxz.apply(x))
|
16
|
-
print(Ryz.apply(y))
|
17
|
-
print(Rzx.apply(z))
|
18
|
-
print(Rzy.apply(z))
|
19
|
-
|
20
|
-
|
21
|
-
def recover_DMI_from_rotated_structure(Ddict, rotation):
|
22
|
-
"""
|
23
|
-
Recover the DMI vector from the rotated structure.
|
24
|
-
D: the dictionary of DMI vector in the rotated structure.
|
25
|
-
rotation: the rotation operator from the original structure to the rotated structure.
|
26
|
-
"""
|
27
|
-
for key, val in Ddict.items():
|
28
|
-
Ddict[key] = rotation.apply(val, inverse=True)
|
29
|
-
return Ddict
|
30
|
-
|
31
|
-
|
32
|
-
def recover_Jani_fom_rotated_structure(Janidict, rotation):
|
33
|
-
"""
|
34
|
-
Recover the Jani tensor from the rotated structure.
|
35
|
-
Janidict: the dictionary of Jani tensor in the rotated structure.
|
36
|
-
rotation: the from the original structure to the rotated structure.
|
37
|
-
"""
|
38
|
-
R = rotation.as_matrix()
|
39
|
-
RT = R.T
|
40
|
-
for key, Jani in Janidict.items():
|
41
|
-
# Note: E=Si J Sj , Si'= Si RT, Sj' = R Sj,
|
42
|
-
# Si' J' Sj' = Si RT R J RT R Sj => J' = R J RT
|
43
|
-
# But here we are doing the opposite rotation back to
|
44
|
-
# the original axis, so we replace R with RT.
|
45
|
-
Janidict[key] = RT @ Jani @ R
|
46
|
-
return Janidict
|
47
|
-
|
48
|
-
|
49
|
-
def recover_spinat_from_rotated_structure(spinat, rotation):
|
50
|
-
"""
|
51
|
-
Recover the spinat from the rotated structure.
|
52
|
-
spinat: the spinat in the rotated structure.
|
53
|
-
rotation: the rotation operator from the original structure to the rotated structure.
|
54
|
-
"""
|
55
|
-
for i, spin in enumerate(spinat):
|
56
|
-
spinat[i] = rotation.apply(spin, inverse=True)
|
57
|
-
return spinat
|
58
|
-
|
59
|
-
|
60
|
-
# test_rotation_matrix()
|
61
|
-
|
62
|
-
# R_xyz = [Rxz.as_matrix(), Ryz.as_matrix(), np.eye(3, dtype=float)]
|
63
|
-
|
64
|
-
|
65
|
-
def rot_merge_DMI(Dx, Dy, Dz):
|
66
|
-
Dx_z = Rzx.apply(Dx)
|
67
|
-
Dy_z = Rzy.apply(Dy)
|
68
|
-
D = (
|
69
|
-
np.array([0.0, 0.5, 0.5]) * Dx_z
|
70
|
-
+ np.array([0.5, 0.0, 0.5]) * Dy_z
|
71
|
-
+ np.array([0.5, 0.5, 0.0]) * Dz
|
72
|
-
)
|
73
|
-
return D
|
74
|
-
|
75
|
-
|
76
|
-
def rot_merge_DMI2(Dx, Dy, Dz):
|
77
|
-
Dx_z = Rzx.apply(Dx)
|
78
|
-
Dy_z = Rzy.apply(Dy)
|
79
|
-
D = (
|
80
|
-
np.array([1, 0, 0]) * Dx_z
|
81
|
-
+ np.array([0, 1, 0]) * Dy_z
|
82
|
-
+ np.array([0, 0, 1]) * Dz
|
83
|
-
)
|
84
|
-
return D
|
12
|
+
def get_Jani_coefficients(a, R=np.eye(3)):
|
85
13
|
|
14
|
+
if len(a) == 1:
|
15
|
+
u = a
|
16
|
+
v = a
|
17
|
+
else:
|
18
|
+
u = a[[0, 0, 1]]
|
19
|
+
v = a[[0, 1, 1]]
|
20
|
+
|
21
|
+
ur = u @ R.T
|
22
|
+
vr = v @ R.T
|
23
|
+
coefficients = np.hstack([ur*vr, np.roll(ur, -1, axis=-1)*vr + np.roll(vr, -1, axis=-1)*ur])
|
86
24
|
|
87
|
-
|
88
|
-
D = (
|
89
|
-
np.array([0.0, 0.5, 0.5]) * Dx
|
90
|
-
+ np.array([0.5, 0.0, 0.5]) * Dy
|
91
|
-
+ np.array([0.5, 0.5, 0.0]) * Dz
|
92
|
-
)
|
93
|
-
return D
|
25
|
+
return coefficients, u, v
|
94
26
|
|
27
|
+
def get_projections(a, b, tol=1e-2):
|
95
28
|
|
96
|
-
|
97
|
-
|
98
|
-
|
29
|
+
projections = np.empty((2, 3))
|
30
|
+
if np.linalg.matrix_rank([a, b], tol=tol) == 1:
|
31
|
+
if np.linalg.matrix_rank([a, uy], tol=tol) == 1:
|
32
|
+
projections[0] = np.cross(a, uz)
|
33
|
+
else:
|
34
|
+
projections[0] = np.cross(a, uy)
|
35
|
+
projections[1] = np.cross(a, projections[0])
|
36
|
+
projections /= np.linalg.norm(projections, axis=-1).reshape(-1, 1)
|
37
|
+
else:
|
38
|
+
projections[0] = np.cross(a, b)
|
39
|
+
projections[0] /= np.linalg.norm(projections[0])
|
40
|
+
projections[1] = u0
|
99
41
|
|
42
|
+
return projections
|
100
43
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
"""
|
106
|
-
idirections = list(idirections)
|
107
|
-
inv = [idirections[1], idirections[0]]
|
108
|
-
n = np.copy(m)
|
109
|
-
n[:, idirections] = n[:, inv]
|
110
|
-
n[idirections, :] = n[inv, :]
|
111
|
-
return n
|
44
|
+
class SpinIO_merge(SpinIO):
|
45
|
+
def __init__(self, *args, **kwargs):
|
46
|
+
super(SpinIO_merge, self).__init__(*args, **kwargs)
|
47
|
+
self.projv = None
|
112
48
|
|
49
|
+
def _set_projection_vectors(self):
|
113
50
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
51
|
+
spinat = self.spinat
|
52
|
+
idx = [self.ind_atoms[i] for i in self.index_spin if i >= 0]
|
53
|
+
projv = {}
|
54
|
+
for i, j in combinations_with_replacement(range(self.nspin), 2):
|
55
|
+
a, b = spinat[idx][[i, j]]
|
56
|
+
projv[i, j] = get_projections(a, b)
|
57
|
+
projv[j, i] = projv[i, j]
|
118
58
|
|
59
|
+
self.projv = projv
|
119
60
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
# + np.array([[1, 0, 1], [0, 0, 0], [1, 0, 1]]) * Janiy
|
125
|
-
# + np.array([[1, 1, 0], [1, 1, 0], [0, 0, 0]]) * Janiz
|
126
|
-
# ) / 2.0
|
127
|
-
wx = np.array([[0, 0, 0], [0, 1, 1], [0, 1, 1]])
|
128
|
-
wy = np.array([[1, 0, 1], [0, 0, 0], [1, 0, 1]])
|
129
|
-
wz = np.array([[1, 1, 0], [1, 1, 0], [0, 0, 0]])
|
130
|
-
Jani = (wx * Janix + wy * Janiy + wz * Janiz) / (wx + wy + wz)
|
131
|
-
return Jani
|
61
|
+
@classmethod
|
62
|
+
def load_pickle(cls, path='TB2J_results', fname='TB2J.pickle'):
|
63
|
+
obj = super(SpinIO_merge, cls).load_pickle(path=path, fname=fname)
|
64
|
+
obj._set_projection_vectors()
|
132
65
|
|
66
|
+
return obj
|
133
67
|
|
134
68
|
def read_pickle(path):
|
135
|
-
p1 = os.path.join(path,
|
136
|
-
p2 = os.path.join(path,
|
69
|
+
p1 = os.path.join(path, 'TB2J_results', 'TB2J.pickle')
|
70
|
+
p2 = os.path.join(path, 'TB2J.pickle')
|
137
71
|
if os.path.exists(p1) and os.path.exists(p2):
|
138
72
|
print(f" WARNING!: Both file {p1} and {p2} exist. Use default {p1}.")
|
139
73
|
if os.path.exists(p1):
|
140
|
-
ret =
|
74
|
+
ret = SpinIO_merge.load_pickle(os.path.join(path, 'TB2J_results'))
|
141
75
|
elif os.path.exists(p2):
|
142
|
-
ret =
|
76
|
+
ret = SpinIO_merge.load_pickle(path)
|
143
77
|
else:
|
144
78
|
raise FileNotFoundError(f"Cannot find either file {p1} or {p2}")
|
145
79
|
return ret
|
146
80
|
|
81
|
+
class Merger():
|
82
|
+
def __init__(self, *paths, main_path=None):
|
83
|
+
self.dat = [read_pickle(path) for path in paths]
|
147
84
|
|
148
|
-
|
149
|
-
|
150
|
-
self.method = method
|
151
|
-
if method.lower() == "spin":
|
152
|
-
self.load_with_rotated_spin(paths)
|
153
|
-
elif method.lower() == "structure":
|
154
|
-
self.load_with_rotated_structure(paths)
|
85
|
+
if main_path is None:
|
86
|
+
self.main_dat = copy.deepcopy(self.dat[-1])
|
155
87
|
else:
|
156
|
-
|
157
|
-
|
158
|
-
def load_with_rotated_structure(self, paths):
|
159
|
-
"""
|
160
|
-
Merge TB2J results from multiple calculations.
|
161
|
-
:param paths: a list of paths to the TB2J results.
|
162
|
-
:param method: 'structure' or 'spin'
|
163
|
-
"""
|
164
|
-
self.paths = paths
|
165
|
-
if len(self.paths) != 3:
|
166
|
-
raise ValueError(
|
167
|
-
"The number of paths should be 3, with structure rotated from z to x, y, z"
|
168
|
-
)
|
169
|
-
for i, path in enumerate(self.paths):
|
170
|
-
read_pickle(path)
|
171
|
-
self.indata = [read_pickle(path) for path in paths]
|
172
|
-
|
173
|
-
self.dat = copy.deepcopy(self.indata[-1])
|
174
|
-
# self.dat.description += (
|
175
|
-
# "Merged from TB2J results in paths: \n " + "\n ".join(paths) + "\n"
|
176
|
-
# )
|
177
|
-
Rotations = [Rzx, Rzy, Rzz]
|
178
|
-
for dat, rotation in zip(self.indata, Rotations):
|
179
|
-
dat.spinat = recover_spinat_from_rotated_structure(dat.spinat, rotation)
|
180
|
-
dat.dmi_ddict = recover_DMI_from_rotated_structure(dat.dmi_ddict, rotation)
|
181
|
-
dat.Jani_dict = recover_Jani_fom_rotated_structure(dat.Jani_dict, rotation)
|
182
|
-
|
183
|
-
def load_with_rotated_spin(self, paths):
|
184
|
-
"""
|
185
|
-
Merge TB2J results from multiple calculations.
|
186
|
-
:param paths: a list of paths to the TB2J results.
|
187
|
-
:param method: 'structure' or 'spin'
|
188
|
-
"""
|
189
|
-
self.paths = paths
|
190
|
-
self.indata = [read_pickle(path) for path in paths]
|
191
|
-
self.dat = copy.deepcopy(self.indata[-1])
|
192
|
-
# self.dat.description += (
|
193
|
-
# "Merged from TB2J results in paths: \n " + "\n ".join(paths) + "\n"
|
194
|
-
# )
|
195
|
-
|
196
|
-
def merge_Jani(self):
|
197
|
-
"""
|
198
|
-
Merge the anisotropic exchange tensor.
|
199
|
-
"""
|
200
|
-
Jani_dict = {}
|
201
|
-
for key, Jani in self.dat.Jani_dict.items():
|
202
|
-
R, i, j = key
|
203
|
-
weights = np.zeros((3, 3), dtype=float)
|
204
|
-
Jani_sum = np.zeros((3, 3), dtype=float)
|
205
|
-
for dat in self.indata:
|
206
|
-
Si = dat.get_spin_ispin(i)
|
207
|
-
Sj = dat.get_spin_ispin(j)
|
208
|
-
# print(f"{Si=}, {Sj=}")
|
209
|
-
Jani = dat.get_Jani(i, j, R, default=np.zeros((3, 3), dtype=float))
|
210
|
-
Jani_removed, w = remove_components(
|
211
|
-
Jani,
|
212
|
-
Si,
|
213
|
-
Sj,
|
214
|
-
remove_indices=[[0, 2], [1, 2], [2, 2], [2, 1], [2, 0]],
|
215
|
-
)
|
216
|
-
w = Jani_removed / Jani
|
217
|
-
Jani_sum += Jani * w # Jani_removed
|
218
|
-
# print(f"{Jani* w=}")
|
219
|
-
weights += w
|
220
|
-
# print(f"{weights=}")
|
221
|
-
if np.any(weights == 0):
|
222
|
-
raise RuntimeError(
|
223
|
-
"The data set to be merged does not give a complete anisotropic J tensor, please add more data"
|
224
|
-
)
|
225
|
-
Jani_dict[key] = Jani_sum / weights
|
226
|
-
self.dat.Jani_dict = Jani_dict
|
227
|
-
|
228
|
-
def merge_DMI(self):
|
229
|
-
"""
|
230
|
-
merge the DMI vector
|
231
|
-
"""
|
232
|
-
DMI = {}
|
233
|
-
for key, D in self.dat.dmi_ddict.items():
|
234
|
-
R, i, j = key
|
235
|
-
weights = np.zeros((3, 3), dtype=float)
|
236
|
-
Dtensor_sum = np.zeros((3, 3), dtype=float)
|
237
|
-
for dat in self.indata:
|
238
|
-
Si = dat.get_spin_ispin(i)
|
239
|
-
Sj = dat.get_spin_ispin(j)
|
240
|
-
D = dat.get_DMI(i, j, R, default=np.zeros((3,), dtype=float))
|
241
|
-
Dtensor = DMI_to_Jtensor(D)
|
242
|
-
Dtensor_removed, w = remove_components(
|
243
|
-
Dtensor, Si, Sj, remove_indices=[[0, 1], [1, 0]]
|
244
|
-
)
|
245
|
-
Dtensor_sum += Dtensor * w # Dtensor_removed
|
246
|
-
weights += w
|
247
|
-
if np.any(weights == 0):
|
248
|
-
raise RuntimeError(
|
249
|
-
"The data set to be merged does not give a complete DMI vector, please add more data"
|
250
|
-
)
|
251
|
-
DMI[key] = Jtensor_to_DMI(Dtensor_sum / weights)
|
252
|
-
self.dat.dmi_ddict = DMI
|
88
|
+
self.main_dat = read_pickle(main_path)
|
89
|
+
self.dat.append(copy.deepcopy(self.main_dat))
|
253
90
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
"""
|
258
|
-
Jiso = {}
|
259
|
-
for key, J in self.dat.exchange_Jdict.items():
|
260
|
-
R, i, j = key
|
261
|
-
weights = 0.0
|
262
|
-
Jiso_sum = 0.0
|
263
|
-
for dat in self.indata:
|
264
|
-
Si = dat.get_spin_ispin(i)
|
265
|
-
Sj = dat.get_spin_ispin(j)
|
266
|
-
J = dat.get_Jiso(i, j, R, default=0.0)
|
267
|
-
Jiso_sum += J # *np.eye(3, dtype=float)
|
268
|
-
weights += 1.0
|
269
|
-
if np.any(weights == 0):
|
270
|
-
raise RuntimeError(
|
271
|
-
"The data set to be merged does not give a complete isotropic exchange, please add more data"
|
272
|
-
)
|
273
|
-
Jiso[key] = Jiso_sum / weights
|
274
|
-
self.dat.exchange_Jdict = Jiso
|
91
|
+
self._set_projv()
|
92
|
+
|
93
|
+
def _set_projv(self):
|
275
94
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
:param path: the path to the folder to write the results.
|
280
|
-
"""
|
281
|
-
self.dat.description += (
|
282
|
-
"Merged from TB2J results in paths: \n " + "\n ".join(self.paths) + "\n"
|
95
|
+
cell = self.main_dat.atoms.cell.array
|
96
|
+
rotated_cells = np.stack(
|
97
|
+
[obj.atoms.cell.array for obj in self.dat], axis=0
|
283
98
|
)
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
99
|
+
R = np.linalg.solve(cell, rotated_cells)
|
100
|
+
indices = range(len(self.dat))
|
101
|
+
|
102
|
+
proju = {}; projv = {}; coeff_matrix = {}; projectors = {};
|
103
|
+
for key in self.main_dat.projv.keys():
|
104
|
+
vectors = [obj.projv[key] for obj in self.dat]
|
105
|
+
coefficients, u, v = zip(*[get_Jani_coefficients(vectors[i], R=R[i]) for i in indices])
|
106
|
+
projectors[key] = np.vstack([u[i] @ R[i].T for i in indices])
|
107
|
+
coeff_matrix[key] = np.vstack(coefficients)
|
108
|
+
proju[key] = np.stack(u)
|
109
|
+
projv[key] = np.stack(v)
|
110
|
+
if np.linalg.matrix_rank(coeff_matrix[key], tol=1e-2) < 6:
|
111
|
+
warnings.warn('''
|
112
|
+
WARNING: The matrix of equations to reconstruct the exchange tensors is
|
113
|
+
close to being singular. This happens when the magnetic moments between
|
114
|
+
different configurations are cloes to being parallel. You need to consider
|
115
|
+
more rotated spin configurations, otherwise the results might have a large
|
116
|
+
error.'''
|
117
|
+
)
|
118
|
+
|
119
|
+
self.proju = proju
|
120
|
+
self.projv = projv
|
121
|
+
self.coeff_matrix = coeff_matrix
|
122
|
+
self.projectors = projectors
|
303
123
|
|
304
124
|
def merge_Jani(self):
|
305
125
|
Jani_dict = {}
|
306
|
-
|
307
|
-
|
308
|
-
Janizdict = self.dat_z.Jani_dict
|
309
|
-
for key, Janiz in Janizdict.items():
|
126
|
+
proju = self.proju; projv = self.projv; coeff_matrix = self.coeff_matrix;
|
127
|
+
for key in self.main_dat.Jani_dict.keys():
|
310
128
|
try:
|
311
129
|
R, i, j = key
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
130
|
+
u = proju[i, j]
|
131
|
+
v = projv[i, j]
|
132
|
+
Jani = np.stack([sio.Jani_dict[key] for sio in self.dat])
|
133
|
+
projections = np.einsum('nmi,nij,nmj->nm', u, Jani, v).flatten()
|
316
134
|
except KeyError as err:
|
317
135
|
raise KeyError(
|
318
136
|
"Can not find key: %s, Please make sure the three calculations use the same k-mesh and same Rcut."
|
319
|
-
% err
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
self.dat.Jani_dict = Jani_dict
|
137
|
+
% err)
|
138
|
+
newJani = np.linalg.lstsq(coeff_matrix[i, j], projections, rcond=1e-2)[0]
|
139
|
+
Jani_dict[key] = np.array([
|
140
|
+
[newJani[0], newJani[3], newJani[5]],
|
141
|
+
[newJani[3], newJani[1], newJani[4]],
|
142
|
+
[newJani[5], newJani[4], newJani[2]]
|
143
|
+
])
|
144
|
+
self.main_dat.Jani_dict = Jani_dict
|
328
145
|
|
329
146
|
def merge_Jiso(self):
|
330
|
-
Jdict
|
331
|
-
|
332
|
-
Jydict = self.dat_y.exchange_Jdict
|
333
|
-
Jzdict = self.dat_z.exchange_Jdict
|
334
|
-
for key, J in Jzdict.items():
|
147
|
+
Jdict={}
|
148
|
+
for key in self.main_dat.exchange_Jdict.keys():
|
335
149
|
try:
|
336
|
-
|
337
|
-
Jy = Jydict[key]
|
338
|
-
Jz = Jzdict[key]
|
150
|
+
J = np.mean([obj.exchange_Jdict[key] for obj in self.dat])
|
339
151
|
except KeyError as err:
|
340
152
|
raise KeyError(
|
341
|
-
"Can not find key: %s, Please make sure the three calculations use the same k-mesh and same Rcut."
|
342
|
-
% err
|
343
|
-
)
|
344
|
-
Jdict[key] = (Jx + Jy + Jz) / 3.0
|
345
|
-
self.dat.exchange_Jdict = Jdict
|
346
|
-
|
347
|
-
def merge_DMI(self):
|
348
|
-
dmi_ddict = {}
|
349
|
-
if self.dat_x.has_dmi and self.dat_y.has_dmi and self.dat_z.has_dmi:
|
350
|
-
Dxdict = self.dat_x.dmi_ddict
|
351
|
-
Dydict = self.dat_y.dmi_ddict
|
352
|
-
Dzdict = self.dat_z.dmi_ddict
|
353
|
-
for key, Dz in Dzdict.items():
|
354
|
-
try:
|
355
|
-
R, i, j = key
|
356
|
-
keyx = R
|
357
|
-
keyy = R
|
358
|
-
Dx = Dxdict[(tuple(keyx), i, j)]
|
359
|
-
Dy = Dydict[(tuple(keyy), i, j)]
|
360
|
-
except KeyError as err:
|
361
|
-
raise KeyError(
|
362
153
|
"Can not find key: %s, Please make sure the three calculations use the same k-mesh and same Rcut."
|
363
|
-
% err
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
else:
|
368
|
-
dmi_ddict[key] = merge_DMI(Dx, Dy, Dz)
|
369
|
-
self.dat.dmi_ddict = dmi_ddict
|
154
|
+
% err)
|
155
|
+
Jdict[key] = J
|
156
|
+
self.main_dat.exchange_Jdict = Jdict
|
157
|
+
|
370
158
|
|
159
|
+
def merge_DMI(self):
|
371
160
|
dmi_ddict = {}
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
Dzdict = self.dat_z.debug_dict["DMI2"]
|
376
|
-
for key, Dz in Dzdict.items():
|
161
|
+
if all(obj.has_dmi for obj in self.dat):
|
162
|
+
projectors = self.projectors; proju = self.proju;
|
163
|
+
for key in self.main_dat.dmi_ddict.keys():
|
377
164
|
try:
|
378
165
|
R, i, j = key
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
Dy = Dydict[(tuple(keyy), i, j)]
|
166
|
+
u = proju[i, j]
|
167
|
+
DMI = np.stack([sio.dmi_ddict[key] for sio in self.dat])
|
168
|
+
projections = np.einsum('nmi,ni->nm', u, DMI).flatten()
|
383
169
|
except KeyError as err:
|
384
170
|
raise KeyError(
|
385
171
|
"Can not find key: %s, Please make sure the three calculations use the same k-mesh and same Rcut."
|
386
|
-
% err
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
elif self.method == "spin":
|
391
|
-
dmi_ddict[key] = merge_DMI2(Dx, Dy, Dz)
|
392
|
-
|
393
|
-
self.dat.debug_dict["DMI2"] = dmi_ddict
|
394
|
-
except:
|
395
|
-
pass
|
396
|
-
|
397
|
-
def write(self, path="TB2J_results"):
|
398
|
-
self.dat.description += (
|
399
|
-
"Merged from TB2J results in paths: \n " + "\n ".join(self.paths) + "\n"
|
400
|
-
)
|
401
|
-
if self.method == "spin":
|
402
|
-
self.dat.description += (
|
403
|
-
", which are from DFT data with spin along x, y, z orientation\n"
|
404
|
-
)
|
405
|
-
elif self.method == "structure":
|
406
|
-
self.dat.description += ", which are from DFT data with structure with z axis rotated to x, y, z\n"
|
407
|
-
self.dat.description += "\n"
|
408
|
-
self.dat.write_all(path=path)
|
409
|
-
|
410
|
-
|
411
|
-
def merge(path_x, path_y, path_z, method, save=True, path="TB2J_results"):
|
412
|
-
m = Merger(path_x, path_y, path_z, method)
|
413
|
-
m.merge_Jiso()
|
414
|
-
m.merge_DMI()
|
415
|
-
m.merge_Jani()
|
416
|
-
if save:
|
417
|
-
m.write(path=path)
|
418
|
-
return m.dat
|
419
|
-
|
172
|
+
% err)
|
173
|
+
newDMI = np.linalg.lstsq(projectors[i, j], projections, rcond=4e-1)[0]
|
174
|
+
dmi_ddict[key] = newDMI
|
175
|
+
self.main_dat.dmi_ddict = dmi_ddict
|
420
176
|
|
421
|
-
def
|
422
|
-
|
423
|
-
Merge TB2J results from multiple calculations.
|
424
|
-
:param paths: a list of paths to the TB2J results.
|
425
|
-
:param method: 'structure' or 'spin'
|
426
|
-
:param save: whether to save the merged results.
|
427
|
-
:param path: the path to the folder to write the results.
|
428
|
-
"""
|
429
|
-
m = Merger2(paths, method)
|
177
|
+
def merge(*paths, main_path=None, save=True, write_path='TB2J_results'):
|
178
|
+
m = Merger(*paths, main_path=main_path)
|
430
179
|
m.merge_Jiso()
|
431
180
|
m.merge_DMI()
|
432
181
|
m.merge_Jani()
|
433
182
|
if save:
|
434
|
-
m.
|
183
|
+
m.main_dat.write_all(path=write_path)
|
435
184
|
return m.dat
|
TB2J/myTB.py
CHANGED
@@ -16,7 +16,6 @@ class AbstractTB:
|
|
16
16
|
def __init__(self, R2kfactor, nspin, norb):
|
17
17
|
#: :math:`\alpha` used in :math:`H(k)=\sum_R H(R) \exp( \alpha k \cdot R)`,
|
18
18
|
#: Should be :math:`2\pi i` or :math:`-2\pi i`
|
19
|
-
self.is_siesta = False
|
20
19
|
self.is_orthogonal = True
|
21
20
|
self.R2kfactor = R2kfactor
|
22
21
|
|
@@ -125,7 +124,6 @@ class MyTB(AbstractTB):
|
|
125
124
|
self.atoms = None
|
126
125
|
self.R2kfactor = 2.0j * np.pi
|
127
126
|
self.k2Rfactor = -2.0j * np.pi
|
128
|
-
self.is_siesta = False
|
129
127
|
self.is_orthogonal = True
|
130
128
|
self._name = "Wannier"
|
131
129
|
|
TB2J/rotate_atoms.py
CHANGED
@@ -5,19 +5,24 @@ import numpy as np
|
|
5
5
|
from TB2J.tensor_rotate import Rxx, Rxy, Rxz, Ryx, Ryy, Ryz, Rzx, Rzy, Rzz
|
6
6
|
|
7
7
|
|
8
|
-
def rotate_atom_xyz(atoms):
|
8
|
+
def rotate_atom_xyz(atoms, noncollinear=False):
|
9
9
|
"""
|
10
|
-
given a atoms, return:
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
given a atoms, return rotated atoms:
|
11
|
+
atoms_1, ..., atoms_n,
|
12
|
+
where we considered n diffeerent roation axes.
|
13
|
+
|
14
|
+
When noncollinear == True, more rotated structures
|
15
|
+
will be generated.
|
14
16
|
"""
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
|
18
|
+
rotation_axes = [(1, 0, 0), (0, 1, 0)]
|
19
|
+
if noncollinear:
|
20
|
+
rotation_axes += [(1, 1, 0), (1, 0, 1), (0, 1, 1)]
|
21
|
+
|
22
|
+
for axis in rotation_axes:
|
23
|
+
rotated_atoms = copy.deepcopy(atoms)
|
24
|
+
rotated_atoms.rotate(90, axis, rotate_cell=True)
|
25
|
+
yield rotated_atoms
|
21
26
|
|
22
27
|
|
23
28
|
def rotate_atom_spin_one_rotation(atoms, Rotation):
|
@@ -96,18 +101,15 @@ def check_ftype(ftype):
|
|
96
101
|
print("=" * 40)
|
97
102
|
|
98
103
|
|
99
|
-
def rotate_xyz(fname, ftype="xyz"):
|
104
|
+
def rotate_xyz(fname, ftype="xyz", noncollinear=False):
|
100
105
|
check_ftype(ftype)
|
101
106
|
atoms = read(fname)
|
102
107
|
atoms.set_pbc(True)
|
103
108
|
|
104
|
-
|
109
|
+
rotated = rotate_atom_xyz(atoms, noncollinear=noncollinear)
|
105
110
|
|
106
|
-
|
107
|
-
|
108
|
-
|
111
|
+
for i, rotated_atoms in enumerate(rotated):
|
112
|
+
write(f"atoms_{i+1}.{ftype}", rotated_atoms)
|
113
|
+
write(f"atoms_0.{ftype}", atoms)
|
109
114
|
|
110
|
-
|
111
|
-
write(fname_y, atoms_y)
|
112
|
-
write(fname_z, atoms_z)
|
113
|
-
print(f"The output has been written to {fname_x}, {fname_y}, {fname_z}")
|
115
|
+
print(f"The output has been written to the atoms_i.{ftype} files. atoms_0.{ftype} contains the reference structure.")
|
TB2J/rotate_siestaDM.py
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
import sisl
|
2
|
+
|
3
|
+
def rotate_siesta_DM(DM, noncollinear=False):
|
4
|
+
|
5
|
+
angles_list = [ [0.0, 90.0, 0.0], [0.0, 90.0, 90.0] ]
|
6
|
+
if noncollinear:
|
7
|
+
angles_list += [[0.0, 45.0, 0.0], [0.0, 90.0, 45.0], [0.0, 45.0, 90.0]]
|
8
|
+
|
9
|
+
for angles in angles_list:
|
10
|
+
yield DM.spin_rotate(angles)
|
11
|
+
|
12
|
+
def read_label(fdf_fname):
|
13
|
+
|
14
|
+
label = 'siesta'
|
15
|
+
with open(fdf_fname, 'r') as File:
|
16
|
+
for line in File:
|
17
|
+
corrected_line = line.lower().replace('.', '').replace('-', '')
|
18
|
+
if 'systemlabel' in corrected_line:
|
19
|
+
label = line.split()[1]
|
20
|
+
break
|
21
|
+
|
22
|
+
return label
|
23
|
+
|
24
|
+
def rotate_DM(fdf_fname, noncollinear=False):
|
25
|
+
|
26
|
+
fdf = sisl.get_sile(fdf_fname)
|
27
|
+
DM = fdf.read_density_matrix()
|
28
|
+
label = read_label(fdf_fname)
|
29
|
+
|
30
|
+
rotated = rotate_siesta_DM(DM, noncollinear=noncollinear)
|
31
|
+
|
32
|
+
for i, rotated_DM in enumerate(rotated):
|
33
|
+
rotated_DM.write(f"{label}_{i+1}.DM")
|
34
|
+
DM.write(f"{label}_0.DM")
|
35
|
+
|
36
|
+
print(f"The output has been written to the {label}_i.DM files. {label}_0.DM contains the reference density matrix.")
|
TB2J/sisl_wrapper.py
CHANGED
@@ -10,7 +10,6 @@ from TB2J.mathutils import Lowdin
|
|
10
10
|
|
11
11
|
class SislWrapper(AbstractTB):
|
12
12
|
def __init__(self, sisl_hamiltonian, geom=None, spin=None):
|
13
|
-
self.is_siesta = False
|
14
13
|
self.is_orthogonal = False
|
15
14
|
self.ham = sisl_hamiltonian
|
16
15
|
# k2Rfactor : H(k) = \int_R H(R) * e^(k2Rfactor * k.R)
|
TB2J/spinham/h_matrix.py
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
import numpy as np
|
2
|
+
import matplotlib.pyplot as plt
|
3
|
+
import aiida
|
4
|
+
from aiida_tb2j.data import ExchangeData
|
5
|
+
|
6
|
+
def plot_dispersion(bands, kpoint_labels, color='blue', title=None):
|
7
|
+
|
8
|
+
fig, axs = plt.subplots(1, 1, constrained_layout=True)
|
9
|
+
fig.set_size_inches(6, 6/1.618)
|
10
|
+
|
11
|
+
'''
|
12
|
+
Plot the bands
|
13
|
+
'''
|
14
|
+
kpoints = np.arange(len(bands))
|
15
|
+
axs.plot(kpoints, bands, color=color, linewidth=1.5)
|
16
|
+
|
17
|
+
'''
|
18
|
+
Plot the symmetry points
|
19
|
+
'''
|
20
|
+
bmin = bands.min(); bmax = bands.max()
|
21
|
+
ymin = bmin - 0.05*np.abs(bmin-bmax); ymax = bmax + 0.05*np.abs(bmax-bmin);
|
22
|
+
axs.set_xticks(kpoint_labels[0], kpoint_labels[1], fontsize=10)
|
23
|
+
axs.vlines(x=kpoint_labels[0], ymin=ymin, ymax=ymax, color='black', linewidth=0.5)
|
24
|
+
axs.set_xlim([0, len(kpoints)])
|
25
|
+
axs.set_ylim([ymin, ymax])
|
26
|
+
|
27
|
+
if title is not None:
|
28
|
+
plt.title(title, fontsize=10)
|
29
|
+
|
30
|
+
plt.show()
|
31
|
+
|
32
|
+
|
33
|
+
if __name__ == "__main__":
|
34
|
+
|
35
|
+
from argparse import ArgumentParser
|
36
|
+
|
37
|
+
parser = ArgumentParser()
|
38
|
+
parser.add_argument('-f', '--pickle_filename', type=str, help="Path of the 'TB2J.pickle' file.", required=True)
|
39
|
+
args = parser.parse_args()
|
40
|
+
|
41
|
+
'''
|
42
|
+
Right now the implementation depends on AiiDA and so we must create and load an AiiDA profile,
|
43
|
+
even if we do not store any information on a data base.
|
44
|
+
'''
|
45
|
+
aiida.load_profile()
|
46
|
+
'''
|
47
|
+
Create an ExchangeData object with the informations from the TB2J.pickle file
|
48
|
+
'''
|
49
|
+
exchange = ExchangeData.load_tb2j(pickle_file=args.pickle_filename, isotropic=False, pbc=(True, True, True))
|
50
|
+
'''
|
51
|
+
Compute the magnon band structure along a high symmetry path generated with
|
52
|
+
the ASE package. The informations is stored in an AiiDA BandsData object.
|
53
|
+
Here tol is the symmetry tolerance to determine the space group of the system.
|
54
|
+
They are in units of eV
|
55
|
+
'''
|
56
|
+
magnon_data = exchange.get_magnon_bands(npoints=300, tol=1e-1, with_DMI=True, with_Jani=True)
|
57
|
+
magnon_bands = 1000*magnon_data.get_bands() # Convert to meV
|
58
|
+
raw_labels = [(k, '$\Gamma$') if s == 'GAMMA' else (k, s) for k, s in magnon_data.labels]
|
59
|
+
kpoint_labels = list( zip( *raw_labels ) )
|
60
|
+
plot_dispersion(magnon_bands, kpoint_labels, color='blue', title='Magnon Bands')
|
61
|
+
'''
|
62
|
+
We can also obtain the dynamical matrix h instead of the actual magnon bands. The result
|
63
|
+
is stored in a numpy array with shape (number of kpoints, 2*natoms, 2*natoms)
|
64
|
+
'''
|
65
|
+
kpoints = magnon_data.get_kpoints() # The shape of the kpoints must be (nkpoints, 3)
|
66
|
+
h_matrix = 1000*exchange._H_matrix(kpoints, with_DMI=True, with_Jani=True) # Convert to meV
|
67
|
+
h_dispersion = np.linalg.eigvalsh(h_matrix) # We can also get the eigenvectors with np.linalg.eigh
|
68
|
+
plot_dispersion(h_dispersion, kpoint_labels, color='red', title='h matrix dispersion')
|
TB2J/spinham/obtain_J.py
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
import numpy as np
|
2
|
+
from aiida_tb2j.data import ExchangeData
|
3
|
+
from aiida_tb2j.data.exchange import get_rotation_arrays
|
4
|
+
from itertools import combinations_with_replacement
|
5
|
+
|
6
|
+
ux, uy, uz = np.eye(3).reshape((3, 1, 3))
|
7
|
+
|
8
|
+
def combine_arrays(u, v):
|
9
|
+
|
10
|
+
return np.concatenate([u*v, np.roll(u, -1, axis=-1)*v, np.roll(v, -1, axis=-1)*u], axis=-1)
|
11
|
+
|
12
|
+
def get_coefficients(magmoms, indices):
|
13
|
+
|
14
|
+
i, j = indices
|
15
|
+
|
16
|
+
U, V = zip(*[get_rotation_arrays(magmoms, u=u) for u in [ux, uy, uz]])
|
17
|
+
U = np.stack(U).swapaxes(0, 1)
|
18
|
+
V = np.stack(V).swapaxes(0, 1)
|
19
|
+
|
20
|
+
uc = combine_arrays(U[i], U[j].conj())
|
21
|
+
ur = combine_arrays(U[i], U[j])
|
22
|
+
uc2 = combine_arrays(U[i].conj(), U[j])
|
23
|
+
u = np.concatenate([uc, ur, uc2], axis=1)
|
24
|
+
|
25
|
+
return u, V
|
26
|
+
|
27
|
+
def get_C(H0, u, V):
|
28
|
+
|
29
|
+
n = int(H0.shape[-1]/2)
|
30
|
+
upi = np.triu_indices(n)
|
31
|
+
dig = np.diag_indices(n)
|
32
|
+
|
33
|
+
i, j = upi
|
34
|
+
AB0 = H0[:, [i, i, i+n], [j, j+n, j+n]]
|
35
|
+
AB0 = np.swapaxes(AB0, 0, 2).reshape(len(i), 9)
|
36
|
+
J0_flat = np.linalg.solve(u, AB0)
|
37
|
+
|
38
|
+
J0 = np.empty((n, n, 3, 3), dtype=complex)
|
39
|
+
J0[*upi] = J0_flat[:, [0, 6, 5, 3, 1, 7, 8, 4, 2]].reshape(-1, 3, 3)
|
40
|
+
J0 += J0.swapaxes(0, 1)
|
41
|
+
J0[*dig] = 0.0
|
42
|
+
|
43
|
+
C = np.array([np.diag(a) for a in np.einsum('imx,ijxy,jmy->mi', V, 2*J0, V)])
|
44
|
+
|
45
|
+
return C
|
46
|
+
|
47
|
+
def get_J(H, kpoints, exchange):
|
48
|
+
|
49
|
+
n = int(H.shape[-1]/2)
|
50
|
+
upi = np.triu_indices(n)
|
51
|
+
dig = np.diag_indices(n)
|
52
|
+
i, j = upi
|
53
|
+
|
54
|
+
magmoms = exchange.magmoms()[np.unique(exchange.pairs)]
|
55
|
+
magmoms /= np.linalg.norm(magmoms, axis=-1).reshape(-1, 1)
|
56
|
+
u, V = get_coefficients(magmoms, indices=upi)
|
57
|
+
|
58
|
+
H0 = np.stack([1000*exchange._H_matrix(kpoints=np.zeros((1, 3)), with_DMI=True, with_Jani=True, u=u) for u in [ux, uy, uz]])[:, 0, :, :]
|
59
|
+
C = get_C(H0, u, V)
|
60
|
+
H[:, :, :n, :n] += C.reshape(3, 1, n, n)
|
61
|
+
H[:, :, n:, n:] += C.reshape(3, 1, n, n)
|
62
|
+
|
63
|
+
AB = H[:, :, [i, i, i+n], [j, j+n, j+n]]
|
64
|
+
AB[:, :, 2, :] = AB[:, ::-1, 2, :]
|
65
|
+
AB = np.moveaxis(AB, [2, 3], [1, 0]).reshape(len(i), 9, -1)
|
66
|
+
|
67
|
+
vectors = exchange.get_vectors()
|
68
|
+
exp_summand = np.exp( -2j*np.pi*vectors @ kpoints.T )
|
69
|
+
nAB = np.einsum('nik,ndk->nid', AB, exp_summand) / len(kpoints)
|
70
|
+
|
71
|
+
ii = np.where(i == j)
|
72
|
+
i0 = np.where(np.linalg.norm(vectors, axis=-1) == 0.0)
|
73
|
+
J = np.linalg.solve(u, nAB).swapaxes(1, 2)
|
74
|
+
J = J[:, :, [0, 6, 5, 3, 1, 7, 8, 4, 2]].reshape(len(i), -1, 3, 3)
|
75
|
+
J *= -1
|
76
|
+
J[ii] *= 2
|
77
|
+
J[i0] *= 0
|
78
|
+
|
79
|
+
return J
|
@@ -2,7 +2,7 @@
|
|
2
2
|
import argparse
|
3
3
|
import os
|
4
4
|
import sys
|
5
|
-
from TB2J.io_merge import merge
|
5
|
+
from TB2J.io_merge import merge
|
6
6
|
|
7
7
|
|
8
8
|
def main():
|
@@ -28,11 +28,18 @@ def main():
|
|
28
28
|
type=str,
|
29
29
|
default="TB2J_results",
|
30
30
|
)
|
31
|
+
parser.add_argument(
|
32
|
+
"--main_path",
|
33
|
+
help="The path containning the reference structure.",
|
34
|
+
type=str,
|
35
|
+
default=None
|
36
|
+
)
|
31
37
|
|
32
38
|
args = parser.parse_args()
|
33
39
|
# merge(*(args.directories), args.type.strip().lower(), path=args.output_path)
|
34
40
|
# merge(*(args.directories), method=args.type.strip().lower(), path=args.output_path)
|
35
|
-
merge2(args.directories, args.type.strip().lower(), path=args.output_path)
|
41
|
+
#merge2(args.directories, args.type.strip().lower(), path=args.output_path)
|
42
|
+
merge(*args.directories, main_path=args.main_path, write_path=args.output_path)
|
36
43
|
|
37
44
|
|
38
45
|
main()
|
@@ -14,9 +14,14 @@ def main():
|
|
14
14
|
default="xyz",
|
15
15
|
type=str,
|
16
16
|
)
|
17
|
+
parser.add_argument(
|
18
|
+
"--noncollinear",
|
19
|
+
action="store_true",
|
20
|
+
help="If present, six different configurations will be generated. These are required for non-collinear systems."
|
21
|
+
)
|
17
22
|
|
18
23
|
args = parser.parse_args()
|
19
|
-
rotate_xyz(args.fname, ftype=args.ftype)
|
24
|
+
rotate_xyz(args.fname, ftype=args.ftype, noncollinear=args.noncollinear)
|
20
25
|
|
21
26
|
|
22
27
|
if __name__ == "__main__":
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!python
|
2
|
+
import argparse
|
3
|
+
from TB2J.rotate_siestaDM import rotate_DM
|
4
|
+
|
5
|
+
def main():
|
6
|
+
parser = argparse.ArgumentParser(description="")
|
7
|
+
parser.add_argument(
|
8
|
+
"--fdf_fname", help="Name of the *.fdf siesta file."
|
9
|
+
)
|
10
|
+
parser.add_argument(
|
11
|
+
"--noncollinear",
|
12
|
+
action="store_true",
|
13
|
+
help="If present, six different configurations will be generated. These are required for non-collinear systems."
|
14
|
+
)
|
15
|
+
|
16
|
+
args = parser.parse_args()
|
17
|
+
rotate_DM(args.fdf_fname, noncollinear=args.noncollinear)
|
18
|
+
|
19
|
+
|
20
|
+
if __name__ == "__main__":
|
21
|
+
main()
|
@@ -2,31 +2,32 @@ TB2J/Jdownfolder.py,sha256=Nw2ixvn2Uq-o1wficz6rdaYHjfRN3U_kQCvrNJGNb68,6980
|
|
2
2
|
TB2J/Jtensor.py,sha256=0fhfOcfVQGu75gytEnApKWTJZfg9ksKJ0anJgco5wRQ,3179
|
3
3
|
TB2J/Oiju.py,sha256=cNGv8N5uH_swGq7cnAt2OyiDfqtjLlLrwseGu0E4iaM,3383
|
4
4
|
TB2J/Oiju_epc.py,sha256=oytM3NYW7nWmklrGgNlqwIpI_JYv_hb7ZnR4o9nYNog,6809
|
5
|
-
TB2J/__init__.py,sha256=
|
5
|
+
TB2J/__init__.py,sha256=H9NWRZb7NbeRRPLP_V1fARmLNXranorVM-OOY-8_2ug,22
|
6
6
|
TB2J/basis.py,sha256=DFo6_QUwjBwisP6zGxvoO0lpGTMDPAOkiL9giNCjOjA,1558
|
7
7
|
TB2J/citation.py,sha256=gcQeyJZaT1Qrtsl8Y3s4neOH3-vvgmIcCvXeV2o3vj0,2891
|
8
8
|
TB2J/contour.py,sha256=aw8LX6wVFCRPhcpkzuI0jGnHisvk4cezvUhkF_6Yx94,2633
|
9
9
|
TB2J/cut_cell.py,sha256=kr9WeQhBQLm8QXL2B3NcsSYmSw-OAtJk3f9wksAOZbs,2952
|
10
10
|
TB2J/density_matrix.py,sha256=D5k8Oe21OCiLVORNYbo4TZOFG0slrQSbj91kJ3TMFjs,1514
|
11
11
|
TB2J/epc.py,sha256=zLbtqZJhDr8DnnGN6YENcXwrMb3Qxu6KB08mLy9Pw20,3474
|
12
|
-
TB2J/exchange.py,sha256=
|
12
|
+
TB2J/exchange.py,sha256=Xg2fuUZbj-Icpqc65Ictllxvdvct8Ec4KQPAmEyo0oM,29586
|
13
13
|
TB2J/exchangeCL2.py,sha256=TIr-d2X56AiGe4qEhyXyZhRuwXvQG6clJMwDmjnTOaE,10985
|
14
14
|
TB2J/exchange_pert.py,sha256=jmFMtQbYa_uczM4VAeS6TijkIHRFIqEzZJswzE9Wfuo,8523
|
15
15
|
TB2J/exchange_qspace.py,sha256=ZL68qBGFUaQ9BsSPsJaaoWOr9RssPiqX34R_9I3nk_8,8436
|
16
16
|
TB2J/gpaw_wrapper.py,sha256=aJ--9Dtyq7jOP1Hkh-Sh1nWcfXm6zKcljOCO0DNCAr0,6890
|
17
|
-
TB2J/green.py,sha256=
|
17
|
+
TB2J/green.py,sha256=X-D8UZcIyz6zh_0W9VgUUv5yXPP3KWJ6C03m6CMWE3o,13377
|
18
18
|
TB2J/greentest.py,sha256=2ISSfhor9ecSEOi_E6b4Cv26wEIQlwlzca0ru8z44_E,1603
|
19
|
-
TB2J/io_merge.py,sha256=
|
19
|
+
TB2J/io_merge.py,sha256=t85k3L6IL9X5ys-PWK7CzResb3xJsyqM3LAlKPUe9vM,6825
|
20
20
|
TB2J/kpoints.py,sha256=6XK2KqTncidEq3o9GuO6VEZRPNTRtWeXg9QfcV-9smI,532
|
21
21
|
TB2J/manager.py,sha256=4-4x9jJRHpUEqJuhc5HqpXfh2-Ze5G9Wg8gOtn-AqR4,15372
|
22
22
|
TB2J/mathutils.py,sha256=tHA6q3KPDpXLIbZHdDZ2NU5s886VVM_oEG490zQ6Ris,300
|
23
|
-
TB2J/myTB.py,sha256=
|
23
|
+
TB2J/myTB.py,sha256=ok_B4my29bOIghMSZfx0Es6G8FaXaIiLP4gPxTdSj00,17659
|
24
24
|
TB2J/orbmap.py,sha256=RCMJkOPGbfPrcZzcc5ia1ZMKBQWxGcyj8W1ve8BJaEw,6669
|
25
25
|
TB2J/pauli.py,sha256=_FIF62jq2CkQdWC473a3S2F6NmzCdeCnglO9PjNVmMI,4120
|
26
26
|
TB2J/pert.py,sha256=RaCJfewl0doht4cjAnzzGKe-uj2le4aqe0iPKFrq9fo,1192
|
27
27
|
TB2J/plot.py,sha256=AnFIFWE2vlmj7Z6f_7-dX_O1stJN-qbuiurPj43dUCM,4104
|
28
|
-
TB2J/rotate_atoms.py,sha256
|
29
|
-
TB2J/
|
28
|
+
TB2J/rotate_atoms.py,sha256=Dwptn-wdDW4zYzjYb95yxTzuZOe9WPuLjh3d3-YcSs0,3277
|
29
|
+
TB2J/rotate_siestaDM.py,sha256=eR97rspdrRaK9YTwQwUKfobI0S9UnEcbEZ2f5IgR7Tk,1070
|
30
|
+
TB2J/sisl_wrapper.py,sha256=A5x1-tt8efUSPeGY5wM5m6-pJYQFXTCzQHVqD6RBa2g,14792
|
30
31
|
TB2J/supercell.py,sha256=4hgLGPBLRUDhtD-eF29v46ex7fHdkH-OENjS2wGLFww,19588
|
31
32
|
TB2J/tensor_rotate.py,sha256=4-DfT_Mg5e40fbd74M5W0D5DqmUq-kVOOLDkkkI834A,8083
|
32
33
|
TB2J/utest.py,sha256=z_ahi7tpHQF9WlHNQihcQ7qzfezRJQXQt28eB1X_z64,3897
|
@@ -34,7 +35,7 @@ TB2J/utils.py,sha256=_ARYKAeWfP1p5w0mEl-d7KwNfXoqC85TveYl0iCBD3c,9880
|
|
34
35
|
TB2J/versioninfo.py,sha256=wZwS9QDFRVDe7rf8JyPDDI8UGdTQiO6Pb_sWv8GAegA,337
|
35
36
|
TB2J/abacus/__init__.py,sha256=5sHiDnF2L-Y80QeET9zOiS83a5T_TQAXvnIhcYB6wNU,56
|
36
37
|
TB2J/abacus/abacus_api.py,sha256=D_NyXW-Pno92d3RVHByx0l1HDPHQAvXsmQVt8cfIGR8,7267
|
37
|
-
TB2J/abacus/abacus_wrapper.py,sha256=
|
38
|
+
TB2J/abacus/abacus_wrapper.py,sha256=QR3ZW6v-d7dgneKwBO5s9FfCjBp-fkWMEaTO4SlcROA,8461
|
38
39
|
TB2J/abacus/gen_exchange_abacus.py,sha256=lKZqkWMnLQtaSwgn8O5Fzr-pV6tzwoMqfZU_vbET6gU,2973
|
39
40
|
TB2J/abacus/orbital_api.py,sha256=l48Hn5z7TA0TH7Is4NDmz74b6B9L2ztYO4dRR37U4mQ,1562
|
40
41
|
TB2J/abacus/stru_api.py,sha256=aBKKlZ2hvAZChVCfNxRdxH51rfHKqZn6kOlazY-yW8k,67888
|
@@ -53,8 +54,10 @@ TB2J/io_exchange/io_vampire.py,sha256=UllC4twf06_q2vBCnAYFzEDGvS8mSefwQXDquBuyc0
|
|
53
54
|
TB2J/spinham/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
55
|
TB2J/spinham/base_parser.py,sha256=oQRHvFE_BlUtTaTZykKgvicu40oXcbICB-D1aAt-qlA,2196
|
55
56
|
TB2J/spinham/constants.py,sha256=y4-hRyl5EAR42k24Oa5XhAsUQtKVn1MAgyqNf-p3PrM,762
|
57
|
+
TB2J/spinham/h_matrix.py,sha256=MfHIz6RViKkEB3Mu-WcwNx5uk7A5sjAlbqVG9wYA4xk,2784
|
56
58
|
TB2J/spinham/hamiltonian.py,sha256=OfsjlGIgFwpXaohopZcgPamSfjm3X46_zc245eyTr_A,16607
|
57
59
|
TB2J/spinham/hamiltonian_terms.py,sha256=7e84tfEjvAfZltUkrSWi1sUEiW_itLKy83lxi5iBpcQ,9714
|
60
|
+
TB2J/spinham/obtain_J.py,sha256=sg8tiCRRLEN57Olb3MHIuqkDhAkmu-w87AkM00ylXtA,2401
|
58
61
|
TB2J/spinham/plot.py,sha256=tLLNqFAATVrP1kmSVLPKzn686i-CUyqu4qgOcs-okHI,6599
|
59
62
|
TB2J/spinham/qsolver.py,sha256=Sr9I3aGfVNYn5wzwPx1QonHe6ZZUXBAujWRa7nTA5u4,4986
|
60
63
|
TB2J/spinham/spin_api.py,sha256=oN3AKg1WQl0YzR4f5ealcJOaVoAy8d7HodIwrbXvQeY,2219
|
@@ -63,17 +66,18 @@ TB2J/spinham/supercell.py,sha256=y17uUC6r3gQb278FhxIW4CABihfLTvKFj6flyXrCPR8,122
|
|
63
66
|
TB2J/wannier/__init__.py,sha256=7ojCbM84PYv1X1Tbo4NHI-d3gWmQsZB_xiYqbfxVV1E,80
|
64
67
|
TB2J/wannier/w90_parser.py,sha256=dbd63LuKyv2DVUzqRINGsbDzEsOxsQyE8_Ear_LQIRg,4620
|
65
68
|
TB2J/wannier/w90_tb_parser.py,sha256=qt8pnuprmPp9iIAYwPkPbmEzk6ZPgMq2xognoQp7vwc,4610
|
66
|
-
TB2J-0.
|
67
|
-
TB2J-0.
|
68
|
-
TB2J-0.
|
69
|
-
TB2J-0.
|
70
|
-
TB2J-0.
|
71
|
-
TB2J-0.
|
72
|
-
TB2J-0.
|
73
|
-
TB2J-0.
|
74
|
-
TB2J-0.
|
75
|
-
TB2J-0.
|
76
|
-
TB2J-0.
|
77
|
-
TB2J-0.
|
78
|
-
TB2J-0.
|
79
|
-
TB2J-0.
|
69
|
+
TB2J-0.9.0.data/scripts/TB2J_downfold.py,sha256=F9oImXFysejCMP7eIBjbCX2jdHFOCvDW5beF1sG-UM8,1854
|
70
|
+
TB2J-0.9.0.data/scripts/TB2J_eigen.py,sha256=Qs9v2hnMm2Tpfoa4h53muUKty2dZjwx8948MBoQooNg,1128
|
71
|
+
TB2J-0.9.0.data/scripts/TB2J_magnon.py,sha256=q7UwAmorRcFNk4tfE7gl_ny05l6p7pbD9Wm_LkIpKEw,3101
|
72
|
+
TB2J-0.9.0.data/scripts/TB2J_magnon_dos.py,sha256=TMXQvD2dIbO5FZ4tUMmxJgCgH2O2hDAPUNfEKO4z-x4,110
|
73
|
+
TB2J-0.9.0.data/scripts/TB2J_merge.py,sha256=y834SF4rIRn1L1ptkhczvavQpC-8Px6DTmDOOSaq_DE,1854
|
74
|
+
TB2J-0.9.0.data/scripts/TB2J_rotate.py,sha256=zgiDFuYZNmzKK0rwDmTaYD2OpRlmKA_VGeBx83w2Xwc,873
|
75
|
+
TB2J-0.9.0.data/scripts/TB2J_rotateDM.py,sha256=kCvF7gotuqAX1VnJ06cwfVm7RrhrdtiV5v7d9P2Pn_E,567
|
76
|
+
TB2J-0.9.0.data/scripts/abacus2J.py,sha256=M4B07lvTCDczTPTqvnDh_PERzCARAd09TLKv4aIdSQM,4408
|
77
|
+
TB2J-0.9.0.data/scripts/siesta2J.py,sha256=hBzS7ZgoHM3oXlTCQd-xVA07Ks2FiIwyRpQWUFITRPE,4303
|
78
|
+
TB2J-0.9.0.data/scripts/wann2J.py,sha256=2t2hWwyELskYCwkGDziCgiIAnfr6odLLJ6cQBJ2RQwQ,5714
|
79
|
+
TB2J-0.9.0.dist-info/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
|
80
|
+
TB2J-0.9.0.dist-info/METADATA,sha256=4ooTIlcMyCl-axTuL5PI9qfK4i7k5zFEoHFl-CiYXOc,1462
|
81
|
+
TB2J-0.9.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
82
|
+
TB2J-0.9.0.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
|
83
|
+
TB2J-0.9.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|