TB2J 0.9.12.9__py3-none-any.whl → 0.9.12.22__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 +78 -61
  3. TB2J/contour.py +3 -2
  4. TB2J/exchange.py +346 -51
  5. TB2J/exchangeCL2.py +285 -47
  6. TB2J/exchange_params.py +48 -0
  7. TB2J/green.py +73 -36
  8. TB2J/interfaces/abacus/gen_exchange_abacus.py +2 -1
  9. TB2J/interfaces/wannier90_interface.py +4 -4
  10. TB2J/io_exchange/__init__.py +19 -1
  11. TB2J/io_exchange/edit.py +594 -0
  12. TB2J/io_exchange/io_espins.py +276 -0
  13. TB2J/io_exchange/io_exchange.py +248 -76
  14. TB2J/io_exchange/io_tomsasd.py +4 -3
  15. TB2J/io_exchange/io_txt.py +72 -7
  16. TB2J/io_exchange/io_vampire.py +4 -2
  17. TB2J/io_merge.py +60 -40
  18. TB2J/magnon/magnon3.py +27 -2
  19. TB2J/mathutils/rotate_spin.py +7 -7
  20. TB2J/myTB.py +11 -11
  21. TB2J/mycfr.py +11 -11
  22. TB2J/pauli.py +32 -2
  23. TB2J/plot.py +26 -0
  24. TB2J/rotate_atoms.py +9 -6
  25. TB2J/scripts/TB2J_edit.py +403 -0
  26. TB2J/scripts/TB2J_plot_exchange.py +48 -0
  27. TB2J/spinham/hamiltonian.py +156 -13
  28. TB2J/spinham/hamiltonian_terms.py +40 -1
  29. TB2J/spinham/spin_xml.py +40 -8
  30. TB2J/symmetrize_J.py +140 -9
  31. TB2J/tests/test_cli_remove_sublattice.py +33 -0
  32. TB2J/tests/test_cli_toggle_exchange.py +50 -0
  33. {tb2j-0.9.12.9.dist-info → tb2j-0.9.12.22.dist-info}/METADATA +10 -7
  34. {tb2j-0.9.12.9.dist-info → tb2j-0.9.12.22.dist-info}/RECORD +38 -34
  35. {tb2j-0.9.12.9.dist-info → tb2j-0.9.12.22.dist-info}/WHEEL +1 -1
  36. {tb2j-0.9.12.9.dist-info → tb2j-0.9.12.22.dist-info}/entry_points.txt +2 -0
  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.9.dist-info → tb2j-0.9.12.22.dist-info}/licenses/LICENSE +0 -0
  40. {tb2j-0.9.12.9.dist-info → tb2j-0.9.12.22.dist-info}/top_level.txt +0 -0
TB2J/green.py CHANGED
@@ -56,13 +56,26 @@ def find_energy_ingap(evals, rbound, gap=2.0):
56
56
  find a energy inside a gap below rbound (right bound),
57
57
  return the energy gap top - 0.5.
58
58
  """
59
+ # print("Finding energy in gap...")
60
+ # print(f"Right bound: {rbound}, min gap size: {gap}")
59
61
  m0 = np.sort(evals.flatten())
60
- m = m0[m0 < rbound]
62
+ # print(f"Min eigenvalue: {m0[0]}, Max eigenvalue: {m0[-1]}")
63
+ m = m0[m0 <= rbound]
64
+ # append the next state above rbound to m
65
+ if len(m0) > len(m):
66
+ m = np.append(m, m0[len(m)])
67
+ # print(f"Number of states below right bound: {len(m)}")
68
+ # print(f"Max eigenvalue below right bound: {m[-1]}")
61
69
  ind = np.where(np.diff(m) > gap)[0]
70
+ # print(f"Number of gaps found: {len(ind)}")
71
+ # print("ind[-1]: ", ind[-1] if len(ind) > 0 else "N/A")
72
+ emin = 0.0
62
73
  if len(ind) == 0:
63
- return m0[0] - 0.5
74
+ emin = m0[0] - 0.5
64
75
  else:
65
- return m[ind[-1] + 1] - 0.5
76
+ emin = m[ind[-1] + 1] - 0.5
77
+ # print("emin:", emin)
78
+ return emin
66
79
 
67
80
 
68
81
  class TBGreen:
@@ -79,12 +92,23 @@ class TBGreen:
79
92
  use_cache=False,
80
93
  cache_path=None,
81
94
  nproc=1,
95
+ initial_emin=-25,
96
+ smearing_width=0.01,
82
97
  ):
83
98
  """
84
99
  :param tbmodel: A tight binding model
85
100
  :param kmesh: size of monkhorst pack. e.g [6,6,6]
86
101
  :param efermi: fermi energy.
102
+ :param gamma: whether to include gamma point in monkhorst pack
103
+ :param kpts: user defined kpoints
104
+ :param kweights: weights for user defined kpoints
105
+ :param k_sym: whether the kpoints are symmetrized
106
+ :param use_cache: whether to use cache to store wavefunctions
107
+ :param cache_path: path to store cache
108
+ :param nproc: number of processes to use
109
+ :param emin: minimum energy relative to fermi level to consider
87
110
  """
111
+ self.initial_emin = initial_emin
88
112
  self.tbmodel = tbmodel
89
113
  self.is_orthogonal = tbmodel.is_orthogonal
90
114
  self.R2kfactor = tbmodel.R2kfactor
@@ -107,6 +131,7 @@ class TBGreen:
107
131
  self.nbasis = tbmodel.nbasis
108
132
  self.k_sym = k_sym
109
133
  self.nproc = nproc
134
+ self.fermi_width = float(smearing_width)
110
135
  self._prepare_eigen()
111
136
 
112
137
  def prepare_kpts(
@@ -235,9 +260,21 @@ class TBGreen:
235
260
  self.efermi = occ.efermi(copy.deepcopy(self.evals))
236
261
  print(f"Fermi energy found: {self.efermi}")
237
262
 
238
- # self.evals, self.evecs = self._reduce_eigens(
239
- # self.evals, self.evecs, emin=self.efermi - 15.0, emax=self.efermi + 10.1
240
- # )
263
+ self.adjusted_emin = (
264
+ find_energy_ingap(
265
+ self.evals, rbound=self.efermi + self.initial_emin, gap=2.0
266
+ )
267
+ - self.efermi
268
+ )
269
+ # print(f"Adjusted emin relative to Fermi level: {self.adjusted_emin}")
270
+ self.evals, self.evecs = self._reduce_eigens(
271
+ self.evals,
272
+ self.evecs,
273
+ emin=self.efermi + self.adjusted_emin,
274
+ emax=self.efermi + 5.1,
275
+ # emin=self.efermi -10,
276
+ # emax=self.efermi + 10,
277
+ )
241
278
  if self._use_cache:
242
279
  evecs = self.evecs
243
280
  self.evecs_shape = self.evecs.shape
@@ -309,14 +346,24 @@ class TBGreen:
309
346
  evecs_k = self.get_evecs(ik)
310
347
  # chekc if any of the evecs element is nan
311
348
  rho += (
312
- (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
+ )
313
355
  @ evecs_k.T.conj()
314
356
  * self.kweights[ik]
315
357
  )
316
358
  else:
317
359
  for ik, _ in enumerate(self.kpts):
318
360
  rho += (
319
- (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
+ )
320
367
  @ self.get_evecs(ik).T.conj()
321
368
  @ self.get_Sk(ik)
322
369
  * self.kweights[ik]
@@ -332,7 +379,7 @@ class TBGreen:
332
379
  rhok = np.einsum(
333
380
  "ib,b, bj-> ij",
334
381
  evec,
335
- fermi(self.evals[ik], self.efermi, nspin=2),
382
+ fermi(self.evals[ik], self.efermi, width=self.fermi_width, nspin=2),
336
383
  evec.conj().T,
337
384
  )
338
385
  for iR, R in enumerate(Rlist):
@@ -376,38 +423,28 @@ class TBGreen:
376
423
  Gk_all[ik] = self.get_Gk(ik, energy)
377
424
  return Gk_all
378
425
 
379
- def get_GR(self, Rpts, energy, get_rho=False, Gk_all=None):
426
+ def compute_GR(self, Rpts, kpts, Gks):
427
+ Rvecs = np.array(Rpts)
428
+ phase = np.exp(self.k2Rfactor * np.einsum("ni,mi->nm", Rvecs, kpts))
429
+ phase *= self.kweights[None]
430
+ GR = np.einsum("kij,rk->rij", Gks, phase, optimize="optimal")
431
+ return GR
432
+
433
+ def get_GR(self, Rpts, energy, Gk_all=None):
380
434
  """calculate real space Green's function for one energy, all R points.
381
435
  G(R, epsilon) = G(k, epsilon) exp(-2\pi i R.dot. k)
382
436
  :param Rpts: R points
383
- :param energy:
384
- :returns: real space green's function for one energy for a list of R.
385
- :rtype: dictionary, the keys are tuple of R, values are matrices of nbasis*nbasis
437
+ :param energy: energy value
438
+ :param Gk_all: optional pre-computed Gk for all k-points
439
+ :returns: real space green's function for one energy for a list of R.
440
+ :rtype: numpy array of shape (len(Rpts), nbasis, nbasis)
386
441
  """
387
- Rpts = [tuple(R) for R in Rpts]
388
- GR = defaultdict(lambda: 0.0j)
389
- rhoR = defaultdict(lambda: 0.0j)
390
- for ik, kpt in enumerate(self.kpts):
391
- if Gk_all is None:
392
- Gk = self.get_Gk(ik, energy)
393
- else:
394
- Gk = Gk_all[ik]
395
- if get_rho:
396
- if self.is_orthogonal:
397
- rhok = Gk
398
- else:
399
- rhok = self.get_Sk(ik) @ Gk
400
- for iR, R in enumerate(Rpts):
401
- phase = np.exp(self.k2Rfactor * np.dot(R, kpt))
402
- tmp = Gk * (phase * self.kweights[ik])
403
- GR[R] += tmp
404
- # change this if need full rho
405
- if get_rho and R == (0, 0, 0):
406
- rhoR[R] += rhok * (phase * self.kweights[ik])
407
- if get_rho:
408
- return GR, rhoR
442
+ if Gk_all is None:
443
+ Gks = self.get_Gk_all(energy)
409
444
  else:
410
- return GR
445
+ Gks = Gk_all
446
+
447
+ return self.compute_GR(Rpts, self.kpts, Gks)
411
448
 
412
449
  def get_GR_and_dGRdx1(self, Rpts, energy, dHdx):
413
450
  """
@@ -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,8 +1,8 @@
1
1
  import os
2
2
 
3
3
  from ase.io import read
4
+ from HamiltonIO.wannier import WannierHam
4
5
 
5
- from TB2J.myTB import MyTB
6
6
  from TB2J.utils import auto_assign_basis_name
7
7
  from TB2J.wannier import parse_atoms
8
8
 
@@ -62,11 +62,11 @@ class WannierManager(Manager):
62
62
 
63
63
  def prepare_model_colinear(self, path, prefix_up, prefix_dn, atoms, output_path):
64
64
  print("Reading Wannier90 hamiltonian: spin up.")
65
- tbmodel_up = MyTB.read_from_wannier_dir(
65
+ tbmodel_up = WannierHam.read_from_wannier_dir(
66
66
  path=path, prefix=prefix_up, atoms=atoms, nls=False
67
67
  )
68
68
  print("Reading Wannier90 hamiltonian: spin down.")
69
- tbmodel_dn = MyTB.read_from_wannier_dir(
69
+ tbmodel_dn = WannierHam.read_from_wannier_dir(
70
70
  path=path, prefix=prefix_dn, atoms=atoms, nls=False
71
71
  )
72
72
  basis, _ = auto_assign_basis_name(
@@ -82,7 +82,7 @@ class WannierManager(Manager):
82
82
  groupby = groupby.lower().strip()
83
83
  if groupby not in ["spin", "orbital"]:
84
84
  raise ValueError("groupby can only be spin or orbital.")
85
- tbmodel = MyTB.read_from_wannier_dir(
85
+ tbmodel = WannierHam.read_from_wannier_dir(
86
86
  path=path, prefix=prefix_SOC, atoms=atoms, groupby=groupby, nls=True
87
87
  )
88
88
  basis, _ = auto_assign_basis_name(
@@ -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
+ ]