TB2J 0.9.4rc0__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.
- TB2J/MAE.py +108 -24
- TB2J/anisotropy.py +672 -0
- TB2J/contour.py +8 -0
- TB2J/exchange.py +43 -103
- TB2J/exchangeCL2.py +11 -13
- TB2J/exchange_params.py +213 -0
- TB2J/green.py +62 -27
- TB2J/interfaces/__init__.py +12 -0
- TB2J/interfaces/abacus/__init__.py +4 -0
- TB2J/{abacus → interfaces/abacus}/abacus_api.py +3 -3
- TB2J/{abacus → interfaces/abacus}/abacus_wrapper.py +11 -7
- TB2J/{abacus → interfaces/abacus}/gen_exchange_abacus.py +6 -3
- TB2J/{abacus → interfaces/abacus}/orbital_api.py +4 -4
- TB2J/{abacus → interfaces/abacus}/stru_api.py +11 -11
- TB2J/{abacus → interfaces/abacus}/test_read_HRSR.py +0 -1
- TB2J/{abacus → interfaces/abacus}/test_read_stru.py +5 -3
- TB2J/interfaces/gpaw_interface.py +54 -0
- TB2J/interfaces/lawaf_interface.py +129 -0
- TB2J/interfaces/manager.py +23 -0
- TB2J/interfaces/siesta_interface.py +174 -0
- TB2J/interfaces/wannier90_interface.py +115 -0
- TB2J/io_exchange/io_exchange.py +21 -7
- TB2J/io_merge.py +2 -1
- TB2J/mathutils/fermi.py +11 -6
- TB2J/mathutils/lowdin.py +12 -2
- TB2J/mathutils/rotate_spin.py +222 -4
- TB2J/pauli.py +38 -2
- TB2J/symmetrize_J.py +120 -0
- TB2J/utils.py +82 -1
- {TB2J-0.9.4rc0.data → TB2J-0.9.6rc0.data}/scripts/abacus2J.py +5 -4
- {TB2J-0.9.4rc0.data → TB2J-0.9.6rc0.data}/scripts/siesta2J.py +21 -4
- TB2J-0.9.6rc0.data/scripts/wann2J.py +96 -0
- {TB2J-0.9.4rc0.dist-info → TB2J-0.9.6rc0.dist-info}/METADATA +4 -3
- {TB2J-0.9.4rc0.dist-info → TB2J-0.9.6rc0.dist-info}/RECORD +46 -46
- {TB2J-0.9.4rc0.dist-info → TB2J-0.9.6rc0.dist-info}/WHEEL +1 -1
- TB2J-0.9.6rc0.dist-info/entry_points.txt +3 -0
- TB2J/abacus/MAE.py +0 -320
- TB2J/abacus/__init__.py +0 -1
- TB2J/abacus/occupations.py +0 -278
- TB2J/cut_cell.py +0 -82
- TB2J/io_exchange/io_pickle.py +0 -0
- TB2J/manager.py +0 -441
- TB2J/mathutils.py +0 -12
- TB2J/patch.py +0 -50
- TB2J/spinham/h_matrix.py +0 -68
- TB2J/spinham/obtain_J.py +0 -79
- TB2J/supercell.py +0 -532
- TB2J-0.9.4rc0.data/scripts/wann2J.py +0 -194
- TB2J/{abacus → interfaces/abacus}/test_density_matrix.py +1 -1
- {TB2J-0.9.4rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_downfold.py +0 -0
- {TB2J-0.9.4rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_eigen.py +0 -0
- {TB2J-0.9.4rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_magnon.py +0 -0
- {TB2J-0.9.4rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_magnon_dos.py +0 -0
- {TB2J-0.9.4rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_merge.py +0 -0
- {TB2J-0.9.4rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_rotate.py +0 -0
- {TB2J-0.9.4rc0.data → TB2J-0.9.6rc0.data}/scripts/TB2J_rotateDM.py +0 -0
- {TB2J-0.9.4rc0.dist-info → TB2J-0.9.6rc0.dist-info}/LICENSE +0 -0
- {TB2J-0.9.4rc0.dist-info → TB2J-0.9.6rc0.dist-info}/top_level.txt +0 -0
TB2J/MAE.py
CHANGED
@@ -1,19 +1,26 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
|
3
|
+
import matplotlib.pyplot as plt
|
1
4
|
import numpy as np
|
2
|
-
|
3
|
-
|
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
|
-
|
8
|
-
from
|
9
|
-
from
|
10
|
-
|
11
|
-
|
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
|
19
|
+
|
20
|
+
# from TB2J.abacus.abacus_wrapper import AbacusWrapper, AbacusParser
|
21
|
+
from TB2J.mathutils.rotate_spin import (
|
22
|
+
rotate_spinor_matrix,
|
23
|
+
)
|
17
24
|
|
18
25
|
|
19
26
|
def get_occupation(evals, kweights, nel, width=0.1):
|
@@ -86,40 +93,117 @@ class MAE:
|
|
86
93
|
return es
|
87
94
|
|
88
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
|
+
|
89
158
|
def get_model_energy(model, kmesh, gamma=True):
|
90
159
|
ham = MAE(model, kmesh, gamma=gamma)
|
91
160
|
return ham.get_band_energy()
|
92
161
|
|
93
162
|
|
94
163
|
def abacus_get_MAE(
|
95
|
-
path_nosoc,
|
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,
|
96
173
|
):
|
97
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."""
|
98
175
|
parser = AbacusSplitSOCParser(
|
99
176
|
outpath_nosoc=path_nosoc, outpath_soc=path_soc, binary=False
|
100
177
|
)
|
101
178
|
model = parser.parse()
|
102
|
-
|
103
|
-
|
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)
|
104
183
|
if outfile:
|
105
184
|
with open(outfile, "w") as f:
|
106
|
-
f.write("#theta,
|
107
|
-
for theta,
|
108
|
-
f.write(f"{theta}, {
|
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")
|
109
188
|
return es
|
110
189
|
|
111
190
|
|
112
|
-
def siesta_get_MAE(
|
191
|
+
def siesta_get_MAE(
|
192
|
+
fdf_fname, kmesh, thetas, phis, gamma=True, outfile="MAE.txt", nel=None, width=0.1
|
193
|
+
):
|
113
194
|
""" """
|
114
|
-
|
115
|
-
|
116
|
-
|
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")
|
206
|
+
f.write(f"{theta:5.3f}, {psi:5.3f}, {e:10.9f}\n")
|
123
207
|
return es
|
124
208
|
|
125
209
|
|