TB2J 0.9.5rc0__py3-none-any.whl → 0.9.6rc0__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 (58) hide show
  1. TB2J/MAE.py +107 -24
  2. TB2J/anisotropy.py +672 -0
  3. TB2J/contour.py +8 -0
  4. TB2J/exchange.py +43 -103
  5. TB2J/exchangeCL2.py +11 -13
  6. TB2J/exchange_params.py +213 -0
  7. TB2J/green.py +62 -27
  8. TB2J/interfaces/__init__.py +12 -0
  9. TB2J/interfaces/abacus/__init__.py +4 -0
  10. TB2J/{abacus → interfaces/abacus}/abacus_api.py +3 -3
  11. TB2J/{abacus → interfaces/abacus}/abacus_wrapper.py +11 -8
  12. TB2J/{abacus → interfaces/abacus}/gen_exchange_abacus.py +5 -3
  13. TB2J/{abacus → interfaces/abacus}/orbital_api.py +4 -4
  14. TB2J/{abacus → interfaces/abacus}/stru_api.py +11 -11
  15. TB2J/{abacus → interfaces/abacus}/test_read_HRSR.py +0 -1
  16. TB2J/{abacus → interfaces/abacus}/test_read_stru.py +5 -3
  17. TB2J/interfaces/gpaw_interface.py +54 -0
  18. TB2J/interfaces/lawaf_interface.py +129 -0
  19. TB2J/interfaces/manager.py +23 -0
  20. TB2J/interfaces/siesta_interface.py +174 -0
  21. TB2J/interfaces/wannier90_interface.py +115 -0
  22. TB2J/io_exchange/io_exchange.py +21 -7
  23. TB2J/io_merge.py +2 -1
  24. TB2J/mathutils/fermi.py +11 -6
  25. TB2J/mathutils/lowdin.py +12 -2
  26. TB2J/mathutils/rotate_spin.py +222 -4
  27. TB2J/pauli.py +11 -3
  28. TB2J/symmetrize_J.py +120 -0
  29. TB2J/utils.py +82 -1
  30. {TB2J-0.9.5rc0.data → TB2J-0.9.6rc0.data}/scripts/abacus2J.py +5 -4
  31. {TB2J-0.9.5rc0.data → TB2J-0.9.6rc0.data}/scripts/siesta2J.py +21 -4
  32. TB2J-0.9.6rc0.data/scripts/wann2J.py +96 -0
  33. {TB2J-0.9.5rc0.dist-info → TB2J-0.9.6rc0.dist-info}/METADATA +5 -3
  34. {TB2J-0.9.5rc0.dist-info → TB2J-0.9.6rc0.dist-info}/RECORD +46 -46
  35. {TB2J-0.9.5rc0.dist-info → TB2J-0.9.6rc0.dist-info}/WHEEL +1 -1
  36. TB2J-0.9.6rc0.dist-info/entry_points.txt +3 -0
  37. TB2J/abacus/MAE.py +0 -320
  38. TB2J/abacus/__init__.py +0 -1
  39. TB2J/abacus/occupations.py +0 -278
  40. TB2J/cut_cell.py +0 -82
  41. TB2J/io_exchange/io_pickle.py +0 -0
  42. TB2J/manager.py +0 -445
  43. TB2J/mathutils.py +0 -12
  44. TB2J/patch.py +0 -50
  45. TB2J/spinham/h_matrix.py +0 -68
  46. TB2J/spinham/obtain_J.py +0 -79
  47. TB2J/supercell.py +0 -532
  48. TB2J-0.9.5rc0.data/scripts/wann2J.py +0 -194
  49. TB2J/{abacus → interfaces/abacus}/test_density_matrix.py +1 -1
  50. {TB2J-0.9.5rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_downfold.py +0 -0
  51. {TB2J-0.9.5rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_eigen.py +0 -0
  52. {TB2J-0.9.5rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_magnon.py +0 -0
  53. {TB2J-0.9.5rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_magnon_dos.py +0 -0
  54. {TB2J-0.9.5rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_merge.py +0 -0
  55. {TB2J-0.9.5rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_rotate.py +0 -0
  56. {TB2J-0.9.5rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_rotateDM.py +0 -0
  57. {TB2J-0.9.5rc0.dist-info → TB2J-0.9.6rc0.dist-info}/LICENSE +0 -0
  58. {TB2J-0.9.5rc0.dist-info → TB2J-0.9.6rc0.dist-info}/top_level.txt +0 -0
TB2J/MAE.py CHANGED
@@ -1,20 +1,26 @@
1
+ from pathlib import Path
2
+
3
+ import matplotlib.pyplot as plt
1
4
  import numpy as np
2
- from TB2J.abacus.abacus_wrapper import AbacusWrapper, AbacusParser
3
- from TB2J.mathutils.rotate_spin import rotate_Matrix_from_z_to_axis
5
+ import tqdm
6
+
7
+ # from TB2J.abacus.abacus_wrapper import AbacusSplitSOCParser
8
+ from HamiltonIO.abacus.abacus_wrapper import AbacusSplitSOCParser
9
+ from HamiltonIO.model.occupations import Occupations
10
+ from HamiltonIO.siesta import SislParser
11
+ from scipy.linalg import eigh
12
+
13
+ from TB2J.contour import Contour
14
+ from TB2J.green import TBGreen
15
+
16
+ # from HamiltonIO.model.rotate_spin import rotate_Matrix_from_z_to_axis, rotate_Matrix_from_z_to_sperical
4
17
  from TB2J.kpoints import monkhorst_pack
5
- from TB2J.mathutils.fermi import fermi
6
18
  from TB2J.mathutils.kR_convert import R_to_k
7
- from scipy.linalg import eigh
8
- from copy import deepcopy
9
- from scipy.spatial.transform import Rotation
10
- import matplotlib.pyplot as plt
11
- from pathlib import Path
12
- from TB2J.mathutils.rotate_spin import spherical_to_cartesian
13
- from HamiltonIO.model.occupations import Occupations
14
- #from TB2J.abacus.abacus_wrapper import AbacusSplitSOCParser
15
- from HamiltonIO.abacus.abacus_wrapper import AbacusSplitSOCParser
16
- from HamiltonIO.siesta import SislParser, SiestaHamiltonian
17
- import tqdm
19
+
20
+ # from TB2J.abacus.abacus_wrapper import AbacusWrapper, AbacusParser
21
+ from TB2J.mathutils.rotate_spin import (
22
+ rotate_spinor_matrix,
23
+ )
18
24
 
19
25
 
20
26
  def get_occupation(evals, kweights, nel, width=0.1):
@@ -87,39 +93,116 @@ class MAE:
87
93
  return es
88
94
 
89
95
 
96
+ class MAEGreen(MAE):
97
+ def __init__(self, model, kmesh, gamma=True, nel=None, width=0.1, **kwargs):
98
+ super().__init__(model, kmesh, gamma=gamma, nel=nel, width=width)
99
+ model.set_so_strength(0.0)
100
+ evals, evecs = model.solve_all(self.kpts)
101
+ occ = Occupations(
102
+ nel=self.model.nel, width=self.width, wk=self.kweights, nspin=2
103
+ )
104
+ # occ.occupy(evals)
105
+ efermi = occ.efermi(evals)
106
+ self.G = TBGreen(model, kmesh, efermi=efermi, gamma=gamma, **kwargs)
107
+ self.emin = -18
108
+ self.emax = 0
109
+ self.nz = 50
110
+ self._prepare_elist()
111
+
112
+ def _prepare_elist(self, method="legendre"):
113
+ """
114
+ prepare list of energy for integration.
115
+ The path has three segments:
116
+ emin --1-> emin + 1j*height --2-> emax+1j*height --3-> emax
117
+ """
118
+ self.contour = Contour(self.emin, self.emax)
119
+ # if method.lower() == "rectangle":
120
+ # self.contour.build_path_rectangle(
121
+ # height=self.height, nz1=self.nz1, nz2=self.nz2, nz3=self.nz3
122
+ # )
123
+ if method.lower() == "semicircle":
124
+ self.contour.build_path_semicircle(npoints=self.nz, endpoint=True)
125
+ elif method.lower() == "legendre":
126
+ self.contour.build_path_legendre(npoints=self.nz, endpoint=True)
127
+ else:
128
+ raise ValueError(f"The path cannot be of type {method}.")
129
+
130
+ def get_efermi(self):
131
+ evals, evecs = self.model.solve_all(self.kpts)
132
+ occ = Occupations(
133
+ nel=self.model.nel, width=self.model.width, wk=self.kweights, nspin=2
134
+ )
135
+ occ.get_efermi(evals, self.kweights)
136
+
137
+ def get_perturbed(self, e, thetas, phis):
138
+ G0K = self.G.get_Gk_all(e)
139
+ Hsoc_k = self.model.get_Hk_soc(self.kpts)
140
+ dE_ang = []
141
+ for theta, phi in zip(thetas, phis):
142
+ dE = 0.0
143
+ for i, dHk in enumerate(Hsoc_k):
144
+ dHi = rotate_spinor_matrix(dHk, theta, phi)
145
+ GdH = G0K[i] @ dHi
146
+ dE += np.trace(GdH @ G0K[i].T.conj() @ dHi) * self.kweights[i]
147
+ dE_ang.append(dE)
148
+ return np.array(dE_ang)
149
+
150
+ def get_band_energy_vs_angles(self, thetas, phis):
151
+ es = np.zeros(len(thetas))
152
+ for ie, e in enumerate(tqdm.tqdm(self.contour.path)):
153
+ dE_angle = self.get_perturbed(e, thetas, phis)
154
+ es += np.imag(dE_angle * self.contour.weights[ie])
155
+ return -es / np.pi
156
+
157
+
90
158
  def get_model_energy(model, kmesh, gamma=True):
91
159
  ham = MAE(model, kmesh, gamma=gamma)
92
160
  return ham.get_band_energy()
93
161
 
94
162
 
95
163
  def abacus_get_MAE(
96
- path_nosoc, path_soc, kmesh, thetas, psis, gamma=True, outfile="MAE.txt", nel=None
164
+ path_nosoc,
165
+ path_soc,
166
+ kmesh,
167
+ thetas,
168
+ phis,
169
+ gamma=True,
170
+ outfile="MAE.txt",
171
+ nel=None,
172
+ width=0.1,
97
173
  ):
98
174
  """Get MAE from Abacus with magnetic force theorem. Two calculations are needed. First we do an calculation with SOC but the soc_lambda is set to 0. Save the density. The next calculatin we start with the density from the first calculation and set the SOC prefactor to 1. With the information from the two calcualtions, we can get the band energy with magnetic moments in the direction, specified in two list, thetas, and phis."""
99
175
  parser = AbacusSplitSOCParser(
100
176
  outpath_nosoc=path_nosoc, outpath_soc=path_soc, binary=False
101
177
  )
102
178
  model = parser.parse()
103
- ham = MAE(model, kmesh, gamma=gamma)
104
- es = ham.get_band_energy_vs_angles(thetas, psis)
179
+ if nel is not None:
180
+ model.nel = nel
181
+ ham = MAEGreen(model, kmesh, gamma=gamma, width=width)
182
+ es = ham.get_band_energy_vs_angles(thetas, phis)
105
183
  if outfile:
106
184
  with open(outfile, "w") as f:
107
- f.write("#theta, psi, energy\n")
108
- for theta, psi, e in zip(thetas, psis, es):
109
- f.write(f"{theta:5.3f}, {psi:5.3f}, {e:10.9f}\n")
185
+ f.write("#theta, phi, energy\n")
186
+ for theta, phi, e in zip(thetas, phis, es):
187
+ f.write(f"{theta:5.3f}, {phi:5.3f}, {e:10.9f}\n")
110
188
  return es
111
189
 
112
190
 
113
- def siesta_get_MAE(fdf_fname, kmesh, thetas, phis, gamma=True, outfile="MAE.txt"):
191
+ def siesta_get_MAE(
192
+ fdf_fname, kmesh, thetas, phis, gamma=True, outfile="MAE.txt", nel=None, width=0.1
193
+ ):
114
194
  """ """
115
- model= SislParser(fdf_fname=fdf_fname, read_H_soc=True).get_model()
116
- ham = MAE(model, kmesh, gamma=gamma)
195
+ model = SislParser(fdf_fname=fdf_fname, read_H_soc=True).get_model()
196
+ if nel is not None:
197
+ model.nel = nel
198
+ ham = MAEGreen(model, kmesh, gamma=gamma, width=width)
199
+ # es = ham.get_band_energy_vs_angles(thetas, phis)
117
200
  es = ham.get_band_energy_vs_angles(thetas, phis)
118
201
  if outfile:
119
202
  with open(outfile, "w") as f:
120
203
  f.write("#theta, psi, energy\n")
121
204
  for theta, psi, e in zip(thetas, phis, es):
122
- #f.write(f"{theta}, {psi}, {e}\n")
205
+ # f.write(f"{theta}, {psi}, {e}\n")
123
206
  f.write(f"{theta:5.3f}, {psi:5.3f}, {e:10.9f}\n")
124
207
  return es
125
208