TB2J 0.9.12.18__py3-none-any.whl → 0.9.12.23__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 (40) hide show
  1. TB2J/MAE.py +8 -1
  2. TB2J/MAEGreen.py +0 -2
  3. TB2J/exchange.py +11 -4
  4. TB2J/exchangeCL2.py +2 -0
  5. TB2J/exchange_params.py +24 -0
  6. TB2J/green.py +15 -3
  7. TB2J/interfaces/abacus/gen_exchange_abacus.py +2 -1
  8. TB2J/io_exchange/__init__.py +19 -1
  9. TB2J/io_exchange/edit.py +594 -0
  10. TB2J/io_exchange/io_exchange.py +243 -74
  11. TB2J/io_exchange/io_tomsasd.py +4 -3
  12. TB2J/io_exchange/io_txt.py +72 -7
  13. TB2J/io_exchange/io_vampire.py +1 -1
  14. TB2J/io_merge.py +60 -40
  15. TB2J/magnon/magnon3.py +27 -2
  16. TB2J/mathutils/rotate_spin.py +7 -7
  17. TB2J/mycfr.py +16 -16
  18. TB2J/plot.py +26 -0
  19. TB2J/scripts/TB2J_edit.py +403 -0
  20. TB2J/scripts/TB2J_plot_exchange.py +48 -0
  21. TB2J/spinham/hamiltonian.py +156 -13
  22. TB2J/spinham/hamiltonian_terms.py +40 -1
  23. TB2J/spinham/spin_xml.py +40 -8
  24. TB2J/symmetrize_J.py +138 -7
  25. TB2J/tests/test_cli_remove_sublattice.py +33 -0
  26. TB2J/tests/test_cli_toggle_exchange.py +50 -0
  27. {tb2j-0.9.12.18.dist-info → tb2j-0.9.12.23.dist-info}/METADATA +7 -3
  28. {tb2j-0.9.12.18.dist-info → tb2j-0.9.12.23.dist-info}/RECORD +32 -35
  29. {tb2j-0.9.12.18.dist-info → tb2j-0.9.12.23.dist-info}/WHEEL +1 -1
  30. {tb2j-0.9.12.18.dist-info → tb2j-0.9.12.23.dist-info}/entry_points.txt +2 -0
  31. TB2J/.gitignore +0 -5
  32. TB2J/agent_files/debug_spinphon_fd/debug_main.py +0 -156
  33. TB2J/agent_files/debug_spinphon_fd/test_compute_dJdx.py +0 -272
  34. TB2J/agent_files/debug_spinphon_fd/test_ispin0_only.py +0 -120
  35. TB2J/agent_files/debug_spinphon_fd/test_no_d2j.py +0 -31
  36. TB2J/agent_files/debug_spinphon_fd/test_with_d2j.py +0 -28
  37. TB2J/interfaces/abacus/test_read_HRSR.py +0 -43
  38. TB2J/interfaces/abacus/test_read_stru.py +0 -32
  39. {tb2j-0.9.12.18.dist-info → tb2j-0.9.12.23.dist-info}/licenses/LICENSE +0 -0
  40. {tb2j-0.9.12.18.dist-info → tb2j-0.9.12.23.dist-info}/top_level.txt +0 -0
TB2J/MAE.py CHANGED
@@ -136,7 +136,14 @@ class MAEGreen(MAE):
136
136
  # occ.occupy(evals)
137
137
  efermi = occ.efermi(evals)
138
138
  print(f"{efermi=}")
139
- self.G = TBGreen(model, kmesh, efermi=efermi, gamma=gamma, **kwargs)
139
+ self.G = TBGreen(
140
+ model,
141
+ kmesh,
142
+ efermi=efermi,
143
+ gamma=gamma,
144
+ smearing_width=self.width,
145
+ **kwargs,
146
+ )
140
147
  self.emin = -52
141
148
  self.emax = 0
142
149
  self.nz = 100
TB2J/MAEGreen.py CHANGED
@@ -374,7 +374,6 @@ def abacus_get_MAE(
374
374
  phis,
375
375
  gamma=True,
376
376
  output_path="TB2J_anisotropy",
377
- magnetic_elements=None,
378
377
  nel=None,
379
378
  width=0.1,
380
379
  with_eigen=False,
@@ -395,7 +394,6 @@ def abacus_get_MAE(
395
394
  efermi=None,
396
395
  basis=model.basis,
397
396
  angles=[thetas, phis],
398
- magnetic_elements=magnetic_elements,
399
397
  **kwargs,
400
398
  )
401
399
  mae.run(output_path=output_path, with_eigen=with_eigen)
TB2J/exchange.py CHANGED
@@ -3,6 +3,7 @@ import pickle
3
3
  from collections import defaultdict
4
4
  from itertools import product
5
5
 
6
+ import ase.units
6
7
  import numpy as np
7
8
  from tqdm import tqdm
8
9
 
@@ -28,8 +29,8 @@ class Exchange(ExchangeParams):
28
29
  self._prepare_Rlist()
29
30
  self.set_tbmodels(tbmodels)
30
31
  self._adjust_emin()
31
- # self._prepare_elist(method="CFR")
32
- self._prepare_elist(method="legendre")
32
+ self._prepare_elist(method="CFR")
33
+ # self._prepare_elist(method="legendre")
33
34
  self._prepare_basis()
34
35
  self._prepare_orb_dict()
35
36
  self._prepare_distance()
@@ -74,12 +75,14 @@ class Exchange(ExchangeParams):
74
75
  for k in kmesh:
75
76
  self.kmesh = list(map(lambda x: x // 2 * 2 + 1, kmesh))
76
77
 
77
- def _prepare_elist(self, method="CFR"):
78
+ def _prepare_elist(self, method=None):
78
79
  """
79
80
  prepare list of energy for integration.
80
81
  The path has three segments:
81
82
  emin --1-> emin + 1j*height --2-> emax+1j*height --3-> emax
82
83
  """
84
+ if method is None:
85
+ method = "CFR"
83
86
  # if method.lower() == "rectangle":
84
87
  # self.contour.build_path_rectangle(
85
88
  # height=self.height, nz1=self.nz1, nz2=self.nz2, nz3=self.nz3
@@ -91,7 +94,10 @@ class Exchange(ExchangeParams):
91
94
  self.contour = Contour(self.emin, self.emax)
92
95
  self.contour.build_path_legendre(npoints=self.nz, endpoint=True)
93
96
  elif method.lower() == "cfr":
94
- self.contour = CFR(nz=self.nz, T=600)
97
+ # Convert smearing from eV to temperature (K) for CFR
98
+ # smearing = kB * T => T = smearing / kB
99
+ T_kelvin = self.smearing / ase.units.kB
100
+ self.contour = CFR(nz=self.nz, T=T_kelvin)
95
101
  else:
96
102
  raise ValueError(f"The path cannot be of type {method}.")
97
103
 
@@ -359,6 +365,7 @@ class ExchangeNCL(Exchange):
359
365
  use_cache=self._use_cache,
360
366
  nproc=self.nproc,
361
367
  initial_emin=self.emin,
368
+ smearing_width=self.smearing,
362
369
  )
363
370
  if self.efermi is None:
364
371
  self.efermi = self.G.efermi
TB2J/exchangeCL2.py CHANGED
@@ -29,6 +29,7 @@ class ExchangeCL2(ExchangeCL):
29
29
  efermi=self.efermi,
30
30
  use_cache=self._use_cache,
31
31
  nproc=self.nproc,
32
+ smearing_width=self.smearing,
32
33
  )
33
34
  self.Gdn = TBGreen(
34
35
  tbmodel=self.tbmodel_dn,
@@ -36,6 +37,7 @@ class ExchangeCL2(ExchangeCL):
36
37
  efermi=self.efermi,
37
38
  use_cache=self._use_cache,
38
39
  nproc=self.nproc,
40
+ smearing_width=self.smearing,
39
41
  )
40
42
  if self.write_density_matrix:
41
43
  self.Gup.write_rho_R(
TB2J/exchange_params.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import argparse
2
2
  from dataclasses import dataclass
3
3
 
4
+ import ase.units
4
5
  import yaml
5
6
 
6
7
  __all__ = ["ExchangeParams", "add_exchange_args_to_parser", "parser_argument_to_dict"]
@@ -13,6 +14,7 @@ class ExchangeParams:
13
14
  """
14
15
 
15
16
  efermi: float
17
+ smearing: float = 600.0 * ase.units.kB
16
18
  basis = []
17
19
  magnetic_elements = []
18
20
  index_magnetic_atoms = None
@@ -43,6 +45,7 @@ class ExchangeParams:
43
45
  def __init__(
44
46
  self,
45
47
  efermi=-10.0,
48
+ smearing=600.0 * ase.units.kB,
46
49
  basis=None,
47
50
  magnetic_elements=None,
48
51
  include_orbs=None,
@@ -66,6 +69,7 @@ class ExchangeParams:
66
69
  debug_options=None,
67
70
  ):
68
71
  self.efermi = efermi
72
+ self.smearing = smearing
69
73
  self.basis = basis
70
74
  # self.magnetic_elements = magnetic_elements
71
75
  # self.include_orbs = include_orbs
@@ -157,6 +161,12 @@ def add_exchange_args_to_parser(parser: argparse.ArgumentParser):
157
161
  type=float,
158
162
  )
159
163
  parser.add_argument("--efermi", help="Fermi energy in eV", default=None, type=float)
164
+ parser.add_argument(
165
+ "--smearing",
166
+ help="Fermi smearing width for density computation and CFR. Units: K (default) or eV. Example: '600K', '0.2eV'. Default: 600K.",
167
+ default="600K",
168
+ type=str,
169
+ )
160
170
  parser.add_argument(
161
171
  "--ne",
162
172
  help="number of electrons in the unit cell. If not given, TB2J will use the fermi energy to compute it.",
@@ -279,8 +289,22 @@ def parser_argument_to_dict(args) -> dict:
279
289
  ind_mag_atoms = [int(i) - 1 for i in ind_mag_atoms]
280
290
  else:
281
291
  ind_mag_atoms = None
292
+
293
+ smearing_str = args.smearing
294
+ if smearing_str is None:
295
+ smearing = 600.0 * ase.units.kB
296
+ else:
297
+ s = smearing_str.strip().lower()
298
+ if s.endswith("ev"):
299
+ smearing = float(s[:-2])
300
+ elif s.endswith("k"):
301
+ smearing = float(s[:-1]) * ase.units.kB
302
+ else:
303
+ smearing = float(s) * ase.units.kB
304
+
282
305
  return {
283
306
  "efermi": args.efermi,
307
+ "smearing": smearing,
284
308
  "magnetic_elements": args.elements,
285
309
  "kmesh": args.kmesh,
286
310
  "emin": args.emin,
TB2J/green.py CHANGED
@@ -93,6 +93,7 @@ class TBGreen:
93
93
  cache_path=None,
94
94
  nproc=1,
95
95
  initial_emin=-25,
96
+ smearing_width=0.01,
96
97
  ):
97
98
  """
98
99
  :param tbmodel: A tight binding model
@@ -130,6 +131,7 @@ class TBGreen:
130
131
  self.nbasis = tbmodel.nbasis
131
132
  self.k_sym = k_sym
132
133
  self.nproc = nproc
134
+ self.fermi_width = float(smearing_width)
133
135
  self._prepare_eigen()
134
136
 
135
137
  def prepare_kpts(
@@ -344,14 +346,24 @@ class TBGreen:
344
346
  evecs_k = self.get_evecs(ik)
345
347
  # chekc if any of the evecs element is nan
346
348
  rho += (
347
- (evecs_k * fermi(self.evals[ik], self.efermi, nspin=2))
349
+ (
350
+ evecs_k
351
+ * fermi(
352
+ self.evals[ik], self.efermi, width=self.fermi_width, nspin=2
353
+ )
354
+ )
348
355
  @ evecs_k.T.conj()
349
356
  * self.kweights[ik]
350
357
  )
351
358
  else:
352
359
  for ik, _ in enumerate(self.kpts):
353
360
  rho += (
354
- (self.get_evecs(ik) * fermi(self.evals[ik], self.efermi, nspin=2))
361
+ (
362
+ self.get_evecs(ik)
363
+ * fermi(
364
+ self.evals[ik], self.efermi, width=self.fermi_width, nspin=2
365
+ )
366
+ )
355
367
  @ self.get_evecs(ik).T.conj()
356
368
  @ self.get_Sk(ik)
357
369
  * self.kweights[ik]
@@ -367,7 +379,7 @@ class TBGreen:
367
379
  rhok = np.einsum(
368
380
  "ib,b, bj-> ij",
369
381
  evec,
370
- fermi(self.evals[ik], self.efermi, nspin=2),
382
+ fermi(self.evals[ik], self.efermi, width=self.fermi_width, nspin=2),
371
383
  evec.conj().T,
372
384
  )
373
385
  for iR, R in enumerate(Rlist):
@@ -91,11 +91,12 @@ data directory: {outpath}
91
91
  Rcut=Rcut,
92
92
  nproc=nproc,
93
93
  use_cache=use_cache,
94
+ output_path=output_path,
94
95
  orb_decomposition=orb_decomposition,
95
96
  index_magnetic_atoms=index_magnetic_atoms,
96
97
  description=description,
97
98
  )
98
- exchange.run()
99
+ exchange.run(path=output_path)
99
100
  print("\n")
100
101
  print("All calculation finsihed. The results are in TB2J_results directory.")
101
102
 
@@ -1,3 +1,21 @@
1
+ from .edit import (
2
+ load,
3
+ save,
4
+ set_anisotropy,
5
+ symmetrize_exchange,
6
+ toggle_DMI,
7
+ toggle_exchange,
8
+ toggle_Jani,
9
+ )
1
10
  from .io_exchange import SpinIO
2
11
 
3
- __all__ = ["SpinIO"]
12
+ __all__ = [
13
+ "SpinIO",
14
+ "load",
15
+ "save",
16
+ "set_anisotropy",
17
+ "toggle_DMI",
18
+ "toggle_Jani",
19
+ "toggle_exchange",
20
+ "symmetrize_exchange",
21
+ ]