TB2J 0.9.9rc5__tar.gz → 0.9.9rc6__tar.gz
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-0.9.9rc5 → tb2j-0.9.9rc6}/PKG-INFO +1 -1
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/MAEGreen.py +37 -7
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/contour.py +16 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/exchange.py +23 -15
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/exchangeCL2.py +20 -11
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/exchange_params.py +8 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/green.py +15 -1
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/siesta_interface.py +1 -1
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/kpoints.py +15 -1
- tb2j-0.9.9rc6/TB2J/mycfr.py +114 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/orbmap.py +4 -4
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/symmetrize_J.py +4 -2
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J.egg-info/PKG-INFO +1 -1
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J.egg-info/SOURCES.txt +1 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/setup.py +1 -1
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/LICENSE +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/README.md +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/Jdownfolder.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/Jtensor.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/MAE.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/Oiju.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/Oiju_epc.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/__init__.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/anisotropy.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/basis.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/citation.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/density_matrix.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/epc.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/exchange_pert.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/exchange_qspace.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/external/__init__.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/external/p_tqdm.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/gpaw_wrapper.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/greentest.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/__init__.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/abacus/__init__.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/abacus/abacus_api.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/abacus/abacus_wrapper.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/abacus/gen_exchange_abacus.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/abacus/orbital_api.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/abacus/stru_api.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/abacus/test_density_matrix.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/abacus/test_read_HRSR.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/abacus/test_read_stru.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/gpaw_interface.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/lawaf_interface.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/manager.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/interfaces/wannier90_interface.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/io_exchange/__init__.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/io_exchange/io_exchange.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/io_exchange/io_multibinit.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/io_exchange/io_tomsasd.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/io_exchange/io_txt.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/io_exchange/io_uppasd.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/io_exchange/io_vampire.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/io_merge.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/mathutils/__init__.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/mathutils/fermi.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/mathutils/kR_convert.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/mathutils/lowdin.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/mathutils/rotate_spin.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/myTB.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/pauli.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/pert.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/plot.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/rotate_atoms.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/rotate_siestaDM.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/sisl_wrapper.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/spinham/__init__.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/spinham/base_parser.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/spinham/constants.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/spinham/hamiltonian.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/spinham/hamiltonian_terms.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/spinham/plot.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/spinham/qsolver.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/spinham/spin_api.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/spinham/spin_xml.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/spinham/supercell.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/tensor_rotate.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/utest.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/utils.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/versioninfo.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/wannier/__init__.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/wannier/w90_parser.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J/wannier/w90_tb_parser.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J.egg-info/dependency_links.txt +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J.egg-info/entry_points.txt +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J.egg-info/requires.txt +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/TB2J.egg-info/top_level.txt +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/scripts/TB2J_downfold.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/scripts/TB2J_eigen.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/scripts/TB2J_magnon.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/scripts/TB2J_magnon_dos.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/scripts/TB2J_merge.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/scripts/TB2J_rotate.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/scripts/TB2J_rotateDM.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/scripts/abacus2J.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/scripts/siesta2J.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/scripts/wann2J.py +0 -0
- {tb2j-0.9.9rc5 → tb2j-0.9.9rc6}/setup.cfg +0 -0
@@ -7,6 +7,7 @@ from HamiltonIO.model.occupations import GaussOccupations
|
|
7
7
|
from typing_extensions import DefaultDict
|
8
8
|
|
9
9
|
from TB2J.exchange import ExchangeNCL
|
10
|
+
from TB2J.external import p_map
|
10
11
|
|
11
12
|
# from HamiltonIO.model.rotate_spin import rotate_Matrix_from_z_to_axis, rotate_Matrix_from_z_to_sperical
|
12
13
|
# from TB2J.abacus.abacus_wrapper import AbacusWrapper, AbacusParser
|
@@ -78,6 +79,17 @@ class MAEGreen(ExchangeNCL):
|
|
78
79
|
|
79
80
|
def get_perturbed(self, e, thetas, phis):
|
80
81
|
self.tbmodel.set_so_strength(0.0)
|
82
|
+
maxsoc = self.tbmodel.get_max_Hsoc_abs()
|
83
|
+
maxH0 = self.tbmodel.get_max_H0_spin_abs()
|
84
|
+
if maxsoc > maxH0 * 0.01:
|
85
|
+
print(f"""Warning: The SOC of the Hamiltonian has a maximum of {maxsoc} eV,
|
86
|
+
comparing to the maximum of {maxH0} eV of the spin part of the Hamiltonian.
|
87
|
+
The SOC is too strong, the perturbation theory may not be valid.""")
|
88
|
+
|
89
|
+
print(f"""Warning: The SOC of the Hamiltonian has a maximum of {maxsoc} eV,
|
90
|
+
comparing to the maximum of {maxH0} eV of the spin part of the Hamiltonian.
|
91
|
+
The SOC is too strong, the perturbation theory may not be valid.""")
|
92
|
+
|
81
93
|
G0K = self.G.get_Gk_all(e)
|
82
94
|
Hsoc_k = self.tbmodel.get_Hk_soc(self.G.kpts)
|
83
95
|
na = len(thetas)
|
@@ -143,15 +155,33 @@ class MAEGreen(ExchangeNCL):
|
|
143
155
|
if with_eigen:
|
144
156
|
self.es2 = self.get_band_energy_vs_angles_from_eigen(thetas, phis)
|
145
157
|
|
146
|
-
for ie, e in enumerate(tqdm.tqdm(self.contour.path)):
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
158
|
+
# for ie, e in enumerate(tqdm.tqdm(self.contour.path)):
|
159
|
+
# dE_angle, dE_angle_atom, dE_angle_atom_orb = self.get_perturbed(
|
160
|
+
# e, thetas, phis
|
161
|
+
# )
|
162
|
+
# self.es += dE_angle * self.contour.weights[ie]
|
163
|
+
# self.es_atom += dE_angle_atom * self.contour.weights[ie]
|
164
|
+
# for key, value in dE_angle_atom_orb.items():
|
165
|
+
# self.es_atom_orb[key] += (
|
166
|
+
# dE_angle_atom_orb[key] * self.contour.weights[ie]
|
167
|
+
# )
|
168
|
+
|
169
|
+
# rewrite the for loop above to use p_map
|
170
|
+
def func(e):
|
171
|
+
return self.get_perturbed(e, thetas, phis)
|
172
|
+
|
173
|
+
if self.nproc > 1:
|
174
|
+
results = p_map(func, self.contour.path, num_cpus=self.nproc)
|
175
|
+
else:
|
176
|
+
npole = len(self.contour.path)
|
177
|
+
results = map(func, tqdm.tqdm(self.contour.path, total=npole))
|
178
|
+
for i, result in enumerate(results):
|
179
|
+
dE_angle, dE_angle_atom, dE_angle_atom_orb = result
|
180
|
+
self.es += dE_angle * self.contour.weights[i]
|
181
|
+
self.es_atom += dE_angle_atom * self.contour.weights[i]
|
152
182
|
for key, value in dE_angle_atom_orb.items():
|
153
183
|
self.es_atom_orb[key] += (
|
154
|
-
dE_angle_atom_orb[key] * self.contour.weights[
|
184
|
+
dE_angle_atom_orb[key] * self.contour.weights[i]
|
155
185
|
)
|
156
186
|
|
157
187
|
self.es = -np.imag(self.es) / (2 * np.pi)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import numpy as np
|
2
2
|
from scipy.special import roots_legendre
|
3
|
+
|
3
4
|
from TB2J.utils import simpson_nonuniform_weight
|
4
5
|
|
5
6
|
|
@@ -15,6 +16,21 @@ class Contour:
|
|
15
16
|
self._weights = simpson_nonuniform_weight(self.path)
|
16
17
|
return self._weights
|
17
18
|
|
19
|
+
def integrate_func(self, func):
|
20
|
+
"""
|
21
|
+
integrate f along the path
|
22
|
+
"""
|
23
|
+
return np.dot(func(self.path), self.weights)
|
24
|
+
|
25
|
+
def integrate_values(self, values):
|
26
|
+
"""
|
27
|
+
integrate f along the path
|
28
|
+
"""
|
29
|
+
ret = 0
|
30
|
+
for i in range(len(values)):
|
31
|
+
ret += values[i] * self.weights[i]
|
32
|
+
return ret
|
33
|
+
|
18
34
|
def build_path_semicircle(self, npoints, endpoint=True):
|
19
35
|
R = (self.emax - self.emin) / 2.0
|
20
36
|
R0 = (self.emin + self.emax) / 2.0
|
@@ -10,13 +10,12 @@ from TB2J.exchange_params import ExchangeParams
|
|
10
10
|
from TB2J.external import p_map
|
11
11
|
from TB2J.green import TBGreen
|
12
12
|
from TB2J.io_exchange import SpinIO
|
13
|
+
from TB2J.mycfr import CFR
|
13
14
|
from TB2J.orbmap import map_orbs_matrix
|
14
15
|
from TB2J.pauli import pauli_block_all, pauli_block_sigma_norm
|
15
16
|
from TB2J.utils import (
|
16
17
|
kmesh_to_R,
|
17
|
-
simpson_nonuniform,
|
18
18
|
symbol_number,
|
19
|
-
trapezoidal_nonuniform,
|
20
19
|
)
|
21
20
|
|
22
21
|
|
@@ -28,6 +27,7 @@ class Exchange(ExchangeParams):
|
|
28
27
|
self._prepare_Rlist()
|
29
28
|
self.set_tbmodels(tbmodels)
|
30
29
|
self._adjust_emin()
|
30
|
+
# self._prepare_elist(method="CFR")
|
31
31
|
self._prepare_elist(method="legendre")
|
32
32
|
self._prepare_basis()
|
33
33
|
self._prepare_orb_dict()
|
@@ -45,8 +45,9 @@ class Exchange(ExchangeParams):
|
|
45
45
|
os.makedirs(self.orbpath, exist_ok=True)
|
46
46
|
|
47
47
|
def _adjust_emin(self):
|
48
|
-
self.emin = self.G.find_energy_ingap(rbound=self.efermi -
|
49
|
-
# self.emin = -
|
48
|
+
self.emin = self.G.find_energy_ingap(rbound=self.efermi - 15.0) - self.efermi
|
49
|
+
# self.emin = self.G.find_energy_ingap(rbound=self.efermi - 15.0) - self.efermi
|
50
|
+
# self.emin = -42.0
|
50
51
|
print(f"A gap is found at {self.emin}, set emin to it.")
|
51
52
|
|
52
53
|
def set_tbmodels(self, tbmodels):
|
@@ -61,21 +62,24 @@ class Exchange(ExchangeParams):
|
|
61
62
|
for k in kmesh:
|
62
63
|
self.kmesh = list(map(lambda x: x // 2 * 2 + 1, kmesh))
|
63
64
|
|
64
|
-
def _prepare_elist(self, method="
|
65
|
+
def _prepare_elist(self, method="CFR"):
|
65
66
|
"""
|
66
67
|
prepare list of energy for integration.
|
67
68
|
The path has three segments:
|
68
69
|
emin --1-> emin + 1j*height --2-> emax+1j*height --3-> emax
|
69
70
|
"""
|
70
|
-
self.contour = Contour(self.emin, self.emax)
|
71
71
|
# if method.lower() == "rectangle":
|
72
72
|
# self.contour.build_path_rectangle(
|
73
73
|
# height=self.height, nz1=self.nz1, nz2=self.nz2, nz3=self.nz3
|
74
74
|
# )
|
75
75
|
if method.lower() == "semicircle":
|
76
|
+
self.contour = Contour(self.emin, self.emax)
|
76
77
|
self.contour.build_path_semicircle(npoints=self.nz, endpoint=True)
|
77
78
|
elif method.lower() == "legendre":
|
79
|
+
self.contour = Contour(self.emin, self.emax)
|
78
80
|
self.contour.build_path_legendre(npoints=self.nz, endpoint=True)
|
81
|
+
elif method.lower() == "cfr":
|
82
|
+
self.contour = CFR(nz=self.nz, T=600)
|
79
83
|
else:
|
80
84
|
raise ValueError(f"The path cannot be of type {method}.")
|
81
85
|
|
@@ -114,6 +118,7 @@ class Exchange(ExchangeParams):
|
|
114
118
|
else:
|
115
119
|
try:
|
116
120
|
atom_sym, orb_sym = base[:2]
|
121
|
+
iatom = sdict[atom_sym]
|
117
122
|
except Exception:
|
118
123
|
iatom = base.iatom
|
119
124
|
atom_sym = base.iatom
|
@@ -168,7 +173,6 @@ or badly localized. Please check the Wannier centers in the Wannier90 output fil
|
|
168
173
|
self.mmats = {}
|
169
174
|
self.orbital_names = {}
|
170
175
|
self.norb_reduced = {}
|
171
|
-
print(f"self.backend_name: {self.backend_name}")
|
172
176
|
if self.backend_name.upper() in ["SIESTA", "ABACUS", "LCAOHAMILTONIAN"]:
|
173
177
|
# print(f"magntic_elements: {self.magnetic_elements}")
|
174
178
|
# print(f"include_orbs: {self.include_orbs}")
|
@@ -562,20 +566,24 @@ class ExchangeNCL(Exchange):
|
|
562
566
|
AijRs: a list of AijR,
|
563
567
|
wherer AijR: array of ((nR, n, n, 4,4), dtype=complex)
|
564
568
|
"""
|
565
|
-
if method == "trapezoidal":
|
566
|
-
|
567
|
-
elif method == "simpson":
|
568
|
-
|
569
|
+
# if method == "trapezoidal":
|
570
|
+
# integrate = trapezoidal_nonuniform
|
571
|
+
# elif method == "simpson":
|
572
|
+
# integrate = simpson_nonuniform
|
573
|
+
#
|
569
574
|
|
570
575
|
# self.rho = integrate(self.contour.path, rhoRs)
|
571
576
|
for iR, R in enumerate(self.R_ijatom_dict):
|
572
577
|
for iatom, jatom in self.R_ijatom_dict[R]:
|
573
578
|
f = AijRs[(R, iatom, jatom)]
|
574
|
-
self.A_ijR[(R, iatom, jatom)] = integrate(self.contour.path, f)
|
579
|
+
# self.A_ijR[(R, iatom, jatom)] = integrate(self.contour.path, f)
|
580
|
+
self.A_ijR[(R, iatom, jatom)] = self.contour.integrate_values(f)
|
581
|
+
|
575
582
|
if self.orb_decomposition:
|
576
|
-
self.A_ijR_orb[(R, iatom, jatom)] = integrate(
|
577
|
-
|
578
|
-
)
|
583
|
+
# self.A_ijR_orb[(R, iatom, jatom)] = integrate(
|
584
|
+
# self.contour.path, AijRs_orb[(R, iatom, jatom)]
|
585
|
+
# )
|
586
|
+
self.contour.integrate_values(AijRs_orb[(R, iatom, jatom)])
|
579
587
|
|
580
588
|
def get_quantities_per_e(self, e):
|
581
589
|
Gk_all = self.G.get_Gk_all(e)
|
@@ -1,15 +1,18 @@
|
|
1
1
|
"""
|
2
2
|
Exchange from Green's function
|
3
3
|
"""
|
4
|
+
|
4
5
|
import os
|
5
6
|
from collections import defaultdict
|
7
|
+
|
6
8
|
import numpy as np
|
7
|
-
from TB2J.green import TBGreen
|
8
|
-
from TB2J.io_exchange import SpinIO
|
9
9
|
from tqdm import tqdm
|
10
|
+
|
10
11
|
from TB2J.external import p_map
|
12
|
+
from TB2J.green import TBGreen
|
13
|
+
from TB2J.io_exchange import SpinIO
|
14
|
+
|
11
15
|
from .exchange import ExchangeCL
|
12
|
-
from .utils import simpson_nonuniform, trapezoidal_nonuniform
|
13
16
|
|
14
17
|
|
15
18
|
class ExchangeCL2(ExchangeCL):
|
@@ -221,17 +224,23 @@ class ExchangeCL2(ExchangeCL):
|
|
221
224
|
# shutil.rmtree(path)
|
222
225
|
|
223
226
|
def integrate(self, method="simpson"):
|
224
|
-
if method == "trapezoidal":
|
225
|
-
|
226
|
-
elif method == "simpson":
|
227
|
-
|
227
|
+
# if method == "trapezoidal":
|
228
|
+
# integrate = trapezoidal_nonuniform
|
229
|
+
# elif method == "simpson":
|
230
|
+
# integrate = simpson_nonuniform
|
228
231
|
for R, ijpairs in self.R_ijatom_dict.items():
|
229
232
|
for iatom, jatom in ijpairs:
|
230
|
-
self.Jorb[(R, iatom, jatom)] = integrate(
|
231
|
-
|
233
|
+
# self.Jorb[(R, iatom, jatom)] = integrate(
|
234
|
+
# self.contour.path, self.Jorb_list[(R, iatom, jatom)]
|
235
|
+
# )
|
236
|
+
# self.JJ[(R, iatom, jatom)] = integrate(
|
237
|
+
# self.contour.path, self.JJ_list[(R, iatom, jatom)]
|
238
|
+
# )
|
239
|
+
self.Jorb[(R, iatom, jatom)] = self.contour.integrate_values(
|
240
|
+
self.Jorb_list[(R, iatom, jatom)]
|
232
241
|
)
|
233
|
-
self.JJ[(R, iatom, jatom)] =
|
234
|
-
self.
|
242
|
+
self.JJ[(R, iatom, jatom)] = self.contour.integrate_values(
|
243
|
+
self.JJ_list[(R, iatom, jatom)]
|
235
244
|
)
|
236
245
|
|
237
246
|
def get_quantities_per_e(self, e):
|
@@ -115,6 +115,14 @@ def add_exchange_args_to_parser(parser: argparse.ArgumentParser):
|
|
115
115
|
type=str,
|
116
116
|
nargs="*",
|
117
117
|
)
|
118
|
+
|
119
|
+
parser.add_argument(
|
120
|
+
"--spinor",
|
121
|
+
help="whether the Wannier functions are spinor. Default: False",
|
122
|
+
action="store_true",
|
123
|
+
default=False,
|
124
|
+
)
|
125
|
+
|
118
126
|
parser.add_argument(
|
119
127
|
"--rcut",
|
120
128
|
help="cutoff of spin pair distance. The default is to calculate all commensurate R point to the k mesh.",
|
@@ -18,6 +18,17 @@ from TB2J.kpoints import ir_kpts, monkhorst_pack
|
|
18
18
|
MAX_EXP_ARGUMENT = np.log(sys.float_info.max)
|
19
19
|
|
20
20
|
|
21
|
+
def eigen_to_G2(H, S, efermi, energy):
|
22
|
+
"""calculate green's function from eigenvalue/eigenvector for energy(e-ef): G(e-ef).
|
23
|
+
:param H: Hamiltonian matrix in eigenbasis
|
24
|
+
:param S: Overlap matrix in eigenbasis
|
25
|
+
:param efermi: fermi energy
|
26
|
+
:param energy: energy level e - efermi
|
27
|
+
"""
|
28
|
+
# G = ((E+Ef) S - H)^-1
|
29
|
+
return np.linalg.inv((energy + efermi) * S - H)
|
30
|
+
|
31
|
+
|
21
32
|
def eigen_to_G(evals, evecs, efermi, energy):
|
22
33
|
"""calculate green's function from eigenvalue/eigenvector for energy(e-ef): G(e-ef).
|
23
34
|
:param evals: eigen values
|
@@ -121,7 +132,10 @@ class TBGreen:
|
|
121
132
|
elif kmesh is not None:
|
122
133
|
if ibz:
|
123
134
|
self.kpts, self.kweights = ir_kpts(
|
124
|
-
atoms=tbmodel.atoms,
|
135
|
+
atoms=tbmodel.atoms,
|
136
|
+
mp_grid=kmesh,
|
137
|
+
ir=True,
|
138
|
+
is_time_reversal=False,
|
125
139
|
)
|
126
140
|
self.nkpts = len(self.kpts)
|
127
141
|
print(f"Using IBZ of kmesh of {kmesh}")
|
@@ -163,7 +163,7 @@ Warning: The DMI component parallel to the spin orientation, the Jani which has
|
|
163
163
|
# thetas = [0, np.pi / 2, np.pi, 3 * np.pi / 2]
|
164
164
|
# phis = [0, 0, 0, 0]
|
165
165
|
# MAE.set_angles(thetas=thetas, phis=phis)
|
166
|
-
MAE.run(output_path=f"{output_path}_anisotropy")
|
166
|
+
MAE.run(output_path=f"{output_path}_anisotropy", with_eigen=True)
|
167
167
|
print(
|
168
168
|
f"MAE calculation finished. The results are in {output_path} directory."
|
169
169
|
)
|
@@ -70,7 +70,21 @@ def ir_kpts(
|
|
70
70
|
# Irreducible k-points
|
71
71
|
# print("Number of ir-kpoints: %d" % len(np.unique(mapping)))
|
72
72
|
# print(grid[np.unique(mapping)] / np.array(mesh, dtype=float))
|
73
|
-
|
73
|
+
|
74
|
+
new_ir_kpts = []
|
75
|
+
new_weight = []
|
76
|
+
for ik, k in enumerate(ird_kpts):
|
77
|
+
# add k and -k to ird_kpts if -k is not in ird_kpts
|
78
|
+
if not any([np.allclose(-1.0 * k, kpt) for kpt in new_ir_kpts]):
|
79
|
+
new_ir_kpts.append(k)
|
80
|
+
new_ir_kpts.append(-1.0 * k)
|
81
|
+
new_weight.append(weight[ik] / 2)
|
82
|
+
new_weight.append(weight[ik] / 2)
|
83
|
+
else:
|
84
|
+
new_ir_kpts.append(k)
|
85
|
+
new_weight.append(weight[ik])
|
86
|
+
# return ird_kpts, weight
|
87
|
+
return np.array(new_ir_kpts), np.array(new_weight)
|
74
88
|
|
75
89
|
|
76
90
|
def test_ir_kpts():
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# File: mycfr.py
|
3
|
+
# Time: 2017/12/10 19:29:43
|
4
|
+
"""
|
5
|
+
Continued fraction representation.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import numpy as np
|
9
|
+
from scipy.linalg import eig
|
10
|
+
|
11
|
+
kb = 8.61733e-5 # Boltzmann constant in eV
|
12
|
+
|
13
|
+
|
14
|
+
class CFR:
|
15
|
+
"""
|
16
|
+
Integration with the continued fraction representation.
|
17
|
+
"""
|
18
|
+
|
19
|
+
def __init__(self, nz=50, T=60):
|
20
|
+
self.nz = nz
|
21
|
+
self.T = 600
|
22
|
+
self.beta = 1 / (kb * self.T)
|
23
|
+
self.Rinf = 1e10
|
24
|
+
if nz <= 0:
|
25
|
+
raise ValueError("nz should be larger than 0.")
|
26
|
+
else:
|
27
|
+
self.prepare_poles()
|
28
|
+
|
29
|
+
def prepare_poles(self):
|
30
|
+
##b_mat = [1 / (2.0 * np.sqrt((2 * (j + 1) - 1) * (2 * (j + 1) + 1)) / (kb * self.#T)) for j in range(0, self.nz- 1)]
|
31
|
+
jmat = np.arange(0, self.nz - 1)
|
32
|
+
b_mat = 1 / (2.0 * np.sqrt((2 * (jmat + 1) - 1) * (2 * (jmat + 1) + 1)))
|
33
|
+
b_mat = np.diag(b_mat, -1) + np.diag(b_mat, 1)
|
34
|
+
self.poles, residules = eig(b_mat)
|
35
|
+
|
36
|
+
residules = 0.25 * np.abs(residules[0, :]) ** 2 / self.poles**2
|
37
|
+
# residules = 0.25 * np.diag(residules) ** 2 / self.poles**2
|
38
|
+
|
39
|
+
# self.weights = np.where(
|
40
|
+
# #np.real(self.poles) > 0, 4.0j / self.beta * residules, 0.0
|
41
|
+
# #np.real(self.poles) > 0, 2.0j / self.beta * residules, 2.0j / self.beta * residules
|
42
|
+
# np.real(self.poles) > 0, 2.0j / self.beta * residules, 0.0
|
43
|
+
# )
|
44
|
+
|
45
|
+
# self.path = 1j / self.poles * kb * self.T
|
46
|
+
|
47
|
+
self.path = []
|
48
|
+
self.weights = []
|
49
|
+
for p, r in zip(self.poles, residules):
|
50
|
+
if p > 0:
|
51
|
+
self.path.append(1j / p * kb * self.T)
|
52
|
+
w = 2.0j / self.beta * r
|
53
|
+
self.weights.append(w)
|
54
|
+
self.path.append(-1j / p * kb * self.T)
|
55
|
+
self.weights.append(w)
|
56
|
+
|
57
|
+
self.path = np.array(self.path)
|
58
|
+
self.weights = np.array(self.weights)
|
59
|
+
|
60
|
+
# from J. Phys. Soc. Jpn. 88, 114706 (2019)
|
61
|
+
# A_mat = -1/2 *np.diag(1, -1) + np.diag(1, 1)
|
62
|
+
# B_mat = np.diag([2*i-1 for i in range(1, self.nz)])
|
63
|
+
# eigp, eigv = eig(A_mat, B_mat)
|
64
|
+
# zp = 1j / eigp * kb * self.T
|
65
|
+
# Rp = 0.25 * np.diag(eigv)**2 * zp **2
|
66
|
+
|
67
|
+
# add a point to the poles: 1e10j
|
68
|
+
self.path = np.concatenate((self.path, [self.Rinf * 1j]))
|
69
|
+
# self.path = np.concatenate((self.path, [0.0]))
|
70
|
+
self.npoles = len(self.poles)
|
71
|
+
|
72
|
+
# add weights for the point 1e10j
|
73
|
+
# self.weights = np.concatenate((self.weights, [-self.Rinf]))
|
74
|
+
self.weights = np.concatenate((self.weights, [00.0]))
|
75
|
+
# zeros moment is 1j * R * test_gf(1j * R), but the real part of it will be taken. In contrast to the other part, where the imaginary part is taken.
|
76
|
+
|
77
|
+
def integrate_values(self, gf_vals, imag=False):
|
78
|
+
ret = 0
|
79
|
+
for i in range(self.npoles + 1):
|
80
|
+
ret += self.weights[i] * gf_vals[i]
|
81
|
+
ret *= (
|
82
|
+
-np.pi / 2
|
83
|
+
) # This is to be compatible with the integration of contour, where /-np.pi is used after the integration. And the factor of 2 is because the Fermi function here is 2-fold degenerate.
|
84
|
+
if imag:
|
85
|
+
return np.imag(ret)
|
86
|
+
return ret
|
87
|
+
|
88
|
+
def integrate_func(self, gf, ef=0):
|
89
|
+
"""
|
90
|
+
Integration with the continued fraction representation.
|
91
|
+
|
92
|
+
:param gf: Green's function
|
93
|
+
:param ef: Fermi energy
|
94
|
+
:return: integration result
|
95
|
+
"""
|
96
|
+
path = self.path
|
97
|
+
gf_vals = gf(path, ef=ef)
|
98
|
+
return self.integrate_values(gf_vals)
|
99
|
+
|
100
|
+
|
101
|
+
def test_cfr():
|
102
|
+
cfr = CFR(nz=100)
|
103
|
+
|
104
|
+
def test_gf(z, ef=0.1):
|
105
|
+
return 1 / (z - 3 + ef)
|
106
|
+
|
107
|
+
r = cfr.integrate_func(test_gf, ef=2)
|
108
|
+
r = -np.imag(r) / np.pi * 2
|
109
|
+
print(r)
|
110
|
+
return r
|
111
|
+
|
112
|
+
|
113
|
+
if __name__ == "__main__":
|
114
|
+
test_cfr()
|
@@ -28,14 +28,14 @@ def map_orbs_matrix(orblist, spinor=False, include_only=None):
|
|
28
28
|
|
29
29
|
norb = len(orblist)
|
30
30
|
|
31
|
-
print("orblist: ", orblist)
|
31
|
+
# print("orblist: ", orblist)
|
32
32
|
ss = [split_orb_name(orb) for orb in orblist]
|
33
33
|
orbdict = dict(zip(ss, range(norb)))
|
34
34
|
|
35
35
|
reduced_orbdict = defaultdict(lambda: [])
|
36
36
|
|
37
|
-
print(f"Orbital dictionary: {orbdict}")
|
38
|
-
print("include_only: ", include_only)
|
37
|
+
# print(f"Orbital dictionary: {orbdict}")
|
38
|
+
# print("include_only: ", include_only)
|
39
39
|
|
40
40
|
if include_only is None:
|
41
41
|
for key, val in orbdict.items():
|
@@ -46,7 +46,7 @@ def map_orbs_matrix(orblist, spinor=False, include_only=None):
|
|
46
46
|
# [:2] for 3d, 4d, 5d, etc. and [:1] for s, p, d, etc
|
47
47
|
reduced_orbdict[key[0]].append(val)
|
48
48
|
|
49
|
-
print(f"reduced_orbdict: {reduced_orbdict}")
|
49
|
+
# print(f"reduced_orbdict: {reduced_orbdict}")
|
50
50
|
reduced_orbs = tuple(reduced_orbdict.keys())
|
51
51
|
ngroup = len(reduced_orbdict)
|
52
52
|
mmat = np.zeros((norb, ngroup), dtype=int)
|
@@ -14,6 +14,7 @@ class TB2JSymmetrizer:
|
|
14
14
|
ijRs = exc.ijR_list_index_atom()
|
15
15
|
finder = SymmetryPairFinder(atoms=exc.atoms, pairs=ijRs, symprec=symprec)
|
16
16
|
self.verbose = verbose
|
17
|
+
self.Jonly = Jonly
|
17
18
|
|
18
19
|
if verbose:
|
19
20
|
print("=" * 30)
|
@@ -124,9 +125,10 @@ def symmetrize_J_cli():
|
|
124
125
|
)
|
125
126
|
|
126
127
|
parser.add_argument(
|
127
|
-
"
|
128
|
+
"--Jonly",
|
128
129
|
action="store_true",
|
129
|
-
help="
|
130
|
+
help="symmetrize only the exchange parameters and discard the DMI and anisotropic exchange",
|
131
|
+
default=False,
|
130
132
|
)
|
131
133
|
|
132
134
|
args = parser.parse_args()
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
from setuptools import find_packages, setup
|
3
3
|
|
4
|
-
__version__ = "0.9.
|
4
|
+
__version__ = "0.9.9_rc6"
|
5
5
|
|
6
6
|
long_description = """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. """
|
7
7
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|