TB2J 0.9.9.13__py3-none-any.whl → 0.9.9.15__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.
Files changed (32) hide show
  1. TB2J/MAEGreen.py +1 -2
  2. TB2J/__init__.py +1 -1
  3. TB2J/exchange.py +1 -1
  4. TB2J/interfaces/abacus/stru_api.py +10 -17
  5. TB2J/interfaces/siesta_interface.py +1 -1
  6. TB2J/io_exchange/io_exchange.py +4 -5
  7. TB2J/io_exchange/io_vampire.py +1 -1
  8. TB2J/io_merge.py +60 -45
  9. TB2J/magnon/magnon3.py +105 -11
  10. TB2J/magnon/magnon_band.py +3 -3
  11. TB2J/magnon/magnon_dos.py +308 -0
  12. TB2J/magnon/magnon_math.py +1 -1
  13. TB2J/magnon/plot_magnon_dos_cli.py +99 -0
  14. {tb2j-0.9.9.13.data → tb2j-0.9.9.15.data}/scripts/TB2J_merge.py +9 -5
  15. tb2j-0.9.9.15.data/scripts/TB2J_plot_magnon_bands.py +27 -0
  16. {tb2j-0.9.9.13.dist-info → tb2j-0.9.9.15.dist-info}/METADATA +1 -1
  17. {tb2j-0.9.9.13.dist-info → tb2j-0.9.9.15.dist-info}/RECORD +31 -29
  18. {tb2j-0.9.9.13.dist-info → tb2j-0.9.9.15.dist-info}/entry_points.txt +1 -0
  19. tb2j-0.9.9.13.data/scripts/TB2J_plot_magnon_bands.py +0 -7
  20. {tb2j-0.9.9.13.data → tb2j-0.9.9.15.data}/scripts/TB2J_downfold.py +0 -0
  21. {tb2j-0.9.9.13.data → tb2j-0.9.9.15.data}/scripts/TB2J_eigen.py +0 -0
  22. {tb2j-0.9.9.13.data → tb2j-0.9.9.15.data}/scripts/TB2J_magnon.py +0 -0
  23. {tb2j-0.9.9.13.data → tb2j-0.9.9.15.data}/scripts/TB2J_magnon2.py +0 -0
  24. {tb2j-0.9.9.13.data → tb2j-0.9.9.15.data}/scripts/TB2J_magnon_dos.py +0 -0
  25. {tb2j-0.9.9.13.data → tb2j-0.9.9.15.data}/scripts/TB2J_rotate.py +0 -0
  26. {tb2j-0.9.9.13.data → tb2j-0.9.9.15.data}/scripts/TB2J_rotateDM.py +0 -0
  27. {tb2j-0.9.9.13.data → tb2j-0.9.9.15.data}/scripts/abacus2J.py +0 -0
  28. {tb2j-0.9.9.13.data → tb2j-0.9.9.15.data}/scripts/siesta2J.py +0 -0
  29. {tb2j-0.9.9.13.data → tb2j-0.9.9.15.data}/scripts/wann2J.py +0 -0
  30. {tb2j-0.9.9.13.dist-info → tb2j-0.9.9.15.dist-info}/WHEEL +0 -0
  31. {tb2j-0.9.9.13.dist-info → tb2j-0.9.9.15.dist-info}/licenses/LICENSE +0 -0
  32. {tb2j-0.9.9.13.dist-info → tb2j-0.9.9.15.dist-info}/top_level.txt +0 -0
TB2J/MAEGreen.py CHANGED
@@ -94,12 +94,11 @@ class MAEGreen(ExchangeNCL):
94
94
  self.thetas.append(i * np.pi / 180)
95
95
  self.phis.append(j * np.pi / 180)
96
96
 
97
- def set_angels_ztox(self, n=16):
97
+ def set_angels_ztox(self, n=16):
98
98
  """Set angles for a scan from z to x"""
99
99
  self.thetas = np.linspace(0, np.pi, n)
100
100
  self.phis = np.zeros(n)
101
101
 
102
-
103
102
  def set_angles_random(self, n=16):
104
103
  # n random pairs of theta, phi
105
104
  self.thetas = np.random.random(n) * np.pi
TB2J/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.9.9.12"
1
+ __version__ = "0.9.9.14"
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,21 +7,28 @@
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
-
13
10
 
14
11
  import os
15
12
  import re
16
13
  import shutil
14
+ import warnings
15
+ from copy import deepcopy
16
+ from math import sqrt
17
17
  from pathlib import Path
18
18
 
19
19
  import numpy as np
20
20
  from ase import Atoms
21
+ from ase.calculators.calculator import kpts2ndarray, kpts2sizeandoffsets
21
22
  from ase.calculators.singlepoint import SinglePointDFTCalculator, arrays_to_kpoints
23
+ from ase.constraints import FixAtoms, FixCartesian
24
+ from ase.dft.kpoints import bandpath
25
+ from ase.stress import full_3x3_to_voigt_6_stress
22
26
  from ase.units import Bohr, GPa, Hartree, Rydberg, _me, mol
23
27
  from ase.utils import lazymethod, lazyproperty, reader, writer
24
28
 
29
+ warnings.simplefilter(action="ignore", category=FutureWarning)
30
+
31
+
25
32
  _re_float = r"[-+]?\d+\.*\d*(?:[Ee][-+]\d+)?"
26
33
  AU_to_MASS = mol * _me * 1e3
27
34
  UNIT_V = np.sqrt(Hartree / AU_to_MASS)
@@ -42,7 +49,6 @@ def write_input(fd, parameters=None):
42
49
  parameters: dict
43
50
  The dictionary of all paramters for the calculation.
44
51
  """
45
- from copy import deepcopy
46
52
 
47
53
  params = deepcopy(parameters)
48
54
  params["dft_functional"] = (
@@ -105,8 +111,6 @@ def write_kpt(fd=None, parameters=None, atoms=None):
105
111
  return
106
112
  elif kpts is not None:
107
113
  if isinstance(kpts, dict) and "path" not in kpts:
108
- from ase.calculators.calculator import kpts2sizeandoffsets
109
-
110
114
  kgrid, shift = kpts2sizeandoffsets(atoms=atoms, **kpts)
111
115
  koffset = []
112
116
  for i, x in enumerate(shift):
@@ -121,8 +125,6 @@ def write_kpt(fd=None, parameters=None, atoms=None):
121
125
  koffset = [koffset] * 3
122
126
 
123
127
  if isinstance(kgrid, dict) or hasattr(kgrid, "kpts"):
124
- from ase.calculators.calculator import kpts2ndarray
125
-
126
128
  kmode = "Direct"
127
129
  kgrid = kpts2ndarray(kgrid, atoms=atoms)
128
130
  elif isinstance(kgrid, str) and (kgrid == "gamma"):
@@ -272,8 +274,6 @@ def judge_exist_stru(stru=None):
272
274
 
273
275
 
274
276
  def read_ase_stru(stru=None, coordinates_type="Cartesian"):
275
- from ase.constraints import FixAtoms, FixCartesian
276
-
277
277
  fix_cart = np.ones((len(stru), 3), dtype=int).tolist()
278
278
  for constr in stru.constraints:
279
279
  for i in constr.index:
@@ -567,8 +567,6 @@ def read_kpt(fd, cell=None):
567
567
  else:
568
568
  knumbers = klines[:, 3].astype(int)
569
569
  if cell is not None:
570
- from ase.dft.kpoints import bandpath
571
-
572
570
  return bandpath(kpts, cell, npoints=knumbers.sum())
573
571
  else:
574
572
  return {
@@ -683,8 +681,6 @@ def read_abacus(fd, latname=None, verbose=False):
683
681
  If `verbose` is True, pseudo-potential, basis and other information along with the Atoms object will be output as a dict.
684
682
  """
685
683
 
686
- from ase.constraints import FixCartesian
687
-
688
684
  contents = fd.read()
689
685
  title_str = r"(?:LATTICE_CONSTANT|NUMERICAL_DESCRIPTOR|NUMERICAL_ORBITAL|ABFS_ORBITAL|LATTICE_VECTORS|LATTICE_PARAMETERS|ATOMIC_POSITIONS)"
690
686
 
@@ -887,8 +883,6 @@ def read_abacus(fd, latname=None, verbose=False):
887
883
 
888
884
 
889
885
  def get_lattice_from_latname(lines, latname=None):
890
- from math import sqrt
891
-
892
886
  if lines:
893
887
  lines = lines.group(1).split(" ")
894
888
 
@@ -1488,7 +1482,6 @@ class AbacusOutCalcChunk(AbacusOutChunk):
1488
1482
  @lazymethod
1489
1483
  def get_stress(self):
1490
1484
  """Get the stress from the output file according to index"""
1491
- from ase.stress import full_3x3_to_voigt_6_stress
1492
1485
 
1493
1486
  try:
1494
1487
  stress = (
@@ -165,7 +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
+ # MAE.set_xyz_angles()
169
169
  MAE.run(output_path=f"{output_path}_anisotropy", with_eigen=False)
170
170
  # print(
171
171
  # f"MAE calculation finished. The results are in {output_path} directory."
@@ -340,20 +340,19 @@ Generation time: {now.strftime("%y/%m/%d %H:%M:%S")}
340
340
  """
341
341
  i = self.i_spin(i)
342
342
  j = self.i_spin(j)
343
- J=D=Ja = None
343
+ J = D = Ja = None
344
344
  if Jiso:
345
- J= self.get_Jiso(i, j, R)
345
+ J = self.get_Jiso(i, j, R)
346
346
  if DMI:
347
347
  D = self.get_DMI(i, j, R)
348
348
  if D is not None:
349
- D*=1
349
+ D *= 1
350
350
  if Jani:
351
351
  Ja = self.get_Jani(i, j, R)
352
352
  if Ja is not None:
353
- Ja*=1
353
+ Ja *= 1
354
354
  Jtensor = combine_J_tensor(Jiso=J, D=D, Jani=Ja)
355
355
 
356
-
357
356
  # if iso_only:
358
357
  # J = self.get_Jiso(i, j, R)
359
358
  # if J is not None:
@@ -60,7 +60,7 @@ def write_vampire_unitcell_file(cls, fname):
60
60
  val = np.real(Jtensor[i, j] * 2.0 / J)
61
61
  if np.abs(val) < 1e-30:
62
62
  val = 0.0
63
- myfile.write(f"{val:<012.5e} ")
63
+ myfile.write(f"{val:< 12.5e} ")
64
64
  myfile.write("\n")
65
65
 
66
66
 
TB2J/io_merge.py CHANGED
@@ -1,31 +1,35 @@
1
- import os
2
1
  import copy
2
+ import os
3
3
  import warnings
4
+ from itertools import combinations_with_replacement
5
+
4
6
  import numpy as np
5
- from itertools import combinations_with_replacement, product
7
+
6
8
  from TB2J.io_exchange import SpinIO
7
9
 
8
10
  u0 = np.zeros(3)
9
11
  uy = np.array([0.0, 1.0, 0.0])
10
12
  uz = np.array([0.0, 0.0, 1.0])
11
13
 
12
- def get_Jani_coefficients(a, R=np.eye(3)):
13
14
 
15
+ def get_Jani_coefficients(a, R=np.eye(3)):
14
16
  if len(a) == 1:
15
17
  u = a
16
18
  v = a
17
19
  else:
18
20
  u = a[[0, 0, 1]]
19
21
  v = a[[0, 1, 1]]
20
-
22
+
21
23
  ur = u @ R.T
22
24
  vr = v @ R.T
23
- coefficients = np.hstack([ur*vr, np.roll(ur, -1, axis=-1)*vr + np.roll(vr, -1, axis=-1)*ur])
25
+ coefficients = np.hstack(
26
+ [ur * vr, np.roll(ur, -1, axis=-1) * vr + np.roll(vr, -1, axis=-1) * ur]
27
+ )
24
28
 
25
29
  return coefficients, u, v
26
30
 
27
- def get_projections(a, b, tol=1e-2):
28
31
 
32
+ def get_projections(a, b, tol=1e-2):
29
33
  projections = np.empty((2, 3))
30
34
  if np.linalg.matrix_rank([a, b], tol=tol) == 1:
31
35
  if np.linalg.matrix_rank([a, uy], tol=tol) == 1:
@@ -41,13 +45,13 @@ def get_projections(a, b, tol=1e-2):
41
45
 
42
46
  return projections
43
47
 
48
+
44
49
  class SpinIO_merge(SpinIO):
45
50
  def __init__(self, *args, **kwargs):
46
51
  super(SpinIO_merge, self).__init__(*args, **kwargs)
47
52
  self.projv = None
48
53
 
49
54
  def _set_projection_vectors(self):
50
-
51
55
  norm = np.linalg.norm(self.spinat, axis=-1).reshape(-1, 1)
52
56
  spinat = self.spinat / norm
53
57
  idx = [self.ind_atoms[i] for i in self.index_spin if i >= 0]
@@ -60,27 +64,29 @@ class SpinIO_merge(SpinIO):
60
64
  self.projv = projv
61
65
 
62
66
  @classmethod
63
- def load_pickle(cls, path='TB2J_results', fname='TB2J.pickle'):
67
+ def load_pickle(cls, path="TB2J_results", fname="TB2J.pickle"):
64
68
  obj = super(SpinIO_merge, cls).load_pickle(path=path, fname=fname)
65
69
  obj._set_projection_vectors()
66
70
 
67
71
  return obj
68
72
 
73
+
69
74
  def read_pickle(path):
70
- p1 = os.path.join(path, 'TB2J_results', 'TB2J.pickle')
71
- p2 = os.path.join(path, 'TB2J.pickle')
75
+ p1 = os.path.join(path, "TB2J_results", "TB2J.pickle")
76
+ p2 = os.path.join(path, "TB2J.pickle")
72
77
  if os.path.exists(p1) and os.path.exists(p2):
73
78
  print(f" WARNING!: Both file {p1} and {p2} exist. Use default {p1}.")
74
79
  if os.path.exists(p1):
75
- ret = SpinIO_merge.load_pickle(os.path.join(path, 'TB2J_results'))
80
+ ret = SpinIO_merge.load_pickle(os.path.join(path, "TB2J_results"))
76
81
  elif os.path.exists(p2):
77
82
  ret = SpinIO_merge.load_pickle(path)
78
83
  else:
79
84
  raise FileNotFoundError(f"Cannot find either file {p1} or {p2}")
80
85
  return ret
81
86
 
82
- class Merger():
83
- def __init__(self, *paths, main_path=None):
87
+
88
+ class Merger:
89
+ def __init__(self, *paths, main_path=None):
84
90
  self.dat = [read_pickle(path) for path in paths]
85
91
 
86
92
  if main_path is None:
@@ -90,32 +96,34 @@ class Merger():
90
96
  self.dat.append(copy.deepcopy(self.main_dat))
91
97
 
92
98
  self._set_projv()
93
-
99
+
94
100
  def _set_projv(self):
95
101
  cell = self.main_dat.atoms.cell.array
96
- rotated_cells = np.stack(
97
- [obj.atoms.cell.array for obj in self.dat], axis=0
98
- )
102
+ rotated_cells = np.stack([obj.atoms.cell.array for obj in self.dat], axis=0)
99
103
  R = np.linalg.solve(cell, rotated_cells)
100
104
  indices = range(len(self.dat))
101
105
 
102
- proju = {}; projv = {}; coeff_matrix = {}; projectors = {};
106
+ proju = {}
107
+ projv = {}
108
+ coeff_matrix = {}
109
+ projectors = {}
103
110
  for key in self.main_dat.projv.keys():
104
111
  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])
112
+ coefficients, u, v = zip(
113
+ *[get_Jani_coefficients(vectors[i], R=R[i]) for i in indices]
114
+ )
106
115
  projectors[key] = np.vstack([u[i] @ R[i].T for i in indices])
107
116
  coeff_matrix[key] = np.vstack(coefficients)
108
117
  proju[key] = np.stack(u)
109
118
  projv[key] = np.stack(v)
110
119
  if np.linalg.matrix_rank(coeff_matrix[key], tol=1e-2) < 6:
111
- warnings.warn('''
120
+ warnings.warn("""
112
121
  WARNING: The matrix of equations to reconstruct the exchange tensors is
113
122
  close to being singular. This happens when the magnetic moments between
114
123
  different configurations are cloes to being parallel. You need to consider
115
124
  more rotated spin configurations, otherwise the results might have a large
116
- error.'''
117
- )
118
-
125
+ error.""")
126
+
119
127
  self.proju = proju
120
128
  self.projv = projv
121
129
  self.coeff_matrix = coeff_matrix
@@ -123,71 +131,78 @@ class Merger():
123
131
 
124
132
  def merge_Jani(self):
125
133
  Jani_dict = {}
126
- proju = self.proju; projv = self.projv; coeff_matrix = self.coeff_matrix;
134
+ proju = self.proju
135
+ projv = self.projv
136
+ coeff_matrix = self.coeff_matrix
127
137
  for key in self.main_dat.Jani_dict.keys():
128
138
  try:
129
139
  R, i, j = key
130
140
  u = proju[i, j]
131
141
  v = projv[i, j]
132
142
  Jani = np.stack([sio.Jani_dict[key] for sio in self.dat])
133
- projections = np.einsum('nmi,nij,nmj->nm', u, Jani, v).flatten()
143
+ projections = np.einsum("nmi,nij,nmj->nm", u, Jani, v).flatten()
134
144
  except KeyError as err:
135
145
  raise KeyError(
136
146
  "Can not find key: %s, Please make sure the three calculations use the same k-mesh and same Rcut."
137
- % err)
147
+ % err
148
+ )
138
149
  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
- ])
150
+ Jani_dict[key] = np.array(
151
+ [
152
+ [newJani[0], newJani[3], newJani[5]],
153
+ [newJani[3], newJani[1], newJani[4]],
154
+ [newJani[5], newJani[4], newJani[2]],
155
+ ]
156
+ )
144
157
  self.main_dat.Jani_dict = Jani_dict
145
158
 
146
159
  def merge_Jiso(self):
147
- Jdict={}
160
+ Jdict = {}
148
161
  for key in self.main_dat.exchange_Jdict.keys():
149
162
  try:
150
- J = np.mean([obj.exchange_Jdict[key] for obj in self.dat])
163
+ J = np.mean([obj.exchange_Jdict[key] for obj in self.dat])
151
164
  except KeyError as err:
152
165
  raise KeyError(
153
- "Can not find key: %s, Please make sure the three calculations use the same k-mesh and same Rcut."
154
- % err)
166
+ "Can not find key: %s, Please make sure the three calculations use the same k-mesh and same Rcut."
167
+ % err
168
+ )
155
169
  Jdict[key] = J
156
170
  self.main_dat.exchange_Jdict = Jdict
157
-
158
171
 
159
172
  def merge_DMI(self):
160
173
  dmi_ddict = {}
161
174
  if all(obj.has_dmi for obj in self.dat):
162
- projectors = self.projectors; proju = self.proju;
175
+ projectors = self.projectors
176
+ proju = self.proju
163
177
  for key in self.main_dat.dmi_ddict.keys():
164
178
  try:
165
179
  R, i, j = key
166
180
  u = proju[i, j]
167
181
  DMI = np.stack([sio.dmi_ddict[key] for sio in self.dat])
168
- projections = np.einsum('nmi,ni->nm', u, DMI).flatten()
182
+ projections = np.einsum("nmi,ni->nm", u, DMI).flatten()
169
183
  except KeyError as err:
170
184
  raise KeyError(
171
185
  "Can not find key: %s, Please make sure the three calculations use the same k-mesh and same Rcut."
172
- % err)
186
+ % err
187
+ )
173
188
  newDMI = np.linalg.lstsq(projectors[i, j], projections, rcond=4e-1)[0]
174
189
  dmi_ddict[key] = newDMI
175
190
  self.main_dat.dmi_ddict = dmi_ddict
176
191
 
177
192
  def standardize(self):
178
193
  # 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
194
+ Jdict = self.main_dat.exchange_Jdict
195
+ Jani_dict = self.main_dat.Jani_dict
181
196
  for key in self.main_dat.Jani_dict.keys():
182
197
  Jani = self.main_dat.Jani_dict[key]
183
- shift = np.trace(Jani)/3.0
184
- Jani_dict[key] -= shift * np.eye(3)
198
+ shift = np.trace(Jani) / 3.0
199
+ Jani_dict[key] -= shift * np.eye(3)
185
200
  Jdict[key] += shift
186
201
  self.main_dat.Jani_dict = Jani_dict
187
202
  self.main_dat.exchange_Jdict = Jdict
188
-
189
203
 
190
- def merge(*paths, main_path=None, save=True, write_path='TB2J_results'):
204
+
205
+ def merge(*paths, main_path=None, save=True, write_path="TB2J_results"):
191
206
  m = Merger(*paths, main_path=main_path)
192
207
  m.merge_Jiso()
193
208
  m.merge_DMI()
TB2J/magnon/magnon3.py CHANGED
@@ -2,12 +2,16 @@ from dataclasses import asdict, dataclass
2
2
  from pathlib import Path
3
3
  from typing import List, Optional, Tuple, Union
4
4
 
5
+ import matplotlib.pyplot as plt
5
6
  import numpy as np
6
7
  import tomli
7
8
  import tomli_w
9
+ from ase.dft.dos import DOS
10
+ from ase.units import J, eV
8
11
  from scipy.spatial.transform import Rotation
9
12
 
10
13
  from TB2J.io_exchange import SpinIO
14
+ from TB2J.kpoints import monkhorst_pack
11
15
  from TB2J.magnon.magnon_band import MagnonBand
12
16
  from TB2J.magnon.magnon_math import get_rotation_arrays
13
17
  from TB2J.mathutils.auto_kpath import auto_kpath
@@ -162,10 +166,10 @@ class Magnon:
162
166
  phase = 2 * np.pi * R @ qpt
163
167
  Jq[iqpt] += np.exp(1j * phase) * JRprime[iR]
164
168
 
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
+ # Jq_copy = Jq.copy()
170
+ # Jq.swapaxes(-1, -2) # swap xyz
171
+ # Jq.swapaxes(-3, -4) # swap ij
172
+ # Jq = (Jq.conj() + Jq_copy) / 2.0
169
173
  return Jq
170
174
 
171
175
  def Hq(self, kpoints):
@@ -187,7 +191,6 @@ class Magnon:
187
191
  magmoms = self.magmom.copy()
188
192
  magmoms /= np.linalg.norm(magmoms, axis=-1)[:, None]
189
193
 
190
-
191
194
  U, V = get_rotation_arrays(magmoms, u=self._uz)
192
195
 
193
196
  J0 = -self.Jq(np.zeros((1, 3)))[0]
@@ -195,7 +198,6 @@ class Magnon:
195
198
  # Jq = -Hermitize(self.Jq(kpoints, anisotropic=anisotropic))
196
199
 
197
200
  Jq = -self.Jq(kpoints)
198
- print(f"J0 shape: {J0.shape}")
199
201
 
200
202
  C = np.diag(np.einsum("ix,ijxy,jy->i", V, 2 * J0, V))
201
203
  B = np.einsum("ix,kijxy,jy->kij", U, Jq, U)
@@ -203,7 +205,6 @@ class Magnon:
203
205
  A2 = np.einsum("ix,kijxy,jy->kij", U.conj(), Jq, U)
204
206
 
205
207
  H = np.block([[A1 - C, B], [B.swapaxes(-1, -2).conj(), A2 - C]])
206
- print(f"H shape: {H.shape}")
207
208
  return H
208
209
 
209
210
  def _magnon_energies(self, kpoints, u=None):
@@ -801,12 +802,11 @@ def main():
801
802
  )
802
803
 
803
804
  parser.add_argument(
804
- "--show",
805
+ "--show",
805
806
  action="store_true",
806
807
  default=False,
807
808
  help="show figure on screen.",
808
- )
809
-
809
+ )
810
810
 
811
811
  args = parser.parse_args()
812
812
 
@@ -834,7 +834,7 @@ def main():
834
834
  Q=args.Q if args.Q is not None else None,
835
835
  uz_file=args.uz_file,
836
836
  n=args.n if args.n is not None else None,
837
- show=args.show
837
+ show=args.show,
838
838
  )
839
839
 
840
840
  plot_magnon_bands_from_TB2J(params)
@@ -842,3 +842,97 @@ def main():
842
842
 
843
843
  if __name__ == "__main__":
844
844
  main()
845
+
846
+
847
+ class MagnonASEWrapper:
848
+ def __init__(self, magnon: Magnon):
849
+ self.magnon = magnon
850
+ self.atoms = None
851
+ self.kpts = None
852
+ self.weights = None
853
+ self.dos_args = {}
854
+
855
+ def set(self, atoms=None, kmesh=[9, 9, 9], gamma=True, **kwargs):
856
+ self.atoms = atoms
857
+ self.dos_args = {
858
+ "kmesh": kmesh,
859
+ "gamma": gamma,
860
+ }
861
+ self.kpts = monkhorst_pack(
862
+ self.dos_args["kmesh"], gamma_center=self.dos_args["gamma"]
863
+ )
864
+ self.weights = np.ones(len(self.kpts)) / len(self.kpts)
865
+
866
+ def get_k_points_and_weights(self):
867
+ return self.kpts, self.weights
868
+
869
+ def get_k_point_weights(self):
870
+ return self.weights
871
+
872
+ def get_number_of_spins(self):
873
+ return 1
874
+
875
+ def get_eigenvalues(self, kpt, spin=0):
876
+ """
877
+ return the eigenvalues at a given k-point. The energy unit is eV
878
+ args:
879
+ kpt: k-point index.
880
+ spin: spin index.
881
+ """
882
+ kpoint = self.kpts[kpt]
883
+ # Magnon energies are already in eV, convert to meV for consistency with plot
884
+ evals = self.magnon._magnon_energies(np.array([kpoint]))[0]
885
+ evals = evals * J / eV # Convert to eV
886
+ return evals
887
+
888
+ def get_fermi_level(self):
889
+ return 0.0
890
+
891
+ def get_bz_k_points(self):
892
+ return self.kpts
893
+
894
+ def get_dos(self, width=0.1, window=None, npts=401):
895
+ dos = DOS(self, width=width, window=window, npts=npts)
896
+ energies = dos.get_energies()
897
+ tdos = dos.get_dos()
898
+ return energies, tdos
899
+
900
+ def plot_dos(
901
+ self,
902
+ smearing_width=0.0001,
903
+ window=None,
904
+ npts=401,
905
+ output="magnon_dos.pdf",
906
+ ax=None,
907
+ show=True,
908
+ dos_filename="magnon_dos.txt",
909
+ ):
910
+ """
911
+ plot total DOS.
912
+ :param width: width of Gaussian smearing
913
+ :param window: energy window
914
+ :param npts: number of points
915
+ :param output: output filename
916
+ :param ax: matplotlib axis
917
+ :return: ax
918
+ """
919
+ if ax is None:
920
+ _fig, ax = plt.subplots()
921
+ energies, tdos = self.get_dos(width=smearing_width, window=window, npts=npts)
922
+ energies = energies * 1000 # Convert to meV
923
+ tdos = tdos / 1000 # Convert to states/meV
924
+ if dos_filename is not None:
925
+ np.savetxt(
926
+ dos_filename,
927
+ np.array([energies, tdos]).T,
928
+ header="Energy(meV) DOS(state/meV)",
929
+ )
930
+ ax.plot(energies, tdos)
931
+ ax.set_xlabel("Energy (meV)")
932
+ ax.set_ylabel("DOS (states/meV)")
933
+ ax.set_title("Total DOS")
934
+ if output is not None:
935
+ plt.savefig(output)
936
+ if show:
937
+ plt.show()
938
+ return ax
@@ -40,7 +40,7 @@ class MagnonBand:
40
40
  if self.xcoords is None:
41
41
  self.xcoords = np.arange(len(self.kpoints))
42
42
 
43
- def plot(self, ax=None, filename=None, show=False, shift=0.0,**kwargs):
43
+ def plot(self, ax=None, filename=None, show=False, shift=0.0, **kwargs):
44
44
  """Plot the magnon band structure.
45
45
 
46
46
  Parameters
@@ -79,7 +79,7 @@ class MagnonBand:
79
79
  for band in segment_bands:
80
80
  ax.plot(
81
81
  x,
82
- band[start_idx : start_idx + nbands]+shift,
82
+ band[start_idx : start_idx + nbands] + shift,
83
83
  linewidth=linewidth,
84
84
  color=color,
85
85
  linestyle=linestyle,
@@ -91,7 +91,7 @@ class MagnonBand:
91
91
  for band in self.energies.T:
92
92
  ax.plot(
93
93
  self.xcoords,
94
- band+shift,
94
+ band + shift,
95
95
  linewidth=linewidth,
96
96
  color=color,
97
97
  linestyle=linestyle,
@@ -0,0 +1,308 @@
1
+ """Module for magnon density of states calculations and plotting."""
2
+
3
+ import json
4
+ from dataclasses import dataclass
5
+ from pathlib import Path
6
+ from typing import Optional
7
+
8
+ import matplotlib.pyplot as plt
9
+ import numpy as np
10
+ from ase.dft.dos import DOS
11
+
12
+ from TB2J.kpoints import monkhorst_pack
13
+
14
+
15
+ @dataclass
16
+ class MagnonDOS:
17
+ """Data class for storing magnon DOS data"""
18
+
19
+ energies: np.ndarray # DOS energy points in meV
20
+ dos: np.ndarray # DOS values in states/meV
21
+ weights: Optional[np.ndarray] = None # k-point weights
22
+ kpoints: Optional[np.ndarray] = None # k-points used for DOS
23
+
24
+ def save(self, filename: str):
25
+ """Save DOS data to a JSON file.
26
+
27
+ Parameters
28
+ ----------
29
+ filename : str
30
+ Output filename (should end in .json)
31
+ """
32
+ # Convert numpy arrays to lists for JSON serialization
33
+ data = {
34
+ "energies": self.energies.tolist(),
35
+ "dos": self.dos.tolist(),
36
+ }
37
+ if self.weights is not None:
38
+ data["weights"] = self.weights.tolist()
39
+ if self.kpoints is not None:
40
+ data["kpoints"] = self.kpoints.tolist()
41
+
42
+ with open(filename, "w") as f:
43
+ json.dump(data, f)
44
+
45
+ @classmethod
46
+ def load(cls, filename: str) -> "MagnonDOS":
47
+ """Load DOS data from a JSON file.
48
+
49
+ Parameters
50
+ ----------
51
+ filename : str
52
+ Input JSON filename
53
+
54
+ Returns
55
+ -------
56
+ MagnonDOS
57
+ Loaded DOS object
58
+ """
59
+ with open(filename) as f:
60
+ data = json.load(f)
61
+
62
+ # Convert lists back to numpy arrays
63
+ data["energies"] = np.array(data["energies"])
64
+ data["dos"] = np.array(data["dos"])
65
+ if "weights" in data:
66
+ data["weights"] = np.array(data["weights"])
67
+ if "kpoints" in data:
68
+ data["kpoints"] = np.array(data["kpoints"])
69
+
70
+ return cls(**data)
71
+
72
+ def plot(self, ax=None, color="blue", show=True, filename=None, **plot_kwargs):
73
+ """Plot the magnon DOS.
74
+
75
+ Parameters
76
+ ----------
77
+ ax : matplotlib.axes.Axes, optional
78
+ Axis to plot on. If None, creates new figure
79
+ color : str, optional
80
+ Color for DOS line
81
+ show : bool, optional
82
+ Whether to show plot
83
+ filename : str, optional
84
+ If provided, saves plot to file
85
+ **plot_kwargs : dict
86
+ Additional keyword arguments passed to plot
87
+
88
+ Returns
89
+ -------
90
+ matplotlib.axes.Axes
91
+ The plotting axes
92
+ """
93
+ if ax is None:
94
+ _, ax = plt.subplots()
95
+
96
+ ax.plot(self.energies, self.dos, color=color, **plot_kwargs)
97
+ ax.set_xlabel("Energy (meV)")
98
+ ax.set_ylabel("DOS (states/meV)")
99
+ ax.set_title("Magnon DOS")
100
+
101
+ if filename:
102
+ plt.savefig(filename)
103
+ if show:
104
+ plt.show()
105
+
106
+ return ax
107
+
108
+
109
+ class MagnonDOSCalculator:
110
+ """Calculator for magnon density of states"""
111
+
112
+ def __init__(self, magnon):
113
+ """Initialize DOS calculator
114
+
115
+ Parameters
116
+ ----------
117
+ magnon : Magnon
118
+ Magnon object containing exchange parameters
119
+ """
120
+ self.magnon = magnon
121
+ self.kpts = None
122
+ self.weights = None
123
+ self.dos_args = {}
124
+
125
+ def estimate_energy_range(self, padding_factor=1.2):
126
+ """Estimate the energy range of eigenvalues.
127
+
128
+ Computes eigenvalues at zone center and high-symmetry points at zone boundaries
129
+ to estimate the full range of magnon energies.
130
+
131
+ Parameters
132
+ ----------
133
+ padding_factor : float, optional
134
+ Factor to extend the energy window beyond min/max values.
135
+ Default is 1.2 (20% padding).
136
+
137
+ Returns
138
+ -------
139
+ tuple
140
+ (min_energy, max_energy) in eV
141
+ """
142
+ # Generate high-symmetry points
143
+ kpoints = np.array(
144
+ [
145
+ [0.0, 0.0, 0.0], # Γ (zone center)
146
+ [0.5, 0.0, 0.0], # X
147
+ [0.5, 0.5, 0.0], # M
148
+ [0.5, 0.5, 0.5], # R (zone corner)
149
+ [0.0, 0.5, 0.0], # Y
150
+ [0.0, 0.0, 0.5], # Z
151
+ ]
152
+ )
153
+
154
+ # Calculate eigenvalues at these points
155
+ evals = self.magnon._magnon_energies(kpoints)
156
+ min_energy = evals.min()
157
+ max_energy = evals.max()
158
+
159
+ # Add padding and convert to eV
160
+ window_size = max_energy - min_energy
161
+ min_energy = min_energy - (padding_factor - 1) * window_size
162
+ max_energy = max_energy + (padding_factor - 1) * window_size
163
+
164
+ return min_energy, max_energy
165
+
166
+ def set_kmesh(self, kmesh=[9, 9, 9], gamma=True):
167
+ """Set k-point mesh for DOS calculation.
168
+
169
+ Parameters
170
+ ----------
171
+ kmesh : list, optional
172
+ Number of k-points along each direction
173
+ gamma : bool, optional
174
+ Whether to include Gamma point
175
+ """
176
+ self.kpts = monkhorst_pack(kmesh, gamma_center=gamma)
177
+ self.weights = np.ones(len(self.kpts)) / len(self.kpts)
178
+
179
+ def get_fermi_level(self):
180
+ return 0.0 # Fermi energy is not used in magnon calculations
181
+
182
+ def get_eigenvalues(self, kpt, spin=0):
183
+ """Get eigenvalues at a k-point.
184
+
185
+ Parameters
186
+ ----------
187
+ kpt : int
188
+ K-point index
189
+ spin : int, optional
190
+ Spin index (unused)
191
+
192
+ Returns
193
+ -------
194
+ numpy.ndarray
195
+ Eigenvalues in eV
196
+ """
197
+ kpoint = self.kpts[kpt]
198
+ evals = self.magnon._magnon_energies(np.array([kpoint]))[0]
199
+ return evals
200
+
201
+ def get_dos(self, width=0.1, window=None, npts=1001):
202
+ """Calculate DOS using ASE's DOS module.
203
+
204
+ Parameters
205
+ ----------
206
+ width : float, optional
207
+ Gaussian smearing width in eV
208
+ window : tuple, optional
209
+ Energy window (min, max) in eV
210
+ npts : int, optional
211
+ Number of energy points
212
+
213
+ Returns
214
+ -------
215
+ MagnonDOS
216
+ Calculated DOS object
217
+ """
218
+ if self.kpts is None:
219
+ self.set_kmesh()
220
+
221
+ # Estimate energy window if not provided
222
+ if window is None:
223
+ window = self.estimate_energy_range()
224
+
225
+ dos_calc = DOS(self, width=width, window=window, npts=npts)
226
+ energies = dos_calc.get_energies()
227
+ dos_vals = dos_calc.get_dos()
228
+
229
+ # Convert to meV
230
+ energies = energies * 1000 # eV to meV
231
+ dos_vals = dos_vals / 1000 # states/eV to states/meV
232
+
233
+ return MagnonDOS(
234
+ energies=energies,
235
+ dos=dos_vals,
236
+ weights=self.weights,
237
+ kpoints=self.kpts,
238
+ )
239
+
240
+ def get_number_of_spins(self):
241
+ """Required by ASE DOS calculator."""
242
+ return 1
243
+
244
+ def get_k_point_weights(self):
245
+ """Required by ASE DOS calculator."""
246
+ return self.weights
247
+
248
+ def get_bz_k_points(self):
249
+ """Required by ASE DOS calculator."""
250
+ return self.kpts
251
+
252
+
253
+ def plot_magnon_dos(
254
+ magnon,
255
+ kmesh=[9, 9, 9],
256
+ gamma=True,
257
+ width=0.0005,
258
+ window=None,
259
+ xlim=None,
260
+ npts=1001,
261
+ filename=None,
262
+ save_data=True,
263
+ show=True,
264
+ ):
265
+ """Convenience function to calculate and plot magnon DOS.
266
+
267
+ Parameters
268
+ ----------
269
+ magnon : Magnon
270
+ Magnon object containing exchange parameters
271
+ kmesh : list, optional
272
+ Number of k-points along each direction
273
+ gamma : bool, optional
274
+ Whether to include Gamma point
275
+ width : float, optional
276
+ Gaussian smearing width in eV
277
+ window : tuple, optional
278
+ Energy window (min, max) in eV
279
+ npts : int, optional
280
+ Number of energy points
281
+ filename : str, optional
282
+ Output filename for plot
283
+ save_data : bool, optional
284
+ Whether to save DOS data to JSON
285
+ show : bool, optional
286
+ Whether to show plot
287
+
288
+ Returns
289
+ -------
290
+ MagnonDOS
291
+ The calculated DOS object
292
+ """
293
+ calculator = MagnonDOSCalculator(magnon)
294
+ calculator.set_kmesh(kmesh=kmesh, gamma=gamma)
295
+ dos = calculator.get_dos(width=width, window=window, npts=npts)
296
+
297
+ # Plot DOS
298
+ dos.plot(filename=filename, show=show)
299
+
300
+ # Save data if requested
301
+ if save_data:
302
+ data_file = (
303
+ Path(filename).with_suffix(".json") if filename else Path("magnon_dos.json")
304
+ )
305
+ dos.save(data_file)
306
+ print(f"DOS data saved to {data_file}")
307
+
308
+ return dos
@@ -32,7 +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
+ # z = u #np.repeat(u, dim, axis=0)
36
36
  z = np.repeat(u, dim, axis=0)
37
37
  A = np.stack([z, np.cross(n, z), n], axis=1)
38
38
  B = np.stack([v, np.cross(n, v), n], axis=1)
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env python3
2
+ """Command-line tool for plotting magnon DOS from TB2J results."""
3
+
4
+ import argparse
5
+ from pathlib import Path
6
+
7
+ from TB2J.magnon.magnon3 import Magnon
8
+ from TB2J.magnon.magnon_dos import plot_magnon_dos
9
+
10
+
11
+ def main():
12
+ parser = argparse.ArgumentParser(
13
+ description="Calculate and plot magnon DOS from TB2J results"
14
+ )
15
+ parser.add_argument(
16
+ "--path",
17
+ default="TB2J_results",
18
+ help="Path to TB2J results directory (default: TB2J_results)",
19
+ )
20
+ parser.add_argument(
21
+ "--kmesh",
22
+ type=int,
23
+ nargs=3,
24
+ default=[20, 20, 20],
25
+ metavar=("nx", "ny", "nz"),
26
+ help="k-point mesh dimensions (default: 20, 20, 20)",
27
+ )
28
+ parser.add_argument(
29
+ "--no-gamma",
30
+ action="store_false",
31
+ dest="gamma",
32
+ help="Exclude Gamma point from k-mesh",
33
+ )
34
+ parser.add_argument(
35
+ "--width",
36
+ type=float,
37
+ default=0.001,
38
+ help="Gaussian smearing width in eV (default: 0.001)",
39
+ )
40
+ parser.add_argument(
41
+ "--window",
42
+ type=float,
43
+ nargs=2,
44
+ metavar=("emin", "emax"),
45
+ help="Energy window in meV (optional)",
46
+ )
47
+ parser.add_argument(
48
+ "--npts",
49
+ type=int,
50
+ default=401,
51
+ help="Number of energy points (default: 401)",
52
+ )
53
+ parser.add_argument(
54
+ "--output",
55
+ default="magnon_dos.png",
56
+ help="Output filename for plot (default: magnon_dos.png)",
57
+ )
58
+ parser.add_argument(
59
+ "-show",
60
+ action="store_true",
61
+ dest="show",
62
+ help="Show plot window",
63
+ )
64
+
65
+ args = parser.parse_args()
66
+
67
+ # Check if TB2J results exist
68
+ if not Path(args.path).exists():
69
+ raise FileNotFoundError(f"TB2J results not found at {args.path}")
70
+
71
+ # Load magnon calculator
72
+ print(f"Loading exchange parameters from {args.path}...")
73
+ magnon = Magnon.from_TB2J_results(path=args.path)
74
+
75
+ # Convert window from meV to eV if provided
76
+ window = None
77
+ if args.window is not None:
78
+ window = (args.window[0] / 1000, args.window[1] / 1000)
79
+
80
+ # Calculate and plot DOS
81
+ print("\nCalculating magnon DOS...")
82
+ _dos = plot_magnon_dos(
83
+ magnon,
84
+ kmesh=args.kmesh,
85
+ gamma=args.gamma,
86
+ width=args.width,
87
+ window=window,
88
+ npts=args.npts,
89
+ filename=args.output,
90
+ show=args.show,
91
+ )
92
+
93
+ print(f"\nPlot saved to {args.output}")
94
+ data_file = Path(args.output).with_suffix(".json")
95
+ print(f"DOS data saved to {data_file}")
96
+
97
+
98
+ if __name__ == "__main__":
99
+ main()
@@ -1,8 +1,8 @@
1
1
  #!python
2
2
  import argparse
3
- import os
4
- import sys
3
+
5
4
  from TB2J.io_merge import merge
5
+ from TB2J.version_info import print_license
6
6
 
7
7
 
8
8
  def main():
@@ -32,14 +32,18 @@ def main():
32
32
  "--main_path",
33
33
  help="The path containning the reference structure.",
34
34
  type=str,
35
- default=None
35
+ default=None,
36
36
  )
37
37
 
38
38
  args = parser.parse_args()
39
39
  # merge(*(args.directories), args.type.strip().lower(), path=args.output_path)
40
40
  # merge(*(args.directories), method=args.type.strip().lower(), path=args.output_path)
41
- #merge2(args.directories, args.type.strip().lower(), path=args.output_path)
41
+ # merge2(args.directories, args.type.strip().lower(), path=args.output_path)
42
+ print_license()
43
+ print("Merging the TB2J results from the following directories: ", args.directories)
42
44
  merge(*args.directories, main_path=args.main_path, write_path=args.output_path)
45
+ print("Merging completed. The results are saved in:", args.output_path)
43
46
 
44
47
 
45
- main()
48
+ if __name__ == "__main__":
49
+ main()
@@ -0,0 +1,27 @@
1
+ #!python
2
+
3
+
4
+ if __name__ == "__main__":
5
+ # add a warning messege that this functionality is under development and should not be used in production.
6
+ # make it visually distinct, e.g. with a different color or formatting.
7
+ import warnings
8
+
9
+ from TB2J.magnon.magnon3 import main
10
+
11
+ warnings.warn(
12
+ """
13
+ # !!!!!!!!!!!!!!!!!! WARNING: =============================
14
+ #
15
+ # This functionality is under development and should not be used in production.
16
+ # It is provided for testing and development purposes only.
17
+ # Please use with caution and report any issues to the developers.
18
+ #
19
+ # This warning will be removed in future releases.
20
+ # =====================================
21
+
22
+ """,
23
+ UserWarning,
24
+ stacklevel=2,
25
+ )
26
+ # Call the main function from the magnons module
27
+ main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: TB2J
3
- Version: 0.9.9.13
3
+ Version: 0.9.9.15
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
@@ -1,17 +1,17 @@
1
1
  TB2J/Jdownfolder.py,sha256=n5BeQCYP4mD9JsAPeE1F3ZKKR3SUxADfDbaG_rzi77k,9658
2
2
  TB2J/Jtensor.py,sha256=Wi06AAbfKFU6f2a2jkFr9zU2cwwfVroajTp-dwCtkTE,3160
3
3
  TB2J/MAE.py,sha256=fM8U-Dgp9HcQOEeC_kyZV1oVrygBvcux9BraUXVouvY,10994
4
- TB2J/MAEGreen.py,sha256=DHoU6nlM0Fk42T_SYd_s-VafB6wCZNzVzRXhuv-hCwM,15762
4
+ TB2J/MAEGreen.py,sha256=zVLjQtFDFcRmC8PYm7MOgKnkOuFJEMKr-eoNBABUsMc,15759
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=TcMW0FTsZFR9McJTh8TBwZl2lylHc2uwsxVV9PsgSwY,25
7
+ TB2J/__init__.py,sha256=VIRI2sifGP0sSwxkmWEp9IvuVn2fBhvrNpmqbwLrG8s,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=rJ7XeHOo6j9A0alauM2XQ5DvTO741dq_pDQQxyyn8mE,26981
14
+ TB2J/exchange.py,sha256=-BEXSQqx374cRbJWjvjyJAZkchzNK1uPUDvTYox3Axs,26982
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=xj5sIo5o62HYwSnijGycem_rAc8kSzY-HI2IJDRhzyE,7405
22
+ TB2J/io_merge.py,sha256=mgoc8ZUP_a_g-9KvWWISp25qo6aBJ8TQsDsBrMSB5nk,7509
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,31 +43,33 @@ 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=Y4rRn_MRZUOI4y4btgCKTtVy8iXrSpaBuK7SMCJ1C2o,7594
46
+ TB2J/interfaces/siesta_interface.py,sha256=Te9-Au0ZGAt-LfEnG8exUFD4lMj6uZu8RmHjopb0XLU,7595
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=UsIs55Y_1AM31N2oCjwmgHIMgRIcusKA6g3K2tjr3uM,67945
53
+ TB2J/interfaces/abacus/stru_api.py,sha256=Hb9MCo_4d_DVEEhntvBNAFw5KQ46TkAADn4z7CT6qOk,67801
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=KnR2UyvMSoBye8dD6ETqZW6nld-CcYchcCrAmHbVsBA,22735
58
+ TB2J/io_exchange/io_exchange.py,sha256=TQPsxpV0vyFq-HFRRt9GQbpnmRw-5KwyM26eb9fKaoY,22743
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
62
62
  TB2J/io_exchange/io_uppasd.py,sha256=bI4iPEgnK4TvCZNvb6x2xYXgjW7pEehCqmcizy2pqFU,3301
63
- TB2J/io_exchange/io_vampire.py,sha256=u4NZhqoC_JBcVq19WZfBkyM5p8u-OMuRoUrtFIcPp5E,5762
63
+ TB2J/io_exchange/io_vampire.py,sha256=vOStLmtCiWLp9GPhZpsAmrtaRHg9KSmtOM2Fky6yCQA,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=75YmSTT652q7lLEmJmn4-TbIkwJnjjelMfu0eyEzjA0,27401
67
- TB2J/magnon/magnon_band.py,sha256=8HJWl1zcYSxJQflFUj4qaITnTWE-rhF5zQ1YgQN78oU,6098
66
+ TB2J/magnon/magnon3.py,sha256=PFZFiyfYTIBscVu8SzvGxtrXhT-QM66EwIhWOqgSYQE,30219
67
+ TB2J/magnon/magnon_band.py,sha256=ZLHK1qf2Clu9jlcvBwBCBEi1MrPfy2BWrow8JJ2v5pk,6103
68
+ TB2J/magnon/magnon_dos.py,sha256=uztzsxCmFZpDHl-JziaUb_NNwBeZw9-L2ozd3XNTvxI,8506
68
69
  TB2J/magnon/magnon_io.py,sha256=H4bmzCcnh1D3Sb6UBIIKWa6jIrA20dg9lX4wfLXHEjo,1241
69
- TB2J/magnon/magnon_math.py,sha256=b4Po_aZm8aIhr5u2nbjjtDDMTKV_ecI2d6Fc_AhiuNc,1358
70
+ TB2J/magnon/magnon_math.py,sha256=0mVQY5tXe6fHsfijivXf-1-Tk-Ku02Gv7-TdAd8qUpc,1359
70
71
  TB2J/magnon/plot.py,sha256=oNavax15jRfW4Sxl6FgwLXSrMntyVz2cgVDbmgkWehw,3193
72
+ TB2J/magnon/plot_magnon_dos_cli.py,sha256=XVozodrIO_w4FBhp-ZcpIZbyGWLdegUFLdvY5zL3XOI,2592
71
73
  TB2J/magnon/structure.py,sha256=rKefzXgQlEjVvV-A7E2IogVDWwf5egZr3Wxxu6HuJU4,7685
72
74
  TB2J/mathutils/__init__.py,sha256=E70Mx8mLXh3DJGmdN3TLWmGYMcsbvKxmgxUbAI6Mzmo,49
73
75
  TB2J/mathutils/auto_kpath.py,sha256=bDXDyQzRByVpPSOpz7NU7F5hYqS6IX-47lwWoMU89lM,4978
@@ -89,21 +91,21 @@ TB2J/spinham/supercell.py,sha256=y17uUC6r3gQb278FhxIW4CABihfLTvKFj6flyXrCPR8,122
89
91
  TB2J/wannier/__init__.py,sha256=7ojCbM84PYv1X1Tbo4NHI-d3gWmQsZB_xiYqbfxVV1E,80
90
92
  TB2J/wannier/w90_parser.py,sha256=dbd63LuKyv2DVUzqRINGsbDzEsOxsQyE8_Ear_LQIRg,4620
91
93
  TB2J/wannier/w90_tb_parser.py,sha256=qt8pnuprmPp9iIAYwPkPbmEzk6ZPgMq2xognoQp7vwc,4610
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,,
94
+ tb2j-0.9.9.15.data/scripts/TB2J_downfold.py,sha256=i4BVqnpDdgrX_amookVWeLGefGBn-qeAutWiwuY9SfQ,2099
95
+ tb2j-0.9.9.15.data/scripts/TB2J_eigen.py,sha256=Qs9v2hnMm2Tpfoa4h53muUKty2dZjwx8948MBoQooNg,1128
96
+ tb2j-0.9.9.15.data/scripts/TB2J_magnon.py,sha256=q7UwAmorRcFNk4tfE7gl_ny05l6p7pbD9Wm_LkIpKEw,3101
97
+ tb2j-0.9.9.15.data/scripts/TB2J_magnon2.py,sha256=tMa7Fg_Wd2UytnrH3C_AsgGM7BciUW0iy6NiPlWvar8,1920
98
+ tb2j-0.9.9.15.data/scripts/TB2J_magnon_dos.py,sha256=TMXQvD2dIbO5FZ4tUMmxJgCgH2O2hDAPUNfEKO4z-x4,110
99
+ tb2j-0.9.9.15.data/scripts/TB2J_merge.py,sha256=WQVrS2FvrjxkKukiPLY-naQxEK-d2T-bAb5n7e6ml2I,2096
100
+ tb2j-0.9.9.15.data/scripts/TB2J_plot_magnon_bands.py,sha256=wLlueNI-wU79cmPFu4LmPDwVBMerKSb5sUlTDSPQK6I,874
101
+ tb2j-0.9.9.15.data/scripts/TB2J_rotate.py,sha256=zgiDFuYZNmzKK0rwDmTaYD2OpRlmKA_VGeBx83w2Xwc,873
102
+ tb2j-0.9.9.15.data/scripts/TB2J_rotateDM.py,sha256=kCvF7gotuqAX1VnJ06cwfVm7RrhrdtiV5v7d9P2Pn_E,567
103
+ tb2j-0.9.9.15.data/scripts/abacus2J.py,sha256=ozYI7qZyja1WEs9oCYVpeYAfVj5PGhehhmdZFcvrd3g,1795
104
+ tb2j-0.9.9.15.data/scripts/siesta2J.py,sha256=QJ6c0DbqxaqYEesxiL5R9nK9-flNLrr7hajKfCwirYc,2318
105
+ tb2j-0.9.9.15.data/scripts/wann2J.py,sha256=OA31VHEXbQMD-JozoLUHDF6vB9Sr62d804OApSKtSnU,3240
106
+ tb2j-0.9.9.15.dist-info/licenses/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
107
+ tb2j-0.9.9.15.dist-info/METADATA,sha256=4MA4Id_pqZPASA3ig_9xiICywGLB06rlUT6bPiccdW4,1768
108
+ tb2j-0.9.9.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
109
+ tb2j-0.9.9.15.dist-info/entry_points.txt,sha256=S81PATMTaKCIznjd3pei3Kb3q3xOy2dU-x_cAFSCS7k,194
110
+ tb2j-0.9.9.15.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
111
+ tb2j-0.9.9.15.dist-info/RECORD,,
@@ -1,3 +1,4 @@
1
1
  [console_scripts]
2
+ TB2J_plot_magnon_dos.py = TB2J.magnon.plot_magnon_dos_cli:main
2
3
  TB2J_symmetrize.py = TB2J.symmetrize_J:symmetrize_J_cli
3
4
  lawaf2J.py = TB2J.interfaces.lawaf_interface:lawaf2J_cli
@@ -1,7 +0,0 @@
1
- #!python
2
-
3
-
4
- if __name__ == "__main__":
5
- from TB2J.magnon.magnon3 import main
6
-
7
- main()