quant-met 0.0.26__py3-none-any.whl → 0.1.0__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/__init__.py +4 -4
- quant_met/bdg/__init__.py +26 -0
- quant_met/bdg/bdg_hamiltonian.py +97 -0
- quant_met/bdg/gap_equation.py +127 -0
- quant_met/bdg/sc_current.py +60 -0
- quant_met/bdg/superfluid_weight.py +110 -0
- quant_met/cli/__init__.py +0 -4
- quant_met/cli/crit_temp.py +18 -15
- quant_met/cli/main.py +8 -8
- quant_met/cli/q_analysis.py +60 -0
- quant_met/cli/q_loop.py +91 -0
- quant_met/cli/scf.py +44 -22
- quant_met/parameters/__init__.py +0 -25
- quant_met/parameters/control.py +57 -0
- quant_met/parameters/main.py +2 -54
- quant_met/quantum_geometry/__init__.py +13 -0
- quant_met/quantum_geometry/qgt.py +37 -0
- quant_met/routines/__init__.py +22 -0
- quant_met/routines/analyse_q_data.py +226 -0
- quant_met/routines/loop_over_q.py +154 -0
- quant_met/{mean_field → routines}/search_crit_temp.py +71 -47
- quant_met/{mean_field → routines}/self_consistency.py +32 -27
- quant_met/utils.py +1 -5
- {quant_met-0.0.26.dist-info → quant_met-0.1.0.dist-info}/METADATA +7 -11
- quant_met-0.1.0.dist-info/RECORD +28 -0
- quant_met/cli/_utils.py +0 -66
- quant_met/cli/dmft.py +0 -96
- quant_met/dmft/__init__.py +0 -5
- quant_met/dmft/dmft_loop.py +0 -178
- quant_met/dmft/utils.py +0 -207
- quant_met/geometry/__init__.py +0 -35
- quant_met/geometry/base_lattice.py +0 -99
- quant_met/geometry/bz_path.py +0 -89
- quant_met/geometry/graphene.py +0 -47
- quant_met/geometry/square.py +0 -46
- quant_met/mean_field/__init__.py +0 -39
- quant_met/mean_field/_utils.py +0 -16
- quant_met/mean_field/hamiltonians/__init__.py +0 -33
- quant_met/mean_field/hamiltonians/base_hamiltonian.py +0 -792
- quant_met/mean_field/hamiltonians/dressed_graphene.py +0 -117
- quant_met/mean_field/hamiltonians/graphene.py +0 -94
- quant_met/mean_field/hamiltonians/one_band_tight_binding.py +0 -69
- quant_met/mean_field/hamiltonians/three_band_tight_binding.py +0 -84
- quant_met/mean_field/hamiltonians/two_band_tight_binding.py +0 -75
- quant_met/parameters/hamiltonians.py +0 -181
- quant_met/plotting/__init__.py +0 -30
- quant_met/plotting/plotting.py +0 -214
- quant_met-0.0.26.dist-info/RECORD +0 -37
- {quant_met-0.0.26.dist-info → quant_met-0.1.0.dist-info}/WHEEL +0 -0
- {quant_met-0.0.26.dist-info → quant_met-0.1.0.dist-info}/entry_points.txt +0 -0
- {quant_met-0.0.26.dist-info → quant_met-0.1.0.dist-info}/licenses/LICENSE.txt +0 -0
quant_met/cli/dmft.py
DELETED
@@ -1,96 +0,0 @@
|
|
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 mpi4py import MPI
|
12
|
-
from triqs.gf import Gf
|
13
|
-
|
14
|
-
from quant_met.cli._utils import _hamiltonian_factory, _tbl_factory
|
15
|
-
from quant_met.dmft.dmft_loop import dmft_loop
|
16
|
-
from quant_met.dmft.utils import get_gloc
|
17
|
-
from quant_met.parameters import Parameters
|
18
|
-
|
19
|
-
logger = logging.getLogger(__name__)
|
20
|
-
|
21
|
-
|
22
|
-
def dmft_scf(parameters: Parameters) -> None:
|
23
|
-
"""Self-consistent calculation for the order parameter.
|
24
|
-
|
25
|
-
Parameters
|
26
|
-
----------
|
27
|
-
parameters: Parameters
|
28
|
-
An instance of Parameters containing control settings, the model,
|
29
|
-
and k-point specifications for the self-consistency calculation.
|
30
|
-
"""
|
31
|
-
result_path = Path(parameters.control.outdir)
|
32
|
-
result_path.mkdir(exist_ok=True, parents=True)
|
33
|
-
|
34
|
-
h = _hamiltonian_factory(parameters=parameters.model, classname=parameters.model.name)
|
35
|
-
tbl = _tbl_factory(h=h)
|
36
|
-
|
37
|
-
kmesh = tbl.get_kmesh(n_k=(parameters.k_points.nk1, parameters.k_points.nk2, 1))
|
38
|
-
|
39
|
-
enk = tbl.fourier(kmesh)
|
40
|
-
n_orbitals = tbl.n_orbitals
|
41
|
-
nambu_shape = (2 * n_orbitals, 2 * n_orbitals)
|
42
|
-
h0_nambu_k = Gf(mesh=kmesh, target_shape=nambu_shape)
|
43
|
-
for k in kmesh:
|
44
|
-
h0_nambu_k[k][:n_orbitals, :n_orbitals] = enk(k)
|
45
|
-
h0_nambu_k[k][n_orbitals:, n_orbitals:] = -enk(-k)
|
46
|
-
|
47
|
-
ust = 0
|
48
|
-
jh = 0
|
49
|
-
xmu = (
|
50
|
-
h.hubbard_int_orbital_basis[0] / 2
|
51
|
-
+ (tbl.n_orbitals - 1) * ust / 2
|
52
|
-
+ (tbl.n_orbitals - 1) * (ust - jh) / 2
|
53
|
-
)
|
54
|
-
|
55
|
-
solver = dmft_loop(
|
56
|
-
tbl=tbl,
|
57
|
-
h=h,
|
58
|
-
h0_nambu_k=h0_nambu_k,
|
59
|
-
n_bath=parameters.control.n_bath,
|
60
|
-
n_iw=parameters.control.n_iw,
|
61
|
-
broadening=parameters.control.broadening,
|
62
|
-
n_w=parameters.control.n_w,
|
63
|
-
w_mixing=parameters.control.wmixing,
|
64
|
-
n_success=parameters.control.n_success,
|
65
|
-
xmu=xmu,
|
66
|
-
kmesh=kmesh,
|
67
|
-
epsilon=parameters.control.conv_treshold,
|
68
|
-
max_iter=parameters.control.max_iter,
|
69
|
-
)
|
70
|
-
|
71
|
-
# Calculate local Green's function on the real axis
|
72
|
-
s_w = solver.Sigma_w["up"]
|
73
|
-
s_an_w = solver.Sigma_an_w["up_dn"]
|
74
|
-
s_iw = solver.Sigma_iw["up"]
|
75
|
-
s_an_iw = solver.Sigma_an_iw["up_dn"]
|
76
|
-
g_iw, g_an_iw = get_gloc(s_iw, s_an_iw, h0_nambu_k, xmu, parameters.control.broadening, kmesh)
|
77
|
-
g_w, g_an_w = get_gloc(s_w, s_an_w, h0_nambu_k, xmu, parameters.control.broadening, kmesh)
|
78
|
-
|
79
|
-
comm = MPI.COMM_WORLD
|
80
|
-
rank = comm.Get_rank()
|
81
|
-
|
82
|
-
if rank == 0:
|
83
|
-
data_dir = Path("data/DressedGraphene/dmft/sweep_V/")
|
84
|
-
data_dir.mkdir(parents=True, exist_ok=True)
|
85
|
-
|
86
|
-
# Save calculation results
|
87
|
-
result_file = result_path / f"{parameters.control.prefix}.hdf5"
|
88
|
-
with HDFArchive(f"{result_file}", "w") as ar:
|
89
|
-
ar["s_iw"] = s_iw
|
90
|
-
ar["s_an_iw"] = s_an_iw
|
91
|
-
ar["g_iw"] = g_iw
|
92
|
-
ar["g_an_iw"] = g_an_iw
|
93
|
-
ar["g_w"] = g_w
|
94
|
-
ar["g_an_w"] = g_an_w
|
95
|
-
|
96
|
-
logger.info("Results saved to %s", result_file)
|
quant_met/dmft/__init__.py
DELETED
quant_met/dmft/dmft_loop.py
DELETED
@@ -1,178 +0,0 @@
|
|
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 edipack2triqs.fit import BathFittingParams
|
13
|
-
from edipack2triqs.solver import EDIpackSolver
|
14
|
-
from triqs.gf import BlockGf, Gf, MeshBrZone
|
15
|
-
from triqs.lattice.tight_binding import TBLattice
|
16
|
-
from triqs.operators import c, c_dag, dagger, n
|
17
|
-
|
18
|
-
from quant_met.mean_field.hamiltonians import BaseHamiltonian
|
19
|
-
from quant_met.parameters import GenericParameters
|
20
|
-
|
21
|
-
from .utils import _check_convergence, _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
|
-
ust = 0
|
84
|
-
jh = 0
|
85
|
-
jx = 0
|
86
|
-
jp = 0
|
87
|
-
|
88
|
-
# Interaction part
|
89
|
-
hamiltonian += h.hubbard_int_orbital_basis[0] * sum(n("up", o) * n("dn", o) for o in orbs)
|
90
|
-
hamiltonian += ust * sum(
|
91
|
-
int(o1 != o2) * n("up", o1) * n("dn", o2) for o1, o2 in product(orbs, orbs)
|
92
|
-
)
|
93
|
-
hamiltonian += (ust - jh) * sum(
|
94
|
-
int(o1 < o2) * n(s, o1) * n(s, o2) for s, o1, o2 in product(spins, orbs, orbs)
|
95
|
-
)
|
96
|
-
hamiltonian -= jx * sum(
|
97
|
-
int(o1 != o2) * c_dag("up", o1) * c("dn", o1) * c_dag("dn", o2) * c("up", o2)
|
98
|
-
for o1, o2 in product(orbs, orbs)
|
99
|
-
)
|
100
|
-
hamiltonian += jp * sum(
|
101
|
-
int(o1 != o2) * c_dag("up", o1) * c_dag("dn", o1) * c("dn", o2) * c("up", o2)
|
102
|
-
for o1, o2 in product(orbs, orbs)
|
103
|
-
)
|
104
|
-
|
105
|
-
# Matrix dimensions of eps and V: 3 orbitals x 2 bath states
|
106
|
-
eps = np.array([[-1.0, -0.5, 0.5, 1.0] for _ in range(tbl.n_orbitals)])
|
107
|
-
v = 0.5 * np.ones((tbl.n_orbitals, n_bath))
|
108
|
-
d = -0.2 * np.eye(tbl.n_orbitals * n_bath)
|
109
|
-
|
110
|
-
# Bath
|
111
|
-
hamiltonian += sum(
|
112
|
-
eps[o, nu] * c_dag("B_" + s, o * n_bath + nu) * c("B_" + s, o * n_bath + nu)
|
113
|
-
for s, o, nu in product(spins, orbs, range(n_bath))
|
114
|
-
)
|
115
|
-
|
116
|
-
hamiltonian += sum(
|
117
|
-
v[o, nu]
|
118
|
-
* (c_dag(s, o) * c("B_" + s, o * n_bath + nu) + c_dag("B_" + s, o * n_bath + nu) * c(s, o))
|
119
|
-
for s, o, nu in product(spins, orbs, range(n_bath))
|
120
|
-
)
|
121
|
-
|
122
|
-
# Anomalous bath
|
123
|
-
hamiltonian += sum(
|
124
|
-
d[o, q] * (c("B_up", o) * c("B_dn", q)) + dagger(d[o, q] * (c("B_up", o) * c("B_dn", q)))
|
125
|
-
for o, q in product(range(tbl.n_orbitals * n_bath), range(tbl.n_orbitals * n_bath))
|
126
|
-
)
|
127
|
-
|
128
|
-
# Create solver object
|
129
|
-
fit_params = BathFittingParams(method="minimize", grad="numeric")
|
130
|
-
solver = EDIpackSolver(
|
131
|
-
hamiltonian,
|
132
|
-
fops_imp_up,
|
133
|
-
fops_imp_dn,
|
134
|
-
fops_bath_up,
|
135
|
-
fops_bath_dn,
|
136
|
-
lanc_dim_threshold=1024,
|
137
|
-
verbose=1,
|
138
|
-
bath_fitting_params=fit_params,
|
139
|
-
)
|
140
|
-
|
141
|
-
for iloop in range(max_iter):
|
142
|
-
print(f"\nLoop {iloop + 1} of {max_iter}")
|
143
|
-
|
144
|
-
# Solve the effective impurity problem
|
145
|
-
solver.solve(
|
146
|
-
beta=h.beta,
|
147
|
-
n_iw=n_iw,
|
148
|
-
energy_window=energy_window,
|
149
|
-
n_w=n_w,
|
150
|
-
broadening=broadening,
|
151
|
-
)
|
152
|
-
|
153
|
-
# Normal and anomalous components of computed self-energy
|
154
|
-
s_iw = solver.Sigma_iw["up"]
|
155
|
-
s_an_iw = solver.Sigma_an_iw["up_dn"]
|
156
|
-
|
157
|
-
# Compute local Green's function
|
158
|
-
g_iw, g_an_iw = get_gloc(s_iw, s_an_iw, h0_nambu_k, xmu, broadening, kmesh)
|
159
|
-
# Compute Weiss field
|
160
|
-
g0_iw, g0_an_iw = _dmft_weiss_field(g_iw, g_an_iw, s_iw, s_an_iw)
|
161
|
-
|
162
|
-
# Bath fitting and mixing
|
163
|
-
g0_iw_full = BlockGf(name_list=spins, block_list=[g0_iw, g0_iw])
|
164
|
-
g0_an_iw_full = BlockGf(name_list=["up_dn"], block_list=[g0_an_iw])
|
165
|
-
|
166
|
-
bath_new = solver.chi2_fit_bath(g0_iw_full, g0_an_iw_full)[0]
|
167
|
-
solver.bath = w_mixing * bath_new + (1 - w_mixing) * solver.bath
|
168
|
-
|
169
|
-
# Check convergence of the Weiss field
|
170
|
-
g0 = np.asarray([g0_iw.data, g0_an_iw.data])
|
171
|
-
# Check convergence of the Weiss field
|
172
|
-
g0 = np.asarray([g0_iw.data, g0_an_iw.data])
|
173
|
-
err, converged = _check_convergence(g0, epsilon, n_success, max_iter)
|
174
|
-
|
175
|
-
if converged:
|
176
|
-
break
|
177
|
-
|
178
|
-
return solver
|
quant_met/dmft/utils.py
DELETED
@@ -1,207 +0,0 @@
|
|
1
|
-
# SPDX-FileCopyrightText: 2025 Tjark Sievers
|
2
|
-
#
|
3
|
-
# SPDX-License-Identifier: MIT
|
4
|
-
|
5
|
-
"""Utility functions used in DMFT."""
|
6
|
-
|
7
|
-
import sys
|
8
|
-
from pathlib import Path
|
9
|
-
|
10
|
-
import numpy as np
|
11
|
-
import numpy.typing as npt
|
12
|
-
from mpi4py import MPI
|
13
|
-
from triqs.gf import Gf, MeshBrZone, MeshImFreq, MeshProduct, conjugate, dyson, inverse, iOmega_n
|
14
|
-
|
15
|
-
|
16
|
-
def _check_convergence(
|
17
|
-
func: npt.NDArray[np.complex128], threshold: float = 1e-6, nsuccess: int = 1, nloop: int = 100
|
18
|
-
) -> tuple[float, bool]:
|
19
|
-
comm = MPI.COMM_WORLD
|
20
|
-
rank = comm.Get_rank()
|
21
|
-
|
22
|
-
func = np.asarray(func)
|
23
|
-
err = 1.0
|
24
|
-
conv_bool = False
|
25
|
-
outfile = "error.err"
|
26
|
-
|
27
|
-
if globals().get("_whichiter") is None:
|
28
|
-
global _whichiter
|
29
|
-
global _gooditer
|
30
|
-
global _oldfunc
|
31
|
-
|
32
|
-
_whichiter = 0
|
33
|
-
_gooditer = 0
|
34
|
-
_oldfunc = np.zeros_like(func)
|
35
|
-
|
36
|
-
green = "\033[92m"
|
37
|
-
yellow = "\033[93m"
|
38
|
-
red = "\033[91m"
|
39
|
-
bold = "\033[1m"
|
40
|
-
colorend = "\033[0m"
|
41
|
-
|
42
|
-
# only the master does the calculation
|
43
|
-
if rank == 0:
|
44
|
-
errvec = np.real(np.sum(abs(func - _oldfunc), axis=-1) / np.sum(abs(func), axis=-1))
|
45
|
-
# first iteration
|
46
|
-
if _whichiter == 0:
|
47
|
-
errvec = np.ones_like(errvec)
|
48
|
-
# remove nan compoments, if some component is divided by zero
|
49
|
-
if np.prod(np.shape(errvec)) > 1:
|
50
|
-
errvec = errvec[~np.isnan(errvec)]
|
51
|
-
errmax = np.max(errvec)
|
52
|
-
errmin = np.min(errvec)
|
53
|
-
err = np.average(errvec)
|
54
|
-
_oldfunc = np.copy(func)
|
55
|
-
if err < threshold:
|
56
|
-
_gooditer += 1 # increase good iterations count
|
57
|
-
else:
|
58
|
-
_gooditer = 0 # reset good iterations count
|
59
|
-
_whichiter += 1
|
60
|
-
conv_bool = ((err < threshold) and (_gooditer > nsuccess) and (_whichiter < nloop)) or (
|
61
|
-
_whichiter >= nloop
|
62
|
-
)
|
63
|
-
|
64
|
-
# write out
|
65
|
-
with Path(outfile).open("a") as file:
|
66
|
-
file.write(f"{_whichiter} {err:.6e}\n")
|
67
|
-
if np.prod(np.shape(errvec)) > 1:
|
68
|
-
with Path(outfile + ".max").open("a") as file:
|
69
|
-
file.write(f"{_whichiter} {errmax:.6e}\n")
|
70
|
-
with Path(outfile + ".min").open("a") as file:
|
71
|
-
file.write(f"{_whichiter} {errmin:.6e}\n")
|
72
|
-
with Path(outfile + ".distribution").open("a") as file:
|
73
|
-
file.write(
|
74
|
-
f"{_whichiter}" + " ".join([f"{x:.6e}" for x in errvec.flatten()]) + "\n"
|
75
|
-
)
|
76
|
-
|
77
|
-
# print convergence message:
|
78
|
-
if conv_bool:
|
79
|
-
colorprefix = bold + green
|
80
|
-
elif (err < threshold) and (_gooditer <= nsuccess):
|
81
|
-
colorprefix = bold + yellow
|
82
|
-
else:
|
83
|
-
colorprefix = bold + red
|
84
|
-
|
85
|
-
if _whichiter < nloop:
|
86
|
-
if np.prod(np.shape(errvec)) > 1:
|
87
|
-
print(colorprefix + "max error=" + colorend + f"{errmax:.6e}")
|
88
|
-
print(
|
89
|
-
colorprefix
|
90
|
-
+ " " * (np.prod(np.shape(errvec)) > 1)
|
91
|
-
+ "error="
|
92
|
-
+ colorend
|
93
|
-
+ f"{err:.6e}"
|
94
|
-
)
|
95
|
-
if np.prod(np.shape(errvec)) > 1:
|
96
|
-
print(colorprefix + "min error=" + colorend + f"{errmin:.6e}")
|
97
|
-
else:
|
98
|
-
if np.prod(np.shape(errvec)) > 1:
|
99
|
-
print(colorprefix + "max error=" + colorend + f"{errmax:.6e}")
|
100
|
-
print(
|
101
|
-
colorprefix
|
102
|
-
+ " " * (np.prod(np.shape(errvec)) > 1)
|
103
|
-
+ "error="
|
104
|
-
+ colorend
|
105
|
-
+ f"{err:.6e}"
|
106
|
-
)
|
107
|
-
if np.prod(np.shape(errvec)) > 1:
|
108
|
-
print(colorprefix + "min error=" + colorend + f"{errmin:.6e}")
|
109
|
-
print("Not converged after " + str(nloop) + " iterations.")
|
110
|
-
with Path("ERROR.README").open("a") as file:
|
111
|
-
file.write("Not converged after " + str(nloop) + " iterations.")
|
112
|
-
print("\n")
|
113
|
-
|
114
|
-
# pass to other cores:
|
115
|
-
conv_bool = comm.bcast(conv_bool, root=0)
|
116
|
-
err = comm.bcast(err, root=0)
|
117
|
-
sys.stdout.flush()
|
118
|
-
return err, conv_bool
|
119
|
-
|
120
|
-
|
121
|
-
def get_gloc(
|
122
|
-
s: Gf,
|
123
|
-
s_an: Gf,
|
124
|
-
h0_nambu_k: Gf,
|
125
|
-
xmu: npt.NDArray[np.complex128],
|
126
|
-
broadening: float,
|
127
|
-
kmesh: MeshBrZone,
|
128
|
-
) -> tuple[Gf, Gf]:
|
129
|
-
"""Compute local GF from bare lattice Hamiltonian and self-energy.
|
130
|
-
|
131
|
-
Parameters
|
132
|
-
----------
|
133
|
-
s
|
134
|
-
s_an
|
135
|
-
h0_nambu_k
|
136
|
-
|
137
|
-
Returns
|
138
|
-
-------
|
139
|
-
tuple[Gf, Gf]
|
140
|
-
|
141
|
-
"""
|
142
|
-
z = Gf(mesh=s.mesh, target_shape=h0_nambu_k.target_shape)
|
143
|
-
n_orbitals = z.target_shape[0] // 2
|
144
|
-
if isinstance(s.mesh, MeshImFreq):
|
145
|
-
z[:n_orbitals, :n_orbitals] << iOmega_n + xmu - s
|
146
|
-
z[:n_orbitals, n_orbitals:] << -s_an
|
147
|
-
z[n_orbitals:, :n_orbitals] << -s_an
|
148
|
-
z[n_orbitals:, n_orbitals:] << iOmega_n - xmu + conjugate(s)
|
149
|
-
else:
|
150
|
-
z[:n_orbitals, n_orbitals:] << -s_an
|
151
|
-
z[n_orbitals:, :n_orbitals] << -s_an
|
152
|
-
for w in z.mesh:
|
153
|
-
z[w][:n_orbitals, :n_orbitals] = (w + 1j * broadening + xmu) * np.eye(n_orbitals) - s[w]
|
154
|
-
z[w][n_orbitals:, n_orbitals:] = (w + 1j * broadening - xmu) * np.eye(
|
155
|
-
n_orbitals
|
156
|
-
) + conjugate(s(-w))
|
157
|
-
|
158
|
-
g_k = Gf(mesh=MeshProduct(kmesh, z.mesh), target_shape=h0_nambu_k.target_shape)
|
159
|
-
for k in kmesh:
|
160
|
-
g_k[k, :] << inverse(z - h0_nambu_k[k])
|
161
|
-
|
162
|
-
g_loc_nambu = sum(g_k[k, :] for k in kmesh) / len(kmesh)
|
163
|
-
|
164
|
-
g_loc = s.copy()
|
165
|
-
g_loc_an = s_an.copy()
|
166
|
-
g_loc[:] = g_loc_nambu[:n_orbitals, :n_orbitals]
|
167
|
-
g_loc_an[:] = g_loc_nambu[:n_orbitals, n_orbitals:]
|
168
|
-
return g_loc, g_loc_an
|
169
|
-
|
170
|
-
|
171
|
-
def _dmft_weiss_field(g_iw: Gf, g_an_iw: Gf, s_iw: Gf, s_an_iw: Gf) -> tuple[Gf, Gf]:
|
172
|
-
"""Compute Weiss field from local GF and self-energy.
|
173
|
-
|
174
|
-
Parameters
|
175
|
-
----------
|
176
|
-
g_iw
|
177
|
-
g_an_iw
|
178
|
-
s_iw
|
179
|
-
s_an_iw
|
180
|
-
|
181
|
-
Returns
|
182
|
-
-------
|
183
|
-
tuple[Gf, Gf]
|
184
|
-
|
185
|
-
"""
|
186
|
-
n_orbitals = g_iw.target_shape[0]
|
187
|
-
nambu_shape = (2 * n_orbitals, 2 * n_orbitals)
|
188
|
-
g_nambu_iw = Gf(mesh=g_iw.mesh, target_shape=nambu_shape)
|
189
|
-
s_nambu_iw = Gf(mesh=s_iw.mesh, target_shape=nambu_shape)
|
190
|
-
|
191
|
-
g_nambu_iw[:n_orbitals, :n_orbitals] = g_iw
|
192
|
-
g_nambu_iw[:n_orbitals, n_orbitals:] = g_an_iw
|
193
|
-
g_nambu_iw[n_orbitals:, :n_orbitals] = g_an_iw
|
194
|
-
g_nambu_iw[n_orbitals:, n_orbitals:] = -conjugate(g_iw)
|
195
|
-
|
196
|
-
s_nambu_iw[:n_orbitals, :n_orbitals] = s_iw
|
197
|
-
s_nambu_iw[:n_orbitals, n_orbitals:] = s_an_iw
|
198
|
-
s_nambu_iw[n_orbitals:, :n_orbitals] = s_an_iw
|
199
|
-
s_nambu_iw[n_orbitals:, n_orbitals:] = -conjugate(s_iw)
|
200
|
-
|
201
|
-
g0_nambu_iw = dyson(G_iw=g_nambu_iw, Sigma_iw=s_nambu_iw)
|
202
|
-
|
203
|
-
g0_iw = g_iw.copy()
|
204
|
-
g0_an_iw = g_an_iw.copy()
|
205
|
-
g0_iw[:] = g0_nambu_iw[:n_orbitals, :n_orbitals]
|
206
|
-
g0_an_iw[:] = g0_nambu_iw[:n_orbitals, n_orbitals:]
|
207
|
-
return g0_iw, g0_an_iw
|
quant_met/geometry/__init__.py
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
-
#
|
3
|
-
# SPDX-License-Identifier: MIT
|
4
|
-
|
5
|
-
"""
|
6
|
-
Geometry
|
7
|
-
========
|
8
|
-
|
9
|
-
.. currentmodule:: quant_met.geometry
|
10
|
-
|
11
|
-
Functions
|
12
|
-
---------
|
13
|
-
|
14
|
-
.. autosummary::
|
15
|
-
:toctree: generated/
|
16
|
-
|
17
|
-
generate_bz_path
|
18
|
-
|
19
|
-
Classes
|
20
|
-
-------
|
21
|
-
|
22
|
-
.. autosummary::
|
23
|
-
:toctree: generated/
|
24
|
-
|
25
|
-
BaseLattice
|
26
|
-
GrapheneLattice
|
27
|
-
SquareLattice
|
28
|
-
""" # noqa: D205, D400
|
29
|
-
|
30
|
-
from .base_lattice import BaseLattice
|
31
|
-
from .bz_path import generate_bz_path
|
32
|
-
from .graphene import GrapheneLattice
|
33
|
-
from .square import SquareLattice
|
34
|
-
|
35
|
-
__all__ = ["BaseLattice", "GrapheneLattice", "SquareLattice", "generate_bz_path"]
|
@@ -1,99 +0,0 @@
|
|
1
|
-
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
-
#
|
3
|
-
# SPDX-License-Identifier: MIT
|
4
|
-
|
5
|
-
"""Base class for lattice geometries."""
|
6
|
-
|
7
|
-
from abc import ABC, abstractmethod
|
8
|
-
|
9
|
-
import numpy as np
|
10
|
-
import numpy.typing as npt
|
11
|
-
|
12
|
-
from quant_met.utils import generate_uniform_grid
|
13
|
-
|
14
|
-
from .bz_path import generate_bz_path
|
15
|
-
|
16
|
-
|
17
|
-
class BaseLattice(ABC):
|
18
|
-
"""Base class for lattice geometries."""
|
19
|
-
|
20
|
-
@property
|
21
|
-
@abstractmethod
|
22
|
-
def lattice_constant(self) -> float: # pragma: no cover
|
23
|
-
"""Lattice constant."""
|
24
|
-
raise NotImplementedError
|
25
|
-
|
26
|
-
@property
|
27
|
-
@abstractmethod
|
28
|
-
def bz_corners(self) -> npt.NDArray[np.floating]: # pragma: no cover
|
29
|
-
"""Corners of the BZ."""
|
30
|
-
raise NotImplementedError
|
31
|
-
|
32
|
-
@property
|
33
|
-
@abstractmethod
|
34
|
-
def reciprocal_basis(
|
35
|
-
self,
|
36
|
-
) -> tuple[npt.NDArray[np.floating], npt.NDArray[np.floating]]: # pragma: no cover
|
37
|
-
"""Reciprocal basis vectors."""
|
38
|
-
raise NotImplementedError
|
39
|
-
|
40
|
-
@property
|
41
|
-
@abstractmethod
|
42
|
-
def high_symmetry_points(
|
43
|
-
self,
|
44
|
-
) -> tuple[tuple[npt.NDArray[np.floating], str], ...]: # pragma: no cover
|
45
|
-
"""Tuple of high symmetry points and names."""
|
46
|
-
raise NotImplementedError
|
47
|
-
|
48
|
-
def generate_bz_grid(self, ncols: int, nrows: int) -> npt.NDArray[np.floating]:
|
49
|
-
"""Generate a grid in the BZ.
|
50
|
-
|
51
|
-
Parameters
|
52
|
-
----------
|
53
|
-
ncols : int
|
54
|
-
Number of points in column.
|
55
|
-
nrows : int
|
56
|
-
Number of points in row.
|
57
|
-
|
58
|
-
Returns
|
59
|
-
-------
|
60
|
-
:class:`numpy.ndarray`
|
61
|
-
Array of grid points in the BZ.
|
62
|
-
|
63
|
-
"""
|
64
|
-
return generate_uniform_grid(
|
65
|
-
ncols,
|
66
|
-
nrows,
|
67
|
-
self.reciprocal_basis[0],
|
68
|
-
self.reciprocal_basis[1],
|
69
|
-
origin=np.array([0, 0]),
|
70
|
-
)
|
71
|
-
|
72
|
-
def generate_high_symmetry_path(
|
73
|
-
self, number_of_points: int
|
74
|
-
) -> tuple[
|
75
|
-
npt.NDArray[np.floating],
|
76
|
-
npt.NDArray[np.floating],
|
77
|
-
list[float],
|
78
|
-
list[str],
|
79
|
-
]:
|
80
|
-
"""Generate a path through high symmetry points.
|
81
|
-
|
82
|
-
Parameters
|
83
|
-
----------
|
84
|
-
number_of_points: int
|
85
|
-
Number of point in the whole path.
|
86
|
-
|
87
|
-
Returns
|
88
|
-
-------
|
89
|
-
:class:`numpy.ndarray`
|
90
|
-
List of two-dimensional k points.
|
91
|
-
:class:`numpy.ndarray`
|
92
|
-
Path for plotting purposes: points between 0 and 1, with appropriate spacing.
|
93
|
-
list[float]
|
94
|
-
A list of ticks for the plotting path.
|
95
|
-
list[str]
|
96
|
-
A list of labels for the plotting path.
|
97
|
-
|
98
|
-
"""
|
99
|
-
return generate_bz_path(list(self.high_symmetry_points), number_of_points=number_of_points)
|