TB2J 0.9.1rc0__py3-none-any.whl → 0.9.3rc0__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.
TB2J/Jdownfolder.py CHANGED
@@ -17,9 +17,23 @@ def ind_to_indn(ind, n=3):
17
17
  return indn
18
18
 
19
19
 
20
+ class JR_model:
21
+ def __init__(self, JR, Rlist):
22
+ self.JR = JR
23
+ self.Rlist = Rlist
24
+ self.nR = len(Rlist)
25
+
26
+ def get_Jq(self, q):
27
+ Jq = np.zeros(self.JR[0].shape, dtype=complex)
28
+ for iR, R in enumerate(self.Rlist):
29
+ phase = np.exp(2.0j * np.pi * np.dot(q, R))
30
+ Jq += self.JR[iR] * phase
31
+ return Jq
32
+
33
+
20
34
  class JDownfolder:
21
35
  def __init__(self, JR, Rlist, iM, iL, qmesh, iso_only=False):
22
- self.JR = JR
36
+ self.model = JR_model(JR, Rlist)
23
37
  self.Rlist = Rlist
24
38
  self.nR = len(Rlist)
25
39
  self.nM = len(iM)
@@ -34,25 +48,18 @@ class JDownfolder:
34
48
  self.nLn = self.nL * 3
35
49
  self.iso_only = iso_only
36
50
 
37
- def get_Jq(self, q):
38
- Jq = np.zeros(self.JR[0].shape, dtype=complex)
39
- for iR, R in enumerate(self.Rlist):
40
- phase = np.exp(2.0j * np.pi * np.dot(q, R))
41
- Jq += self.JR[iR] * phase
42
- return Jq
43
-
44
51
  def get_JR(self):
45
52
  JR_downfolded = np.zeros((self.nR, self.nMn, self.nMn), dtype=float)
46
53
  Jq_downfolded = np.zeros((self.nqpt, self.nMn, self.nMn), dtype=complex)
47
54
  self.iMn = ind_to_indn(self.iM, n=3)
48
55
  self.iLn = ind_to_indn(self.iL, n=3)
49
56
  for iq, q in enumerate(self.qpts):
50
- Jq = self.get_Jq(q)
57
+ Jq = self.model.get_Jq(q)
51
58
  Jq_downfolded[iq] = self.downfold_oneq(Jq)
52
59
  for iR, R in enumerate(self.Rlist):
53
60
  phase = np.exp(-2.0j * np.pi * np.dot(q, R))
54
61
  JR_downfolded[iR] += np.real(Jq_downfolded[iq] * phase / self.nqpt)
55
- return JR_downfolded
62
+ return JR_downfolded, self.Rlist
56
63
 
57
64
  def downfold_oneq(self, J):
58
65
  JMM = J[np.ix_(self.iMn, self.iMn)]
@@ -63,17 +70,80 @@ class JDownfolder:
63
70
  return Jn
64
71
 
65
72
 
73
+ class PWFDownfolder:
74
+ def __init__(self, JR, Rlist, iM, iL, qmesh, atoms=None, iso_only=False, **kwargs):
75
+ from lawaf.interfaces.magnon.magnon_downfolder import (
76
+ MagnonWrapper,
77
+ MagnonDownfolder,
78
+ )
79
+
80
+ model = MagnonWrapper(JR, Rlist, atoms)
81
+ wann = MagnonDownfolder(model)
82
+ # Downfold the band structure.
83
+ index_basis = []
84
+ for i in iM:
85
+ index_basis += list(range(i * 3, i * 3 + 3))
86
+ params = dict(
87
+ method="projected",
88
+ # method="maxprojected",
89
+ kmesh=qmesh,
90
+ nwann=len(index_basis),
91
+ selected_basis=index_basis,
92
+ # anchors={(0, 0, 0): (-1, -2, -3, -4)},
93
+ # anchors={(0, 0, 0): ()},
94
+ # use_proj=True,
95
+ enhance_Amn=2.0,
96
+ )
97
+ params.update(kwargs)
98
+ wann.set_parameters(**params)
99
+ print("begin downfold")
100
+ ewf = wann.downfold()
101
+ ewf.save_hr_pickle("downfolded_JR.pickle")
102
+
103
+ # Plot the band structure.
104
+ wann.plot_band_fitting(
105
+ # kvectors=np.array([[0, 0, 0], [0.5, 0, 0],
106
+ # [0.5, 0.5, 0], [0, 0, 0],
107
+ # [.5, .5, .5]]),
108
+ # knames=['$\Gamma$', 'X', 'M', '$\Gamma$', 'R'],
109
+ cell=model.atoms.cell,
110
+ supercell_matrix=None,
111
+ npoints=100,
112
+ efermi=None,
113
+ erange=None,
114
+ fullband_color="blue",
115
+ downfolded_band_color="green",
116
+ marker="o",
117
+ ax=None,
118
+ savefig="downfold_band.png",
119
+ show=True,
120
+ )
121
+ self.JR_downfolded = ewf.HwannR
122
+ self.Rlist = ewf.Rlist
123
+
124
+ def get_JR(self):
125
+ return self.JR_downfolded, self.Rlist
126
+
127
+
66
128
  class JDownfolder_pickle:
67
129
  def __init__(
68
- self, inpath, metals, ligands, outpath, qmesh=[7, 7, 7], iso_only=False
130
+ self,
131
+ inpath,
132
+ metals,
133
+ ligands,
134
+ outpath,
135
+ qmesh=[7, 7, 7],
136
+ iso_only=False,
137
+ method="pwf",
138
+ **kwargs
69
139
  ):
70
140
  self.exc = SpinIO.load_pickle(path=inpath, fname="TB2J.pickle")
71
141
 
72
142
  self.iso_only = (self.exc.dmi_ddict is None) or iso_only
73
-
74
143
  self.metals = metals
75
144
  self.ligands = ligands
76
145
  self.outpath = outpath
146
+ self.method = method
77
147
 
78
148
  # read atomic structure
79
149
  self.atoms = self.exc.atoms
@@ -83,7 +153,8 @@ class JDownfolder_pickle:
83
153
  self.Rcut = None
84
154
  self._build_atom_index()
85
155
  self._prepare_distance()
86
- self._downfold()
156
+ Jd, Rlist = self._downfold(**kwargs)
157
+ self._Jd_to_exchange(Jd, Rlist)
87
158
 
88
159
  def _build_atom_index(self):
89
160
  self.magnetic_elements = self.metals
@@ -101,18 +172,33 @@ class JDownfolder_pickle:
101
172
  self.nL = len(self.iL)
102
173
  self.nsite = self.nM + self.nL
103
174
 
104
- def _downfold(self):
175
+ def _downfold(self, **kwargs):
105
176
  JR2 = self.exc.get_full_Jtensor_for_Rlist(asr=True)
106
- d = JDownfolder(
107
- JR2,
108
- self.exc.Rlist,
109
- iM=self.iM,
110
- iL=self.iL,
111
- qmesh=self.qmesh,
112
- iso_only=self.iso_only,
113
- )
114
- Jd = d.get_JR()
177
+ if self.method == "lowdin":
178
+ d = JDownfolder(
179
+ JR2,
180
+ self.exc.Rlist,
181
+ iM=self.iM,
182
+ iL=self.iL,
183
+ qmesh=self.qmesh,
184
+ iso_only=self.iso_only,
185
+ )
186
+ Jd, Rlist = d.get_JR()
187
+ else:
188
+ d = PWFDownfolder(
189
+ JR2,
190
+ self.exc.Rlist,
191
+ iM=self.iM,
192
+ iL=self.iL,
193
+ qmesh=self.qmesh,
194
+ atoms=self.atoms,
195
+ iso_only=self.iso_only,
196
+ **kwargs
197
+ )
198
+ Jd, Rlist = d.get_JR()
199
+ return Jd, Rlist
115
200
 
201
+ def _Jd_to_exchange(self, Jd, Rlist):
116
202
  self._prepare_distance()
117
203
  self._prepare_index_spin()
118
204
  self.Jdict = {}
@@ -123,7 +209,7 @@ class JDownfolder_pickle:
123
209
  self.DMIdict = {}
124
210
  self.Janidict = {}
125
211
 
126
- for iR, R in enumerate(d.Rlist):
212
+ for iR, R in enumerate(Rlist):
127
213
  for i, ispin in enumerate(self.index_spin):
128
214
  for j, jspin in enumerate(self.index_spin):
129
215
  if ispin >= 0 and jspin >= 0:
TB2J/Jtensor.py CHANGED
@@ -79,7 +79,7 @@ def combine_J_tensor(Jiso=0.0, D=np.zeros(3), Jani=np.zeros((3, 3), dtype=float)
79
79
  :param Jani: 3x3 matrix anisotropic exchange
80
80
  :returns: A 3x3 matrix, the exchange paraemter in tensor form.
81
81
  """
82
- Jtensor = np.zeros((3, 3), dtype=float)
82
+ Jtensor = np.zeros((3, 3), dtype=complex)
83
83
  if Jiso is not None:
84
84
  Jtensor += np.eye(3, dtype=float) * Jiso
85
85
  if Jani is not None:
TB2J/MAE.py ADDED
@@ -0,0 +1,185 @@
1
+ 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
4
+ from TB2J.kpoints import monkhorst_pack
5
+ from TB2J.mathutils.fermi import fermi
6
+ 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.siesta import SislWrapper
16
+ import tqdm
17
+
18
+
19
+ def get_occupation(evals, kweights, nel, width=0.1):
20
+ occ = Occupations(nel=nel, width=width, wk=kweights, nspin=2)
21
+ return occ.occupy(evals)
22
+
23
+
24
+ def get_density_matrix(evals=None, evecs=None, kweights=None, nel=None, width=0.1):
25
+ occ = get_occupation(evals, kweights, nel, width=width)
26
+ rho = np.einsum("kib, kb, kjb -> kij", evecs, occ, evecs.conj())
27
+ return rho
28
+
29
+
30
+ class MAE:
31
+ def __init__(self, model, kmesh, gamma=True, width=0.1, nel=None):
32
+ self.model = model
33
+ if nel is not None:
34
+ self.model.nel = nel
35
+ self.kpts = monkhorst_pack(kmesh, gamma_center=gamma)
36
+ self.kweights = np.ones(len(self.kpts), dtype=float) / len(self.kpts)
37
+ self.width = width
38
+
39
+ def get_band_energy(self):
40
+ evals, evecs = self.model.solve_all(self.kpts)
41
+ occ = get_occupation(evals, self.kweights, self.model.nel, width=self.width)
42
+ eband = np.sum(evals * occ * self.kweights[:, np.newaxis])
43
+ return eband
44
+
45
+ def calc_ref(self):
46
+ # calculate the Hk_ref, Sk_ref, Hk_soc_ref, and rho_ref
47
+ self.Sk_ref = R_to_k(self.kpts, self.model.Rlist, self.model.SR)
48
+ self.Hk_xc_ref = R_to_k(self.kpts, self.model.Rlist, self.model._HR_copy)
49
+ self.Hk_soc_ref = R_to_k(self.kpts, self.model.Rlist, self.model.HR_soc)
50
+ self.rho_ref = np.zeros(
51
+ (len(self.kpts), self.model.nbasis, self.model.nbasis), dtype=complex
52
+ )
53
+
54
+ evals = np.zeros((len(self.kpts), self.model.nbasis), dtype=float)
55
+ evecs = np.zeros(
56
+ (len(self.kpts), self.model.nbasis, self.model.nbasis), dtype=complex
57
+ )
58
+
59
+ for ik, kpt in enumerate(self.kpts):
60
+ # evals, evecs = eigh(self.Hk_xc_ref[ik]+self.Hk_soc_ref[ik], self.Sk_ref[ik])
61
+ evals[ik], evecs[ik] = eigh(self.Hk_xc_ref[ik], self.Sk_ref[ik])
62
+ occ = get_occupation(
63
+ evals, self.kweights, self.model.nel, width=self.model.width
64
+ )
65
+ # occ = fermi(evals, self.model.efermi, width=self.model.width)
66
+ self.rho_ref = np.einsum("kib, kb, kjb -> kij", evecs, occ, evecs.conj())
67
+
68
+ def get_band_energy_vs_angles(
69
+ self,
70
+ thetas,
71
+ phis,
72
+ ):
73
+ es = []
74
+ # es2 = []
75
+ # e,rho = self.model.get_band_energy(dm=True)
76
+ # self.calc_ref()
77
+ # thetas = np.linspace(*angle_range, npoints)
78
+ for i, (theta, phi) in tqdm.tqdm(enumerate(zip(thetas, phis))):
79
+ self.model.set_Hsoc_rotation_angle([theta, phi])
80
+ e = self.get_band_energy()
81
+ es.append(e)
82
+ # es2.append(e2)
83
+ return es
84
+
85
+
86
+ def get_model_energy(model, kmesh, gamma=True):
87
+ ham = MAE(model, kmesh, gamma=gamma)
88
+ return ham.get_band_energy()
89
+
90
+
91
+ def abacus_get_MAE(
92
+ path_nosoc, path_soc, kmesh, thetas, psis, gamma=True, outfile="MAE.txt", nel=None
93
+ ):
94
+ """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."""
95
+ parser = AbacusSplitSOCParser(
96
+ outpath_nosoc=path_nosoc, outpath_soc=path_soc, binary=False
97
+ )
98
+ model = parser.parse()
99
+ model.nel = 16
100
+ ham = MAE(model, kmesh, gamma=gamma)
101
+ es = ham.get_band_energy_vs_angles(thetas, psis)
102
+ if outfile:
103
+ with open(outfile, "w") as f:
104
+ f.write("#theta, psi, energy\n")
105
+ for theta, psi, e in zip(thetas, psis, es):
106
+ f.write(f"{theta}, {psi}, {e}\n")
107
+ return es
108
+
109
+
110
+ def siesta_get_MAE(fdf_fname, kmesh, thetas, phis, gamma=True, outfile="MAE.txt"):
111
+ """ """
112
+ parser = SiestaParser(fdf_fname=fdf_fname, read_H_soc=True)
113
+ model = parser.parse()
114
+ ham = MAE(model, kmesh, gamma=gamma)
115
+ es = ham.get_band_energy_vs_angles(thetas, phis)
116
+ if outfile:
117
+ with open(outfile, "w") as f:
118
+ f.write("#theta, psi, energy\n")
119
+ for theta, psi, e in zip(thetas, phis, es):
120
+ f.write(f"{theta}, {psi}, {e}\n")
121
+ return es
122
+
123
+
124
+ def test_AbacusSplitSOCWrapper():
125
+ # path = Path("~/projects/2D_Fe").expanduser()
126
+ path = Path("~/projects/TB2Jflows/examples/2D_Fe/Fe_z").expanduser()
127
+ outpath_nosoc = f"{path}/soc0/OUT.ABACUS"
128
+ outpath_soc = f"{path}/soc1/OUT.ABACUS"
129
+ parser = AbacusSplitSOCParser(
130
+ outpath_nosoc=outpath_nosoc, outpath_soc=outpath_soc, binary=False
131
+ )
132
+ model = parser.parse()
133
+ kmesh = [6, 6, 1]
134
+
135
+ r = MAE(model, kmesh, gamma=True)
136
+ # thetas, es = r.get_band_energy_vs_theta(angle_range=(0, np.pi*2), rotation_axis="z", initial_direction=(1,0,0), npoints=21)
137
+ thetas, es, es2 = r.get_band_energy_vs_theta(
138
+ angle_range=(0, np.pi),
139
+ rotation_axis="y",
140
+ initial_direction=(0, 0, 1),
141
+ npoints=11,
142
+ )
143
+ # print the table of thetas and es, es2
144
+ for theta, e, e2 in zip(thetas, es, es2):
145
+ print(f"{theta=}, {e=}, {e2=}")
146
+
147
+ plt.plot(thetas / np.pi, es - es[0], marker="o")
148
+ plt.plot(thetas / np.pi, es2 - es2[0], marker=".")
149
+ plt.savefig("E_along_z_x_z.png")
150
+ plt.show()
151
+
152
+
153
+ def abacus_get_MAE_cli():
154
+ import argparse
155
+
156
+ parser = argparse.ArgumentParser(
157
+ description="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. "
158
+ )
159
+ parser.add_argument("path_nosoc", type=str, help="Path to the calculation with ")
160
+ parser.add_argument("path_soc", type=str, help="Path to the SOC calculation")
161
+ parser.add_argument("thetas", type=float, nargs="+", help="Thetas")
162
+ parser.add_argument("psis", type=float, nargs="+", help="Phis")
163
+ parser.add_argument("kmesh", type=int, nargs=3, help="K-mesh")
164
+ parser.add_argument(
165
+ "--gamma", action="store_true", help="Use Gamma centered kpoints"
166
+ )
167
+ parser.add_argument(
168
+ "--outfile",
169
+ type=str,
170
+ help="The angles and the energey will be saved in this file.",
171
+ )
172
+ args = parser.parse_args()
173
+ abacus_get_MAE(
174
+ args.path_nosoc,
175
+ args.path_soc,
176
+ args.kmesh,
177
+ args.thetas,
178
+ args.psis,
179
+ gamma=args.gamma,
180
+ outfile=args.outfile,
181
+ )
182
+
183
+
184
+ if __name__ == "__main__":
185
+ abacus_get_MAE_cli()
@@ -7,6 +7,8 @@ from pathlib import Path
7
7
  import os
8
8
  import numpy as np
9
9
  from scipy.linalg import eigh
10
+ from copy import deepcopy
11
+ from TB2J.mathutils.rotate_spin import rotate_Matrix_from_z_to_spherical
10
12
  from TB2J.utils import symbol_number_list
11
13
  from TB2J.myTB import AbstractTB
12
14
  from TB2J.abacus.abacus_api import read_HR_SR
@@ -15,9 +17,12 @@ from TB2J.abacus.stru_api import read_abacus, read_abacus_out
15
17
 
16
18
 
17
19
  class AbacusWrapper(AbstractTB):
18
- def __init__(self, HR, SR, Rlist, nbasis, nspin=1):
20
+ def __init__(
21
+ self, HR, SR, Rlist, nbasis, nspin=1, HR_soc=None, HR_nosoc=None, nel=None
22
+ ):
19
23
  self.R2kfactor = 2j * np.pi
20
24
  self.is_orthogonal = False
25
+ self.split_soc = False
21
26
  self._name = "ABACUS"
22
27
  self._HR = HR
23
28
  self.SR = SR
@@ -25,11 +30,38 @@ class AbacusWrapper(AbstractTB):
25
30
  self.nbasis = nbasis
26
31
  self.nspin = nspin
27
32
  self.norb = nbasis * nspin
33
+ self.nel = nel
28
34
  self._build_Rdict()
35
+ if HR_soc is not None:
36
+ self.set_HR_soc(HR_soc=HR_soc, HR_nosoc=HR_nosoc, HR_full=HR)
37
+ self.soc_rotation_angle = 0.0
38
+
39
+ def set_HR_soc(self, HR_soc=None, HR_nosoc=None, HR_full=None):
40
+ self.split_soc = True
41
+ self.HR_soc = HR_soc
42
+ if HR_nosoc is not None:
43
+ self.HR_nosoc = HR_nosoc
44
+ if HR_full is not None:
45
+ self.HR_nosoc = HR_full - HR_soc
46
+
47
+ def set_Hsoc_rotation_angle(self, angle):
48
+ """
49
+ Set the rotation angle for SOC part of Hamiltonian
50
+ """
51
+ self.soc_rotation_angle = angle
29
52
 
30
53
  @property
31
54
  def HR(self):
32
- return self._HR
55
+ if self.split_soc:
56
+ _HR = np.zeros_like(self.HR_soc)
57
+ for iR, _ in enumerate(self.Rlist):
58
+ theta, phi = self.soc_rotation_angle
59
+ _HR[iR] = self.HR_nosoc[iR] + rotate_Matrix_from_z_to_spherical(
60
+ self.HR_soc[iR], theta, phi
61
+ )
62
+ return _HR
63
+ else:
64
+ return self._HR
33
65
 
34
66
  @HR.setter
35
67
  def set_HR(self, HR):
@@ -214,6 +246,20 @@ class AbacusParser:
214
246
  raise ValueError(f"EFERMI not found in the {str(fname)} file.")
215
247
  return efermi
216
248
 
249
+ def read_nel(self):
250
+ """
251
+ Reading the number of electrons from the scf log file.
252
+ """
253
+ fname = str(Path(self.outpath) / "running_scf.log")
254
+ nel = None
255
+ with open(fname, "r") as myfile:
256
+ for line in myfile:
257
+ if "NELECT" in line:
258
+ nel = float(line.split()[2])
259
+ if nel is None:
260
+ raise ValueError(f"NELECT not found in the {str(fname)} file.")
261
+ return nel
262
+
217
263
  def get_basis(self):
218
264
  slist = symbol_number_list(self.atoms)
219
265
  if self.spin == "collinear":
@@ -231,6 +277,42 @@ class AbacusParser:
231
277
  return basis
232
278
 
233
279
 
280
+ class AbacusSplitSOCParser:
281
+ """
282
+ Abacus parser with Hamiltonian split to SOC and non-SOC parts
283
+ """
284
+
285
+ def __init__(self, outpath_nosoc=None, outpath_soc=None, binary=False):
286
+ self.outpath_nosoc = outpath_nosoc
287
+ self.outpath_soc = outpath_soc
288
+ self.binary = binary
289
+ self.parser_nosoc = AbacusParser(outpath=outpath_nosoc, binary=binary)
290
+ self.parser_soc = AbacusParser(outpath=outpath_soc, binary=binary)
291
+ spin1 = self.parser_nosoc.read_spin()
292
+ spin2 = self.parser_soc.read_spin()
293
+ if spin1 != "noncollinear" or spin2 != "noncollinear":
294
+ raise ValueError("Spin should be noncollinear")
295
+
296
+ def parse(self):
297
+ nbasis, Rlist, HR_nosoc, SR = self.parser_nosoc.Read_HSR_noncollinear()
298
+ nbasis2, Rlist2, HR2, SR2 = self.parser_soc.Read_HSR_noncollinear()
299
+ # print(HR[0])
300
+ HR_soc = HR2 - HR_nosoc
301
+ model = AbacusWrapper(
302
+ HR=None,
303
+ SR=SR,
304
+ Rlist=Rlist,
305
+ nbasis=nbasis,
306
+ nspin=2,
307
+ HR_soc=HR_soc,
308
+ HR_nosoc=HR_nosoc,
309
+ )
310
+ model.efermi = self.parser_soc.efermi
311
+ model.basis = self.parser_nosoc.basis
312
+ model.atoms = self.parser_nosoc.atoms
313
+ return model
314
+
315
+
234
316
  def test_abacus_wrapper_collinear():
235
317
  outpath = "/Users/hexu/projects/TB2J_abacus/abacus-tb2j-master/abacus_example/case_Fe/1_no_soc/OUT.Fe"
236
318
  parser = AbacusParser(outpath=outpath, spin=None, binary=False)
@@ -239,7 +321,6 @@ def test_abacus_wrapper_collinear():
239
321
  # parser.read_HSR_collinear()
240
322
  model_up, model_dn = parser.get_models()
241
323
  H, S, E, V = model_up.HSE_k([0, 0, 0])
242
- # print(H.shape)
243
324
  # print(H.diagonal().real)
244
325
  # print(model_up.get_HR0().diagonal().real)
245
326
  print(parser.efermi)
TB2J/exchange.py CHANGED
@@ -1,6 +1,9 @@
1
1
  from collections import defaultdict, OrderedDict
2
2
  import os
3
3
  import numpy as np
4
+ import pickle
5
+ from dataclasses import dataclass
6
+ import yaml
4
7
  from TB2J.green import TBGreen
5
8
  from TB2J.pauli import pauli_block_all, pauli_block_sigma_norm, pauli_mat
6
9
  from TB2J.utils import symbol_number, kmesh_to_R
@@ -10,25 +13,47 @@ from TB2J.external import p_map
10
13
  from TB2J.contour import Contour
11
14
  from TB2J.utils import simpson_nonuniform, trapezoidal_nonuniform, split_symbol_number
12
15
  from TB2J.orbmap import map_orbs_matrix
13
- import pickle
16
+ from typing import List, Tuple
14
17
 
15
18
 
19
+ @dataclass
16
20
  class ExchangeParams:
21
+ """
22
+ A class to store the parameters for exchange calculation.
23
+ """
24
+
25
+ efermi: float
26
+ basis: list = None
27
+ magnetic_elements: list = None
28
+ include_orbs = {}
29
+ _kmesh = [4, 4, 4]
30
+ emin: float = -15
31
+ emax: float = 0.05
32
+ nz: int = 100
33
+ exclude_orbs = []
34
+ ne: int = None
35
+ Rcut: float = None
36
+ _use_cache: bool = False
37
+ np: int = 1
38
+ description: str = ""
39
+ write_density_matrix: bool = False
40
+ orb_decomposition: bool = False
41
+ output_path: str = "TB2J_results"
42
+ mae_angles = None
43
+
17
44
  def __init__(
18
45
  self,
19
- efermi,
46
+ efermi=-10.0,
20
47
  basis=None,
21
- magnetic_elements=[],
22
- include_orbs={},
48
+ magnetic_elements=None,
49
+ include_orbs=None,
23
50
  kmesh=[4, 4, 4],
24
- emin=-15, # integration lower bound, relative to fermi energy
25
- # integration upper bound. Should be 0 (fermi energy). But DFT codes define Fermi energy in various ways.
51
+ emin=-15,
26
52
  emax=0.05,
27
53
  nz=100,
28
- # the delta in the (i delta) in green's function to prevent divergence
29
- exclude_orbs=[], #
30
- ne=None, # number of electrons in Wannier function.
31
- Rcut=None, # Rcut.
54
+ exclude_orbs=[],
55
+ ne=None,
56
+ Rcut=None,
32
57
  use_cache=False,
33
58
  np=1,
34
59
  description="",
@@ -37,70 +62,41 @@ class ExchangeParams:
37
62
  output_path="TB2J_results",
38
63
  ):
39
64
  self.efermi = efermi
40
- self.emin = emin
41
- self.emax = emax
42
- self.nz = nz
43
- self.Rcut = Rcut
44
65
  self.basis = basis
45
66
  self.magnetic_elements = magnetic_elements
46
67
  self.include_orbs = include_orbs
47
-
68
+ self._kmesh = kmesh
69
+ self.emin = emin
70
+ self.emax = emax
71
+ self.nz = nz
48
72
  self.exclude_orbs = exclude_orbs
49
73
  self.ne = ne
74
+ self.Rcut = Rcut
50
75
  self._use_cache = use_cache
51
76
  self.np = np
52
- self._kmesh = kmesh
53
- self.orb_decomposition = orb_decomposition
54
- self.write_density_matrix = write_density_matrix
55
77
  self.description = description
78
+ self.write_density_matrix = write_density_matrix
79
+ self.orb_decomposition = orb_decomposition
56
80
  self.output_path = output_path
57
81
 
82
+ def set_params(self, **kwargs):
83
+ for key, val in kwargs.items():
84
+ setattr(self, key, val)
85
+
86
+ def save_to_yaml(self, fname):
87
+ with open(fname, "w") as myfile:
88
+ yaml.dump(self.__dict__, myfile)
89
+
58
90
 
59
91
  class Exchange(ExchangeParams):
60
92
  def __init__(
61
93
  self,
62
94
  tbmodels,
63
95
  atoms,
64
- efermi,
65
- basis=None,
66
- magnetic_elements=[],
67
- include_orbs={},
68
- kmesh=[4, 4, 4],
69
- emin=-15, # integration lower bound, relative to fermi energy
70
- # integration upper bound. Should be 0 (fermi energy). But DFT codes define Fermi energy in various ways.
71
- emax=0.05,
72
- nz=100,
73
- # the delta in the (i delta) in green's function to prevent divergence
74
- exclude_orbs=[], #
75
- ne=None, # number of electrons in Wannier function.
76
- Rcut=None, # Rcut.
77
- use_cache=False,
78
- np=1,
79
- description="",
80
- write_density_matrix=False,
81
- output_path="TB2J_results",
82
- orb_decomposition=False,
96
+ **params: ExchangeParams,
83
97
  ):
84
98
  self.atoms = atoms
85
- super().__init__(
86
- efermi=efermi,
87
- basis=basis,
88
- magnetic_elements=magnetic_elements,
89
- include_orbs=include_orbs,
90
- kmesh=kmesh,
91
- emin=emin,
92
- emax=emax,
93
- nz=nz,
94
- exclude_orbs=exclude_orbs,
95
- ne=ne,
96
- Rcut=Rcut,
97
- use_cache=use_cache,
98
- np=np,
99
- description=description,
100
- write_density_matrix=write_density_matrix,
101
- orb_decomposition=orb_decomposition,
102
- output_path=output_path,
103
- )
99
+ super().__init__(**params)
104
100
  self._prepare_kmesh(self._kmesh)
105
101
  self._prepare_Rlist()
106
102
  self.set_tbmodels(tbmodels)
@@ -334,7 +330,6 @@ class ExchangeNCL(Exchange):
334
330
  """
335
331
  self.tbmodel = tbmodels
336
332
  self.backend_name = self.tbmodel.name
337
- # TODO: check if tbmodels are really a tbmodel with SOC.
338
333
  self.G = TBGreen(
339
334
  self.tbmodel,
340
335
  self.kmesh,
@@ -355,6 +350,12 @@ class ExchangeNCL(Exchange):
355
350
  if self.write_density_matrix:
356
351
  self.G.write_rho_R()
357
352
 
353
+ def get_MAE(self, thetas, phis):
354
+ """
355
+ Calculate the magnetic anisotropy energy.
356
+ """
357
+ pass
358
+
358
359
  def _prepare_NijR(self):
359
360
  self.N = {}
360
361
  for R in self.Rlist:
@@ -615,7 +616,7 @@ class ExchangeNCL(Exchange):
615
616
  def calculate_DMI_NJT(self):
616
617
  """
617
618
  calculate exchange and DMI with the
618
- D(i,j) =
619
+ This did not work and should be removed.
619
620
  """
620
621
  Ddict_NJT = {}
621
622
  Jdict_NJT = {}
@@ -679,10 +680,36 @@ class ExchangeNCL(Exchange):
679
680
  self.contour.path, AijRs_orb[(R, iatom, jatom)]
680
681
  )
681
682
 
682
- def get_AijR(self, e):
683
- GR = self.G.get_GR(self.short_Rlist, energy=e, get_rho=False)
683
+ def get_quantities_per_e(self, e):
684
+ Gk_all = self.G.get_Gk_all(e)
685
+ mae = self.get_mae_kspace(Gk_all)
686
+ # TODO: get the MAE from Gk_all
687
+ GR = self.G.get_GR(self.short_Rlist, energy=e, get_rho=False, Gk_all=Gk_all)
688
+ # TODO: define the quantities for one energy.
684
689
  AijR, AijR_orb = self.get_all_A(GR)
685
- return AijR, AijR_orb
690
+ return dict(AijR=AijR, AijR_orb=AijR_orb, mae=mae)
691
+
692
+ def get_mae_kspace(self, Gk_all):
693
+ """
694
+ get the MAE from Gk_all
695
+ TODO: This is only a place holder.
696
+ """
697
+ return None
698
+ Hso_k = self.model.get_Hso_k(k)
699
+ mae_e = np.zeros(len(self.mae_angles), dtype=complex)
700
+ # rotate the Hso_k to angles
701
+ for ik, k in enumerate(self.G.kpoints):
702
+ Gk = Gk_all[ik]
703
+ for i_angle, angle in enumerate(self.mae_angles):
704
+ # TODO: implementa rotate_H
705
+ Hso_k_rot = rotate_H(Hso_k, angle)
706
+ mae_e[i_angle] = Gk @ Hso_k @ Gk @ Hso_k
707
+ return mae_e
708
+
709
+ def get_mae_rspace(self, GR):
710
+ """
711
+ get the MAE from GR
712
+ """
686
713
 
687
714
  def save_AijR(self, AijRs, fname):
688
715
  result = dict(path=self.contour.path, AijRs=AijRs)
@@ -693,6 +720,7 @@ class ExchangeNCL(Exchange):
693
720
  """
694
721
  Do some sanity check before proceding.
695
722
  """
723
+ pass
696
724
 
697
725
  def calculate_all(self):
698
726
  """
@@ -701,40 +729,38 @@ class ExchangeNCL(Exchange):
701
729
  print("Green's function Calculation started.")
702
730
 
703
731
  AijRs = {}
704
-
705
732
  AijRs_orb = {}
706
733
 
707
734
  self.validate()
708
735
 
709
736
  npole = len(self.contour.path)
710
737
  if self.np > 1:
711
- results = p_map(self.get_AijR, self.contour.path, num_cpus=self.np)
738
+ results = p_map(
739
+ self.get_quantities_per_e, self.contour.path, num_cpus=self.np
740
+ )
712
741
  else:
713
- results = map(self.get_AijR, tqdm(self.contour.path, total=npole))
742
+ results = map(
743
+ self.get_quantities_per_e, tqdm(self.contour.path, total=npole)
744
+ )
714
745
 
715
746
  for i, result in enumerate(results):
716
747
  for iR, R in enumerate(self.R_ijatom_dict):
717
748
  for iatom, jatom in self.R_ijatom_dict[R]:
718
749
  if (R, iatom, jatom) in AijRs:
719
- AijRs[(R, iatom, jatom)].append(result[0][R, iatom, jatom])
750
+ AijRs[(R, iatom, jatom)].append(result["AijR"][R, iatom, jatom])
720
751
  if self.orb_decomposition:
721
752
  AijRs_orb[(R, iatom, jatom)].append(
722
- result[1][R, iatom, jatom]
753
+ result["AijR_orb"][R, iatom, jatom]
723
754
  )
724
755
 
725
756
  else:
726
757
  AijRs[(R, iatom, jatom)] = []
727
- AijRs[(R, iatom, jatom)].append(result[0][R, iatom, jatom])
758
+ AijRs[(R, iatom, jatom)].append(result["AijR"][R, iatom, jatom])
728
759
  if self.orb_decomposition:
729
760
  AijRs_orb[(R, iatom, jatom)] = []
730
761
  AijRs_orb[(R, iatom, jatom)].append(
731
- result[1][R, iatom, jatom]
762
+ result["AijR_orb"][R, iatom, jatom]
732
763
  )
733
- if self.np > 1:
734
- # executor.close()
735
- # executor.join()
736
- # executor.clear()
737
- pass
738
764
 
739
765
  # self.save_AijRs(AijRs)
740
766
  self.integrate(AijRs, AijRs_orb)
TB2J/exchangeCL2.py CHANGED
@@ -234,11 +234,11 @@ class ExchangeCL2(ExchangeCL):
234
234
  self.contour.path, self.JJ_list[(R, iatom, jatom)]
235
235
  )
236
236
 
237
- def get_AijR(self, e):
237
+ def get_quantities_per_e(self, e):
238
238
  GR_up = self.Gup.get_GR(self.short_Rlist, energy=e, get_rho=False)
239
239
  GR_dn = self.Gdn.get_GR(self.short_Rlist, energy=e, get_rho=False)
240
240
  Jorb_list, JJ_list = self.get_all_A(GR_up, GR_dn)
241
- return Jorb_list, JJ_list
241
+ return dict(Jorb_list=Jorb_list, JJ_list=JJ_list)
242
242
 
243
243
  def calculate_all(self):
244
244
  """
@@ -248,13 +248,18 @@ class ExchangeCL2(ExchangeCL):
248
248
 
249
249
  npole = len(self.contour.path)
250
250
  if self.np == 1:
251
- results = map(self.get_AijR, tqdm(self.contour.path, total=npole))
251
+ results = map(
252
+ self.get_quantities_per_e, tqdm(self.contour.path, total=npole)
253
+ )
252
254
  else:
253
255
  # pool = ProcessPool(nodes=self.np)
254
256
  # results = pool.map(self.get_AijR_rhoR ,self.contour.path)
255
- results = p_map(self.get_AijR, self.contour.path, num_cpus=self.np)
257
+ results = p_map(
258
+ self.get_quantities_per_e, self.contour.path, num_cpus=self.np
259
+ )
256
260
  for i, result in enumerate(results):
257
- Jorb_list, JJ_list = result
261
+ Jorb_list = result["Jorb_list"]
262
+ JJ_list = result["JJ_list"]
258
263
  for iR, R in enumerate(self.R_ijatom_dict):
259
264
  for iatom, jatom in self.R_ijatom_dict[R]:
260
265
  key = (R, iatom, jatom)
TB2J/green.py CHANGED
@@ -270,7 +270,14 @@ class TBGreen:
270
270
  # Gk = np.linalg.inv((energy+self.efermi)*self.S[ik,:,:] - self.H[ik,:,:])
271
271
  return Gk
272
272
 
273
- def get_GR(self, Rpts, energy, get_rho=False):
273
+ def get_Gk_all(self, energy):
274
+ """Green's function G(k) for one energy for all kpoints"""
275
+ Gk_all = np.zeros((self.nkpts, self.nbasis, self.nbasis), dtype=complex)
276
+ for ik, _ in enumerate(self.kpts):
277
+ Gk_all[ik] = self.get_Gk(ik, energy)
278
+ return Gk_all
279
+
280
+ def get_GR(self, Rpts, energy, get_rho=False, Gk_all=None):
274
281
  """calculate real space Green's function for one energy, all R points.
275
282
  G(R, epsilon) = G(k, epsilon) exp(-2\pi i R.dot. k)
276
283
  :param Rpts: R points
@@ -282,7 +289,10 @@ class TBGreen:
282
289
  GR = defaultdict(lambda: 0.0j)
283
290
  rhoR = defaultdict(lambda: 0.0j)
284
291
  for ik, kpt in enumerate(self.kpts):
285
- Gk = self.get_Gk(ik, energy)
292
+ if Gk_all is None:
293
+ Gk = self.get_Gk(ik, energy)
294
+ else:
295
+ Gk = Gk_all[ik]
286
296
  if get_rho:
287
297
  if self.is_orthogonal:
288
298
  rhok = Gk
TB2J/manager.py CHANGED
@@ -6,7 +6,13 @@ from TB2J.exchangeCL2 import ExchangeCL2
6
6
  from TB2J.exchange_qspace import ExchangeCLQspace
7
7
  from TB2J.utils import read_basis, auto_assign_basis_name
8
8
  from ase.io import read
9
- from TB2J.sisl_wrapper import SislWrapper
9
+
10
+ #from TB2J.sisl_wrapper import SislWrapper
11
+ try:
12
+ from HamiltonIO.siesta import SislWrapper
13
+ except ImportError:
14
+ print("Cannot import SislWrapper from HamiltonIO.siesta. Please install HamiltonIO first.")
15
+ from TB2J.sisl_wrapper import SislWrapper
10
16
  from TB2J.gpaw_wrapper import GPAWWrapper
11
17
  from TB2J.wannier import parse_atoms
12
18
 
@@ -283,8 +289,8 @@ def gen_exchange_siesta(
283
289
  geom = H.geometry
284
290
  if H.spin.is_colinear:
285
291
  print("Reading Siesta hamiltonian: colinear spin.")
286
- tbmodel_up = SislWrapper(H, spin=0, geom=geom)
287
- tbmodel_dn = SislWrapper(H, spin=1, geom=geom)
292
+ tbmodel_up = SislWrapper(fdf_fname=None,sisl_hamiltonian=H, spin=0, geom=geom)
293
+ tbmodel_dn = SislWrapper(fdf_fname=None, sisl_hamiltonian=H, spin=1, geom=geom)
288
294
  basis = dict(zip(tbmodel_up.orbs, list(range(tbmodel_up.norb))))
289
295
  print("Starting to calculate exchange.")
290
296
  description = f""" Input from collinear Siesta data.
@@ -351,7 +357,7 @@ def gen_exchange_siesta(
351
357
 
352
358
  elif H.spin.is_spinorbit or H.spin.is_noncolinear:
353
359
  print("Reading Siesta hamiltonian: non-colinear spin.")
354
- tbmodel = SislWrapper(H, spin=None, geom=geom)
360
+ tbmodel = SislWrapper(fdf_fname=None, sisl_hamiltonian=H, spin=None, geom=geom)
355
361
  basis = dict(zip(tbmodel.orbs, list(range(tbmodel.nbasis))))
356
362
  print("Starting to calculate exchange.")
357
363
  description = f""" Input from non-collinear Siesta data.
@@ -14,6 +14,27 @@ def rotate_Matrix_from_z_to_axis(M, axis, normalize=True):
14
14
  return M_new
15
15
 
16
16
 
17
+ def spherical_to_cartesian(theta, phi, normalize=True):
18
+ """
19
+ Convert spherical coordinates to cartesian
20
+ """
21
+ x = np.sin(theta) * np.cos(phi)
22
+ y = np.sin(theta) * np.sin(phi)
23
+ z = np.cos(theta)
24
+ vec = np.array([x, y, z])
25
+ if normalize:
26
+ vec = vec / np.linalg.norm(vec)
27
+ return vec
28
+
29
+
30
+ def rotate_Matrix_from_z_to_spherical(M, theta, phi, normalize=True):
31
+ """
32
+ Given a spinor matrix M, rotate it from z-axis to spherical coordinates
33
+ """
34
+ axis = spherical_to_cartesian(theta, phi, normalize)
35
+ return rotate_Matrix_from_z_to_axis(M, axis, normalize)
36
+
37
+
17
38
  def test_rotate_Matrix_from_z_to_axis():
18
39
  M = np.array([[1.1, 0], [0, 0.9]])
19
40
  print(pauli_block_all(M))
TB2J/patch.py ADDED
@@ -0,0 +1,50 @@
1
+ import types
2
+ from unittest import mock
3
+
4
+ class A(object):#but seems to work for old style objects too
5
+ def funcx(self,x):
6
+ print("x1=",x)
7
+ print("called from", self)
8
+
9
+ def method(self,x):
10
+ print("xmethod=",x)
11
+ print("called from", self)
12
+
13
+ def patch_me(target):
14
+ def method(target,x):
15
+ print("x=",x)
16
+ print("called from", target)
17
+ target.method = types.MethodType(method,target)
18
+
19
+ def method(self,x):
20
+ print("x=",x)
21
+ print("called from", self)
22
+
23
+ @mock.patch("__main__.A")
24
+ def funcx(self,x):
25
+ print("new x=",x)
26
+ print("called from", self)
27
+
28
+ A.method=method
29
+ #add more if needed
30
+ a = A()
31
+ print(A.__dict__)
32
+ print(a)
33
+ #out: <__main__.A object at 0x2b73ac88bfd0>
34
+
35
+ @mock.patch("__main__.a")
36
+ def funcx(self,x):
37
+ print("x=",x)
38
+ print("called from", self)
39
+
40
+ a.funcx(3)
41
+ patch_me(a) #patch instance
42
+ a.method=method
43
+ #a.method(5)
44
+ #out: x= 5
45
+ #out: called from <__main__.A object at 0x2b73ac88bfd0>
46
+ patch_me(A)
47
+
48
+ a.method(6) #can patch class too
49
+ #out: x= 6
50
+ #out: called from <class '__main__.A'>
@@ -58,6 +58,13 @@ def main():
58
58
  default=False,
59
59
  )
60
60
 
61
+ parser.add_argument(
62
+ "--method",
63
+ help="The method to downfold the exchange parameter. Options are Lowdin and PWF (projected Wannier function). ",
64
+ type=str,
65
+ default="Lowdin",
66
+ )
67
+
61
68
  args = parser.parse_args()
62
69
 
63
70
  if len(args.metals) == []:
@@ -73,6 +80,7 @@ def main():
73
80
  outpath=args.outpath,
74
81
  qmesh=args.qmesh,
75
82
  iso_only=args.iso_only,
83
+ method=args.method,
76
84
  )
77
85
 
78
86
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: TB2J
3
- Version: 0.9.1rc0
3
+ Version: 0.9.3rc0
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
@@ -22,5 +22,6 @@ Requires-Dist: tqdm
22
22
  Requires-Dist: pathos
23
23
  Requires-Dist: packaging >=20.0
24
24
  Requires-Dist: pre-commit
25
+ Requires-Dist: HamiltonIO >=0.1.4
25
26
 
26
27
  TB2J is a Python package aimed to compute automatically the magnetic interactions (superexchange and Dzyaloshinskii-Moriya) between atoms of magnetic crystals from DFT Hamiltonian based on Wannier functions or Linear combination of atomic orbitals. It uses the Green's function method and take the local rigid spin rotation as a perturbation. The package can take the output from Wannier90, which is interfaced with many density functional theory codes or from codes based on localised orbitals. A minimal user input is needed, which allows for an easily integration into a high-throughput workflows.
@@ -1,5 +1,6 @@
1
- TB2J/Jdownfolder.py,sha256=Nw2ixvn2Uq-o1wficz6rdaYHjfRN3U_kQCvrNJGNb68,6980
2
- TB2J/Jtensor.py,sha256=0fhfOcfVQGu75gytEnApKWTJZfg9ksKJ0anJgco5wRQ,3179
1
+ TB2J/Jdownfolder.py,sha256=Rmg6KfQ-Lkhei5daTJ2POzr0XL-R1WM-rzUnDcfoDhc,9595
2
+ TB2J/Jtensor.py,sha256=t6OsqrSlYW6Im4H7ykVAW8Al_pFXN4C5yj2UEsV6r7g,3181
3
+ TB2J/MAE.py,sha256=0yU11DNKwcW5fL2EWgangIqHdWW4Vp97IiXGdi70Ayo,7396
3
4
  TB2J/Oiju.py,sha256=cNGv8N5uH_swGq7cnAt2OyiDfqtjLlLrwseGu0E4iaM,3383
4
5
  TB2J/Oiju_epc.py,sha256=oytM3NYW7nWmklrGgNlqwIpI_JYv_hb7ZnR4o9nYNog,6809
5
6
  TB2J/__init__.py,sha256=hcEWkag_UvLm1ZSbjsgcTWkGVlR3Bwmzg1QYAwsvf-g,24
@@ -9,19 +10,20 @@ TB2J/contour.py,sha256=aw8LX6wVFCRPhcpkzuI0jGnHisvk4cezvUhkF_6Yx94,2633
9
10
  TB2J/cut_cell.py,sha256=kr9WeQhBQLm8QXL2B3NcsSYmSw-OAtJk3f9wksAOZbs,2952
10
11
  TB2J/density_matrix.py,sha256=D5k8Oe21OCiLVORNYbo4TZOFG0slrQSbj91kJ3TMFjs,1514
11
12
  TB2J/epc.py,sha256=zLbtqZJhDr8DnnGN6YENcXwrMb3Qxu6KB08mLy9Pw20,3474
12
- TB2J/exchange.py,sha256=dsXQhlxXaBurxa7z3YkBjqmEFFtfEy1xaHf0VT3eKZE,29581
13
- TB2J/exchangeCL2.py,sha256=TIr-d2X56AiGe4qEhyXyZhRuwXvQG6clJMwDmjnTOaE,10985
13
+ TB2J/exchange.py,sha256=Tltunv85eNr-jsVL_SvfqG_WVkQyJX99RszaJRQRBD8,29945
14
+ TB2J/exchangeCL2.py,sha256=QSbQ_WxgJyiByn2U-tJ3xy2iYIQI8YMrN3vhw9_k2Cs,11149
14
15
  TB2J/exchange_pert.py,sha256=jmFMtQbYa_uczM4VAeS6TijkIHRFIqEzZJswzE9Wfuo,8523
15
16
  TB2J/exchange_qspace.py,sha256=ZL68qBGFUaQ9BsSPsJaaoWOr9RssPiqX34R_9I3nk_8,8436
16
17
  TB2J/gpaw_wrapper.py,sha256=aJ--9Dtyq7jOP1Hkh-Sh1nWcfXm6zKcljOCO0DNCAr0,6890
17
- TB2J/green.py,sha256=QAJbDaR91QLres5gUPk37iqVsuQdPTt92VtEYLCl240,13170
18
+ TB2J/green.py,sha256=giWSPhrLKc3ZKOpwyY3snUKFWH08GMqBlsJWbFG9Qo8,13565
18
19
  TB2J/greentest.py,sha256=2ISSfhor9ecSEOi_E6b4Cv26wEIQlwlzca0ru8z44_E,1603
19
20
  TB2J/io_merge.py,sha256=t85k3L6IL9X5ys-PWK7CzResb3xJsyqM3LAlKPUe9vM,6825
20
21
  TB2J/kpoints.py,sha256=6XK2KqTncidEq3o9GuO6VEZRPNTRtWeXg9QfcV-9smI,532
21
- TB2J/manager.py,sha256=4-4x9jJRHpUEqJuhc5HqpXfh2-Ze5G9Wg8gOtn-AqR4,15372
22
+ TB2J/manager.py,sha256=Ogb_yRCnroNmGttKPRcbF70ddF9UNV_1UytdKbNFN4E,15685
22
23
  TB2J/mathutils.py,sha256=tHA6q3KPDpXLIbZHdDZ2NU5s886VVM_oEG490zQ6Ris,300
23
24
  TB2J/myTB.py,sha256=ok_B4my29bOIghMSZfx0Es6G8FaXaIiLP4gPxTdSj00,17659
24
25
  TB2J/orbmap.py,sha256=RCMJkOPGbfPrcZzcc5ia1ZMKBQWxGcyj8W1ve8BJaEw,6669
26
+ TB2J/patch.py,sha256=Z3KZklID9U8zKuk6Ek1Tq95JcY3eT4770dsdcXz6mAA,1067
25
27
  TB2J/pauli.py,sha256=zOELm7Vgxw6SMaO5l7qVWx1pBKZt25RLnEpnVM3dz_0,4545
26
28
  TB2J/pert.py,sha256=RaCJfewl0doht4cjAnzzGKe-uj2le4aqe0iPKFrq9fo,1192
27
29
  TB2J/plot.py,sha256=AnFIFWE2vlmj7Z6f_7-dX_O1stJN-qbuiurPj43dUCM,4104
@@ -36,7 +38,7 @@ TB2J/versioninfo.py,sha256=wZwS9QDFRVDe7rf8JyPDDI8UGdTQiO6Pb_sWv8GAegA,337
36
38
  TB2J/abacus/MAE.py,sha256=q9aSVDRZFAnZL3gHdNmde7sxj80oe-BRjwDO-ipyfew,12237
37
39
  TB2J/abacus/__init__.py,sha256=5sHiDnF2L-Y80QeET9zOiS83a5T_TQAXvnIhcYB6wNU,56
38
40
  TB2J/abacus/abacus_api.py,sha256=D_NyXW-Pno92d3RVHByx0l1HDPHQAvXsmQVt8cfIGR8,7267
39
- TB2J/abacus/abacus_wrapper.py,sha256=PaO7qEE-h1tv2nKsV8h2RZUrmAWjkw8MKapj8Fk9U5s,9006
41
+ TB2J/abacus/abacus_wrapper.py,sha256=k0ZyTQ0jungp7jtlVCcdFQVK9YKeWokZvASCvfKCuKs,11880
40
42
  TB2J/abacus/gen_exchange_abacus.py,sha256=lKZqkWMnLQtaSwgn8O5Fzr-pV6tzwoMqfZU_vbET6gU,2973
41
43
  TB2J/abacus/occupations.py,sha256=vaMVeZwldgzGDxjA7i3-2-V6akXjpgJwJFWKozJ-l2k,8947
42
44
  TB2J/abacus/orbital_api.py,sha256=l48Hn5z7TA0TH7Is4NDmz74b6B9L2ztYO4dRR37U4mQ,1562
@@ -58,7 +60,7 @@ TB2J/mathutils/__init__.py,sha256=tQLBfHkZqdVfVxPOahy42qMUkFYnFFFhM-uc4QsYFxI,27
58
60
  TB2J/mathutils/fermi.py,sha256=tzEicVoxE_5DxPDDZMvi4ynR1_Iqf-Qh0-0zfm-iVBo,480
59
61
  TB2J/mathutils/kR_convert.py,sha256=p_9XWJVNanTzTK2rI6KRjTkbSq42la6N448-zJOsMwY,2671
60
62
  TB2J/mathutils/lowdin.py,sha256=tHA6q3KPDpXLIbZHdDZ2NU5s886VVM_oEG490zQ6Ris,300
61
- TB2J/mathutils/rotate_spin.py,sha256=XtfwHGfIqI9nRYZcCd_yQ3Ud1AXVJj9fwqIHloMcaCs,1111
63
+ TB2J/mathutils/rotate_spin.py,sha256=NT12khB8lN1qf_jQ2SwnAhhtWxptZXkzpUQ2JvZEnkM,1710
62
64
  TB2J/spinham/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
65
  TB2J/spinham/base_parser.py,sha256=oQRHvFE_BlUtTaTZykKgvicu40oXcbICB-D1aAt-qlA,2196
64
66
  TB2J/spinham/constants.py,sha256=y4-hRyl5EAR42k24Oa5XhAsUQtKVn1MAgyqNf-p3PrM,762
@@ -74,18 +76,18 @@ TB2J/spinham/supercell.py,sha256=y17uUC6r3gQb278FhxIW4CABihfLTvKFj6flyXrCPR8,122
74
76
  TB2J/wannier/__init__.py,sha256=7ojCbM84PYv1X1Tbo4NHI-d3gWmQsZB_xiYqbfxVV1E,80
75
77
  TB2J/wannier/w90_parser.py,sha256=dbd63LuKyv2DVUzqRINGsbDzEsOxsQyE8_Ear_LQIRg,4620
76
78
  TB2J/wannier/w90_tb_parser.py,sha256=qt8pnuprmPp9iIAYwPkPbmEzk6ZPgMq2xognoQp7vwc,4610
77
- TB2J-0.9.1rc0.data/scripts/TB2J_downfold.py,sha256=F9oImXFysejCMP7eIBjbCX2jdHFOCvDW5beF1sG-UM8,1854
78
- TB2J-0.9.1rc0.data/scripts/TB2J_eigen.py,sha256=Qs9v2hnMm2Tpfoa4h53muUKty2dZjwx8948MBoQooNg,1128
79
- TB2J-0.9.1rc0.data/scripts/TB2J_magnon.py,sha256=q7UwAmorRcFNk4tfE7gl_ny05l6p7pbD9Wm_LkIpKEw,3101
80
- TB2J-0.9.1rc0.data/scripts/TB2J_magnon_dos.py,sha256=TMXQvD2dIbO5FZ4tUMmxJgCgH2O2hDAPUNfEKO4z-x4,110
81
- TB2J-0.9.1rc0.data/scripts/TB2J_merge.py,sha256=y834SF4rIRn1L1ptkhczvavQpC-8Px6DTmDOOSaq_DE,1854
82
- TB2J-0.9.1rc0.data/scripts/TB2J_rotate.py,sha256=zgiDFuYZNmzKK0rwDmTaYD2OpRlmKA_VGeBx83w2Xwc,873
83
- TB2J-0.9.1rc0.data/scripts/TB2J_rotateDM.py,sha256=kCvF7gotuqAX1VnJ06cwfVm7RrhrdtiV5v7d9P2Pn_E,567
84
- TB2J-0.9.1rc0.data/scripts/abacus2J.py,sha256=M4B07lvTCDczTPTqvnDh_PERzCARAd09TLKv4aIdSQM,4408
85
- TB2J-0.9.1rc0.data/scripts/siesta2J.py,sha256=hBzS7ZgoHM3oXlTCQd-xVA07Ks2FiIwyRpQWUFITRPE,4303
86
- TB2J-0.9.1rc0.data/scripts/wann2J.py,sha256=2t2hWwyELskYCwkGDziCgiIAnfr6odLLJ6cQBJ2RQwQ,5714
87
- TB2J-0.9.1rc0.dist-info/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
88
- TB2J-0.9.1rc0.dist-info/METADATA,sha256=ymoIhPvH2rmZH5KQRPcDlCBqhctXKTukTDCmdFzZM4w,1421
89
- TB2J-0.9.1rc0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
90
- TB2J-0.9.1rc0.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
91
- TB2J-0.9.1rc0.dist-info/RECORD,,
79
+ TB2J-0.9.3rc0.data/scripts/TB2J_downfold.py,sha256=i4BVqnpDdgrX_amookVWeLGefGBn-qeAutWiwuY9SfQ,2099
80
+ TB2J-0.9.3rc0.data/scripts/TB2J_eigen.py,sha256=Qs9v2hnMm2Tpfoa4h53muUKty2dZjwx8948MBoQooNg,1128
81
+ TB2J-0.9.3rc0.data/scripts/TB2J_magnon.py,sha256=q7UwAmorRcFNk4tfE7gl_ny05l6p7pbD9Wm_LkIpKEw,3101
82
+ TB2J-0.9.3rc0.data/scripts/TB2J_magnon_dos.py,sha256=TMXQvD2dIbO5FZ4tUMmxJgCgH2O2hDAPUNfEKO4z-x4,110
83
+ TB2J-0.9.3rc0.data/scripts/TB2J_merge.py,sha256=y834SF4rIRn1L1ptkhczvavQpC-8Px6DTmDOOSaq_DE,1854
84
+ TB2J-0.9.3rc0.data/scripts/TB2J_rotate.py,sha256=zgiDFuYZNmzKK0rwDmTaYD2OpRlmKA_VGeBx83w2Xwc,873
85
+ TB2J-0.9.3rc0.data/scripts/TB2J_rotateDM.py,sha256=kCvF7gotuqAX1VnJ06cwfVm7RrhrdtiV5v7d9P2Pn_E,567
86
+ TB2J-0.9.3rc0.data/scripts/abacus2J.py,sha256=M4B07lvTCDczTPTqvnDh_PERzCARAd09TLKv4aIdSQM,4408
87
+ TB2J-0.9.3rc0.data/scripts/siesta2J.py,sha256=hBzS7ZgoHM3oXlTCQd-xVA07Ks2FiIwyRpQWUFITRPE,4303
88
+ TB2J-0.9.3rc0.data/scripts/wann2J.py,sha256=2t2hWwyELskYCwkGDziCgiIAnfr6odLLJ6cQBJ2RQwQ,5714
89
+ TB2J-0.9.3rc0.dist-info/LICENSE,sha256=CbZI-jyRTjiqIcWa244cRSHJdjjtUNqGR4HeJkgEwJw,1332
90
+ TB2J-0.9.3rc0.dist-info/METADATA,sha256=9kUPr5GCrvzdnzjbhCmByaSBj6qZ-991Hab3hJ7WUzE,1455
91
+ TB2J-0.9.3rc0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
92
+ TB2J-0.9.3rc0.dist-info/top_level.txt,sha256=whYa5ByLYhl5XnTPBHSWr-IGD6VWmr5Ql2bye2qwV_s,5
93
+ TB2J-0.9.3rc0.dist-info/RECORD,,