TB2J 0.9.9.8__py3-none-any.whl → 0.9.9.10__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/io_exchange/io_exchange.py +57 -25
- TB2J/io_exchange/io_vampire.py +9 -3
- TB2J/magnon/__init__.py +2 -2
- TB2J/magnon/magnon3.py +546 -56
- TB2J/magnon/magnon_band.py +180 -0
- TB2J/magnon/plot.py +60 -21
- TB2J/mathutils/auto_kpath.py +154 -0
- tb2j-0.9.9.10.data/scripts/TB2J_plot_magnon_bands.py +7 -0
- {tb2j-0.9.9.8.dist-info → tb2j-0.9.9.10.dist-info}/METADATA +3 -1
- {tb2j-0.9.9.8.dist-info → tb2j-0.9.9.10.dist-info}/RECORD +26 -23
- {tb2j-0.9.9.8.data → tb2j-0.9.9.10.data}/scripts/TB2J_downfold.py +0 -0
- {tb2j-0.9.9.8.data → tb2j-0.9.9.10.data}/scripts/TB2J_eigen.py +0 -0
- {tb2j-0.9.9.8.data → tb2j-0.9.9.10.data}/scripts/TB2J_magnon.py +0 -0
- {tb2j-0.9.9.8.data → tb2j-0.9.9.10.data}/scripts/TB2J_magnon2.py +0 -0
- {tb2j-0.9.9.8.data → tb2j-0.9.9.10.data}/scripts/TB2J_magnon_dos.py +0 -0
- {tb2j-0.9.9.8.data → tb2j-0.9.9.10.data}/scripts/TB2J_merge.py +0 -0
- {tb2j-0.9.9.8.data → tb2j-0.9.9.10.data}/scripts/TB2J_rotate.py +0 -0
- {tb2j-0.9.9.8.data → tb2j-0.9.9.10.data}/scripts/TB2J_rotateDM.py +0 -0
- {tb2j-0.9.9.8.data → tb2j-0.9.9.10.data}/scripts/abacus2J.py +0 -0
- {tb2j-0.9.9.8.data → tb2j-0.9.9.10.data}/scripts/siesta2J.py +0 -0
- {tb2j-0.9.9.8.data → tb2j-0.9.9.10.data}/scripts/wann2J.py +0 -0
- {tb2j-0.9.9.8.dist-info → tb2j-0.9.9.10.dist-info}/WHEEL +0 -0
- {tb2j-0.9.9.8.dist-info → tb2j-0.9.9.10.dist-info}/entry_points.txt +0 -0
- {tb2j-0.9.9.8.dist-info → tb2j-0.9.9.10.dist-info}/licenses/LICENSE +0 -0
- {tb2j-0.9.9.8.dist-info → tb2j-0.9.9.10.dist-info}/top_level.txt +0 -0
TB2J/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.9.9.
|
1
|
+
__version__ = "0.9.9.9"
|
TB2J/io_exchange/io_exchange.py
CHANGED
@@ -190,6 +190,7 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
|
|
190
190
|
def _build_Rlist(self):
|
191
191
|
Rset = set()
|
192
192
|
ispin_set = set()
|
193
|
+
Rset.add((0, 0, 0)) # always add the zero vector
|
193
194
|
for R, i, j in self.exchange_Jdict:
|
194
195
|
Rset.add(R)
|
195
196
|
ispin_set.add(i)
|
@@ -236,6 +237,23 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
|
|
236
237
|
i = self.i_spin(i)
|
237
238
|
return self.charges[self.iatom(i)]
|
238
239
|
|
240
|
+
def get_magnetic_moments(self):
|
241
|
+
"""Get magnetic moments for magnetic atoms only.
|
242
|
+
|
243
|
+
Returns
|
244
|
+
-------
|
245
|
+
np.ndarray
|
246
|
+
Array of shape (n_magnetic_atoms, 3) containing the magnetic moments.
|
247
|
+
For collinear calculations, only the z component is meaningful.
|
248
|
+
"""
|
249
|
+
mag_atoms = [i for i, idx in enumerate(self.index_spin) if idx >= 0]
|
250
|
+
if self.spinat.ndim == 1: # Handle collinear case with only z-component
|
251
|
+
moments = np.zeros((len(mag_atoms), 3))
|
252
|
+
moments[:, 2] = self.spinat[mag_atoms]
|
253
|
+
return moments
|
254
|
+
else: # Full 3D magnetic moments
|
255
|
+
return self.spinat[mag_atoms]
|
256
|
+
|
239
257
|
def get_spin_iatom(self, iatom):
|
240
258
|
return self.spinat[iatom]
|
241
259
|
|
@@ -263,7 +281,7 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
|
|
263
281
|
j,
|
264
282
|
)
|
265
283
|
if self.exchange_Jdict is not None and key in self.exchange_Jdict:
|
266
|
-
return self.exchange_Jdict[key]
|
284
|
+
return np.real(self.exchange_Jdict[key])
|
267
285
|
else:
|
268
286
|
return default
|
269
287
|
|
@@ -276,7 +294,7 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
|
|
276
294
|
j,
|
277
295
|
)
|
278
296
|
if self.exchange_Jdict is not None and key in self.exchange_Jdict:
|
279
|
-
return self.exchange_Jdict[key]
|
297
|
+
return np.real(self.exchange_Jdict[key])
|
280
298
|
else:
|
281
299
|
return default
|
282
300
|
|
@@ -289,7 +307,7 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
|
|
289
307
|
j,
|
290
308
|
)
|
291
309
|
if self.dmi_ddict is not None and key in self.dmi_ddict:
|
292
|
-
return self.dmi_ddict[(tuple(R), i, j)]
|
310
|
+
return np.real(self.dmi_ddict[(tuple(R), i, j)])
|
293
311
|
else:
|
294
312
|
return default
|
295
313
|
|
@@ -308,11 +326,11 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
|
|
308
326
|
j,
|
309
327
|
)
|
310
328
|
if self.Jani_dict is not None and key in self.Jani_dict:
|
311
|
-
return self.Jani_dict[(tuple(R), i, j)]
|
329
|
+
return np.real(self.Jani_dict[(tuple(R), i, j)])
|
312
330
|
else:
|
313
331
|
return default
|
314
332
|
|
315
|
-
def get_J_tensor(self, i, j, R,
|
333
|
+
def get_J_tensor(self, i, j, R, Jiso=True, Jani=False, DMI=False):
|
316
334
|
"""
|
317
335
|
Return the full exchange tensor for atom i and j, and cell R.
|
318
336
|
param i : spin index i
|
@@ -321,21 +339,26 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
|
|
321
339
|
"""
|
322
340
|
i = self.i_spin(i)
|
323
341
|
j = self.i_spin(j)
|
324
|
-
|
325
|
-
|
326
|
-
if
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
342
|
+
Jtensor = combine_J_tensor(
|
343
|
+
Jiso=self.get_J(i, j, R) if Jiso else None,
|
344
|
+
D=self.get_DMI(i, j, R) if DMI else None,
|
345
|
+
Jani=self.get_Jani(i, j, R) if Jani else None,
|
346
|
+
)
|
347
|
+
# if iso_only:
|
348
|
+
# J = self.get_Jiso(i, j, R)
|
349
|
+
# if J is not None:
|
350
|
+
# Jtensor = np.eye(3) * self.get_J(i, j, R)
|
351
|
+
# else:
|
352
|
+
# Jtensor = np.eye(3) * 0
|
353
|
+
# else:
|
354
|
+
# Jtensor = combine_J_tensor(
|
355
|
+
# Jiso=self.get_J(i, j, R),
|
356
|
+
# D=self.get_DMI(i, j, R),
|
357
|
+
# Jani=self.get_Jani(i, j, R),
|
358
|
+
# )
|
336
359
|
return Jtensor
|
337
360
|
|
338
|
-
def get_full_Jtensor_for_one_R_i3j3(self, R,
|
361
|
+
def get_full_Jtensor_for_one_R_i3j3(self, R, Jiso=True, Jani=True, DMI=True):
|
339
362
|
"""
|
340
363
|
Return the full exchange tensor of all i and j for cell R.
|
341
364
|
param R (tuple of integers): cell index R
|
@@ -347,11 +370,11 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
|
|
347
370
|
for i in range(self.nspin):
|
348
371
|
for j in range(self.nspin):
|
349
372
|
Jmat[i * 3 : i * 3 + 3, j * 3 : j * 3 + 3] = self.get_J_tensor(
|
350
|
-
i, j, R,
|
373
|
+
i, j, R, Jiso=Jiso, Jani=Jani, DMI=DMI
|
351
374
|
)
|
352
375
|
return Jmat
|
353
376
|
|
354
|
-
def get_full_Jtensor_for_one_R_ij33(self, R,
|
377
|
+
def get_full_Jtensor_for_one_R_ij33(self, R, Jiso=True, Jani=True, DMI=True):
|
355
378
|
"""
|
356
379
|
Return the full exchange tensor of all i and j for cell R.
|
357
380
|
param R (tuple of integers): cell index R
|
@@ -362,27 +385,36 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
|
|
362
385
|
Jmat = np.zeros((n, n, 3, 3), dtype=float)
|
363
386
|
for i in range(self.nspin):
|
364
387
|
for j in range(self.nspin):
|
365
|
-
Jmat[i, j, :, :] = self.get_J_tensor(
|
388
|
+
Jmat[i, j, :, :] = self.get_J_tensor(
|
389
|
+
i, j, R, Jiso=Jiso, Jani=Jani, DMI=DMI
|
390
|
+
)
|
366
391
|
return Jmat
|
367
392
|
|
368
|
-
def get_full_Jtensor_for_Rlist(
|
393
|
+
def get_full_Jtensor_for_Rlist(
|
394
|
+
self, asr=False, Jiso=True, Jani=True, DMI=True, order="i3j3"
|
395
|
+
):
|
369
396
|
n = self.nspin
|
370
397
|
n3 = n * 3
|
371
398
|
nR = len(self.Rlist)
|
372
399
|
if order == "i3j3":
|
373
400
|
Jmat = np.zeros((nR, n3, n3), dtype=float)
|
374
401
|
for iR, R in enumerate(self.Rlist):
|
375
|
-
Jmat[iR] = self.get_full_Jtensor_for_one_R_i3j3(
|
402
|
+
Jmat[iR] = self.get_full_Jtensor_for_one_R_i3j3(
|
403
|
+
R, Jiso=Jiso, Jani=Jani, DMI=DMI
|
404
|
+
)
|
376
405
|
if asr:
|
377
406
|
iR0 = np.argmin(np.linalg.norm(self.Rlist, axis=1))
|
378
407
|
assert np.linalg.norm(self.Rlist[iR0]) == 0
|
379
408
|
for i in range(n3):
|
380
409
|
sum_JRi = np.sum(np.sum(Jmat, axis=0)[i])
|
381
|
-
Jmat[iR0][i, i] -= sum_JRi
|
410
|
+
Jmat[iR0][i, :, i, :] -= sum_JRi
|
382
411
|
|
383
412
|
elif order == "ij33":
|
384
413
|
Jmat = np.zeros((nR, n, n, 3, 3), dtype=float)
|
385
|
-
|
414
|
+
for iR, R in enumerate(self.Rlist):
|
415
|
+
Jmat[iR] = self.get_full_Jtensor_for_one_R_ij33(
|
416
|
+
R, Jiso=Jiso, Jani=Jani, DMI=DMI
|
417
|
+
)
|
386
418
|
if asr:
|
387
419
|
iR0 = np.argmin(np.linalg.norm(self.Rlist, axis=1))
|
388
420
|
assert np.linalg.norm(self.Rlist[iR0]) == 0
|
TB2J/io_exchange/io_vampire.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
import numpy as np
|
2
1
|
import os
|
2
|
+
|
3
|
+
import numpy as np
|
3
4
|
from ase.units import J
|
4
5
|
|
5
6
|
|
@@ -51,10 +52,15 @@ def write_vampire_unitcell_file(cls, fname):
|
|
51
52
|
R, ispin, jspin = key
|
52
53
|
Jtensor = cls.get_J_tensor(ispin, jspin, R)
|
53
54
|
counter += 1 # starts at 0
|
54
|
-
myfile.write(
|
55
|
+
myfile.write(
|
56
|
+
f"{counter:5d} {ispin:3d} {jspin:3d} {R[0]:3d} {R[1]:3d} {R[2]:3d} "
|
57
|
+
)
|
55
58
|
for i in range(3):
|
56
59
|
for j in range(3):
|
57
|
-
|
60
|
+
val = np.real(Jtensor[i, j] * 2.0 / J)
|
61
|
+
if np.abs(val) < 1e-30:
|
62
|
+
val = 0.0
|
63
|
+
myfile.write(f"{val:<012.5e} ")
|
58
64
|
myfile.write("\n")
|
59
65
|
|
60
66
|
|
TB2J/magnon/__init__.py
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
from .io_exchange2 import ExchangeIO, plot_tb2j_magnon_bands
|
1
|
+
# from .io_exchange2 import ExchangeIO, plot_tb2j_magnon_bands
|
2
2
|
|
3
|
-
__all__ = ["ExchangeIO", "plot_tb2j_magnon_bands"]
|
3
|
+
# __all__ = ["ExchangeIO", "plot_tb2j_magnon_bands"]
|