TB2J 0.9.9.10__py3-none-any.whl → 0.9.9.13__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/Jtensor.py +5 -6
- TB2J/MAEGreen.py +8 -0
- TB2J/__init__.py +1 -1
- TB2J/exchange.py +1 -1
- TB2J/interfaces/abacus/stru_api.py +3 -1
- TB2J/interfaces/siesta_interface.py +2 -1
- TB2J/io_exchange/io_exchange.py +17 -7
- TB2J/io_merge.py +15 -1
- TB2J/magnon/magnon3.py +36 -16
- TB2J/magnon/magnon_band.py +38 -33
- TB2J/magnon/magnon_math.py +1 -0
- TB2J/magnon/plot.py +3 -3
- TB2J/mathutils/auto_kpath.py +4 -7
- {tb2j-0.9.9.10.dist-info → tb2j-0.9.9.13.dist-info}/METADATA +3 -2
- {tb2j-0.9.9.10.dist-info → tb2j-0.9.9.13.dist-info}/RECORD +31 -31
- {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_downfold.py +0 -0
- {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_eigen.py +0 -0
- {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_magnon.py +0 -0
- {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_magnon2.py +0 -0
- {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_magnon_dos.py +0 -0
- {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_merge.py +0 -0
- {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_plot_magnon_bands.py +0 -0
- {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_rotate.py +0 -0
- {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_rotateDM.py +0 -0
- {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/abacus2J.py +0 -0
- {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/siesta2J.py +0 -0
- {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/wann2J.py +0 -0
- {tb2j-0.9.9.10.dist-info → tb2j-0.9.9.13.dist-info}/WHEEL +0 -0
- {tb2j-0.9.9.10.dist-info → tb2j-0.9.9.13.dist-info}/entry_points.txt +0 -0
- {tb2j-0.9.9.10.dist-info → tb2j-0.9.9.13.dist-info}/licenses/LICENSE +0 -0
- {tb2j-0.9.9.10.dist-info → tb2j-0.9.9.13.dist-info}/top_level.txt +0 -0
TB2J/Jtensor.py
CHANGED
@@ -71,22 +71,21 @@ def decompose_J_tensor(Jtensor):
|
|
71
71
|
return Jiso, D, Jani
|
72
72
|
|
73
73
|
|
74
|
-
def combine_J_tensor(Jiso=
|
74
|
+
def combine_J_tensor(Jiso=None, D=None, Jani=None, dtype=float):
|
75
75
|
"""Combine isotropic exchange, DMI, and anisotropic exchange into tensor form
|
76
|
-
|
77
76
|
:param Jiso: scalar, isotropice exchange
|
78
77
|
:param D: vector, DMI.
|
79
78
|
:param Jani: 3x3 matrix anisotropic exchange
|
80
79
|
:returns: A 3x3 matrix, the exchange paraemter in tensor form.
|
81
80
|
"""
|
82
|
-
Jtensor = np.zeros((3, 3), dtype=
|
81
|
+
Jtensor = np.zeros((3, 3), dtype=dtype)
|
83
82
|
if Jiso is not None:
|
84
|
-
Jtensor += np.eye(3, dtype=
|
83
|
+
Jtensor += np.eye(3, dtype=dtype) * Jiso
|
85
84
|
if Jani is not None:
|
86
|
-
Jtensor += np.array(Jani, dtype=
|
85
|
+
Jtensor += np.array(Jani, dtype=dtype)
|
87
86
|
if D is not None:
|
88
87
|
Jtensor += np.array(
|
89
|
-
[[0, D[2], -D[1]], [-D[2], 0, D[0]], [D[1], -D[0], 0]], dtype=
|
88
|
+
[[0, D[2], -D[1]], [-D[2], 0, D[0]], [D[1], -D[0], 0]], dtype=dtype
|
90
89
|
)
|
91
90
|
return Jtensor
|
92
91
|
|
TB2J/MAEGreen.py
CHANGED
@@ -43,6 +43,8 @@ class MAEGreen(ExchangeNCL):
|
|
43
43
|
self.set_angles_random()
|
44
44
|
elif angles == "miller":
|
45
45
|
self.set_angles_miller()
|
46
|
+
elif angles == "ztox":
|
47
|
+
self.set_angels_ztox()
|
46
48
|
else:
|
47
49
|
self.thetas = angles[0]
|
48
50
|
self.phis = angles[1]
|
@@ -92,6 +94,12 @@ class MAEGreen(ExchangeNCL):
|
|
92
94
|
self.thetas.append(i * np.pi / 180)
|
93
95
|
self.phis.append(j * np.pi / 180)
|
94
96
|
|
97
|
+
def set_angels_ztox(self, n=16):
|
98
|
+
"""Set angles for a scan from z to x"""
|
99
|
+
self.thetas = np.linspace(0, np.pi, n)
|
100
|
+
self.phis = np.zeros(n)
|
101
|
+
|
102
|
+
|
95
103
|
def set_angles_random(self, n=16):
|
96
104
|
# n random pairs of theta, phi
|
97
105
|
self.thetas = np.random.random(n) * np.pi
|
TB2J/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.9.9.
|
1
|
+
__version__ = "0.9.9.12"
|
TB2J/exchange.py
CHANGED
@@ -48,7 +48,7 @@ class Exchange(ExchangeParams):
|
|
48
48
|
self.emin = self.G.find_energy_ingap(rbound=self.efermi - 15.0) - self.efermi
|
49
49
|
# self.emin = self.G.find_energy_ingap(rbound=self.efermi - 15.0) - self.efermi
|
50
50
|
# self.emin = -42.0
|
51
|
-
print(f"A gap is found at {self.emin}, set emin to it.")
|
51
|
+
#print(f"A gap is found at {self.emin}, set emin to it.")
|
52
52
|
|
53
53
|
def set_tbmodels(self, tbmodels):
|
54
54
|
pass
|
@@ -7,11 +7,13 @@
|
|
7
7
|
Modified on Wed Aug 01 11:44:51 2022
|
8
8
|
@author: Ji Yu-yang
|
9
9
|
"""
|
10
|
+
import warnings
|
11
|
+
warnings.simplefilter(action='ignore', category=FutureWarning)
|
12
|
+
|
10
13
|
|
11
14
|
import os
|
12
15
|
import re
|
13
16
|
import shutil
|
14
|
-
import warnings
|
15
17
|
from pathlib import Path
|
16
18
|
|
17
19
|
import numpy as np
|
@@ -157,7 +157,7 @@ Warning: The DMI component parallel to the spin orientation, the Jani which has
|
|
157
157
|
atoms=model.atoms,
|
158
158
|
basis=basis,
|
159
159
|
efermi=None,
|
160
|
-
angles="
|
160
|
+
angles="xyz",
|
161
161
|
# magnetic_elements=magnetic_elements,
|
162
162
|
# include_orbs=include_orbs,
|
163
163
|
**exargs,
|
@@ -165,6 +165,7 @@ Warning: The DMI component parallel to the spin orientation, the Jani which has
|
|
165
165
|
# thetas = [0, np.pi / 2, np.pi, 3 * np.pi / 2]
|
166
166
|
# phis = [0, 0, 0, 0]
|
167
167
|
# MAE.set_angles(thetas=thetas, phis=phis)
|
168
|
+
#MAE.set_xyz_angles()
|
168
169
|
MAE.run(output_path=f"{output_path}_anisotropy", with_eigen=False)
|
169
170
|
# print(
|
170
171
|
# f"MAE calculation finished. The results are in {output_path} directory."
|
TB2J/io_exchange/io_exchange.py
CHANGED
@@ -54,6 +54,7 @@ class SpinIO(object):
|
|
54
54
|
gyro_ratio=None,
|
55
55
|
write_experimental=True,
|
56
56
|
description=None,
|
57
|
+
standardize_Jani=False,
|
57
58
|
):
|
58
59
|
"""
|
59
60
|
:param atoms: Ase atoms structure.
|
@@ -307,7 +308,7 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
|
|
307
308
|
j,
|
308
309
|
)
|
309
310
|
if self.dmi_ddict is not None and key in self.dmi_ddict:
|
310
|
-
return
|
311
|
+
return self.dmi_ddict[(tuple(R), i, j)]
|
311
312
|
else:
|
312
313
|
return default
|
313
314
|
|
@@ -326,7 +327,7 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
|
|
326
327
|
j,
|
327
328
|
)
|
328
329
|
if self.Jani_dict is not None and key in self.Jani_dict:
|
329
|
-
return
|
330
|
+
return self.Jani_dict[(tuple(R), i, j)]
|
330
331
|
else:
|
331
332
|
return default
|
332
333
|
|
@@ -339,11 +340,20 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
|
|
339
340
|
"""
|
340
341
|
i = self.i_spin(i)
|
341
342
|
j = self.i_spin(j)
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
343
|
+
J=D=Ja = None
|
344
|
+
if Jiso:
|
345
|
+
J= self.get_Jiso(i, j, R)
|
346
|
+
if DMI:
|
347
|
+
D = self.get_DMI(i, j, R)
|
348
|
+
if D is not None:
|
349
|
+
D*=1
|
350
|
+
if Jani:
|
351
|
+
Ja = self.get_Jani(i, j, R)
|
352
|
+
if Ja is not None:
|
353
|
+
Ja*=1
|
354
|
+
Jtensor = combine_J_tensor(Jiso=J, D=D, Jani=Ja)
|
355
|
+
|
356
|
+
|
347
357
|
# if iso_only:
|
348
358
|
# J = self.get_Jiso(i, j, R)
|
349
359
|
# if J is not None:
|
TB2J/io_merge.py
CHANGED
@@ -92,7 +92,6 @@ class Merger():
|
|
92
92
|
self._set_projv()
|
93
93
|
|
94
94
|
def _set_projv(self):
|
95
|
-
|
96
95
|
cell = self.main_dat.atoms.cell.array
|
97
96
|
rotated_cells = np.stack(
|
98
97
|
[obj.atoms.cell.array for obj in self.dat], axis=0
|
@@ -175,11 +174,26 @@ class Merger():
|
|
175
174
|
dmi_ddict[key] = newDMI
|
176
175
|
self.main_dat.dmi_ddict = dmi_ddict
|
177
176
|
|
177
|
+
def standardize(self):
|
178
|
+
# make sure that the Jani has the trace of zero
|
179
|
+
Jdict=self.main_dat.exchange_Jdict
|
180
|
+
Jani_dict=self.main_dat.Jani_dict
|
181
|
+
for key in self.main_dat.Jani_dict.keys():
|
182
|
+
Jani = self.main_dat.Jani_dict[key]
|
183
|
+
shift = np.trace(Jani)/3.0
|
184
|
+
Jani_dict[key] -= shift * np.eye(3)
|
185
|
+
Jdict[key] += shift
|
186
|
+
self.main_dat.Jani_dict = Jani_dict
|
187
|
+
self.main_dat.exchange_Jdict = Jdict
|
188
|
+
|
189
|
+
|
178
190
|
def merge(*paths, main_path=None, save=True, write_path='TB2J_results'):
|
179
191
|
m = Merger(*paths, main_path=main_path)
|
180
192
|
m.merge_Jiso()
|
181
193
|
m.merge_DMI()
|
182
194
|
m.merge_Jani()
|
195
|
+
m.standardize()
|
196
|
+
|
183
197
|
if save:
|
184
198
|
m.main_dat.write_all(path=write_path)
|
185
199
|
return m.dat
|
TB2J/magnon/magnon3.py
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
import json
|
2
1
|
from dataclasses import asdict, dataclass
|
3
2
|
from pathlib import Path
|
4
3
|
from typing import List, Optional, Tuple, Union
|
@@ -9,9 +8,9 @@ import tomli_w
|
|
9
8
|
from scipy.spatial.transform import Rotation
|
10
9
|
|
11
10
|
from TB2J.io_exchange import SpinIO
|
11
|
+
from TB2J.magnon.magnon_band import MagnonBand
|
12
12
|
from TB2J.magnon.magnon_math import get_rotation_arrays
|
13
13
|
from TB2J.mathutils.auto_kpath import auto_kpath
|
14
|
-
from TB2J.magnon.magnon_band import MagnonBand
|
15
14
|
|
16
15
|
|
17
16
|
@dataclass
|
@@ -28,6 +27,7 @@ class MagnonParameters:
|
|
28
27
|
Q: Optional[List[float]] = None
|
29
28
|
uz_file: Optional[str] = None
|
30
29
|
n: Optional[List[float]] = None
|
30
|
+
show: bool = False
|
31
31
|
|
32
32
|
@classmethod
|
33
33
|
def from_toml(cls, filename: str) -> "MagnonParameters":
|
@@ -162,10 +162,10 @@ class Magnon:
|
|
162
162
|
phase = 2 * np.pi * R @ qpt
|
163
163
|
Jq[iqpt] += np.exp(1j * phase) * JRprime[iR]
|
164
164
|
|
165
|
-
Jq_copy = Jq.copy()
|
166
|
-
Jq.swapaxes(-1, -2) # swap xyz
|
167
|
-
Jq.swapaxes(-3, -4) # swap ij
|
168
|
-
Jq = (Jq.conj() + Jq_copy) / 2.0
|
165
|
+
#Jq_copy = Jq.copy()
|
166
|
+
#Jq.swapaxes(-1, -2) # swap xyz
|
167
|
+
#Jq.swapaxes(-3, -4) # swap ij
|
168
|
+
#Jq = (Jq.conj() + Jq_copy) / 2.0
|
169
169
|
return Jq
|
170
170
|
|
171
171
|
def Hq(self, kpoints):
|
@@ -187,6 +187,7 @@ class Magnon:
|
|
187
187
|
magmoms = self.magmom.copy()
|
188
188
|
magmoms /= np.linalg.norm(magmoms, axis=-1)[:, None]
|
189
189
|
|
190
|
+
|
190
191
|
U, V = get_rotation_arrays(magmoms, u=self._uz)
|
191
192
|
|
192
193
|
J0 = -self.Jq(np.zeros((1, 3)))[0]
|
@@ -283,7 +284,9 @@ class Magnon:
|
|
283
284
|
if kpoints.size == 0:
|
284
285
|
if path is None:
|
285
286
|
# Use auto_kpath to generate path automatically
|
286
|
-
xlist, kptlist, Xs, knames, spk = auto_kpath(
|
287
|
+
xlist, kptlist, Xs, knames, spk = auto_kpath(
|
288
|
+
self.cell, None, npoints=npoints
|
289
|
+
)
|
287
290
|
kpoints = np.concatenate(kptlist)
|
288
291
|
# Create labels from special points
|
289
292
|
labels = []
|
@@ -340,13 +343,17 @@ class Magnon:
|
|
340
343
|
"""
|
341
344
|
filename = kwargs.pop("filename", None)
|
342
345
|
kpath_labels, bands, xlist = self.get_magnon_bands(**kwargs)
|
343
|
-
|
346
|
+
|
344
347
|
# Get k-points and special points
|
345
|
-
if
|
346
|
-
_, kptlist, _, _, spk = auto_kpath(
|
348
|
+
if "path" in kwargs and kwargs["path"] is None:
|
349
|
+
_, kptlist, _, _, spk = auto_kpath(
|
350
|
+
self.cell, None, npoints=kwargs.get("npoints", 300)
|
351
|
+
)
|
347
352
|
kpoints = np.concatenate(kptlist)
|
348
353
|
else:
|
349
|
-
bandpath = self.cell.bandpath(
|
354
|
+
bandpath = self.cell.bandpath(
|
355
|
+
path=kwargs.get("path", "GXMG"), npoints=kwargs.get("npoints", 300)
|
356
|
+
)
|
350
357
|
kpoints = bandpath.kpts
|
351
358
|
spk = bandpath.special_points.copy()
|
352
359
|
spk[r"$\Gamma$"] = spk.pop("G", np.zeros(3))
|
@@ -358,7 +365,7 @@ class Magnon:
|
|
358
365
|
special_points=spk,
|
359
366
|
xcoords=xlist,
|
360
367
|
)
|
361
|
-
|
368
|
+
|
362
369
|
return bands_plot.plot(filename=filename, **kwargs)
|
363
370
|
|
364
371
|
@classmethod
|
@@ -380,7 +387,7 @@ class Magnon:
|
|
380
387
|
"""
|
381
388
|
# Get magnetic moments for magnetic atoms
|
382
389
|
magmoms = exc.get_magnetic_moments()
|
383
|
-
nspin = len(magmoms) # Number of magnetic atoms
|
390
|
+
# nspin = len(magmoms) # Number of magnetic atoms
|
384
391
|
|
385
392
|
cell = exc.atoms.get_cell()
|
386
393
|
pbc = exc.atoms.get_pbc()
|
@@ -544,12 +551,14 @@ if __name__ == "__main__":
|
|
544
551
|
)
|
545
552
|
'''
|
546
553
|
|
547
|
-
with open(script_name,
|
554
|
+
with open(script_name, "w") as f:
|
548
555
|
f.write(script)
|
549
|
-
|
556
|
+
|
550
557
|
import os
|
558
|
+
|
551
559
|
os.chmod(script_name, 0o755) # Make executable
|
552
560
|
|
561
|
+
|
553
562
|
def save_bands_data(
|
554
563
|
kpoints: np.ndarray,
|
555
564
|
energies: np.ndarray,
|
@@ -587,7 +596,7 @@ def save_bands_data(
|
|
587
596
|
bands.save(filename)
|
588
597
|
|
589
598
|
# Create plotting script
|
590
|
-
base_name = filename.rsplit(
|
599
|
+
base_name = filename.rsplit(".", 1)[0]
|
591
600
|
create_plot_script(base_name)
|
592
601
|
|
593
602
|
print(f"Band structure data saved to {filename}")
|
@@ -628,6 +637,8 @@ def plot_magnon_bands_from_TB2J(
|
|
628
637
|
If not provided, default [0, 0, 1] will be used for all spins
|
629
638
|
n : array-like, optional
|
630
639
|
Normal vector for rotation [nx, ny, nz], default is [0, 0, 1]
|
640
|
+
show: bool, optional
|
641
|
+
whether to show figure.
|
631
642
|
|
632
643
|
Returns
|
633
644
|
-------
|
@@ -789,6 +800,14 @@ def main():
|
|
789
800
|
help="Normal vector for rotation [nx, ny, nz] (default: [0, 0, 1])",
|
790
801
|
)
|
791
802
|
|
803
|
+
parser.add_argument(
|
804
|
+
"--show",
|
805
|
+
action="store_true",
|
806
|
+
default=False,
|
807
|
+
help="show figure on screen.",
|
808
|
+
)
|
809
|
+
|
810
|
+
|
792
811
|
args = parser.parse_args()
|
793
812
|
|
794
813
|
# Handle configuration file options
|
@@ -815,6 +834,7 @@ def main():
|
|
815
834
|
Q=args.Q if args.Q is not None else None,
|
816
835
|
uz_file=args.uz_file,
|
817
836
|
n=args.n if args.n is not None else None,
|
837
|
+
show=args.show
|
818
838
|
)
|
819
839
|
|
820
840
|
plot_magnon_bands_from_TB2J(params)
|
TB2J/magnon/magnon_band.py
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
"""Module for handling magnon band structure data and plotting."""
|
2
|
+
|
3
|
+
import json
|
2
4
|
from dataclasses import dataclass
|
3
|
-
from pathlib import Path
|
4
5
|
from typing import List, Optional, Tuple, Union
|
5
|
-
import json
|
6
6
|
|
7
|
-
import numpy as np
|
8
7
|
import matplotlib.pyplot as plt
|
8
|
+
import numpy as np
|
9
|
+
|
9
10
|
|
10
11
|
@dataclass
|
11
12
|
class MagnonBand:
|
@@ -35,11 +36,11 @@ class MagnonBand:
|
|
35
36
|
"""Convert input arrays to numpy arrays and set default x-coordinates."""
|
36
37
|
self.energies = np.array(self.energies)
|
37
38
|
self.kpoints = np.array(self.kpoints)
|
38
|
-
|
39
|
+
|
39
40
|
if self.xcoords is None:
|
40
41
|
self.xcoords = np.arange(len(self.kpoints))
|
41
42
|
|
42
|
-
def plot(self, ax=None, filename=None, show=False,
|
43
|
+
def plot(self, ax=None, filename=None, show=False, shift=0.0,**kwargs):
|
43
44
|
"""Plot the magnon band structure.
|
44
45
|
|
45
46
|
Parameters
|
@@ -65,20 +66,20 @@ class MagnonBand:
|
|
65
66
|
fig, ax = plt.subplots(constrained_layout=True)
|
66
67
|
|
67
68
|
# Plot settings
|
68
|
-
linewidth = kwargs.pop(
|
69
|
-
color = kwargs.pop(
|
70
|
-
linestyle = kwargs.pop(
|
69
|
+
linewidth = kwargs.pop("linewidth", 1.5)
|
70
|
+
color = kwargs.pop("color", "blue")
|
71
|
+
linestyle = kwargs.pop("linestyle", "-")
|
71
72
|
|
72
73
|
# Plot bands
|
73
74
|
if isinstance(self.xcoords, list): # Segmented path
|
74
75
|
start_idx = 0
|
75
76
|
for x in self.xcoords:
|
76
77
|
nbands = x.shape[0]
|
77
|
-
segment_bands = self.energies[start_idx:start_idx + nbands].T
|
78
|
+
segment_bands = self.energies[start_idx : start_idx + nbands].T
|
78
79
|
for band in segment_bands:
|
79
80
|
ax.plot(
|
80
81
|
x,
|
81
|
-
band[start_idx:start_idx + nbands],
|
82
|
+
band[start_idx : start_idx + nbands]+shift,
|
82
83
|
linewidth=linewidth,
|
83
84
|
color=color,
|
84
85
|
linestyle=linestyle,
|
@@ -90,7 +91,7 @@ class MagnonBand:
|
|
90
91
|
for band in self.energies.T:
|
91
92
|
ax.plot(
|
92
93
|
self.xcoords,
|
93
|
-
band,
|
94
|
+
band+shift,
|
94
95
|
linewidth=linewidth,
|
95
96
|
color=color,
|
96
97
|
linestyle=linestyle,
|
@@ -113,14 +114,14 @@ class MagnonBand:
|
|
113
114
|
x=kpoint_pos,
|
114
115
|
ymin=ymin,
|
115
116
|
ymax=ymax,
|
116
|
-
color=
|
117
|
+
color="black",
|
117
118
|
linewidth=linewidth / 5,
|
118
119
|
)
|
119
120
|
|
120
|
-
ax.set_ylabel(
|
121
|
+
ax.set_ylabel("Energy (meV)")
|
121
122
|
|
122
123
|
if filename is not None:
|
123
|
-
plt.savefig(filename, dpi=300, bbox_inches=
|
124
|
+
plt.savefig(filename, dpi=300, bbox_inches="tight")
|
124
125
|
if show:
|
125
126
|
plt.show()
|
126
127
|
|
@@ -134,24 +135,26 @@ class MagnonBand:
|
|
134
135
|
filename : str
|
135
136
|
Output filename (will append .json if needed)
|
136
137
|
"""
|
137
|
-
if not filename.endswith(
|
138
|
-
filename = filename +
|
138
|
+
if not filename.endswith(".json"):
|
139
|
+
filename = filename + ".json"
|
139
140
|
|
140
141
|
data = {
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
142
|
+
"kpoints": self.kpoints.tolist(),
|
143
|
+
"energies": self.energies.tolist(),
|
144
|
+
"kpath_labels": [(int(i), str(l)) for i, l in self.kpath_labels],
|
145
|
+
"special_points": {k: v.tolist() for k, v in self.special_points.items()},
|
146
|
+
"xcoords": self.xcoords.tolist()
|
147
|
+
if isinstance(self.xcoords, np.ndarray)
|
148
|
+
else [x.tolist() for x in self.xcoords]
|
149
|
+
if self.xcoords is not None
|
150
|
+
else None,
|
148
151
|
}
|
149
152
|
|
150
|
-
with open(filename,
|
153
|
+
with open(filename, "w") as f:
|
151
154
|
json.dump(data, f, indent=2)
|
152
155
|
|
153
156
|
@classmethod
|
154
|
-
def load(cls, filename: str) ->
|
157
|
+
def load(cls, filename: str) -> "MagnonBand":
|
155
158
|
"""Load band structure from a JSON file.
|
156
159
|
|
157
160
|
Parameters
|
@@ -168,13 +171,15 @@ class MagnonBand:
|
|
168
171
|
data = json.load(f)
|
169
172
|
|
170
173
|
# Convert lists back to numpy arrays
|
171
|
-
data[
|
172
|
-
data[
|
173
|
-
if data[
|
174
|
-
if isinstance(data[
|
175
|
-
data[
|
174
|
+
data["kpoints"] = np.array(data["kpoints"])
|
175
|
+
data["energies"] = np.array(data["energies"])
|
176
|
+
if data["xcoords"] is not None:
|
177
|
+
if isinstance(data["xcoords"][0], list): # Segmented path
|
178
|
+
data["xcoords"] = [np.array(x) for x in data["xcoords"]]
|
176
179
|
else: # Continuous path
|
177
|
-
data[
|
178
|
-
data[
|
180
|
+
data["xcoords"] = np.array(data["xcoords"])
|
181
|
+
data["special_points"] = {
|
182
|
+
k: np.array(v) for k, v in data["special_points"].items()
|
183
|
+
}
|
179
184
|
|
180
|
-
return cls(**data)
|
185
|
+
return cls(**data)
|
TB2J/magnon/magnon_math.py
CHANGED
@@ -32,6 +32,7 @@ def get_rotation_arrays(magmoms, u=uz):
|
|
32
32
|
v = magmoms
|
33
33
|
n = np.cross(u, v)
|
34
34
|
n /= np.linalg.norm(n, axis=-1).reshape(dim, 1)
|
35
|
+
#z = u #np.repeat(u, dim, axis=0)
|
35
36
|
z = np.repeat(u, dim, axis=0)
|
36
37
|
A = np.stack([z, np.cross(n, z), n], axis=1)
|
37
38
|
B = np.stack([v, np.cross(n, v), n], axis=1)
|
TB2J/magnon/plot.py
CHANGED
@@ -8,7 +8,7 @@ class BandsPlot:
|
|
8
8
|
|
9
9
|
def __init__(self, bands, kpath, xlist=None, **kwargs):
|
10
10
|
"""Initialize BandsPlot.
|
11
|
-
|
11
|
+
|
12
12
|
Parameters
|
13
13
|
----------
|
14
14
|
bands : array_like
|
@@ -53,11 +53,11 @@ class BandsPlot:
|
|
53
53
|
start_idx = 0
|
54
54
|
for x in self.xlist:
|
55
55
|
nbands = x.shape[0]
|
56
|
-
segment_bands = self.bands[start_idx:start_idx + nbands].T
|
56
|
+
segment_bands = self.bands[start_idx : start_idx + nbands].T
|
57
57
|
for band in segment_bands:
|
58
58
|
axs.plot(
|
59
59
|
x,
|
60
|
-
band[start_idx:start_idx + nbands],
|
60
|
+
band[start_idx : start_idx + nbands],
|
61
61
|
linewidth=self.linewidth,
|
62
62
|
color=self.color,
|
63
63
|
**self.plot_options,
|
TB2J/mathutils/auto_kpath.py
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env python
|
2
2
|
from __future__ import division
|
3
|
+
|
3
4
|
import ase
|
4
5
|
import matplotlib.pyplot as plt
|
5
6
|
import numpy as np
|
6
|
-
from ase.geometry import cell_to_cellpar, cellpar_to_cell
|
7
|
-
from ase.dft.kpoints import get_special_points, parse_path_string
|
8
7
|
from ase.cell import Cell
|
9
8
|
from ase.dft.kpoints import bandpath
|
10
9
|
|
@@ -63,13 +62,13 @@ def group_band_path(bp, eps=1e-8, shift=0.15):
|
|
63
62
|
|
64
63
|
def test_group_band_path():
|
65
64
|
"""Visualize the band path grouping functionality.
|
66
|
-
|
65
|
+
|
67
66
|
This function demonstrates how group_band_path works by:
|
68
67
|
1. Creating a simple test case (H atom with rectangular cell)
|
69
68
|
2. Generating a band path with 50 points
|
70
69
|
3. Grouping the path segments using group_band_path
|
71
70
|
4. Plotting each segment to visualize how segments are shifted
|
72
|
-
|
71
|
+
|
73
72
|
The resulting plot shows:
|
74
73
|
- Each path segment plotted separately
|
75
74
|
- Special k-points labeled on x-axis
|
@@ -88,8 +87,6 @@ def test_group_band_path():
|
|
88
87
|
plt.xticks(Xs, knames)
|
89
88
|
plt.show()
|
90
89
|
|
91
|
-
|
92
|
-
|
93
90
|
|
94
91
|
def auto_kpath(cell, knames, kvectors=None, npoints=100, supercell_matrix=None):
|
95
92
|
"""Generates an automatic k-path for band structure calculations.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: TB2J
|
3
|
-
Version: 0.9.9.
|
3
|
+
Version: 0.9.9.13
|
4
4
|
Summary: TB2J: First principle to Heisenberg exchange J using tight-binding Green function method
|
5
5
|
Author: Xu He
|
6
6
|
Author-email: mailhexu@gmail.com
|
@@ -21,12 +21,13 @@ Requires-Dist: ase>=3.19
|
|
21
21
|
Requires-Dist: tqdm
|
22
22
|
Requires-Dist: pathos
|
23
23
|
Requires-Dist: packaging>=20.0
|
24
|
-
Requires-Dist: HamiltonIO>=0.2.
|
24
|
+
Requires-Dist: HamiltonIO>=0.2.4
|
25
25
|
Requires-Dist: pre-commit
|
26
26
|
Requires-Dist: sympair>0.1.0
|
27
27
|
Requires-Dist: sisl>=0.9.0
|
28
28
|
Requires-Dist: tomli>=2.0.0
|
29
29
|
Requires-Dist: tomli-w>=1.0.0
|
30
|
+
Requires-Dist: netcdf4
|
30
31
|
Dynamic: author
|
31
32
|
Dynamic: author-email
|
32
33
|
Dynamic: classifier
|
@@ -1,17 +1,17 @@
|
|
1
1
|
TB2J/Jdownfolder.py,sha256=n5BeQCYP4mD9JsAPeE1F3ZKKR3SUxADfDbaG_rzi77k,9658
|
2
|
-
TB2J/Jtensor.py,sha256=
|
2
|
+
TB2J/Jtensor.py,sha256=Wi06AAbfKFU6f2a2jkFr9zU2cwwfVroajTp-dwCtkTE,3160
|
3
3
|
TB2J/MAE.py,sha256=fM8U-Dgp9HcQOEeC_kyZV1oVrygBvcux9BraUXVouvY,10994
|
4
|
-
TB2J/MAEGreen.py,sha256=
|
4
|
+
TB2J/MAEGreen.py,sha256=DHoU6nlM0Fk42T_SYd_s-VafB6wCZNzVzRXhuv-hCwM,15762
|
5
5
|
TB2J/Oiju.py,sha256=cNGv8N5uH_swGq7cnAt2OyiDfqtjLlLrwseGu0E4iaM,3383
|
6
6
|
TB2J/Oiju_epc.py,sha256=oytM3NYW7nWmklrGgNlqwIpI_JYv_hb7ZnR4o9nYNog,6809
|
7
|
-
TB2J/__init__.py,sha256=
|
7
|
+
TB2J/__init__.py,sha256=TcMW0FTsZFR9McJTh8TBwZl2lylHc2uwsxVV9PsgSwY,25
|
8
8
|
TB2J/anisotropy.py,sha256=0zmvXkmDmakbBOwGYLa3IIkv5cE99SHLAQJsGoZz7JQ,25463
|
9
9
|
TB2J/basis.py,sha256=DFo6_QUwjBwisP6zGxvoO0lpGTMDPAOkiL9giNCjOjA,1558
|
10
10
|
TB2J/citation.py,sha256=gcQeyJZaT1Qrtsl8Y3s4neOH3-vvgmIcCvXeV2o3vj0,2891
|
11
11
|
TB2J/contour.py,sha256=zLHQZZ3hhgLkLFPATCraLOJyLJKLC0fba_L_5sRz23o,3246
|
12
12
|
TB2J/density_matrix.py,sha256=D5k8Oe21OCiLVORNYbo4TZOFG0slrQSbj91kJ3TMFjs,1514
|
13
13
|
TB2J/epc.py,sha256=zLbtqZJhDr8DnnGN6YENcXwrMb3Qxu6KB08mLy9Pw20,3474
|
14
|
-
TB2J/exchange.py,sha256=
|
14
|
+
TB2J/exchange.py,sha256=rJ7XeHOo6j9A0alauM2XQ5DvTO741dq_pDQQxyyn8mE,26981
|
15
15
|
TB2J/exchangeCL2.py,sha256=P7bklMXVYX_tn9DbjEPqeTir1SeZyfPBIP1fhWUzLmY,11419
|
16
16
|
TB2J/exchange_params.py,sha256=VW9nGVio6M_Ub9-36L_LExhjgdD1E_joYpI8AxmM360,8029
|
17
17
|
TB2J/exchange_pert.py,sha256=jmFMtQbYa_uczM4VAeS6TijkIHRFIqEzZJswzE9Wfuo,8523
|
@@ -19,7 +19,7 @@ TB2J/exchange_qspace.py,sha256=ZL68qBGFUaQ9BsSPsJaaoWOr9RssPiqX34R_9I3nk_8,8436
|
|
19
19
|
TB2J/gpaw_wrapper.py,sha256=aJ--9Dtyq7jOP1Hkh-Sh1nWcfXm6zKcljOCO0DNCAr0,6890
|
20
20
|
TB2J/green.py,sha256=ySXjoV3Cj_E2C41dRfc3TkS7M4vmM6qcHXkt-_-jxsY,17071
|
21
21
|
TB2J/greentest.py,sha256=2ISSfhor9ecSEOi_E6b4Cv26wEIQlwlzca0ru8z44_E,1603
|
22
|
-
TB2J/io_merge.py,sha256=
|
22
|
+
TB2J/io_merge.py,sha256=xj5sIo5o62HYwSnijGycem_rAc8kSzY-HI2IJDRhzyE,7405
|
23
23
|
TB2J/kpoints.py,sha256=9L7tBarFBHoIhpuc9zuwA6HdnlgH834SQrPek4yRoWk,3191
|
24
24
|
TB2J/myTB.py,sha256=ok_B4my29bOIghMSZfx0Es6G8FaXaIiLP4gPxTdSj00,17659
|
25
25
|
TB2J/mycfr.py,sha256=ZF1PEE2khlKd_4gPyMkoNXepX3XqwWAL2kDbRJNVX-Y,3908
|
@@ -43,19 +43,19 @@ TB2J/interfaces/__init__.py,sha256=4tiLoXQ73Nlyi9L4j8jJXOYzXluVNPxQZkwfkQZEGHg,3
|
|
43
43
|
TB2J/interfaces/gpaw_interface.py,sha256=GCDlJ-hRWfChvWwsgBDYSmVqO4sH9HAuGZTV9GqgN6c,1504
|
44
44
|
TB2J/interfaces/lawaf_interface.py,sha256=PieLnmppdafOYsgeHznqOou1g9L1sam5jOm3KaObdqo,4408
|
45
45
|
TB2J/interfaces/manager.py,sha256=PQMLEfMCT5GnDWSl2nI4JOgRPm_fysyR-6Y6l97xWcw,860
|
46
|
-
TB2J/interfaces/siesta_interface.py,sha256=
|
46
|
+
TB2J/interfaces/siesta_interface.py,sha256=Y4rRn_MRZUOI4y4btgCKTtVy8iXrSpaBuK7SMCJ1C2o,7594
|
47
47
|
TB2J/interfaces/wannier90_interface.py,sha256=qzRgXUBb7t1Aiegrl_RV51BB8csdtVM0EP0Z4pjmTcs,4467
|
48
48
|
TB2J/interfaces/abacus/__init__.py,sha256=leas71oCvM_HxrF4gnO5A_VKcJmDAgsI1BUctLU3OBw,177
|
49
49
|
TB2J/interfaces/abacus/abacus_api.py,sha256=lNV4LNkLcKw7Zux4MQYM9wnh3eFTlcSqbf4Pb7pqhrk,7243
|
50
50
|
TB2J/interfaces/abacus/abacus_wrapper.py,sha256=bQFnvvy-0hruTavH_VspMk1wD32t2UFybEkCgwkwle0,11941
|
51
51
|
TB2J/interfaces/abacus/gen_exchange_abacus.py,sha256=v-AUHGkJWeMNf4D5A4wOpCjM6DygQsFB6SWu-BGdTxM,3262
|
52
52
|
TB2J/interfaces/abacus/orbital_api.py,sha256=QEAyy4y_uM5GnwRyLvmShjd_z5A2fwqk7L8yj0Y2Mgc,1577
|
53
|
-
TB2J/interfaces/abacus/stru_api.py,sha256=
|
53
|
+
TB2J/interfaces/abacus/stru_api.py,sha256=UsIs55Y_1AM31N2oCjwmgHIMgRIcusKA6g3K2tjr3uM,67945
|
54
54
|
TB2J/interfaces/abacus/test_density_matrix.py,sha256=bMWWJYtDS57SpPZ-eZXZ9Hr_UK4mv8ZHM7SzItG3IVA,774
|
55
55
|
TB2J/interfaces/abacus/test_read_HRSR.py,sha256=W1oO_yigT50Yb5_u-KB_IfTpM7kArGkBuMSMs0H4CTs,1235
|
56
56
|
TB2J/interfaces/abacus/test_read_stru.py,sha256=hoKPHVco8vwzC7Gao4bOPCdAPhh29x-9DTJJqRr7AYM,788
|
57
57
|
TB2J/io_exchange/__init__.py,sha256=LqEnG67qDVKt4hCUywDEQvUIJ7jsQjmtueOW_J16NOE,54
|
58
|
-
TB2J/io_exchange/io_exchange.py,sha256=
|
58
|
+
TB2J/io_exchange/io_exchange.py,sha256=KnR2UyvMSoBye8dD6ETqZW6nld-CcYchcCrAmHbVsBA,22735
|
59
59
|
TB2J/io_exchange/io_multibinit.py,sha256=8PDmWxzGuv-GwJosj2ZTmiyNY_duFVWJ4ekCuSqGdd8,6739
|
60
60
|
TB2J/io_exchange/io_tomsasd.py,sha256=NqkAC1Fl-CUnFA21eBzSy_S5F_oeQFJysw4UukQbN8o,4173
|
61
61
|
TB2J/io_exchange/io_txt.py,sha256=BMr1eSILlKpgtjvDx7uw2VMAkEKSvGEPNxpaT_zev0I,10547
|
@@ -63,14 +63,14 @@ TB2J/io_exchange/io_uppasd.py,sha256=bI4iPEgnK4TvCZNvb6x2xYXgjW7pEehCqmcizy2pqFU
|
|
63
63
|
TB2J/io_exchange/io_vampire.py,sha256=u4NZhqoC_JBcVq19WZfBkyM5p8u-OMuRoUrtFIcPp5E,5762
|
64
64
|
TB2J/magnon/__init__.py,sha256=Q69duroGIIotgW_71ZdHYarSiJLGAu9NPYgEacUk6eI,117
|
65
65
|
TB2J/magnon/io_exchange2.py,sha256=EcC3x6H13qq61WBsr__xKzHDtSvy_dMz1tEdUaqSG2I,23265
|
66
|
-
TB2J/magnon/magnon3.py,sha256=
|
67
|
-
TB2J/magnon/magnon_band.py,sha256=
|
66
|
+
TB2J/magnon/magnon3.py,sha256=75YmSTT652q7lLEmJmn4-TbIkwJnjjelMfu0eyEzjA0,27401
|
67
|
+
TB2J/magnon/magnon_band.py,sha256=8HJWl1zcYSxJQflFUj4qaITnTWE-rhF5zQ1YgQN78oU,6098
|
68
68
|
TB2J/magnon/magnon_io.py,sha256=H4bmzCcnh1D3Sb6UBIIKWa6jIrA20dg9lX4wfLXHEjo,1241
|
69
|
-
TB2J/magnon/magnon_math.py,sha256=
|
70
|
-
TB2J/magnon/plot.py,sha256=
|
69
|
+
TB2J/magnon/magnon_math.py,sha256=b4Po_aZm8aIhr5u2nbjjtDDMTKV_ecI2d6Fc_AhiuNc,1358
|
70
|
+
TB2J/magnon/plot.py,sha256=oNavax15jRfW4Sxl6FgwLXSrMntyVz2cgVDbmgkWehw,3193
|
71
71
|
TB2J/magnon/structure.py,sha256=rKefzXgQlEjVvV-A7E2IogVDWwf5egZr3Wxxu6HuJU4,7685
|
72
72
|
TB2J/mathutils/__init__.py,sha256=E70Mx8mLXh3DJGmdN3TLWmGYMcsbvKxmgxUbAI6Mzmo,49
|
73
|
-
TB2J/mathutils/auto_kpath.py,sha256=
|
73
|
+
TB2J/mathutils/auto_kpath.py,sha256=bDXDyQzRByVpPSOpz7NU7F5hYqS6IX-47lwWoMU89lM,4978
|
74
74
|
TB2J/mathutils/fermi.py,sha256=72tZ5CptGmYaBUD0xLWltuH7LBXcrMUwODyW6-WqlzI,638
|
75
75
|
TB2J/mathutils/fibonacci_sphere.py,sha256=1rqf5n3a9aDjSydA4qGkR1eIeLJKuoblA73cchWJzNg,2342
|
76
76
|
TB2J/mathutils/kR_convert.py,sha256=p_9XWJVNanTzTK2rI6KRjTkbSq42la6N448-zJOsMwY,2671
|
@@ -89,21 +89,21 @@ TB2J/spinham/supercell.py,sha256=y17uUC6r3gQb278FhxIW4CABihfLTvKFj6flyXrCPR8,122
|
|
89
89
|
TB2J/wannier/__init__.py,sha256=7ojCbM84PYv1X1Tbo4NHI-d3gWmQsZB_xiYqbfxVV1E,80
|
90
90
|
TB2J/wannier/w90_parser.py,sha256=dbd63LuKyv2DVUzqRINGsbDzEsOxsQyE8_Ear_LQIRg,4620
|
91
91
|
TB2J/wannier/w90_tb_parser.py,sha256=qt8pnuprmPp9iIAYwPkPbmEzk6ZPgMq2xognoQp7vwc,4610
|
92
|
-
tb2j-0.9.9.
|
93
|
-
tb2j-0.9.9.
|
94
|
-
tb2j-0.9.9.
|
95
|
-
tb2j-0.9.9.
|
96
|
-
tb2j-0.9.9.
|
97
|
-
tb2j-0.9.9.
|
98
|
-
tb2j-0.9.9.
|
99
|
-
tb2j-0.9.9.
|
100
|
-
tb2j-0.9.9.
|
101
|
-
tb2j-0.9.9.
|
102
|
-
tb2j-0.9.9.
|
103
|
-
tb2j-0.9.9.
|
104
|
-
tb2j-0.9.9.
|
105
|
-
tb2j-0.9.9.
|
106
|
-
tb2j-0.9.9.
|
107
|
-
tb2j-0.9.9.
|
108
|
-
tb2j-0.9.9.
|
109
|
-
tb2j-0.9.9.
|
92
|
+
tb2j-0.9.9.13.data/scripts/TB2J_downfold.py,sha256=i4BVqnpDdgrX_amookVWeLGefGBn-qeAutWiwuY9SfQ,2099
|
93
|
+
tb2j-0.9.9.13.data/scripts/TB2J_eigen.py,sha256=Qs9v2hnMm2Tpfoa4h53muUKty2dZjwx8948MBoQooNg,1128
|
94
|
+
tb2j-0.9.9.13.data/scripts/TB2J_magnon.py,sha256=q7UwAmorRcFNk4tfE7gl_ny05l6p7pbD9Wm_LkIpKEw,3101
|
95
|
+
tb2j-0.9.9.13.data/scripts/TB2J_magnon2.py,sha256=tMa7Fg_Wd2UytnrH3C_AsgGM7BciUW0iy6NiPlWvar8,1920
|
96
|
+
tb2j-0.9.9.13.data/scripts/TB2J_magnon_dos.py,sha256=TMXQvD2dIbO5FZ4tUMmxJgCgH2O2hDAPUNfEKO4z-x4,110
|
97
|
+
tb2j-0.9.9.13.data/scripts/TB2J_merge.py,sha256=y834SF4rIRn1L1ptkhczvavQpC-8Px6DTmDOOSaq_DE,1854
|
98
|
+
tb2j-0.9.9.13.data/scripts/TB2J_plot_magnon_bands.py,sha256=qUbisPFLvW_j1IdTpc_jU0WiT-7CT-WErbkhNvAPM0Y,91
|
99
|
+
tb2j-0.9.9.13.data/scripts/TB2J_rotate.py,sha256=zgiDFuYZNmzKK0rwDmTaYD2OpRlmKA_VGeBx83w2Xwc,873
|
100
|
+
tb2j-0.9.9.13.data/scripts/TB2J_rotateDM.py,sha256=kCvF7gotuqAX1VnJ06cwfVm7RrhrdtiV5v7d9P2Pn_E,567
|
101
|
+
tb2j-0.9.9.13.data/scripts/abacus2J.py,sha256=ozYI7qZyja1WEs9oCYVpeYAfVj5PGhehhmdZFcvrd3g,1795
|
102
|
+
tb2j-0.9.9.13.data/scripts/siesta2J.py,sha256=QJ6c0DbqxaqYEesxiL5R9nK9-flNLrr7hajKfCwirYc,2318
|
103
|
+
tb2j-0.9.9.13.data/scripts/wann2J.py,sha256=OA31VHEXbQMD-JozoLUHDF6vB9Sr62d804OApSKtSnU,3240
|
104
|
+
tb2j-0.9.9.13.dist-info/licenses/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
|
105
|
+
tb2j-0.9.9.13.dist-info/METADATA,sha256=XJtwVxFDDV27HFqNVsgHrjlRbY3g-dKnsc0FiLjJ3kg,1768
|
106
|
+
tb2j-0.9.9.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
107
|
+
tb2j-0.9.9.13.dist-info/entry_points.txt,sha256=Hdz1WC9waUzyFVmowKnbbZ6j-J4adHh_Ko6JpxGYAtE,131
|
108
|
+
tb2j-0.9.9.13.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
|
109
|
+
tb2j-0.9.9.13.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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|