quant-met 0.0.19__py3-none-any.whl → 0.0.21__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.
- quant_met/cli/_utils.py +32 -1
- quant_met/cli/dmft.py +91 -0
- quant_met/cli/main.py +4 -0
- quant_met/dmft/__init__.py +5 -0
- quant_met/dmft/dmft_loop.py +189 -0
- quant_met/dmft/utils.py +98 -0
- quant_met/mean_field/__init__.py +0 -2
- quant_met/mean_field/hamiltonians/base_hamiltonian.py +60 -1
- quant_met/parameters/main.py +8 -0
- {quant_met-0.0.19.dist-info → quant_met-0.0.21.dist-info}/METADATA +2 -1
- {quant_met-0.0.19.dist-info → quant_met-0.0.21.dist-info}/RECORD +14 -11
- quant_met/mean_field/quantum_metric.py +0 -69
- {quant_met-0.0.19.dist-info → quant_met-0.0.21.dist-info}/WHEEL +0 -0
- {quant_met-0.0.19.dist-info → quant_met-0.0.21.dist-info}/entry_points.txt +0 -0
- {quant_met-0.0.19.dist-info → quant_met-0.0.21.dist-info}/licenses/LICENSE.txt +0 -0
quant_met/cli/_utils.py
CHANGED
@@ -2,8 +2,11 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MIT
|
4
4
|
|
5
|
+
import numpy as np
|
6
|
+
from triqs.lattice.tight_binding import TBLattice
|
7
|
+
|
5
8
|
from quant_met.mean_field.hamiltonians import BaseHamiltonian
|
6
|
-
from quant_met.parameters import HamiltonianParameters
|
9
|
+
from quant_met.parameters import GenericParameters, HamiltonianParameters
|
7
10
|
|
8
11
|
|
9
12
|
def _hamiltonian_factory(
|
@@ -29,3 +32,31 @@ def _hamiltonian_factory(
|
|
29
32
|
cls = getattr(hamiltonians, classname)
|
30
33
|
h: BaseHamiltonian[HamiltonianParameters] = cls(parameters)
|
31
34
|
return h
|
35
|
+
|
36
|
+
|
37
|
+
def _tbl_factory(h: BaseHamiltonian[GenericParameters]) -> TBLattice:
|
38
|
+
lattice_constant = np.sqrt(3)
|
39
|
+
|
40
|
+
basis_vectors = [
|
41
|
+
0.5 * lattice_constant * np.array([1, np.sqrt(3), 0]),
|
42
|
+
0.5 * lattice_constant * np.array([1, -np.sqrt(3), 0]),
|
43
|
+
]
|
44
|
+
orbital_positions = [(0, 0.5, 0), (0, -0.5, 0), (0, -0.5, 0)]
|
45
|
+
hoppings = {
|
46
|
+
(0, 0): [
|
47
|
+
[0, h.hopping_gr, h.hopping_x_gr_a],
|
48
|
+
[h.hopping_gr, 0, 0],
|
49
|
+
[h.hopping_x_gr_a, 0, 0],
|
50
|
+
],
|
51
|
+
(1, 0): [[0, 0, 0], [h.hopping_gr, 0, 0], [0, 0, 0]],
|
52
|
+
(-1, 0): [[0, h.hopping_gr, 0], [0, 0, 0], [0, 0, 0]],
|
53
|
+
(0, 1): [[0, 0, 0], [h.hopping_gr, 0, 0], [0, 0, 0]],
|
54
|
+
(0, -1): [[0, h.hopping_gr, 0], [0, 0, 0], [0, 0, 0]],
|
55
|
+
}
|
56
|
+
|
57
|
+
return TBLattice(
|
58
|
+
units=basis_vectors,
|
59
|
+
hoppings=hoppings,
|
60
|
+
orbital_positions=orbital_positions,
|
61
|
+
orbital_names=["C1", "C2", "X"],
|
62
|
+
)
|
quant_met/cli/dmft.py
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
|
5
|
+
"""Functions to run self-consistent calculation for the order parameter."""
|
6
|
+
|
7
|
+
import logging
|
8
|
+
from pathlib import Path
|
9
|
+
|
10
|
+
from h5 import HDFArchive
|
11
|
+
from triqs.gf import Gf, Idx
|
12
|
+
|
13
|
+
from quant_met.cli._utils import _hamiltonian_factory, _tbl_factory
|
14
|
+
from quant_met.dmft.dmft_loop import dmft_loop
|
15
|
+
from quant_met.dmft.utils import get_gloc
|
16
|
+
from quant_met.parameters import Parameters
|
17
|
+
|
18
|
+
logger = logging.getLogger(__name__)
|
19
|
+
|
20
|
+
|
21
|
+
def dmft_scf(parameters: Parameters) -> None:
|
22
|
+
"""Self-consistent calculation for the order parameter.
|
23
|
+
|
24
|
+
Parameters
|
25
|
+
----------
|
26
|
+
parameters: Parameters
|
27
|
+
An instance of Parameters containing control settings, the model,
|
28
|
+
and k-point specifications for the self-consistency calculation.
|
29
|
+
"""
|
30
|
+
result_path = Path(parameters.control.outdir)
|
31
|
+
result_path.mkdir(exist_ok=True, parents=True)
|
32
|
+
|
33
|
+
h = _hamiltonian_factory(parameters=parameters.model, classname=parameters.model.name)
|
34
|
+
tbl = _tbl_factory(h=h)
|
35
|
+
|
36
|
+
kmesh = tbl.get_kmesh(n_k=(parameters.k_points.nk1, parameters.k_points.nk2, 1))
|
37
|
+
|
38
|
+
enk = tbl.fourier(kmesh)
|
39
|
+
n_orbitals = tbl.n_orbitals
|
40
|
+
nambu_shape = (2 * n_orbitals, 2 * n_orbitals)
|
41
|
+
h0_nambu_k = Gf(mesh=kmesh, target_shape=nambu_shape)
|
42
|
+
for k in kmesh:
|
43
|
+
h0_nambu_k[k][:n_orbitals, :n_orbitals] = enk(k)
|
44
|
+
h0_nambu_k[k][n_orbitals:, n_orbitals:] = -enk(-k)
|
45
|
+
|
46
|
+
xmu = h.hubbard_int_orbital_basis[0] / 2
|
47
|
+
|
48
|
+
solver = dmft_loop(
|
49
|
+
tbl=tbl,
|
50
|
+
h=h,
|
51
|
+
h0_nambu_k=h0_nambu_k,
|
52
|
+
n_bath=parameters.control.n_bath,
|
53
|
+
n_iw=parameters.control.n_iw,
|
54
|
+
broadening=parameters.control.broadening,
|
55
|
+
n_w=parameters.control.n_w,
|
56
|
+
w_mixing=parameters.control.wmixing,
|
57
|
+
n_success=parameters.control.n_success,
|
58
|
+
xmu=xmu,
|
59
|
+
kmesh=kmesh,
|
60
|
+
epsilon=parameters.control.conv_treshold,
|
61
|
+
max_iter=parameters.control.max_iter,
|
62
|
+
)
|
63
|
+
|
64
|
+
# Calculate local Green's function on the real axis
|
65
|
+
s_w = solver.Sigma_w["up"]
|
66
|
+
s_an_w = solver.Sigma_an_w["up_dn"]
|
67
|
+
s_iw = solver.Sigma_iw["up"]
|
68
|
+
s_an_iw = solver.Sigma_an_iw["up_dn"]
|
69
|
+
g_iw, g_an_iw = get_gloc(s_iw, s_an_iw, h0_nambu_k, xmu, parameters.control.broadening, kmesh)
|
70
|
+
g_w, g_an_w = get_gloc(s_w, s_an_w, h0_nambu_k, xmu, parameters.control.broadening, kmesh)
|
71
|
+
|
72
|
+
n_iw0 = int(0.5 * len(s_iw.mesh))
|
73
|
+
iw_0 = s_iw.mesh[n_iw0].value.imag
|
74
|
+
|
75
|
+
gap = s_an_iw[Idx(0)][0, 0].real / (1 - (s_iw[Idx(0)][0, 0].imag / iw_0))
|
76
|
+
|
77
|
+
data_dir = Path("data/DressedGraphene/dmft/sweep_V/")
|
78
|
+
data_dir.mkdir(parents=True, exist_ok=True)
|
79
|
+
|
80
|
+
# Save calculation results
|
81
|
+
result_file = result_path / f"{parameters.control.prefix}.hdf5"
|
82
|
+
with HDFArchive(f"{result_file}", "w") as ar:
|
83
|
+
ar["s_iw"] = s_iw
|
84
|
+
ar["s_an_iw"] = s_an_iw
|
85
|
+
ar["g_iw"] = g_iw
|
86
|
+
ar["g_an_iw"] = g_an_iw
|
87
|
+
ar["g_w"] = g_w
|
88
|
+
ar["g_an_w"] = g_an_w
|
89
|
+
ar["gap"] = gap
|
90
|
+
|
91
|
+
logger.info("Results saved to %s", result_file)
|
quant_met/cli/main.py
CHANGED
@@ -14,6 +14,7 @@ import yaml
|
|
14
14
|
from quant_met.parameters import Parameters
|
15
15
|
|
16
16
|
from .crit_temp import crit_temp
|
17
|
+
from .dmft import dmft_scf
|
17
18
|
from .scf import scf
|
18
19
|
|
19
20
|
logger = logging.getLogger(__name__)
|
@@ -60,6 +61,9 @@ def cli(input_file: TextIO, *, debug: bool) -> None:
|
|
60
61
|
case "crit-temp":
|
61
62
|
logger.info("Starting T_C calculation.")
|
62
63
|
crit_temp(params)
|
64
|
+
case "dmft-scf":
|
65
|
+
logger.info("Starting DMFT SCF calculation.")
|
66
|
+
dmft_scf(params)
|
63
67
|
case _:
|
64
68
|
logger.error("Calculation %s not found.", params.control.calculation)
|
65
69
|
sys.exit(1)
|
@@ -0,0 +1,189 @@
|
|
1
|
+
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
|
5
|
+
"""Functions to run self-consistent calculation for the order parameter."""
|
6
|
+
|
7
|
+
import logging
|
8
|
+
from itertools import product
|
9
|
+
|
10
|
+
import numpy as np
|
11
|
+
import numpy.typing as npt
|
12
|
+
from triqs.gf import BlockGf, Gf, MeshBrZone
|
13
|
+
from triqs.lattice.tight_binding import TBLattice
|
14
|
+
from triqs.operators import c, c_dag, dagger, n
|
15
|
+
|
16
|
+
from edipack2triqs.fit import BathFittingParams
|
17
|
+
from edipack2triqs.solver import EDIpackSolver
|
18
|
+
from quant_met.mean_field.hamiltonians import BaseHamiltonian
|
19
|
+
from quant_met.parameters import GenericParameters
|
20
|
+
|
21
|
+
from .utils import _dmft_weiss_field, get_gloc
|
22
|
+
|
23
|
+
logger = logging.getLogger(__name__)
|
24
|
+
|
25
|
+
|
26
|
+
def dmft_loop(
|
27
|
+
tbl: TBLattice,
|
28
|
+
h: BaseHamiltonian[GenericParameters],
|
29
|
+
h0_nambu_k: Gf,
|
30
|
+
n_bath: float,
|
31
|
+
n_iw: int,
|
32
|
+
broadening: float,
|
33
|
+
n_w: int,
|
34
|
+
w_mixing: float,
|
35
|
+
n_success: int,
|
36
|
+
xmu: npt.NDArray[np.float64],
|
37
|
+
kmesh: MeshBrZone,
|
38
|
+
epsilon: float,
|
39
|
+
max_iter: int,
|
40
|
+
) -> EDIpackSolver:
|
41
|
+
"""DMFT loop.
|
42
|
+
|
43
|
+
Parameters
|
44
|
+
----------
|
45
|
+
tbl
|
46
|
+
h
|
47
|
+
h0_nambu_k
|
48
|
+
n_bath
|
49
|
+
n_iw
|
50
|
+
broadening
|
51
|
+
n_w
|
52
|
+
w_mixing
|
53
|
+
n_success
|
54
|
+
xmu
|
55
|
+
kmesh
|
56
|
+
epsilon
|
57
|
+
max_iter
|
58
|
+
|
59
|
+
Returns
|
60
|
+
-------
|
61
|
+
EDIpackSolver
|
62
|
+
|
63
|
+
"""
|
64
|
+
energy_window = (-2.0 * h.hopping_gr, 2.0 * h.hopping_gr)
|
65
|
+
|
66
|
+
spins = ("up", "dn")
|
67
|
+
orbs = range(tbl.n_orbitals)
|
68
|
+
|
69
|
+
# Fundamental sets for impurity degrees of freedom
|
70
|
+
fops_imp_up = [("up", o) for o in orbs]
|
71
|
+
fops_imp_dn = [("dn", o) for o in orbs]
|
72
|
+
|
73
|
+
# Fundamental sets for bath degrees of freedom
|
74
|
+
fops_bath_up = [("B_up", i) for i in range(tbl.n_orbitals * n_bath)]
|
75
|
+
fops_bath_dn = [("B_dn", i) for i in range(tbl.n_orbitals * n_bath)]
|
76
|
+
|
77
|
+
# Non-interacting part of the impurity Hamiltonian
|
78
|
+
h_loc = -xmu * np.eye(tbl.n_orbitals)
|
79
|
+
hamiltonian = sum(
|
80
|
+
h_loc[o1, o2] * c_dag(spin, o1) * c(spin, o2) for spin, o1, o2 in product(spins, orbs, orbs)
|
81
|
+
)
|
82
|
+
|
83
|
+
# Interaction part
|
84
|
+
hamiltonian += -h.hubbard_int_orbital_basis[0] * sum(n("up", o) * n("dn", o) for o in orbs)
|
85
|
+
|
86
|
+
# Matrix dimensions of eps and V: 3 orbitals x 2 bath states
|
87
|
+
eps = np.array([[-1.0, -0.5, 0.5, 1.0] for _ in range(tbl.n_orbitals)])
|
88
|
+
v = 0.5 * np.ones((tbl.n_orbitals, n_bath))
|
89
|
+
d = -0.2 * np.eye(tbl.n_orbitals * n_bath)
|
90
|
+
|
91
|
+
# Bath
|
92
|
+
hamiltonian += sum(
|
93
|
+
eps[o, nu] * c_dag("B_" + s, o * n_bath + nu) * c("B_" + s, o * n_bath + nu)
|
94
|
+
for s, o, nu in product(spins, orbs, range(n_bath))
|
95
|
+
)
|
96
|
+
|
97
|
+
hamiltonian += sum(
|
98
|
+
v[o, nu]
|
99
|
+
* (c_dag(s, o) * c("B_" + s, o * n_bath + nu) + c_dag("B_" + s, o * n_bath + nu) * c(s, o))
|
100
|
+
for s, o, nu in product(spins, orbs, range(n_bath))
|
101
|
+
)
|
102
|
+
|
103
|
+
# Anomalous bath
|
104
|
+
hamiltonian += sum(
|
105
|
+
d[o, q] * (c("B_up", o) * c("B_dn", q)) + dagger(d[o, q] * (c("B_up", o) * c("B_dn", q)))
|
106
|
+
for o, q in product(range(tbl.n_orbitals * n_bath), range(tbl.n_orbitals * n_bath))
|
107
|
+
)
|
108
|
+
|
109
|
+
# Create solver object
|
110
|
+
fit_params = BathFittingParams(method="minimize", grad="numeric")
|
111
|
+
solver = EDIpackSolver(
|
112
|
+
hamiltonian,
|
113
|
+
fops_imp_up,
|
114
|
+
fops_imp_dn,
|
115
|
+
fops_bath_up,
|
116
|
+
fops_bath_dn,
|
117
|
+
lanc_dim_threshold=1024,
|
118
|
+
verbose=1,
|
119
|
+
bath_fitting_params=fit_params,
|
120
|
+
)
|
121
|
+
|
122
|
+
gooditer = 0
|
123
|
+
g0_prev = np.zeros((2, 2 * n_iw, tbl.n_orbitals, tbl.n_orbitals), dtype=complex)
|
124
|
+
for iloop in range(max_iter):
|
125
|
+
print(f"\nLoop {iloop + 1} of {max_iter}")
|
126
|
+
|
127
|
+
# Solve the effective impurity problem
|
128
|
+
solver.solve(
|
129
|
+
beta=h.beta,
|
130
|
+
n_iw=n_iw,
|
131
|
+
energy_window=energy_window,
|
132
|
+
n_w=n_w,
|
133
|
+
broadening=broadening,
|
134
|
+
)
|
135
|
+
|
136
|
+
# Normal and anomalous components of computed self-energy
|
137
|
+
s_iw = solver.Sigma_iw["up"]
|
138
|
+
s_an_iw = solver.Sigma_an_iw["up_dn"]
|
139
|
+
|
140
|
+
# Compute local Green's function
|
141
|
+
g_iw, g_an_iw = get_gloc(s_iw, s_an_iw, h0_nambu_k, xmu, broadening, kmesh)
|
142
|
+
# Compute Weiss field
|
143
|
+
g0_iw, g0_an_iw = _dmft_weiss_field(g_iw, g_an_iw, s_iw, s_an_iw)
|
144
|
+
|
145
|
+
# Bath fitting and mixing
|
146
|
+
g0_iw_full = BlockGf(name_list=spins, block_list=[g0_iw, g0_iw])
|
147
|
+
g0_an_iw_full = BlockGf(name_list=["up_dn"], block_list=[g0_an_iw])
|
148
|
+
|
149
|
+
bath_new = solver.chi2_fit_bath(g0_iw_full, g0_an_iw_full)[0]
|
150
|
+
solver.bath = w_mixing * bath_new + (1 - w_mixing) * solver.bath
|
151
|
+
|
152
|
+
# Check convergence of the Weiss field
|
153
|
+
g0 = np.asarray([g0_iw.data, g0_an_iw.data])
|
154
|
+
errvec = np.real(np.sum(abs(g0 - g0_prev), axis=1) / np.sum(abs(g0), axis=1))
|
155
|
+
# First iteration
|
156
|
+
if iloop == 0:
|
157
|
+
errvec = np.ones_like(errvec)
|
158
|
+
errmin, err, errmax = np.min(errvec), np.average(errvec), np.max(errvec)
|
159
|
+
|
160
|
+
g0_prev = np.copy(g0)
|
161
|
+
|
162
|
+
if err < epsilon:
|
163
|
+
gooditer += 1 # Increase good iterations count
|
164
|
+
else:
|
165
|
+
gooditer = 0 # Reset good iterations count
|
166
|
+
|
167
|
+
conv_bool = ((err < epsilon) and (gooditer > n_success) and (iloop < max_iter)) or (
|
168
|
+
iloop >= max_iter
|
169
|
+
)
|
170
|
+
|
171
|
+
# Print convergence message
|
172
|
+
if iloop < max_iter:
|
173
|
+
if errvec.size > 1:
|
174
|
+
print(f"max error={errmax:.6e}")
|
175
|
+
print(" " * (errvec.size > 1) + f"error={err:.6e}")
|
176
|
+
if errvec.size > 1:
|
177
|
+
print(f"min error={errmin:.6e}")
|
178
|
+
else:
|
179
|
+
if errvec.size > 1:
|
180
|
+
print(f"max error={errmax:.6e}")
|
181
|
+
print(" " * (errvec.size > 1) + f"error={err:.6e}")
|
182
|
+
if errvec.size > 1:
|
183
|
+
print(f"min error={errmin:.6e}")
|
184
|
+
print(f"Not converged after {max_iter} iterations.")
|
185
|
+
|
186
|
+
if conv_bool:
|
187
|
+
break
|
188
|
+
|
189
|
+
return solver
|
quant_met/dmft/utils.py
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Tjark Sievers
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
|
5
|
+
"""Utility functions used in DMFT."""
|
6
|
+
|
7
|
+
import numpy as np
|
8
|
+
import numpy.typing as npt
|
9
|
+
from triqs.gf import Gf, MeshBrZone, MeshImFreq, MeshProduct, conjugate, dyson, inverse, iOmega_n
|
10
|
+
|
11
|
+
|
12
|
+
def get_gloc(
|
13
|
+
s: Gf,
|
14
|
+
s_an: Gf,
|
15
|
+
h0_nambu_k: Gf,
|
16
|
+
xmu: npt.NDArray[np.complex128],
|
17
|
+
broadening: float,
|
18
|
+
kmesh: MeshBrZone,
|
19
|
+
) -> tuple[Gf, Gf]:
|
20
|
+
"""Compute local GF from bare lattice Hamiltonian and self-energy.
|
21
|
+
|
22
|
+
Parameters
|
23
|
+
----------
|
24
|
+
s
|
25
|
+
s_an
|
26
|
+
h0_nambu_k
|
27
|
+
|
28
|
+
Returns
|
29
|
+
-------
|
30
|
+
tuple[Gf, Gf]
|
31
|
+
|
32
|
+
"""
|
33
|
+
z = Gf(mesh=s.mesh, target_shape=h0_nambu_k.target_shape)
|
34
|
+
n_orbitals = z.target_shape[0] // 2
|
35
|
+
if isinstance(s.mesh, MeshImFreq):
|
36
|
+
z[:n_orbitals, :n_orbitals] << iOmega_n + xmu - s
|
37
|
+
z[:n_orbitals, n_orbitals:] << -s_an
|
38
|
+
z[n_orbitals:, :n_orbitals] << -s_an
|
39
|
+
z[n_orbitals:, n_orbitals:] << iOmega_n - xmu + conjugate(s)
|
40
|
+
else:
|
41
|
+
z[:n_orbitals, n_orbitals:] << -s_an
|
42
|
+
z[n_orbitals:, :n_orbitals] << -s_an
|
43
|
+
for w in z.mesh:
|
44
|
+
z[w][:n_orbitals, :n_orbitals] = (w + 1j * broadening + xmu) * np.eye(n_orbitals) - s[w]
|
45
|
+
z[w][n_orbitals:, n_orbitals:] = (w + 1j * broadening - xmu) * np.eye(
|
46
|
+
n_orbitals
|
47
|
+
) + conjugate(s(-w))
|
48
|
+
|
49
|
+
g_k = Gf(mesh=MeshProduct(kmesh, z.mesh), target_shape=h0_nambu_k.target_shape)
|
50
|
+
for k in kmesh:
|
51
|
+
g_k[k, :] << inverse(z - h0_nambu_k[k])
|
52
|
+
|
53
|
+
g_loc_nambu = sum(g_k[k, :] for k in kmesh) / len(kmesh)
|
54
|
+
|
55
|
+
g_loc = s.copy()
|
56
|
+
g_loc_an = s_an.copy()
|
57
|
+
g_loc[:] = g_loc_nambu[:n_orbitals, :n_orbitals]
|
58
|
+
g_loc_an[:] = g_loc_nambu[:n_orbitals, n_orbitals:]
|
59
|
+
return g_loc, g_loc_an
|
60
|
+
|
61
|
+
|
62
|
+
def _dmft_weiss_field(g_iw: Gf, g_an_iw: Gf, s_iw: Gf, s_an_iw: Gf) -> tuple[Gf, Gf]:
|
63
|
+
"""Compute Weiss field from local GF and self-energy.
|
64
|
+
|
65
|
+
Parameters
|
66
|
+
----------
|
67
|
+
g_iw
|
68
|
+
g_an_iw
|
69
|
+
s_iw
|
70
|
+
s_an_iw
|
71
|
+
|
72
|
+
Returns
|
73
|
+
-------
|
74
|
+
tuple[Gf, Gf]
|
75
|
+
|
76
|
+
"""
|
77
|
+
n_orbitals = g_iw.target_shape[0]
|
78
|
+
nambu_shape = (2 * n_orbitals, 2 * n_orbitals)
|
79
|
+
g_nambu_iw = Gf(mesh=g_iw.mesh, target_shape=nambu_shape)
|
80
|
+
s_nambu_iw = Gf(mesh=s_iw.mesh, target_shape=nambu_shape)
|
81
|
+
|
82
|
+
g_nambu_iw[:n_orbitals, :n_orbitals] = g_iw
|
83
|
+
g_nambu_iw[:n_orbitals, n_orbitals:] = g_an_iw
|
84
|
+
g_nambu_iw[n_orbitals:, :n_orbitals] = g_an_iw
|
85
|
+
g_nambu_iw[n_orbitals:, n_orbitals:] = -conjugate(g_iw)
|
86
|
+
|
87
|
+
s_nambu_iw[:n_orbitals, :n_orbitals] = s_iw
|
88
|
+
s_nambu_iw[:n_orbitals, n_orbitals:] = s_an_iw
|
89
|
+
s_nambu_iw[n_orbitals:, :n_orbitals] = s_an_iw
|
90
|
+
s_nambu_iw[n_orbitals:, n_orbitals:] = -conjugate(s_iw)
|
91
|
+
|
92
|
+
g0_nambu_iw = dyson(G_iw=g_nambu_iw, Sigma_iw=s_nambu_iw)
|
93
|
+
|
94
|
+
g0_iw = g_iw.copy()
|
95
|
+
g0_an_iw = g_an_iw.copy()
|
96
|
+
g0_iw[:] = g0_nambu_iw[:n_orbitals, :n_orbitals]
|
97
|
+
g0_an_iw[:] = g0_nambu_iw[:n_orbitals, n_orbitals:]
|
98
|
+
return g0_iw, g0_an_iw
|
quant_met/mean_field/__init__.py
CHANGED
@@ -29,13 +29,11 @@ Functions
|
|
29
29
|
|
30
30
|
from quant_met.mean_field import hamiltonians
|
31
31
|
|
32
|
-
from .quantum_metric import quantum_metric
|
33
32
|
from .search_crit_temp import search_crit_temp
|
34
33
|
from .self_consistency import self_consistency_loop
|
35
34
|
|
36
35
|
__all__ = [
|
37
36
|
"hamiltonians",
|
38
|
-
"quantum_metric",
|
39
37
|
"search_crit_temp",
|
40
38
|
"self_consistency_loop",
|
41
39
|
]
|
@@ -603,7 +603,7 @@ class BaseHamiltonian(Generic[GenericParameters], ABC):
|
|
603
603
|
* bdg_wavefunctions[k_index, j, n]
|
604
604
|
* fermi_dirac(bdg_energies[k_index, n].item(), self.beta)
|
605
605
|
)
|
606
|
-
matrix_y[i, j]
|
606
|
+
matrix_y[i, j] += (
|
607
607
|
h_der_y[k_index, i, j]
|
608
608
|
* np.conjugate(bdg_wavefunctions[k_index, i, n])
|
609
609
|
* bdg_wavefunctions[k_index, j, n]
|
@@ -721,6 +721,65 @@ class BaseHamiltonian(Generic[GenericParameters], ABC):
|
|
721
721
|
|
722
722
|
return c_mnpq
|
723
723
|
|
724
|
+
def calculate_quantum_metric(
|
725
|
+
self, k: npt.NDArray[np.floating], bands: list[int]
|
726
|
+
) -> npt.NDArray[np.floating]:
|
727
|
+
"""Calculate the quantum metric (geometric tensor) for specified bands.
|
728
|
+
|
729
|
+
This function computes the quantum geometric tensor associated with
|
730
|
+
the specified bands of a given Hamiltonian over a grid of k-points.
|
731
|
+
The output is a 2x2 matrix representing the quantum metric.
|
732
|
+
|
733
|
+
Parameters
|
734
|
+
----------
|
735
|
+
h : BaseHamiltonian
|
736
|
+
Hamiltonian object used to compute Bloch states and their derivatives.
|
737
|
+
k : numpy.ndarray
|
738
|
+
Array of k points in the Brillouin zone.
|
739
|
+
bands : list of int
|
740
|
+
Indices of the bands for which the quantum metric is to be calculated.
|
741
|
+
|
742
|
+
Returns
|
743
|
+
-------
|
744
|
+
:class:`numpy.ndarray`
|
745
|
+
A 2x2 matrix representing the quantum metric.
|
746
|
+
|
747
|
+
Raises
|
748
|
+
------
|
749
|
+
ValueError
|
750
|
+
If `bands` contains invalid indices or `k_grid` is empty.
|
751
|
+
"""
|
752
|
+
energies, bloch = self.diagonalize_nonint(k)
|
753
|
+
|
754
|
+
number_k_points = len(k)
|
755
|
+
|
756
|
+
quantum_geom_tensor = np.zeros(shape=(2, 2), dtype=np.complex128)
|
757
|
+
|
758
|
+
for band in bands:
|
759
|
+
for i, direction_1 in enumerate(["x", "y"]):
|
760
|
+
h_derivative_direction_1 = self.hamiltonian_derivative(k=k, direction=direction_1)
|
761
|
+
for j, direction_2 in enumerate(["x", "y"]):
|
762
|
+
h_derivative_direction_2 = self.hamiltonian_derivative(
|
763
|
+
k=k, direction=direction_2
|
764
|
+
)
|
765
|
+
for k_index in range(len(k)):
|
766
|
+
for n in [i for i in range(self.number_of_bands) if i != band]:
|
767
|
+
quantum_geom_tensor[i, j] += (
|
768
|
+
(
|
769
|
+
bloch[k_index][:, band].conjugate()
|
770
|
+
@ h_derivative_direction_1[k_index]
|
771
|
+
@ bloch[k_index][:, n]
|
772
|
+
)
|
773
|
+
* (
|
774
|
+
bloch[k_index][:, n].conjugate()
|
775
|
+
@ h_derivative_direction_2[k_index]
|
776
|
+
@ bloch[k_index][:, band]
|
777
|
+
)
|
778
|
+
/ (energies[k_index][band] - energies[k_index][n]) ** 2
|
779
|
+
)
|
780
|
+
|
781
|
+
return np.real(quantum_geom_tensor) / number_k_points
|
782
|
+
|
724
783
|
|
725
784
|
def _fermi_dirac_derivative() -> float:
|
726
785
|
return 0
|
quant_met/parameters/main.py
CHANGED
@@ -41,6 +41,14 @@ class Control(BaseModel):
|
|
41
41
|
n_temp_points: int = 50
|
42
42
|
calculate_additional: bool = False
|
43
43
|
|
44
|
+
n_spin: int = 1
|
45
|
+
n_success: int = 1
|
46
|
+
wmixing: float = 0.5
|
47
|
+
n_bath: int = 2
|
48
|
+
n_iw: int = 1024
|
49
|
+
n_w: int = 4000
|
50
|
+
broadening: float = 0.005
|
51
|
+
|
44
52
|
|
45
53
|
class KPoints(BaseModel):
|
46
54
|
"""Control for k points.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: quant-met
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.21
|
4
4
|
Summary: Calculate superconductivity in flat-band systems.
|
5
5
|
Author-email: Tjark Sievers <tsievers@physnet.uni-hamburg.de>
|
6
6
|
License-File: LICENSE.txt
|
@@ -13,6 +13,7 @@ Requires-Dist: numpy<2.1
|
|
13
13
|
Requires-Dist: numpydantic>=1.6.6
|
14
14
|
Requires-Dist: pandas>=2.2.3
|
15
15
|
Requires-Dist: pydantic>=2.10.4
|
16
|
+
Requires-Dist: pyyaml>=6.0.2
|
16
17
|
Requires-Dist: scipy>=1.15.0
|
17
18
|
Requires-Dist: tables>=3.10.2
|
18
19
|
Description-Content-Type: text/markdown
|
@@ -1,22 +1,25 @@
|
|
1
1
|
quant_met/__init__.py,sha256=ZO1UFz1awUYTI7B9ZkBwucvDz7GMGXnLLUGnEwLBhkc,155
|
2
2
|
quant_met/utils.py,sha256=J3kCbKg0tPEoGJExX04QwifHn4ch482J8IcmRQxIfP4,2067
|
3
3
|
quant_met/cli/__init__.py,sha256=nGFXhK8zWyEKQtsQTyJWfEOLFOHTCjZnfEcrVb2dARc,254
|
4
|
-
quant_met/cli/_utils.py,sha256=
|
4
|
+
quant_met/cli/_utils.py,sha256=vGXWDXqs15F4MiU-gRk4lHdmP7FB8vQQXuvbx-sesyE,1952
|
5
5
|
quant_met/cli/crit_temp.py,sha256=t9sPZKORl6dpa1UNAOMH2gDmeQxf80iFH7p_L3FI5q8,2027
|
6
|
-
quant_met/cli/
|
6
|
+
quant_met/cli/dmft.py,sha256=4sbTddeHhTxV0DBUNxcQDUBxQe1J9ntqnEQOLluHh1o,3016
|
7
|
+
quant_met/cli/main.py,sha256=1D1-KhGkzibts9b7Cv3JsR5Q-PnkowBWKE1Owc8tdD8,2010
|
7
8
|
quant_met/cli/scf.py,sha256=3_rwtQHwypFjAwjrsO2r2sqjJKpNiDLAj6svU52CCcU,2613
|
9
|
+
quant_met/dmft/__init__.py,sha256=2H0bN40Tvn-VnZgix6MugN0Q6iNwD_9AQxUC_LVLh70,99
|
10
|
+
quant_met/dmft/dmft_loop.py,sha256=R3lYIhUNtBVa_XyjUphZchTAeG3gWXbR1leLz0EhP2A,5738
|
11
|
+
quant_met/dmft/utils.py,sha256=z9Y9EP_V8_Bj7NIvz_GSnaQ7tha7QwqtJsEYhKIEoxQ,2897
|
8
12
|
quant_met/geometry/__init__.py,sha256=2N8l0-2-PhEOQxaUO7e8Dqy5oaxt2y9343XENDTCGPE,592
|
9
13
|
quant_met/geometry/base_lattice.py,sha256=OJNDMyzJB-0hK1BLgF-SV4jUYfOSUksIv1XG1bH-zyY,2649
|
10
14
|
quant_met/geometry/bz_path.py,sha256=vwN5RxyrgFkHTSqm_6cWuOigICgxa-FX5NZ7SkgKScw,2503
|
11
15
|
quant_met/geometry/graphene.py,sha256=ZLE55wV1E-jRCkGxW66pca2y5VWaNtMmXiXi-HB6bgs,1627
|
12
16
|
quant_met/geometry/square.py,sha256=17XZH79lK9TeeDtXiBBa8rd2d9kv5yt2S9F6te0YZPU,1565
|
13
|
-
quant_met/mean_field/__init__.py,sha256=
|
17
|
+
quant_met/mean_field/__init__.py,sha256=Unweog9Tst1NxUMQ4X1OYiUQtyxI2ho-OQoCaekoMFk,597
|
14
18
|
quant_met/mean_field/_utils.py,sha256=7hr0DDSdIqjft5Jjluvbw_HGoNLWgYJTxyuPJJvhBnc,356
|
15
|
-
quant_met/mean_field/quantum_metric.py,sha256=aiZLdUsWmoBLunv-aJr_BCQVfhD7t0GHbeYrT60s3cI,2583
|
16
19
|
quant_met/mean_field/search_crit_temp.py,sha256=Z9te3O7zsyBGLRrPjmNA85vxHOfBfIQ7svdDVFEJedg,8782
|
17
20
|
quant_met/mean_field/self_consistency.py,sha256=YY_zhCurxOK3RLkK-Hglfkx33uhsvqpoAKOP4FuPdfo,3371
|
18
21
|
quant_met/mean_field/hamiltonians/__init__.py,sha256=r-8TaLqRnRbAro-TMIyxzCCZHwVqyKrausODpQJb2tw,681
|
19
|
-
quant_met/mean_field/hamiltonians/base_hamiltonian.py,sha256=
|
22
|
+
quant_met/mean_field/hamiltonians/base_hamiltonian.py,sha256=4sp2LD213-6aNpbEQAgclJEWOdZdTpDf5QwkgigD0f0,29383
|
20
23
|
quant_met/mean_field/hamiltonians/dressed_graphene.py,sha256=Q5LiA3rgK88ZZV1V7JflgjlkEpve7uNZFzFCIoQND-w,4048
|
21
24
|
quant_met/mean_field/hamiltonians/graphene.py,sha256=sa3H8jVq9Fkc_qcz5gJTCMgN8YD3N18JWLRBImhLyxo,3276
|
22
25
|
quant_met/mean_field/hamiltonians/one_band_tight_binding.py,sha256=DZXaD95yWv1VZSMqgxkqEZv3PGihNGy7PuqupnN75ew,2512
|
@@ -24,11 +27,11 @@ quant_met/mean_field/hamiltonians/three_band_tight_binding.py,sha256=g8XNImzCn_6
|
|
24
27
|
quant_met/mean_field/hamiltonians/two_band_tight_binding.py,sha256=DMySc94YQ1M2nPIKZjfc-Ax5Ysf7inwSuVKyd6dfqr0,2865
|
25
28
|
quant_met/parameters/__init__.py,sha256=9yu7i0J-O3QxSicnLEh2ci7FSMwB8bPW0pbl8KWHJUs,1007
|
26
29
|
quant_met/parameters/hamiltonians.py,sha256=PiWVV-miCdT4Z9GWloDVvIU_1QpRHHV-zVOga7DWwCw,6046
|
27
|
-
quant_met/parameters/main.py,sha256=
|
30
|
+
quant_met/parameters/main.py,sha256=QP7Z24-QePMcy6txujqxbx5ztQTdC67m6elNsJtGtXQ,2325
|
28
31
|
quant_met/plotting/__init__.py,sha256=VypHrLAGmCiQaQggGh5Cs4EF4YAjRiETddf_7mOX9MQ,544
|
29
32
|
quant_met/plotting/plotting.py,sha256=4ZYclWJH3hlE8S7b7bL_JJlP3CKaCGcVzdIsqolCAaM,6592
|
30
|
-
quant_met-0.0.
|
31
|
-
quant_met-0.0.
|
32
|
-
quant_met-0.0.
|
33
|
-
quant_met-0.0.
|
34
|
-
quant_met-0.0.
|
33
|
+
quant_met-0.0.21.dist-info/METADATA,sha256=cyCRB0PAwVRHwgPFcI7WZBtlubWfvgZoJDq0hKZNSrc,1978
|
34
|
+
quant_met-0.0.21.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
35
|
+
quant_met-0.0.21.dist-info/entry_points.txt,sha256=1Al3Kt-cMeQxwMp84ZSNL0qFwlbOVBu1o8A19MH8lEU,48
|
36
|
+
quant_met-0.0.21.dist-info/licenses/LICENSE.txt,sha256=QO_duPQihSJlaxSLxPAXo52X3esROP5wBkhxqBd1Z4E,1104
|
37
|
+
quant_met-0.0.21.dist-info/RECORD,,
|
@@ -1,69 +0,0 @@
|
|
1
|
-
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
-
#
|
3
|
-
# SPDX-License-Identifier: MIT
|
4
|
-
|
5
|
-
"""Functions to calculate the quantum metric."""
|
6
|
-
|
7
|
-
import numpy as np
|
8
|
-
import numpy.typing as npt
|
9
|
-
|
10
|
-
from quant_met.mean_field.hamiltonians.base_hamiltonian import BaseHamiltonian
|
11
|
-
from quant_met.parameters import GenericParameters
|
12
|
-
|
13
|
-
|
14
|
-
def quantum_metric(
|
15
|
-
h: BaseHamiltonian[GenericParameters], k: npt.NDArray[np.floating], bands: list[int]
|
16
|
-
) -> npt.NDArray[np.floating]:
|
17
|
-
"""Calculate the quantum metric (geometric tensor) for specified bands.
|
18
|
-
|
19
|
-
This function computes the quantum geometric tensor associated with
|
20
|
-
the specified bands of a given Hamiltonian over a grid of k-points.
|
21
|
-
The output is a 2x2 matrix representing the quantum metric.
|
22
|
-
|
23
|
-
Parameters
|
24
|
-
----------
|
25
|
-
h : BaseHamiltonian
|
26
|
-
Hamiltonian object used to compute Bloch states and their derivatives.
|
27
|
-
k : numpy.ndarray
|
28
|
-
Array of k points in the Brillouin zone.
|
29
|
-
bands : list of int
|
30
|
-
Indices of the bands for which the quantum metric is to be calculated.
|
31
|
-
|
32
|
-
Returns
|
33
|
-
-------
|
34
|
-
:class:`numpy.ndarray`
|
35
|
-
A 2x2 matrix representing the quantum metric.
|
36
|
-
|
37
|
-
Raises
|
38
|
-
------
|
39
|
-
ValueError
|
40
|
-
If `bands` contains invalid indices or `k_grid` is empty.
|
41
|
-
"""
|
42
|
-
energies, bloch = h.diagonalize_nonint(k)
|
43
|
-
|
44
|
-
number_k_points = len(k)
|
45
|
-
|
46
|
-
quantum_geom_tensor = np.zeros(shape=(2, 2), dtype=np.complex128)
|
47
|
-
|
48
|
-
for band in bands:
|
49
|
-
for i, direction_1 in enumerate(["x", "y"]):
|
50
|
-
h_derivative_direction_1 = h.hamiltonian_derivative(k=k, direction=direction_1)
|
51
|
-
for j, direction_2 in enumerate(["x", "y"]):
|
52
|
-
h_derivative_direction_2 = h.hamiltonian_derivative(k=k, direction=direction_2)
|
53
|
-
for k_index in range(len(k)):
|
54
|
-
for n in [i for i in range(h.number_of_bands) if i != band]:
|
55
|
-
quantum_geom_tensor[i, j] += (
|
56
|
-
(
|
57
|
-
bloch[k_index][:, band].conjugate()
|
58
|
-
@ h_derivative_direction_1[k_index]
|
59
|
-
@ bloch[k_index][:, n]
|
60
|
-
)
|
61
|
-
* (
|
62
|
-
bloch[k_index][:, n].conjugate()
|
63
|
-
@ h_derivative_direction_2[k_index]
|
64
|
-
@ bloch[k_index][:, band]
|
65
|
-
)
|
66
|
-
/ (energies[k_index][band] - energies[k_index][n]) ** 2
|
67
|
-
)
|
68
|
-
|
69
|
-
return np.real(quantum_geom_tensor) / number_k_points
|
File without changes
|
File without changes
|
File without changes
|