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
@@ -0,0 +1,154 @@
|
|
1
|
+
"""Function to run search for critical temperature."""
|
2
|
+
|
3
|
+
import logging
|
4
|
+
from functools import partial
|
5
|
+
from multiprocessing import Pool
|
6
|
+
from typing import Any
|
7
|
+
|
8
|
+
import numpy as np
|
9
|
+
import numpy.typing as npt
|
10
|
+
import pandas as pd
|
11
|
+
import sisl
|
12
|
+
|
13
|
+
from quant_met import bdg
|
14
|
+
|
15
|
+
from .self_consistency import self_consistency_loop
|
16
|
+
|
17
|
+
logger = logging.getLogger(__name__)
|
18
|
+
|
19
|
+
MAX_Q = 0.5
|
20
|
+
|
21
|
+
|
22
|
+
def is_gap_zero(result: dict[str, float], atol: float = 1e-8) -> bool:
|
23
|
+
"""Check if all delta values in result are (approximately) zero."""
|
24
|
+
deltas = np.array([x for key, x in result.items() if key.startswith("delta")])
|
25
|
+
return np.isclose(np.max(np.abs(deltas)), 0, atol=atol)
|
26
|
+
|
27
|
+
|
28
|
+
def adjust_q_upper_bound(
|
29
|
+
gap_for_q_partial: partial[dict[str, Any] | None], initial_q: float = 0.5
|
30
|
+
) -> float:
|
31
|
+
"""
|
32
|
+
Adjust q_upper_bound until gap is non-zero or exceeds upper limit.
|
33
|
+
|
34
|
+
Returns the adjusted q_upper_bound.
|
35
|
+
"""
|
36
|
+
q_upper_bound = initial_q
|
37
|
+
|
38
|
+
while True:
|
39
|
+
result_tmp: dict[str, float] | None = gap_for_q_partial(q_upper_bound)
|
40
|
+
|
41
|
+
if result_tmp is None or is_gap_zero(result_tmp):
|
42
|
+
q_upper_bound /= 2
|
43
|
+
else:
|
44
|
+
break
|
45
|
+
|
46
|
+
while True:
|
47
|
+
result_tmp = gap_for_q_partial(q_upper_bound)
|
48
|
+
|
49
|
+
if result_tmp is None or is_gap_zero(result_tmp):
|
50
|
+
q_upper_bound *= 1.1
|
51
|
+
if q_upper_bound > MAX_Q:
|
52
|
+
break
|
53
|
+
else:
|
54
|
+
break
|
55
|
+
|
56
|
+
return q_upper_bound
|
57
|
+
|
58
|
+
|
59
|
+
def _gap_for_q( # noqa: PLR0913
|
60
|
+
q_fraction: float,
|
61
|
+
hamiltonian: sisl.Hamiltonian,
|
62
|
+
kgrid: sisl.MonkhorstPack,
|
63
|
+
hubbard_int_orbital_basis: npt.NDArray[np.float64],
|
64
|
+
epsilon: float,
|
65
|
+
temp: float,
|
66
|
+
max_iter: int = 1000,
|
67
|
+
) -> dict[str, Any] | None: # pragma: no cover
|
68
|
+
beta = np.inf if temp == 0 else 1 / temp
|
69
|
+
q = q_fraction * hamiltonian.geometry.rcell[0]
|
70
|
+
data_dict: dict[str, Any] = {
|
71
|
+
"q_fraction": q_fraction,
|
72
|
+
}
|
73
|
+
try:
|
74
|
+
gap = self_consistency_loop(
|
75
|
+
hamiltonian=hamiltonian,
|
76
|
+
kgrid=kgrid,
|
77
|
+
beta=beta,
|
78
|
+
hubbard_int_orbital_basis=hubbard_int_orbital_basis,
|
79
|
+
epsilon=epsilon,
|
80
|
+
max_iter=max_iter,
|
81
|
+
q=q,
|
82
|
+
)
|
83
|
+
except RuntimeError:
|
84
|
+
logger.exception("Did not converge.")
|
85
|
+
return None
|
86
|
+
else:
|
87
|
+
bdg_energies, bdg_wavefunctions = bdg.diagonalize_bdg(
|
88
|
+
hamiltonian=hamiltonian,
|
89
|
+
kgrid=kgrid,
|
90
|
+
delta_orbital_basis=gap,
|
91
|
+
q=q,
|
92
|
+
)
|
93
|
+
current = bdg.calculate_current_density(
|
94
|
+
hamiltonian=hamiltonian,
|
95
|
+
k=kgrid,
|
96
|
+
bdg_energies=bdg_energies,
|
97
|
+
bdg_wavefunctions=bdg_wavefunctions,
|
98
|
+
beta=beta,
|
99
|
+
)
|
100
|
+
data_dict.update({f"delta_{orbital}": gap[orbital] for orbital in range(len(gap))})
|
101
|
+
data_dict.update(
|
102
|
+
{
|
103
|
+
"current_x": current[0],
|
104
|
+
"current_y": current[1],
|
105
|
+
"current_abs": np.linalg.norm(current),
|
106
|
+
},
|
107
|
+
)
|
108
|
+
return data_dict
|
109
|
+
|
110
|
+
|
111
|
+
def loop_over_q( # noqa: PLR0913
|
112
|
+
hamiltonian: sisl.Hamiltonian,
|
113
|
+
kgrid: sisl.MonkhorstPack,
|
114
|
+
hubbard_int_orbital_basis: npt.NDArray[np.float64],
|
115
|
+
epsilon: float,
|
116
|
+
max_iter: int,
|
117
|
+
n_q_points: int,
|
118
|
+
crit_temps: npt.NDArray[np.float64],
|
119
|
+
) -> dict[str, pd.DataFrame]: # pragma: no cover
|
120
|
+
"""Loop over q."""
|
121
|
+
logger.info("Start search for upper bound for q.")
|
122
|
+
|
123
|
+
crit_temp = np.max(crit_temps)
|
124
|
+
temp_list = [crit_temp * x for x in [0.65, 0.7, 0.75, 0.8, 0.85, 0.87, 0.89, 0.91, 0.93, 0.95]]
|
125
|
+
|
126
|
+
delta_vs_q = {}
|
127
|
+
for temp in temp_list:
|
128
|
+
gap_for_q_partial = partial(
|
129
|
+
_gap_for_q,
|
130
|
+
hamiltonian=hamiltonian,
|
131
|
+
kgrid=kgrid,
|
132
|
+
hubbard_int_orbital_basis=hubbard_int_orbital_basis,
|
133
|
+
epsilon=epsilon,
|
134
|
+
max_iter=max_iter,
|
135
|
+
temp=temp,
|
136
|
+
)
|
137
|
+
q_upper_bound = adjust_q_upper_bound(gap_for_q_partial, initial_q=0.5)
|
138
|
+
logger.info("q upper bound: %s", q_upper_bound)
|
139
|
+
|
140
|
+
q_list = np.linspace(
|
141
|
+
0,
|
142
|
+
q_upper_bound,
|
143
|
+
num=n_q_points,
|
144
|
+
)
|
145
|
+
|
146
|
+
with Pool() as p:
|
147
|
+
delta_vs_q_list = [x for x in p.map(gap_for_q_partial, q_list) if x is not None] # type: ignore[arg-type]
|
148
|
+
|
149
|
+
delta_vs_q_tmp = (
|
150
|
+
pd.DataFrame(delta_vs_q_list).sort_values(by=["q_fraction"]).reset_index(drop=True)
|
151
|
+
)
|
152
|
+
delta_vs_q[f"{temp}"] = delta_vs_q_tmp
|
153
|
+
|
154
|
+
return delta_vs_q
|
@@ -1,7 +1,3 @@
|
|
1
|
-
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
-
#
|
3
|
-
# SPDX-License-Identifier: MIT
|
4
|
-
|
5
1
|
"""Function to run search for critical temperature."""
|
6
2
|
|
7
3
|
import logging
|
@@ -14,16 +10,16 @@ import matplotlib.pyplot as plt
|
|
14
10
|
import numpy as np
|
15
11
|
import numpy.typing as npt
|
16
12
|
import pandas as pd
|
13
|
+
import sisl
|
17
14
|
from scipy import stats
|
18
15
|
|
19
|
-
from quant_met import plotting
|
20
|
-
from quant_met.parameters import GenericParameters
|
21
|
-
|
22
|
-
from .hamiltonians import BaseHamiltonian
|
23
16
|
from .self_consistency import self_consistency_loop
|
24
17
|
|
25
18
|
logger = logging.getLogger(__name__)
|
26
19
|
|
20
|
+
MIN_NUMBER_OF_T_POINTS_FITTING = 4
|
21
|
+
MAX_ITERATIONS_GET_BOUNDS = 100
|
22
|
+
|
27
23
|
|
28
24
|
def _get_bounds(
|
29
25
|
initial_temp: float,
|
@@ -37,7 +33,9 @@ def _get_bounds(
|
|
37
33
|
temp = initial_temp
|
38
34
|
direction = "down"
|
39
35
|
iterations = 0
|
40
|
-
while (
|
36
|
+
while (
|
37
|
+
found_zero_gap and found_nonzero_gap
|
38
|
+
) is False and iterations < MAX_ITERATIONS_GET_BOUNDS:
|
41
39
|
logger.info("Trying temperature: %s", temp)
|
42
40
|
data_dict = gap_for_temp_partial(temp)
|
43
41
|
logger.info("Result: %s", data_dict)
|
@@ -50,7 +48,9 @@ def _get_bounds(
|
|
50
48
|
found_zero_gap = True
|
51
49
|
temp = 0.5 * temp
|
52
50
|
elif np.allclose(
|
53
|
-
gap,
|
51
|
+
gap,
|
52
|
+
zero_temperature_gap,
|
53
|
+
atol=0.10 * np.max(np.abs(zero_temperature_gap)),
|
54
54
|
):
|
55
55
|
logger.info("Found temperature with nonzero gap.")
|
56
56
|
nonzero_gap_temp = temp
|
@@ -61,7 +61,7 @@ def _get_bounds(
|
|
61
61
|
temp = 0.5 * temp
|
62
62
|
else:
|
63
63
|
logger.info(
|
64
|
-
"Gap is neither zero nor equal to the zero gap. Increasing temperature."
|
64
|
+
"Gap is neither zero nor equal to the zero gap. Increasing temperature.",
|
65
65
|
)
|
66
66
|
temp = 2 * temp
|
67
67
|
elif direction == "down":
|
@@ -85,7 +85,8 @@ def _get_bounds(
|
|
85
85
|
|
86
86
|
|
87
87
|
def _fit_for_crit_temp(
|
88
|
-
delta_vs_temp: pd.DataFrame,
|
88
|
+
delta_vs_temp: pd.DataFrame,
|
89
|
+
orbital: int,
|
89
90
|
) -> tuple[pd.DataFrame | None, pd.DataFrame, float | None, float | None]: # pragma: no cover
|
90
91
|
filtered_results = delta_vs_temp.iloc[
|
91
92
|
np.where(
|
@@ -103,21 +104,22 @@ def _fit_for_crit_temp(
|
|
103
104
|
rtol=1e-2,
|
104
105
|
atol=0,
|
105
106
|
),
|
106
|
-
)
|
107
|
-
)
|
107
|
+
),
|
108
|
+
),
|
108
109
|
)
|
109
110
|
]
|
110
111
|
|
111
112
|
err = []
|
112
|
-
if len(filtered_results) <=
|
113
|
+
if len(filtered_results) <= MIN_NUMBER_OF_T_POINTS_FITTING:
|
113
114
|
return None, filtered_results, None, None
|
114
115
|
|
115
|
-
lengths = range(
|
116
|
+
lengths = range(MIN_NUMBER_OF_T_POINTS_FITTING, len(filtered_results))
|
116
117
|
|
117
118
|
for length in lengths:
|
118
119
|
range_results = filtered_results.iloc[-length:]
|
119
120
|
linreg = stats.linregress(
|
120
|
-
range_results["T"],
|
121
|
+
range_results["T"],
|
122
|
+
np.abs(range_results[f"delta_{orbital}"]) ** 2,
|
121
123
|
)
|
122
124
|
err.append(linreg.stderr)
|
123
125
|
|
@@ -128,64 +130,83 @@ def _fit_for_crit_temp(
|
|
128
130
|
return range_results, filtered_results, linreg.intercept, linreg.slope
|
129
131
|
|
130
132
|
|
131
|
-
def _gap_for_temp(
|
133
|
+
def _gap_for_temp( # noqa: PLR0913
|
132
134
|
temp: float,
|
133
|
-
|
134
|
-
|
135
|
+
hamiltonian: sisl.Hamiltonian,
|
136
|
+
kgrid: sisl.MonkhorstPack,
|
137
|
+
hubbard_int_orbital_basis: npt.NDArray[np.float64],
|
135
138
|
epsilon: float,
|
136
139
|
max_iter: int = 1000,
|
140
|
+
delta_init: npt.NDArray[np.complex128] | None = None,
|
141
|
+
q: npt.NDArray[np.float64] | None = None,
|
137
142
|
) -> dict[str, Any] | None: # pragma: no cover
|
138
143
|
beta = np.inf if temp == 0 else 1 / temp
|
139
|
-
h.beta = beta
|
140
144
|
try:
|
141
|
-
|
145
|
+
gap = self_consistency_loop(
|
146
|
+
hamiltonian=hamiltonian,
|
147
|
+
kgrid=kgrid,
|
148
|
+
beta=beta,
|
149
|
+
hubbard_int_orbital_basis=hubbard_int_orbital_basis,
|
150
|
+
epsilon=epsilon,
|
151
|
+
max_iter=max_iter,
|
152
|
+
delta_init=delta_init,
|
153
|
+
q=q,
|
154
|
+
)
|
142
155
|
except RuntimeError:
|
143
156
|
logger.exception("Did not converge.")
|
144
157
|
return None
|
145
158
|
else:
|
146
|
-
data_dict = {
|
159
|
+
data_dict: dict[str, Any] = {
|
147
160
|
"T": temp,
|
148
161
|
}
|
149
|
-
|
150
|
-
data_dict.update(
|
151
|
-
{
|
152
|
-
f"delta_{orbital}": zero_temperature_gap[orbital]
|
153
|
-
for orbital in range(len(zero_temperature_gap))
|
154
|
-
}
|
155
|
-
)
|
162
|
+
data_dict.update({f"delta_{orbital}": gap[orbital] for orbital in range(len(gap))})
|
156
163
|
return data_dict
|
157
164
|
|
158
165
|
|
159
|
-
def search_crit_temp(
|
160
|
-
|
161
|
-
|
166
|
+
def search_crit_temp( # noqa: PLR0913
|
167
|
+
hamiltonian: sisl.Hamiltonian,
|
168
|
+
kgrid: sisl.MonkhorstPack,
|
169
|
+
hubbard_int_orbital_basis: npt.NDArray[np.float64],
|
162
170
|
epsilon: float,
|
163
171
|
max_iter: int,
|
164
172
|
n_temp_points: int,
|
173
|
+
q: npt.NDArray[np.float64] | None = None,
|
174
|
+
beta_init: float | None = None,
|
165
175
|
) -> tuple[pd.DataFrame, list[float], matplotlib.figure.Figure]: # pragma: no cover
|
166
176
|
"""Search for critical temperature."""
|
167
177
|
logger.info("Start search for bounds for T_C")
|
168
|
-
|
178
|
+
beta = 10 * hubbard_int_orbital_basis[0] if beta_init is None else beta_init
|
179
|
+
temp = 1 / beta if not np.isinf(beta) else 1e-8
|
169
180
|
|
170
181
|
delta_vs_temp_list = []
|
171
182
|
critical_temp_list = []
|
172
183
|
|
173
184
|
gap_for_temp_partial = partial(
|
174
|
-
_gap_for_temp,
|
185
|
+
_gap_for_temp,
|
186
|
+
hamiltonian=hamiltonian,
|
187
|
+
kgrid=kgrid,
|
188
|
+
hubbard_int_orbital_basis=hubbard_int_orbital_basis,
|
189
|
+
epsilon=epsilon,
|
190
|
+
max_iter=max_iter,
|
191
|
+
q=q,
|
175
192
|
)
|
176
193
|
|
177
194
|
logger.info("Calculating zero temperature gap")
|
178
195
|
data_dict = gap_for_temp_partial(0)
|
179
|
-
|
196
|
+
if data_dict is None:
|
197
|
+
err_msg = "Calculation for T = 0 did not converge."
|
198
|
+
raise ValueError(err_msg)
|
180
199
|
logger.info("Result: %s", data_dict)
|
181
200
|
|
182
201
|
zero_temperature_gap = np.array(
|
183
|
-
[data_dict[key] for key in data_dict if key.startswith("delta")]
|
202
|
+
[data_dict[key] for key in data_dict if key.startswith("delta")],
|
184
203
|
)
|
185
204
|
delta_vs_temp_list.append(data_dict)
|
186
205
|
|
187
206
|
delta_vs_temp_list_tmp, zero_gap_temp, nonzero_gap_temp = _get_bounds(
|
188
|
-
temp,
|
207
|
+
temp,
|
208
|
+
gap_for_temp_partial,
|
209
|
+
zero_temperature_gap,
|
189
210
|
)
|
190
211
|
delta_vs_temp_list.extend(delta_vs_temp_list_tmp)
|
191
212
|
logger.info("Temperature bounds: %s to %s", nonzero_gap_temp, zero_gap_temp)
|
@@ -199,12 +220,18 @@ def search_crit_temp(
|
|
199
220
|
endpoint=False,
|
200
221
|
),
|
201
222
|
np.linspace(
|
202
|
-
nonzero_gap_temp,
|
223
|
+
nonzero_gap_temp,
|
224
|
+
zero_gap_temp,
|
225
|
+
num=int(0.9 * n_temp_points),
|
226
|
+
endpoint=False,
|
203
227
|
),
|
204
228
|
np.linspace(
|
205
|
-
zero_gap_temp,
|
229
|
+
zero_gap_temp,
|
230
|
+
1.2 * zero_gap_temp,
|
231
|
+
num=int(0.05 * n_temp_points),
|
232
|
+
endpoint=True,
|
206
233
|
),
|
207
|
-
]
|
234
|
+
],
|
208
235
|
)
|
209
236
|
|
210
237
|
with Pool() as p:
|
@@ -213,14 +240,12 @@ def search_crit_temp(
|
|
213
240
|
|
214
241
|
delta_vs_temp = pd.DataFrame(delta_vs_temp_list).sort_values(by=["T"]).reset_index(drop=True)
|
215
242
|
|
216
|
-
fit_fig, fit_axs = plt.subplots(
|
217
|
-
nrows=1, ncols=h.number_of_bands, figsize=(h.number_of_bands * 6, 6)
|
218
|
-
)
|
243
|
+
fit_fig, fit_axs = plt.subplots(nrows=1, ncols=hamiltonian.no, figsize=(hamiltonian.no * 6, 6))
|
219
244
|
|
220
|
-
for orbital in range(
|
245
|
+
for orbital in range(hamiltonian.no):
|
221
246
|
fit_range, filtered_range, intercept, slope = _fit_for_crit_temp(delta_vs_temp, orbital)
|
222
247
|
|
223
|
-
ax = fit_axs if
|
248
|
+
ax = fit_axs if hamiltonian.no == 1 else fit_axs[orbital]
|
224
249
|
|
225
250
|
if fit_range is not None and intercept is not None and slope is not None:
|
226
251
|
critical_temp = -intercept / slope
|
@@ -248,7 +273,6 @@ def search_crit_temp(
|
|
248
273
|
"--x",
|
249
274
|
color=f"C{orbital}",
|
250
275
|
)
|
251
|
-
ax = plotting.format_plot(ax)
|
252
276
|
ax.set_ylabel(r"$\vert\Delta\vert^2\ [t^2]$")
|
253
277
|
|
254
278
|
return delta_vs_temp, critical_temp_list, fit_fig
|
@@ -1,27 +1,27 @@
|
|
1
|
-
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
-
#
|
3
|
-
# SPDX-License-Identifier: MIT
|
4
|
-
|
5
1
|
"""Self-consistency loop."""
|
6
2
|
|
7
3
|
import logging
|
8
4
|
|
9
5
|
import numpy as np
|
10
6
|
import numpy.typing as npt
|
7
|
+
import sisl
|
8
|
+
from numpy import complexfloating, dtype, ndarray
|
11
9
|
|
12
|
-
from quant_met.
|
13
|
-
from quant_met.parameters import GenericParameters
|
10
|
+
from quant_met.bdg import gap_equation
|
14
11
|
|
15
12
|
logger = logging.getLogger(__name__)
|
16
13
|
|
17
14
|
|
18
|
-
def self_consistency_loop(
|
19
|
-
|
20
|
-
|
15
|
+
def self_consistency_loop( # noqa: PLR0913
|
16
|
+
hamiltonian: sisl.Hamiltonian,
|
17
|
+
kgrid: sisl.MonkhorstPack,
|
18
|
+
beta: float,
|
19
|
+
hubbard_int_orbital_basis: npt.NDArray[np.float64],
|
21
20
|
epsilon: float,
|
22
21
|
max_iter: int = 1000,
|
23
22
|
delta_init: npt.NDArray[np.complex128] | None = None,
|
24
|
-
|
23
|
+
q: npt.NDArray[np.float64] | None = None,
|
24
|
+
) -> ndarray[tuple[int, ...], dtype[complexfloating]]:
|
25
25
|
"""Self-consistently solves the gap equation for a given Hamiltonian.
|
26
26
|
|
27
27
|
This function performs a self-consistency loop to solve the gap equation
|
@@ -31,11 +31,12 @@ def self_consistency_loop(
|
|
31
31
|
|
32
32
|
Parameters
|
33
33
|
----------
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
q
|
35
|
+
kgrid
|
36
|
+
hubbard_int_orbital_basis
|
37
|
+
beta
|
38
|
+
hamiltonian : sisl.Hamiltonian
|
39
|
+
The Hamiltonian object.
|
39
40
|
|
40
41
|
epsilon : float
|
41
42
|
The convergence criterion. The loop will terminate when the change
|
@@ -63,12 +64,12 @@ def self_consistency_loop(
|
|
63
64
|
|
64
65
|
if delta_init is None:
|
65
66
|
rng = np.random.default_rng()
|
66
|
-
delta_init = np.zeros(shape=
|
67
|
-
delta_init += (0.2 * rng.random(size=
|
68
|
-
0.2 * rng.random(size=
|
67
|
+
delta_init = np.zeros(shape=hamiltonian.no, dtype=np.complex128)
|
68
|
+
delta_init += (0.2 * rng.random(size=hamiltonian.no) - 1) + 1.0j * (
|
69
|
+
0.2 * rng.random(size=hamiltonian.no) - 1
|
69
70
|
)
|
70
|
-
|
71
|
-
|
71
|
+
logger.debug("Initial gaps set to: %s", delta_init)
|
72
|
+
delta = delta_init
|
72
73
|
|
73
74
|
iteration_count = 0
|
74
75
|
while True:
|
@@ -79,16 +80,20 @@ def self_consistency_loop(
|
|
79
80
|
|
80
81
|
logger.debug("Iteration %d: Computing new gaps.", iteration_count)
|
81
82
|
|
82
|
-
new_gap =
|
83
|
+
new_gap = gap_equation(
|
84
|
+
hamiltonian=hamiltonian,
|
85
|
+
kgrid=kgrid,
|
86
|
+
q=q,
|
87
|
+
beta=beta,
|
88
|
+
hubbard_int_orbital_basis=hubbard_int_orbital_basis,
|
89
|
+
delta_orbital_basis=delta,
|
90
|
+
)
|
83
91
|
|
84
92
|
logger.debug("New gaps computed: %s", new_gap)
|
85
93
|
|
86
|
-
if np.allclose(
|
87
|
-
h.delta_orbital_basis = new_gap # type: ignore[assignment]
|
94
|
+
if np.allclose(delta, new_gap, atol=1e-10, rtol=epsilon):
|
88
95
|
logger.info("Convergence achieved after %d iterations.", iteration_count)
|
89
|
-
return
|
96
|
+
return new_gap
|
90
97
|
|
91
98
|
mixing_greed = 0.2
|
92
|
-
|
93
|
-
logger.debug("Updated gaps: %s", h.delta_orbital_basis)
|
94
|
-
logger.debug("Change in gaps: %s", np.abs(h.delta_orbital_basis - new_gap))
|
99
|
+
delta = mixing_greed * new_gap + (1 - mixing_greed) * delta
|
quant_met/utils.py
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
-
#
|
3
|
-
# SPDX-License-Identifier: MIT
|
4
|
-
|
5
1
|
"""
|
6
2
|
Utility functions (:mod:`quant_met.utils`)
|
7
3
|
==========================================
|
@@ -66,7 +62,7 @@ def generate_uniform_grid(
|
|
66
62
|
num=ncols,
|
67
63
|
)
|
68
64
|
for i in range(nrows)
|
69
|
-
]
|
65
|
+
],
|
70
66
|
)
|
71
67
|
|
72
68
|
return grid
|
@@ -1,35 +1,31 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: quant-met
|
3
|
-
Version: 0.0
|
3
|
+
Version: 0.1.0
|
4
4
|
Summary: Calculate superconductivity in flat-band systems.
|
5
|
-
Author-email: Tjark Sievers <
|
5
|
+
Author-email: Tjark Sievers <tjarksievers@icloud.com>
|
6
6
|
License-File: LICENSE.txt
|
7
7
|
Requires-Python: >=3.11
|
8
8
|
Requires-Dist: click>=8.1.8
|
9
9
|
Requires-Dist: h5py>=3.12.1
|
10
10
|
Requires-Dist: matplotlib>=3.10.0
|
11
|
-
Requires-Dist: numba>=0.
|
12
|
-
Requires-Dist: numpy
|
13
|
-
Requires-Dist: numpydantic>=1.6.
|
11
|
+
Requires-Dist: numba>=0.61.0
|
12
|
+
Requires-Dist: numpy>=2.1
|
13
|
+
Requires-Dist: numpydantic>=1.6.8
|
14
14
|
Requires-Dist: pandas>=2.2.3
|
15
15
|
Requires-Dist: pydantic>=2.10.4
|
16
16
|
Requires-Dist: pyyaml>=6.0.2
|
17
17
|
Requires-Dist: scipy>=1.15.0
|
18
|
+
Requires-Dist: sisl[viz]>0.16.0
|
18
19
|
Requires-Dist: tables>=3.10.2
|
20
|
+
Requires-Dist: tbmodels>=1.4.3
|
19
21
|
Description-Content-Type: text/markdown
|
20
22
|
|
21
|
-
<!--
|
22
|
-
SPDX-FileCopyrightText: 2024 Tjark Sievers
|
23
|
-
|
24
|
-
SPDX-License-Identifier: MIT
|
25
|
-
-->
|
26
23
|
|
27
24
|
# quant-met
|
28
25
|
|
29
26
|
[](https://zenodo.org/badge/latestdoi/800628635)
|
30
27
|
[](https://github.com/Ruberhauptmann/quant-met/actions/workflows/unit_tests.yml)
|
31
28
|
[](https://coveralls.io/github/Ruberhauptmann/quant-met?branch=main)
|
32
|
-
[](https://pypi.org/project/quant-met/)
|
33
29
|
[](https://pypi.org/project/quant-met/)
|
34
30
|
|
35
31
|
quant-met is a python package to treat superconductivity in flat-band systems.
|
@@ -0,0 +1,28 @@
|
|
1
|
+
quant_met/__init__.py,sha256=9WVEpcOuJ6ObayeK9u9Vkm2D-iPyb5Olc4PZdLWPORk,186
|
2
|
+
quant_met/utils.py,sha256=pr-J_ElUDKxmSdErxsz4Eclvojoejbaup-Fg12QKMVQ,1989
|
3
|
+
quant_met/bdg/__init__.py,sha256=RHxvGyCTDeK4vlIm807K9wJkLOI0jGA3ibuq0YRfo74,605
|
4
|
+
quant_met/bdg/bdg_hamiltonian.py,sha256=6zKW_a7XVXYk61RFvJjp_av4Gh7KSMqLUV1Ir8iS1sY,2708
|
5
|
+
quant_met/bdg/gap_equation.py,sha256=VyGbQxNxjbUkp-NHzGs3-5vejc6CcBfvmtXREWRS3eI,3372
|
6
|
+
quant_met/bdg/sc_current.py,sha256=fRX4KH1J7IY1T8Oxrpd_0RJd8fvPDNeP3yCg-UwRLpI,1840
|
7
|
+
quant_met/bdg/superfluid_weight.py,sha256=rLS6fK41Pt8aXxPL0KNVvK0dMWwYdbZ0eAqBEoGvAQ8,4207
|
8
|
+
quant_met/cli/__init__.py,sha256=11q_R4KoAKZy2EOuUgnAn4GxbS9yyTA6nSjKpDl-UjI,175
|
9
|
+
quant_met/cli/crit_temp.py,sha256=l4jPXY07z75FD7xgACrj_C2B3t3xX-yQeWlcnkEGIAA,2179
|
10
|
+
quant_met/cli/main.py,sha256=DNgXguBfVpp-pddmN-RKePeO1R2Dsr_b97BKei1MMG0,2074
|
11
|
+
quant_met/cli/q_analysis.py,sha256=H-3o-of_xEv3c1uUqtREGKroY-pk8Yu7RWXmLxi0xpU,1986
|
12
|
+
quant_met/cli/q_loop.py,sha256=6T01sS65pzqOwLx5gymC-6kbEa3XJjGerujfkB4D1cQ,3524
|
13
|
+
quant_met/cli/scf.py,sha256=jpFoIpC0ghf48lK7SfNeTXXADEtyCzv6kzyMvdcBF1Y,3283
|
14
|
+
quant_met/parameters/__init__.py,sha256=d1XBoH8siW0fNRz5I8tpI2-JQfiSjadFBcmQANV97Zk,448
|
15
|
+
quant_met/parameters/control.py,sha256=ZxtAf35Gnb2LwooazcFrdb1d2b_sipGHIUtF5bZwTIg,1384
|
16
|
+
quant_met/parameters/main.py,sha256=P0o7f4o2woHNtLEqYJnO7dXdKEX3t_dsCky8-Sr_W88,977
|
17
|
+
quant_met/quantum_geometry/__init__.py,sha256=RMD7pNHPFAJuOtUfNiV4XssA1RjL6h1eZBsh76Fc-8Y,185
|
18
|
+
quant_met/quantum_geometry/qgt.py,sha256=jdYUxBOeKYYR96Zex2xIVOVCsT11HZ1NVrUBmmjTlLY,1358
|
19
|
+
quant_met/routines/__init__.py,sha256=a8xHRD6j4v8lkrwGSzwmj4BHUg2tgTN0Hp0Vpu4863Y,479
|
20
|
+
quant_met/routines/analyse_q_data.py,sha256=8q32GBB2ftYgdjWJ1_EpvcNJO9_Fn1kfKSaWLhIAJeY,8409
|
21
|
+
quant_met/routines/loop_over_q.py,sha256=3yYhCf_Xo7ziT5Pj4HmLDvvq8crbb7-MdJOjmyluYao,4460
|
22
|
+
quant_met/routines/search_crit_temp.py,sha256=phK2pJTibj8sgtxOghEJkurbG4xt2LRq23MTdfwygAE,9598
|
23
|
+
quant_met/routines/self_consistency.py,sha256=nb-gRzyEd24kc6ZU2O53ov07Zg3pN6wSz-9jjo68RCM,3071
|
24
|
+
quant_met-0.1.0.dist-info/METADATA,sha256=Eos9y8wuLVX9JdvRwf5QXAnD8XDgL22NpRd9MCSwDXo,1837
|
25
|
+
quant_met-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
26
|
+
quant_met-0.1.0.dist-info/entry_points.txt,sha256=1Al3Kt-cMeQxwMp84ZSNL0qFwlbOVBu1o8A19MH8lEU,48
|
27
|
+
quant_met-0.1.0.dist-info/licenses/LICENSE.txt,sha256=QO_duPQihSJlaxSLxPAXo52X3esROP5wBkhxqBd1Z4E,1104
|
28
|
+
quant_met-0.1.0.dist-info/RECORD,,
|
quant_met/cli/_utils.py
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
-
#
|
3
|
-
# SPDX-License-Identifier: MIT
|
4
|
-
|
5
|
-
import numpy as np
|
6
|
-
from triqs.lattice.tight_binding import TBLattice
|
7
|
-
|
8
|
-
from quant_met.mean_field.hamiltonians import BaseHamiltonian
|
9
|
-
from quant_met.parameters import GenericParameters, HamiltonianParameters
|
10
|
-
|
11
|
-
|
12
|
-
def _hamiltonian_factory(
|
13
|
-
classname: str, parameters: HamiltonianParameters
|
14
|
-
) -> BaseHamiltonian[HamiltonianParameters]:
|
15
|
-
"""Create a Hamiltonian by its class name.
|
16
|
-
|
17
|
-
Parameters
|
18
|
-
----------
|
19
|
-
classname: str
|
20
|
-
The name of the Hamiltonian class to instantiate.
|
21
|
-
parameters: HamiltonianParameters
|
22
|
-
An instance of HamiltonianParameters containing all necessary
|
23
|
-
configuration for the specific Hamiltonian.
|
24
|
-
|
25
|
-
Returns
|
26
|
-
-------
|
27
|
-
BaseHamiltonian[HamiltonianParameters]
|
28
|
-
An instance of the specified Hamiltonian class.
|
29
|
-
"""
|
30
|
-
from quant_met.mean_field import hamiltonians
|
31
|
-
|
32
|
-
cls = getattr(hamiltonians, classname)
|
33
|
-
h: BaseHamiltonian[HamiltonianParameters] = cls(parameters)
|
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 = [
|
45
|
-
(0.5 * (np.sqrt(3) - 1), 0, 0),
|
46
|
-
(0.5 * (np.sqrt(3) + 1), 0, 0),
|
47
|
-
(0.5 * (np.sqrt(3) - 1), 0, 0),
|
48
|
-
]
|
49
|
-
hoppings = {
|
50
|
-
(0, 0): [
|
51
|
-
[0, h.hopping_gr, h.hopping_x_gr_a],
|
52
|
-
[h.hopping_gr, 0, 0],
|
53
|
-
[h.hopping_x_gr_a, 0, 0],
|
54
|
-
],
|
55
|
-
(1, 0): [[0, 0, 0], [h.hopping_gr, 0, 0], [0, 0, 0]],
|
56
|
-
(-1, 0): [[0, h.hopping_gr, 0], [0, 0, 0], [0, 0, 0]],
|
57
|
-
(0, 1): [[0, h.hopping_gr, 0], [0, 0, 0], [0, 0, 0]],
|
58
|
-
(0, -1): [[0, 0, 0], [h.hopping_gr, 0, 0], [0, 0, 0]],
|
59
|
-
}
|
60
|
-
|
61
|
-
return TBLattice(
|
62
|
-
units=basis_vectors,
|
63
|
-
hoppings=hoppings,
|
64
|
-
orbital_positions=orbital_positions,
|
65
|
-
orbital_names=["A", "B", "X"],
|
66
|
-
)
|