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.
Files changed (31) hide show
  1. TB2J/Jtensor.py +5 -6
  2. TB2J/MAEGreen.py +8 -0
  3. TB2J/__init__.py +1 -1
  4. TB2J/exchange.py +1 -1
  5. TB2J/interfaces/abacus/stru_api.py +3 -1
  6. TB2J/interfaces/siesta_interface.py +2 -1
  7. TB2J/io_exchange/io_exchange.py +17 -7
  8. TB2J/io_merge.py +15 -1
  9. TB2J/magnon/magnon3.py +36 -16
  10. TB2J/magnon/magnon_band.py +38 -33
  11. TB2J/magnon/magnon_math.py +1 -0
  12. TB2J/magnon/plot.py +3 -3
  13. TB2J/mathutils/auto_kpath.py +4 -7
  14. {tb2j-0.9.9.10.dist-info → tb2j-0.9.9.13.dist-info}/METADATA +3 -2
  15. {tb2j-0.9.9.10.dist-info → tb2j-0.9.9.13.dist-info}/RECORD +31 -31
  16. {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_downfold.py +0 -0
  17. {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_eigen.py +0 -0
  18. {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_magnon.py +0 -0
  19. {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_magnon2.py +0 -0
  20. {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_magnon_dos.py +0 -0
  21. {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_merge.py +0 -0
  22. {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_plot_magnon_bands.py +0 -0
  23. {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_rotate.py +0 -0
  24. {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/TB2J_rotateDM.py +0 -0
  25. {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/abacus2J.py +0 -0
  26. {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/siesta2J.py +0 -0
  27. {tb2j-0.9.9.10.data → tb2j-0.9.9.13.data}/scripts/wann2J.py +0 -0
  28. {tb2j-0.9.9.10.dist-info → tb2j-0.9.9.13.dist-info}/WHEEL +0 -0
  29. {tb2j-0.9.9.10.dist-info → tb2j-0.9.9.13.dist-info}/entry_points.txt +0 -0
  30. {tb2j-0.9.9.10.dist-info → tb2j-0.9.9.13.dist-info}/licenses/LICENSE +0 -0
  31. {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=0.0, D=np.zeros(3), Jani=np.zeros((3, 3), dtype=float)):
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=complex)
81
+ Jtensor = np.zeros((3, 3), dtype=dtype)
83
82
  if Jiso is not None:
84
- Jtensor += np.eye(3, dtype=float) * Jiso
83
+ Jtensor += np.eye(3, dtype=dtype) * Jiso
85
84
  if Jani is not None:
86
- Jtensor += np.array(Jani, dtype=float)
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=float
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.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="axis",
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."
@@ -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 np.real(self.dmi_ddict[(tuple(R), i, j)])
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 np.real(self.Jani_dict[(tuple(R), i, j)])
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
- 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
- )
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(self.cell, None, npoints=npoints)
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 'path' in kwargs and kwargs['path'] is None:
346
- _, kptlist, _, _, spk = auto_kpath(self.cell, None, npoints=kwargs.get('npoints', 300))
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(path=kwargs.get('path', 'GXMG'), npoints=kwargs.get('npoints', 300))
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, 'w') as f:
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('.', 1)[0]
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)
@@ -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, **kwargs):
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('linewidth', 1.5)
69
- color = kwargs.pop('color', 'blue')
70
- linestyle = kwargs.pop('linestyle', '-')
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='black',
117
+ color="black",
117
118
  linewidth=linewidth / 5,
118
119
  )
119
120
 
120
- ax.set_ylabel('Energy (meV)')
121
+ ax.set_ylabel("Energy (meV)")
121
122
 
122
123
  if filename is not None:
123
- plt.savefig(filename, dpi=300, bbox_inches='tight')
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('.json'):
138
- filename = filename + '.json'
138
+ if not filename.endswith(".json"):
139
+ filename = filename + ".json"
139
140
 
140
141
  data = {
141
- 'kpoints': self.kpoints.tolist(),
142
- 'energies': self.energies.tolist(),
143
- 'kpath_labels': [(int(i), str(l)) for i, l in self.kpath_labels],
144
- 'special_points': {k: v.tolist() for k, v in self.special_points.items()},
145
- 'xcoords': self.xcoords.tolist() if isinstance(self.xcoords, np.ndarray)
146
- else [x.tolist() for x in self.xcoords] if self.xcoords is not None
147
- else None,
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, 'w') as f:
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) -> 'MagnonBand':
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['kpoints'] = np.array(data['kpoints'])
172
- data['energies'] = np.array(data['energies'])
173
- if data['xcoords'] is not None:
174
- if isinstance(data['xcoords'][0], list): # Segmented path
175
- data['xcoords'] = [np.array(x) for x in data['xcoords']]
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['xcoords'] = np.array(data['xcoords'])
178
- data['special_points'] = {k: np.array(v) for k, v in data['special_points'].items()}
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)
@@ -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,
@@ -1,10 +1,9 @@
1
- #!/usr/bin/env python
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.10
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.3
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=t6OsqrSlYW6Im4H7ykVAW8Al_pFXN4C5yj2UEsV6r7g,3181
2
+ TB2J/Jtensor.py,sha256=Wi06AAbfKFU6f2a2jkFr9zU2cwwfVroajTp-dwCtkTE,3160
3
3
  TB2J/MAE.py,sha256=fM8U-Dgp9HcQOEeC_kyZV1oVrygBvcux9BraUXVouvY,10994
4
- TB2J/MAEGreen.py,sha256=Iq4hlZrKEOycPvpV66_t13WIcJ1FJgBS79NleXYpFzw,15528
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=AuZFEUeBNk8Hny02OhG2Y1omWiUh5m4XffiIIrWZkoI,24
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=P0GR2mlb-c_59fM_rFmc2C5zN8G7z5-cCsI7YAN5Aik,26980
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=E1_GfAB2HGpW-ipaO2lqU9SvaslwkiLxssn4DqJpMT8,6899
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=nkb8CTjHtv3DgMok4njyiaE-vDGDJFCjLHat71R_Z48,7561
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=Ac03ikHRsZRXqTul4IUge7D2iG_xLh4_oyYfeP9tzGE,67881
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=px0FcH_Vx7FfoB2rA3ERXImjfrbYuBB7UImBxg6R_8E,22585
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=IhuDqqkWP5NzMjaPoVk2C5aw4xIgrxgWfNdrZfoPd70,27064
67
- TB2J/magnon/magnon_band.py,sha256=S8W0sP-uR0urmi85QZRIDevIYnALUKAd1DPF99KLvAI,6076
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=hJ2k24eR4TzdaFMxfxgCr10lWV4GEcfaf2WxhWj-uUk,1320
70
- TB2J/magnon/plot.py,sha256=QxkI2bIs-wF31rUzyxL-SRR_r7XY-gFVLb9SVFnGaJY,3197
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=9vhb_3iRSYE7eRmY1sVRqkK3i4KzaGAw1w0SmCzIA7Y,5119
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.10.data/scripts/TB2J_downfold.py,sha256=i4BVqnpDdgrX_amookVWeLGefGBn-qeAutWiwuY9SfQ,2099
93
- tb2j-0.9.9.10.data/scripts/TB2J_eigen.py,sha256=Qs9v2hnMm2Tpfoa4h53muUKty2dZjwx8948MBoQooNg,1128
94
- tb2j-0.9.9.10.data/scripts/TB2J_magnon.py,sha256=q7UwAmorRcFNk4tfE7gl_ny05l6p7pbD9Wm_LkIpKEw,3101
95
- tb2j-0.9.9.10.data/scripts/TB2J_magnon2.py,sha256=tMa7Fg_Wd2UytnrH3C_AsgGM7BciUW0iy6NiPlWvar8,1920
96
- tb2j-0.9.9.10.data/scripts/TB2J_magnon_dos.py,sha256=TMXQvD2dIbO5FZ4tUMmxJgCgH2O2hDAPUNfEKO4z-x4,110
97
- tb2j-0.9.9.10.data/scripts/TB2J_merge.py,sha256=y834SF4rIRn1L1ptkhczvavQpC-8Px6DTmDOOSaq_DE,1854
98
- tb2j-0.9.9.10.data/scripts/TB2J_plot_magnon_bands.py,sha256=qUbisPFLvW_j1IdTpc_jU0WiT-7CT-WErbkhNvAPM0Y,91
99
- tb2j-0.9.9.10.data/scripts/TB2J_rotate.py,sha256=zgiDFuYZNmzKK0rwDmTaYD2OpRlmKA_VGeBx83w2Xwc,873
100
- tb2j-0.9.9.10.data/scripts/TB2J_rotateDM.py,sha256=kCvF7gotuqAX1VnJ06cwfVm7RrhrdtiV5v7d9P2Pn_E,567
101
- tb2j-0.9.9.10.data/scripts/abacus2J.py,sha256=ozYI7qZyja1WEs9oCYVpeYAfVj5PGhehhmdZFcvrd3g,1795
102
- tb2j-0.9.9.10.data/scripts/siesta2J.py,sha256=QJ6c0DbqxaqYEesxiL5R9nK9-flNLrr7hajKfCwirYc,2318
103
- tb2j-0.9.9.10.data/scripts/wann2J.py,sha256=OA31VHEXbQMD-JozoLUHDF6vB9Sr62d804OApSKtSnU,3240
104
- tb2j-0.9.9.10.dist-info/licenses/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
105
- tb2j-0.9.9.10.dist-info/METADATA,sha256=BlrZOTmf-aA9vZ2QD5g3JzA4nHxJPNjvJlGeHVQ9KYI,1745
106
- tb2j-0.9.9.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
107
- tb2j-0.9.9.10.dist-info/entry_points.txt,sha256=Hdz1WC9waUzyFVmowKnbbZ6j-J4adHh_Ko6JpxGYAtE,131
108
- tb2j-0.9.9.10.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
109
- tb2j-0.9.9.10.dist-info/RECORD,,
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,,