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/exchange.py
CHANGED
@@ -1,91 +1,23 @@
|
|
1
|
-
from collections import defaultdict, OrderedDict
|
2
1
|
import os
|
3
|
-
import numpy as np
|
4
2
|
import pickle
|
5
|
-
from
|
6
|
-
|
7
|
-
|
8
|
-
from TB2J.pauli import pauli_block_all, pauli_block_sigma_norm, pauli_mat
|
9
|
-
from TB2J.utils import symbol_number, kmesh_to_R
|
10
|
-
from TB2J.io_exchange import SpinIO
|
3
|
+
from collections import OrderedDict, defaultdict
|
4
|
+
|
5
|
+
import numpy as np
|
11
6
|
from tqdm import tqdm
|
12
|
-
|
7
|
+
|
13
8
|
from TB2J.contour import Contour
|
14
|
-
from TB2J.
|
9
|
+
from TB2J.exchange_params import ExchangeParams
|
10
|
+
from TB2J.external import p_map
|
11
|
+
from TB2J.green import TBGreen
|
12
|
+
from TB2J.io_exchange import SpinIO
|
15
13
|
from TB2J.orbmap import map_orbs_matrix
|
16
|
-
from
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
44
|
-
def __init__(
|
45
|
-
self,
|
46
|
-
efermi=-10.0,
|
47
|
-
basis=None,
|
48
|
-
magnetic_elements=None,
|
49
|
-
include_orbs=None,
|
50
|
-
kmesh=[4, 4, 4],
|
51
|
-
emin=-15,
|
52
|
-
emax=0.05,
|
53
|
-
nz=100,
|
54
|
-
exclude_orbs=[],
|
55
|
-
ne=None,
|
56
|
-
Rcut=None,
|
57
|
-
use_cache=False,
|
58
|
-
np=1,
|
59
|
-
description="",
|
60
|
-
write_density_matrix=False,
|
61
|
-
orb_decomposition=False,
|
62
|
-
output_path="TB2J_results",
|
63
|
-
):
|
64
|
-
self.efermi = efermi
|
65
|
-
self.basis = basis
|
66
|
-
self.magnetic_elements = magnetic_elements
|
67
|
-
self.include_orbs = include_orbs
|
68
|
-
self._kmesh = kmesh
|
69
|
-
self.emin = emin
|
70
|
-
self.emax = emax
|
71
|
-
self.nz = nz
|
72
|
-
self.exclude_orbs = exclude_orbs
|
73
|
-
self.ne = ne
|
74
|
-
self.Rcut = Rcut
|
75
|
-
self._use_cache = use_cache
|
76
|
-
self.np = np
|
77
|
-
self.description = description
|
78
|
-
self.write_density_matrix = write_density_matrix
|
79
|
-
self.orb_decomposition = orb_decomposition
|
80
|
-
self.output_path = output_path
|
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)
|
14
|
+
from TB2J.pauli import pauli_block_all, pauli_block_sigma_norm, pauli_mat
|
15
|
+
from TB2J.utils import (
|
16
|
+
kmesh_to_R,
|
17
|
+
simpson_nonuniform,
|
18
|
+
symbol_number,
|
19
|
+
trapezoidal_nonuniform,
|
20
|
+
)
|
89
21
|
|
90
22
|
|
91
23
|
class Exchange(ExchangeParams):
|
@@ -219,9 +151,9 @@ class Exchange(ExchangeParams):
|
|
219
151
|
raise ValueError(
|
220
152
|
f"""The number of spin-orbitals for atom {iatom} is not even,
|
221
153
|
{nsorb} spin-orbitals are found near this atom.
|
222
|
-
which means the spin up/down does not have same number of orbitals.
|
154
|
+
which means the spin up/down does not have same number of orbitals.
|
223
155
|
This is often because the Wannier functions are wrongly defined,
|
224
|
-
or badly localized. Please check the Wannier centers in the Wannier90 output file.
|
156
|
+
or badly localized. Please check the Wannier centers in the Wannier90 output file.
|
225
157
|
"""
|
226
158
|
)
|
227
159
|
self._spin_dict = {}
|
@@ -331,12 +263,14 @@ class ExchangeNCL(Exchange):
|
|
331
263
|
self.tbmodel = tbmodels
|
332
264
|
self.backend_name = self.tbmodel.name
|
333
265
|
self.G = TBGreen(
|
334
|
-
self.tbmodel,
|
335
|
-
self.kmesh,
|
336
|
-
self.efermi,
|
266
|
+
tbmodel=self.tbmodel,
|
267
|
+
kmesh=self.kmesh,
|
268
|
+
efermi=self.efermi,
|
337
269
|
use_cache=self._use_cache,
|
338
|
-
nproc=self.
|
270
|
+
nproc=self.nproc,
|
339
271
|
)
|
272
|
+
if self.efermi is None:
|
273
|
+
self.efermi = self.G.efermi
|
340
274
|
self.norb = self.G.norb
|
341
275
|
self.nbasis = self.G.nbasis
|
342
276
|
# self.rho = np.zeros((self.nbasis, self.nbasis), dtype=complex)
|
@@ -344,7 +278,11 @@ class ExchangeNCL(Exchange):
|
|
344
278
|
self.A_ijR_list = defaultdict(lambda: [])
|
345
279
|
self.A_ijR = defaultdict(lambda: np.zeros((4, 4), dtype=complex))
|
346
280
|
self.A_ijR_orb = dict()
|
347
|
-
self.HR0 = self.
|
281
|
+
# self.HR0 = self.tbmodel.get_H0()
|
282
|
+
if hasattr(self.tbmodel, "get_H0"):
|
283
|
+
self.HR0 = self.tbmodel.get_H0()
|
284
|
+
else:
|
285
|
+
self.HR0 = self.G.H0
|
348
286
|
self._is_collinear = False
|
349
287
|
self.Pdict = {}
|
350
288
|
if self.write_density_matrix:
|
@@ -477,7 +415,7 @@ class ExchangeNCL(Exchange):
|
|
477
415
|
if self.orb_decomposition:
|
478
416
|
for key, val in self.A_ijR_orb.items():
|
479
417
|
R, iatom, jatom = key
|
480
|
-
Rm = tuple(-x for x in R)
|
418
|
+
# Rm = tuple(-x for x in R)
|
481
419
|
# valm = self.A_ijR_orb[(Rm, jatom, iatom)]
|
482
420
|
ni = self.norb_reduced[iatom]
|
483
421
|
nj = self.norb_reduced[jatom]
|
@@ -695,21 +633,23 @@ class ExchangeNCL(Exchange):
|
|
695
633
|
TODO: This is only a place holder.
|
696
634
|
"""
|
697
635
|
return None
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
636
|
+
|
637
|
+
# mae_e = np.zeros(len(self.mae_angles), dtype=complex)
|
638
|
+
# # rotate the Hso_k to angles
|
639
|
+
# for ik, k in enumerate(self.G.kpoints):
|
640
|
+
# Hso_k = self.model.get_Hso_k(k)
|
641
|
+
# Gk = Gk_all[ik]
|
642
|
+
# for i_angle, angle in enumerate(self.mae_angles):
|
643
|
+
# # TODO: implementa rotate_H
|
644
|
+
# Hso_k_rot = rotate_H(Hso_k, angle)
|
645
|
+
# mae_e[i_angle] = Gk @ Hso_k @ Gk @ Hso_k
|
646
|
+
# return mae_e
|
708
647
|
|
709
648
|
def get_mae_rspace(self, GR):
|
710
649
|
"""
|
711
650
|
get the MAE from GR
|
712
651
|
"""
|
652
|
+
raise NotImplementedError("Not yet implemented.")
|
713
653
|
|
714
654
|
def save_AijR(self, AijRs, fname):
|
715
655
|
result = dict(path=self.contour.path, AijRs=AijRs)
|
@@ -734,9 +674,9 @@ class ExchangeNCL(Exchange):
|
|
734
674
|
self.validate()
|
735
675
|
|
736
676
|
npole = len(self.contour.path)
|
737
|
-
if self.
|
677
|
+
if self.nproc > 1:
|
738
678
|
results = p_map(
|
739
|
-
self.get_quantities_per_e, self.contour.path, num_cpus=self.
|
679
|
+
self.get_quantities_per_e, self.contour.path, num_cpus=self.nproc
|
740
680
|
)
|
741
681
|
else:
|
742
682
|
results = map(
|
TB2J/exchangeCL2.py
CHANGED
@@ -20,18 +20,18 @@ class ExchangeCL2(ExchangeCL):
|
|
20
20
|
self.tbmodel_up, self.tbmodel_dn = tbmodels
|
21
21
|
self.backend_name = self.tbmodel_up.name
|
22
22
|
self.Gup = TBGreen(
|
23
|
-
self.tbmodel_up,
|
24
|
-
self.kmesh,
|
25
|
-
self.efermi,
|
23
|
+
tbmodel=self.tbmodel_up,
|
24
|
+
kmesh=self.kmesh,
|
25
|
+
efermi=self.efermi,
|
26
26
|
use_cache=self._use_cache,
|
27
|
-
nproc=self.
|
27
|
+
nproc=self.nproc,
|
28
28
|
)
|
29
29
|
self.Gdn = TBGreen(
|
30
|
-
self.tbmodel_dn,
|
31
|
-
self.kmesh,
|
32
|
-
self.efermi,
|
30
|
+
tbmodel=self.tbmodel_dn,
|
31
|
+
kmesh=self.kmesh,
|
32
|
+
efermi=self.efermi,
|
33
33
|
use_cache=self._use_cache,
|
34
|
-
nproc=self.
|
34
|
+
nproc=self.nproc,
|
35
35
|
)
|
36
36
|
if self.write_density_matrix:
|
37
37
|
self.Gup.write_rho_R(
|
@@ -247,15 +247,15 @@ class ExchangeCL2(ExchangeCL):
|
|
247
247
|
print("Green's function Calculation started.")
|
248
248
|
|
249
249
|
npole = len(self.contour.path)
|
250
|
-
if self.
|
250
|
+
if self.nproc == 1:
|
251
251
|
results = map(
|
252
252
|
self.get_quantities_per_e, tqdm(self.contour.path, total=npole)
|
253
253
|
)
|
254
254
|
else:
|
255
|
-
# pool = ProcessPool(nodes=self.
|
255
|
+
# pool = ProcessPool(nodes=self.nproc)
|
256
256
|
# results = pool.map(self.get_AijR_rhoR ,self.contour.path)
|
257
257
|
results = p_map(
|
258
|
-
self.get_quantities_per_e, self.contour.path, num_cpus=self.
|
258
|
+
self.get_quantities_per_e, self.contour.path, num_cpus=self.nproc
|
259
259
|
)
|
260
260
|
for i, result in enumerate(results):
|
261
261
|
Jorb_list = result["Jorb_list"]
|
@@ -265,8 +265,6 @@ class ExchangeCL2(ExchangeCL):
|
|
265
265
|
key = (R, iatom, jatom)
|
266
266
|
self.Jorb_list[key].append(Jorb_list[key])
|
267
267
|
self.JJ_list[key].append(JJ_list[key])
|
268
|
-
if self.np > 1:
|
269
|
-
pass
|
270
268
|
self.integrate()
|
271
269
|
self.get_rho_atom()
|
272
270
|
self.A_to_Jtensor()
|
TB2J/exchange_params.py
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
import argparse
|
2
|
+
from dataclasses import dataclass
|
3
|
+
|
4
|
+
import yaml
|
5
|
+
|
6
|
+
__all__ = ["ExchangeParams", "add_exchange_args_to_parser", "parser_argument_to_dict"]
|
7
|
+
|
8
|
+
|
9
|
+
@dataclass
|
10
|
+
class ExchangeParams:
|
11
|
+
"""
|
12
|
+
A class to store the parameters for exchange calculation.
|
13
|
+
"""
|
14
|
+
|
15
|
+
efermi: float
|
16
|
+
basis = []
|
17
|
+
magnetic_elements = []
|
18
|
+
include_orbs = {}
|
19
|
+
_kmesh = [4, 4, 4]
|
20
|
+
emin: float = -15
|
21
|
+
emax: float = 0.05
|
22
|
+
nz: int = 100
|
23
|
+
exclude_orbs = []
|
24
|
+
ne: int = 0
|
25
|
+
Rcut: float = None
|
26
|
+
_use_cache: bool = False
|
27
|
+
nproc: int = 1
|
28
|
+
description: str = ""
|
29
|
+
write_density_matrix: bool = False
|
30
|
+
orb_decomposition: bool = False
|
31
|
+
output_path: str = "TB2J_results"
|
32
|
+
mae_angles = None
|
33
|
+
orth = False
|
34
|
+
|
35
|
+
def __init__(
|
36
|
+
self,
|
37
|
+
efermi=-10.0,
|
38
|
+
basis=None,
|
39
|
+
magnetic_elements=None,
|
40
|
+
include_orbs=None,
|
41
|
+
kmesh=[4, 4, 4],
|
42
|
+
emin=-15,
|
43
|
+
emax=0.05,
|
44
|
+
nz=100,
|
45
|
+
ne=None,
|
46
|
+
Rcut=None,
|
47
|
+
use_cache=False,
|
48
|
+
nproc=1,
|
49
|
+
description="",
|
50
|
+
write_density_matrix=False,
|
51
|
+
orb_decomposition=False,
|
52
|
+
output_path="TB2J_results",
|
53
|
+
exclude_orbs=[],
|
54
|
+
mae_angles=None,
|
55
|
+
orth=False,
|
56
|
+
):
|
57
|
+
self.efermi = efermi
|
58
|
+
self.basis = basis
|
59
|
+
self.magnetic_elements = magnetic_elements
|
60
|
+
self.include_orbs = include_orbs
|
61
|
+
self._kmesh = kmesh
|
62
|
+
self.emin = emin
|
63
|
+
self.emax = emax
|
64
|
+
self.nz = nz
|
65
|
+
self.exclude_orbs = exclude_orbs
|
66
|
+
self.ne = ne
|
67
|
+
self.Rcut = Rcut
|
68
|
+
self._use_cache = use_cache
|
69
|
+
self.nproc = nproc
|
70
|
+
self.description = description
|
71
|
+
self.write_density_matrix = write_density_matrix
|
72
|
+
self.orb_decomposition = orb_decomposition
|
73
|
+
self.output_path = output_path
|
74
|
+
self.mae_angles = mae_angles
|
75
|
+
self.orth = orth
|
76
|
+
|
77
|
+
def set_params(self, **kwargs):
|
78
|
+
for key, val in kwargs.items():
|
79
|
+
setattr(self, key, val)
|
80
|
+
|
81
|
+
def save_to_yaml(self, fname):
|
82
|
+
with open(fname, "w") as myfile:
|
83
|
+
yaml.dump(self.__dict__, myfile)
|
84
|
+
|
85
|
+
|
86
|
+
def add_exchange_args_to_parser(parser: argparse.ArgumentParser):
|
87
|
+
parser.add_argument(
|
88
|
+
"--elements",
|
89
|
+
help="elements to be considered in Heisenberg model",
|
90
|
+
default=None,
|
91
|
+
type=str,
|
92
|
+
nargs="*",
|
93
|
+
)
|
94
|
+
parser.add_argument(
|
95
|
+
"--rcut",
|
96
|
+
help="cutoff of spin pair distance. The default is to calculate all commensurate R point to the k mesh.",
|
97
|
+
default=None,
|
98
|
+
type=float,
|
99
|
+
)
|
100
|
+
parser.add_argument("--efermi", help="Fermi energy in eV", default=None, type=float)
|
101
|
+
parser.add_argument(
|
102
|
+
"--ne",
|
103
|
+
help="number of electrons in the unit cell. If not given, TB2J will use the fermi energy to compute it.",
|
104
|
+
)
|
105
|
+
parser.add_argument(
|
106
|
+
"--kmesh",
|
107
|
+
help="kmesh in the format of kx ky kz",
|
108
|
+
type=int,
|
109
|
+
nargs="*",
|
110
|
+
default=[5, 5, 5],
|
111
|
+
)
|
112
|
+
parser.add_argument(
|
113
|
+
"--emin",
|
114
|
+
help="energy minimum below efermi, default -14 eV",
|
115
|
+
type=float,
|
116
|
+
default=-14.0,
|
117
|
+
)
|
118
|
+
parser.add_argument(
|
119
|
+
"--emax",
|
120
|
+
help="energy maximum above efermi, default 0.0 eV",
|
121
|
+
type=float,
|
122
|
+
default=0.0,
|
123
|
+
)
|
124
|
+
parser.add_argument(
|
125
|
+
"--nz",
|
126
|
+
help="number of steps for semicircle contour, default: 100",
|
127
|
+
default=100,
|
128
|
+
type=int,
|
129
|
+
)
|
130
|
+
parser.add_argument(
|
131
|
+
"--cutoff",
|
132
|
+
help="The minimum of J amplitude to write, (in eV), default is 1e-5 eV",
|
133
|
+
default=1e-5,
|
134
|
+
type=float,
|
135
|
+
)
|
136
|
+
parser.add_argument(
|
137
|
+
"--exclude_orbs",
|
138
|
+
help="the indices of wannier functions to be excluded from magnetic site. counting start from 0",
|
139
|
+
default=[],
|
140
|
+
type=int,
|
141
|
+
nargs="+",
|
142
|
+
)
|
143
|
+
|
144
|
+
parser.add_argument(
|
145
|
+
"--np",
|
146
|
+
"--nproc",
|
147
|
+
help="number of cpu cores to use in parallel, default: 1",
|
148
|
+
default=1,
|
149
|
+
type=int,
|
150
|
+
)
|
151
|
+
|
152
|
+
parser.add_argument(
|
153
|
+
"--use_cache",
|
154
|
+
help="whether to use disk file for temporary storing wavefunctions and hamiltonian to reduce memory usage. Default: False",
|
155
|
+
action="store_true",
|
156
|
+
default=False,
|
157
|
+
)
|
158
|
+
|
159
|
+
parser.add_argument(
|
160
|
+
"--description",
|
161
|
+
help="add description of the calculatiion to the xml file. Essential information, like the xc functional, U values, magnetic state should be given.",
|
162
|
+
type=str,
|
163
|
+
default="Calculated with TB2J.",
|
164
|
+
)
|
165
|
+
|
166
|
+
parser.add_argument(
|
167
|
+
"--orb_decomposition",
|
168
|
+
default=False,
|
169
|
+
action="store_true",
|
170
|
+
help="whether to do orbital decomposition in the non-collinear mode.",
|
171
|
+
)
|
172
|
+
|
173
|
+
parser.add_argument(
|
174
|
+
"--output_path",
|
175
|
+
help="The path of the output directory, default is TB2J_results",
|
176
|
+
type=str,
|
177
|
+
default="TB2J_results",
|
178
|
+
)
|
179
|
+
parser.add_argument(
|
180
|
+
"--write_dm",
|
181
|
+
help="whether to write density matrix",
|
182
|
+
action="store_true",
|
183
|
+
default=False,
|
184
|
+
)
|
185
|
+
|
186
|
+
parser.add_argument(
|
187
|
+
"--orth",
|
188
|
+
help="whether to use lowdin orthogonalization before diagonalization (for testing only)",
|
189
|
+
action="store_true",
|
190
|
+
default=False,
|
191
|
+
)
|
192
|
+
return parser
|
193
|
+
|
194
|
+
|
195
|
+
def parser_argument_to_dict(args) -> dict:
|
196
|
+
return {
|
197
|
+
"efermi": args.efermi,
|
198
|
+
"magnetic_elements": args.elements,
|
199
|
+
"kmesh": args.kmesh,
|
200
|
+
"emin": args.emin,
|
201
|
+
"emax": args.emax,
|
202
|
+
"nz": args.nz,
|
203
|
+
"exclude_orbs": args.exclude_orbs,
|
204
|
+
"ne": args.ne,
|
205
|
+
"Rcut": args.rcut,
|
206
|
+
"use_cache": args.use_cache,
|
207
|
+
"nproc": args.np,
|
208
|
+
"description": args.description,
|
209
|
+
"write_density_matrix": args.write_dm,
|
210
|
+
"orb_decomposition": args.orb_decomposition,
|
211
|
+
"output_path": args.output_path,
|
212
|
+
"orth": args.orth,
|
213
|
+
}
|
TB2J/green.py
CHANGED
@@ -1,14 +1,19 @@
|
|
1
|
-
import
|
2
|
-
from collections import defaultdict
|
3
|
-
from ase.dft.kpoints import monkhorst_pack
|
4
|
-
from shutil import rmtree
|
1
|
+
import copy
|
5
2
|
import os
|
3
|
+
import pickle
|
4
|
+
import sys
|
6
5
|
import tempfile
|
6
|
+
from collections import defaultdict
|
7
|
+
from shutil import rmtree
|
8
|
+
|
9
|
+
import numpy as np
|
10
|
+
from HamiltonIO.model.occupations import Occupations
|
11
|
+
from HamiltonIO.model.occupations import myfermi as fermi
|
7
12
|
from pathos.multiprocessing import ProcessPool
|
8
|
-
|
9
|
-
import
|
10
|
-
|
11
|
-
from TB2J.mathutils.fermi import fermi
|
13
|
+
|
14
|
+
from TB2J.kpoints import monkhorst_pack
|
15
|
+
|
16
|
+
# from TB2J.mathutils.fermi import fermi
|
12
17
|
|
13
18
|
MAX_EXP_ARGUMENT = np.log(sys.float_info.max)
|
14
19
|
|
@@ -22,9 +27,16 @@ def eigen_to_G(evals, evecs, efermi, energy):
|
|
22
27
|
:returns: Green's function G,
|
23
28
|
:rtype: Matrix with same shape of the Hamiltonian (and eigenvector)
|
24
29
|
"""
|
25
|
-
return (
|
26
|
-
|
27
|
-
|
30
|
+
# return (
|
31
|
+
# np.einsum("ij, j-> ij", evecs, 1.0 / (-evals + (energy + efermi)))
|
32
|
+
# @ evecs.conj().T
|
33
|
+
# )
|
34
|
+
return np.einsum(
|
35
|
+
"ib, b, jb-> ij",
|
36
|
+
evecs,
|
37
|
+
1.0 / (-evals + (energy + efermi)),
|
38
|
+
evecs.conj(),
|
39
|
+
optimize=True,
|
28
40
|
)
|
29
41
|
|
30
42
|
|
@@ -46,8 +58,10 @@ class TBGreen:
|
|
46
58
|
def __init__(
|
47
59
|
self,
|
48
60
|
tbmodel,
|
49
|
-
kmesh, # [ikpt, 3]
|
50
|
-
efermi, # efermi
|
61
|
+
kmesh=None, # [ikpt, 3]
|
62
|
+
efermi=None, # efermi
|
63
|
+
gamma=False,
|
64
|
+
kpts=None,
|
51
65
|
k_sym=False,
|
52
66
|
use_cache=False,
|
53
67
|
cache_path=None,
|
@@ -67,12 +81,14 @@ class TBGreen:
|
|
67
81
|
self.cache_path = cache_path
|
68
82
|
if use_cache:
|
69
83
|
self._prepare_cache()
|
70
|
-
if
|
71
|
-
self.kpts =
|
84
|
+
if kpts is not None:
|
85
|
+
self.kpts = kpts
|
86
|
+
elif kmesh is not None:
|
87
|
+
self.kpts = monkhorst_pack(kmesh, gamma_center=gamma)
|
72
88
|
else:
|
73
89
|
self.kpts = tbmodel.get_kpts()
|
74
90
|
self.nkpts = len(self.kpts)
|
75
|
-
self.kweights = [1.0 / self.nkpts] * self.nkpts
|
91
|
+
self.kweights = np.array([1.0 / self.nkpts] * self.nkpts)
|
76
92
|
self.norb = tbmodel.norb
|
77
93
|
self.nbasis = tbmodel.nbasis
|
78
94
|
self.k_sym = k_sym
|
@@ -145,9 +161,19 @@ class TBGreen:
|
|
145
161
|
if not saveH:
|
146
162
|
self.H = None
|
147
163
|
|
148
|
-
|
149
|
-
|
150
|
-
|
164
|
+
# get efermi
|
165
|
+
if self.efermi is None:
|
166
|
+
print("Calculating Fermi energy from eigenvalues")
|
167
|
+
print(f"Number of electrons: {self.tbmodel.nel} ")
|
168
|
+
occ = Occupations(
|
169
|
+
nel=self.tbmodel.nel, width=0.05, wk=self.kweights, nspin=2
|
170
|
+
)
|
171
|
+
self.efermi = occ.efermi(copy.deepcopy(self.evals))
|
172
|
+
print(f"Fermi energy found: {self.efermi}")
|
173
|
+
|
174
|
+
# self.evals, self.evecs = self._reduce_eigens(
|
175
|
+
# self.evals, self.evecs, emin=self.efermi - 15.0, emax=self.efermi + 10.1
|
176
|
+
# )
|
151
177
|
if self._use_cache:
|
152
178
|
evecs = self.evecs
|
153
179
|
self.evecs_shape = self.evecs.shape
|
@@ -216,20 +242,22 @@ class TBGreen:
|
|
216
242
|
rho = np.zeros((self.nbasis, self.nbasis), dtype=complex)
|
217
243
|
if self.is_orthogonal:
|
218
244
|
for ik, _ in enumerate(self.kpts):
|
245
|
+
evecs_k = self.get_evecs(ik)
|
246
|
+
# chekc if any of the evecs element is nan
|
219
247
|
rho += (
|
220
|
-
(
|
221
|
-
@
|
248
|
+
(evecs_k * fermi(self.evals[ik], self.efermi, nspin=2))
|
249
|
+
@ evecs_k.T.conj()
|
222
250
|
* self.kweights[ik]
|
223
251
|
)
|
224
252
|
else:
|
225
253
|
for ik, _ in enumerate(self.kpts):
|
226
254
|
rho += (
|
227
|
-
(self.get_evecs(ik) * fermi(self.evals[ik], self.efermi))
|
255
|
+
(self.get_evecs(ik) * fermi(self.evals[ik], self.efermi, nspin=2))
|
228
256
|
@ self.get_evecs(ik).T.conj()
|
229
257
|
@ self.get_Sk(ik)
|
230
258
|
* self.kweights[ik]
|
231
259
|
)
|
232
|
-
|
260
|
+
# check if rho has nan values
|
233
261
|
return rho
|
234
262
|
|
235
263
|
def get_rho_R(self, Rlist):
|
@@ -238,7 +266,10 @@ class TBGreen:
|
|
238
266
|
for ik, kpt in enumerate(self.kpts):
|
239
267
|
evec = self.get_evecs(ik)
|
240
268
|
rhok = np.einsum(
|
241
|
-
"ib,b, bj-> ij",
|
269
|
+
"ib,b, bj-> ij",
|
270
|
+
evec,
|
271
|
+
fermi(self.evals[ik], self.efermi, nspin=2),
|
272
|
+
evec.conj().T,
|
242
273
|
)
|
243
274
|
for iR, R in enumerate(Rlist):
|
244
275
|
rho_R[iR] += rhok * np.exp(self.k2Rfactor * kpt @ R) * self.kweights[ik]
|
@@ -252,16 +283,20 @@ class TBGreen:
|
|
252
283
|
def get_density(self):
|
253
284
|
return np.real(np.diag(self.get_density_matrix()))
|
254
285
|
|
255
|
-
def get_Gk(self, ik, energy):
|
286
|
+
def get_Gk(self, ik, energy, evals=None, evecs=None):
|
256
287
|
"""Green's function G(k) for one energy
|
257
288
|
G(\epsilon)= (\epsilon I- H)^{-1}
|
258
289
|
:param ik: indices for kpoint
|
259
290
|
:returns: Gk
|
260
291
|
:rtype: a matrix of indices (nbasis, nbasis)
|
261
292
|
"""
|
293
|
+
if evals is None:
|
294
|
+
evals = self.get_evalue(ik)
|
295
|
+
if evecs is None:
|
296
|
+
evecs = self.get_evecs(ik)
|
262
297
|
Gk = eigen_to_G(
|
263
|
-
evals=
|
264
|
-
evecs=
|
298
|
+
evals=evals,
|
299
|
+
evecs=evecs,
|
265
300
|
efermi=self.efermi,
|
266
301
|
energy=energy,
|
267
302
|
)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
from .abacus import gen_exchange_abacus
|
2
|
+
from .manager import Manager
|
3
|
+
from .siesta_interface import gen_exchange_siesta
|
4
|
+
from .wannier90_interface import WannierManager, gen_exchange
|
5
|
+
|
6
|
+
__all__ = [
|
7
|
+
"Manager",
|
8
|
+
"gen_exchange_siesta",
|
9
|
+
"WannierManager",
|
10
|
+
"gen_exchange",
|
11
|
+
"gen_exchange_abacus",
|
12
|
+
]
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
import numpy as np
|
3
|
-
from scipy import sparse
|
4
|
-
from scipy.sparse import csr_matrix
|
5
2
|
import re
|
6
3
|
import struct
|
7
4
|
|
5
|
+
import numpy as np
|
6
|
+
from scipy.sparse import csr_matrix
|
7
|
+
|
8
8
|
|
9
9
|
class XR_matrix:
|
10
10
|
def __init__(self, nspin, XR_fileName):
|