quant-met 0.0.3__py3-none-any.whl → 0.0.5__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/mean_field/__init__.py +2 -1
- quant_met/mean_field/base_hamiltonian.py +93 -79
- quant_met/mean_field/eg_x.py +94 -41
- quant_met/mean_field/graphene.py +71 -26
- quant_met/mean_field/quantum_metric.py +52 -2
- quant_met/mean_field/superfluid_weight.py +6 -32
- {quant_met-0.0.3.dist-info → quant_met-0.0.5.dist-info}/METADATA +2 -2
- quant_met-0.0.5.dist-info/RECORD +17 -0
- quant_met-0.0.3.dist-info/RECORD +0 -17
- {quant_met-0.0.3.dist-info → quant_met-0.0.5.dist-info}/LICENSE.txt +0 -0
- {quant_met-0.0.3.dist-info → quant_met-0.0.5.dist-info}/LICENSES/MIT.txt +0 -0
- {quant_met-0.0.3.dist-info → quant_met-0.0.5.dist-info}/WHEEL +0 -0
quant_met/mean_field/__init__.py
CHANGED
@@ -44,12 +44,13 @@ from .free_energy import (
|
|
44
44
|
free_energy_uniform_pairing,
|
45
45
|
)
|
46
46
|
from .graphene import GrapheneHamiltonian
|
47
|
-
from .quantum_metric import quantum_metric
|
47
|
+
from .quantum_metric import quantum_metric, quantum_metric_bdg
|
48
48
|
from .superfluid_weight import superfluid_weight
|
49
49
|
|
50
50
|
__all__ = [
|
51
51
|
"superfluid_weight",
|
52
52
|
"quantum_metric",
|
53
|
+
"quantum_metric_bdg",
|
53
54
|
"free_energy",
|
54
55
|
"free_energy_complex_gap",
|
55
56
|
"free_energy_real_gap",
|
@@ -54,29 +54,44 @@ class BaseHamiltonian(ABC):
|
|
54
54
|
raise NotImplementedError
|
55
55
|
|
56
56
|
@abstractmethod
|
57
|
-
def
|
57
|
+
def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
|
58
|
+
"""
|
59
|
+
Return the normal state Hamiltonian in orbital basis.
|
60
|
+
|
61
|
+
Parameters
|
62
|
+
----------
|
63
|
+
k : :class:`numpy.ndarray`
|
64
|
+
List of k points.
|
65
|
+
|
66
|
+
Returns
|
67
|
+
-------
|
68
|
+
:class:`numpy.ndarray`
|
69
|
+
Hamiltonian in matrix form.
|
70
|
+
|
71
|
+
"""
|
58
72
|
raise NotImplementedError
|
59
73
|
|
60
74
|
@abstractmethod
|
61
|
-
def
|
62
|
-
self,
|
75
|
+
def hamiltonian_derivative(
|
76
|
+
self, k: npt.NDArray[np.float64], direction: str
|
63
77
|
) -> npt.NDArray[np.complex64]:
|
64
|
-
|
78
|
+
"""
|
79
|
+
Deriative of the Hamiltonian.
|
65
80
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
np.fill_diagonal(delta_matrix, self.delta_orbital_basis)
|
81
|
+
Parameters
|
82
|
+
----------
|
83
|
+
k: :class:`numpy.ndarray`
|
84
|
+
List of k points.
|
85
|
+
direction: str
|
86
|
+
Direction for derivative, either 'x' oder 'y'.
|
73
87
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
88
|
+
Returns
|
89
|
+
-------
|
90
|
+
:class:`numpy.ndarray`
|
91
|
+
Derivative of Hamiltonian.
|
92
|
+
|
93
|
+
"""
|
94
|
+
raise NotImplementedError
|
80
95
|
|
81
96
|
def save(self, filename: pathlib.Path) -> None:
|
82
97
|
"""
|
@@ -88,7 +103,7 @@ class BaseHamiltonian(ABC):
|
|
88
103
|
Filename to save the Hamiltonian to, should end in .hdf5
|
89
104
|
|
90
105
|
"""
|
91
|
-
with h5py.File(f"{filename}", "
|
106
|
+
with h5py.File(f"{filename}", "w") as f:
|
92
107
|
f.create_dataset("delta", data=self.delta_orbital_basis)
|
93
108
|
for key, value in vars(self).items():
|
94
109
|
if not key.startswith("_"):
|
@@ -126,42 +141,32 @@ class BaseHamiltonian(ABC):
|
|
126
141
|
BdG Hamiltonian.
|
127
142
|
|
128
143
|
"""
|
129
|
-
|
130
|
-
msg = "k is NaN or Infinity"
|
131
|
-
raise ValueError(msg)
|
144
|
+
assert _check_valid_array(k)
|
132
145
|
if k.ndim == 1:
|
133
|
-
|
134
|
-
else:
|
135
|
-
h = np.array([self._bdg_hamiltonian_one_point(k) for k in k])
|
136
|
-
return h
|
146
|
+
k = np.expand_dims(k, axis=0)
|
137
147
|
|
138
|
-
|
139
|
-
|
140
|
-
|
148
|
+
h = np.zeros(
|
149
|
+
(k.shape[0], 2 * self.number_of_bands, 2 * self.number_of_bands), dtype=np.complex64
|
150
|
+
)
|
141
151
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
152
|
+
h[:, 0 : self.number_of_bands, 0 : self.number_of_bands] = self.hamiltonian(k)
|
153
|
+
h[
|
154
|
+
:,
|
155
|
+
self.number_of_bands : 2 * self.number_of_bands,
|
156
|
+
self.number_of_bands : 2 * self.number_of_bands,
|
157
|
+
] = -self.hamiltonian(-k).conjugate()
|
146
158
|
|
147
|
-
|
148
|
-
|
149
|
-
:
|
150
|
-
Hamiltonian in matrix form.
|
159
|
+
for i in range(self.number_of_bands):
|
160
|
+
h[:, self.number_of_bands + i, i] = self.delta_orbital_basis[i]
|
161
|
+
h[:, 0:2, 2:4] = h[:, 2:4, 0:2].copy().conjugate()
|
151
162
|
|
152
|
-
|
153
|
-
assert _check_valid_array(k)
|
154
|
-
if k.ndim == 1:
|
155
|
-
h = self._hamiltonian_one_point(k)
|
156
|
-
else:
|
157
|
-
h = np.array([self._hamiltonian_one_point(k) for k in k])
|
158
|
-
return h
|
163
|
+
return h.squeeze()
|
159
164
|
|
160
|
-
def
|
165
|
+
def bdg_hamiltonian_derivative(
|
161
166
|
self, k: npt.NDArray[np.float64], direction: str
|
162
167
|
) -> npt.NDArray[np.complex64]:
|
163
168
|
"""
|
164
|
-
Deriative of the Hamiltonian.
|
169
|
+
Deriative of the BdG Hamiltonian.
|
165
170
|
|
166
171
|
Parameters
|
167
172
|
----------
|
@@ -178,10 +183,22 @@ class BaseHamiltonian(ABC):
|
|
178
183
|
"""
|
179
184
|
assert _check_valid_array(k)
|
180
185
|
if k.ndim == 1:
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
186
|
+
k = np.expand_dims(k, axis=0)
|
187
|
+
|
188
|
+
h = np.zeros(
|
189
|
+
(k.shape[0], 2 * self.number_of_bands, 2 * self.number_of_bands), dtype=np.complex64
|
190
|
+
)
|
191
|
+
|
192
|
+
h[:, 0 : self.number_of_bands, 0 : self.number_of_bands] = self.hamiltonian_derivative(
|
193
|
+
k, direction
|
194
|
+
)
|
195
|
+
h[
|
196
|
+
:,
|
197
|
+
self.number_of_bands : 2 * self.number_of_bands,
|
198
|
+
self.number_of_bands : 2 * self.number_of_bands,
|
199
|
+
] = -self.hamiltonian_derivative(-k, direction).conjugate()
|
200
|
+
|
201
|
+
return h.squeeze()
|
185
202
|
|
186
203
|
def diagonalize_nonint(
|
187
204
|
self, k: npt.NDArray[np.float64]
|
@@ -203,20 +220,20 @@ class BaseHamiltonian(ABC):
|
|
203
220
|
|
204
221
|
"""
|
205
222
|
k_point_matrix = self.hamiltonian(k)
|
223
|
+
if k_point_matrix.ndim == 2:
|
224
|
+
k_point_matrix = np.expand_dims(k_point_matrix, axis=0)
|
225
|
+
k = np.expand_dims(k, axis=0)
|
206
226
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
dtype=complex,
|
213
|
-
)
|
214
|
-
band_energies = np.zeros((len(k), self.number_of_bands))
|
227
|
+
bloch_wavefunctions = np.zeros(
|
228
|
+
(len(k), self.number_of_bands, self.number_of_bands),
|
229
|
+
dtype=complex,
|
230
|
+
)
|
231
|
+
band_energies = np.zeros((len(k), self.number_of_bands))
|
215
232
|
|
216
|
-
|
217
|
-
|
233
|
+
for i in range(len(k)):
|
234
|
+
band_energies[i], bloch_wavefunctions[i] = np.linalg.eigh(k_point_matrix[i])
|
218
235
|
|
219
|
-
return band_energies, bloch_wavefunctions
|
236
|
+
return band_energies.squeeze(), bloch_wavefunctions.squeeze()
|
220
237
|
|
221
238
|
def diagonalize_bdg(
|
222
239
|
self, k: npt.NDArray[np.float64]
|
@@ -238,20 +255,20 @@ class BaseHamiltonian(ABC):
|
|
238
255
|
|
239
256
|
"""
|
240
257
|
bdg_matrix = self.bdg_hamiltonian(k)
|
258
|
+
if bdg_matrix.ndim == 2:
|
259
|
+
bdg_matrix = np.expand_dims(bdg_matrix, axis=0)
|
260
|
+
k = np.expand_dims(k, axis=0)
|
241
261
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
dtype=np.complex64,
|
248
|
-
)
|
249
|
-
bdg_energies = np.zeros((len(k), 2 * self.number_of_bands))
|
262
|
+
bdg_wavefunctions = np.zeros(
|
263
|
+
(len(k), 2 * self.number_of_bands, 2 * self.number_of_bands),
|
264
|
+
dtype=np.complex64,
|
265
|
+
)
|
266
|
+
bdg_energies = np.zeros((len(k), 2 * self.number_of_bands))
|
250
267
|
|
251
|
-
|
252
|
-
|
268
|
+
for i in range(len(k)):
|
269
|
+
bdg_energies[i], bdg_wavefunctions[i] = np.linalg.eigh(bdg_matrix[i])
|
253
270
|
|
254
|
-
return bdg_energies, bdg_wavefunctions
|
271
|
+
return bdg_energies.squeeze(), bdg_wavefunctions.squeeze()
|
255
272
|
|
256
273
|
def calculate_bandstructure(
|
257
274
|
self,
|
@@ -274,23 +291,20 @@ class BaseHamiltonian(ABC):
|
|
274
291
|
Band structure.
|
275
292
|
|
276
293
|
"""
|
277
|
-
k_point_matrix = self.hamiltonian(k)
|
278
|
-
|
279
294
|
results = pd.DataFrame(
|
280
295
|
index=range(len(k)),
|
281
296
|
dtype=float,
|
282
297
|
)
|
298
|
+
energies, wavefunctions = self.diagonalize_nonint(k)
|
283
299
|
|
284
|
-
for i in
|
285
|
-
energies, eigenvectors = np.linalg.eigh(k_point_matrix[i])
|
286
|
-
|
300
|
+
for i, (energy_k, wavefunction_k) in enumerate(zip(energies, wavefunctions, strict=False)):
|
287
301
|
for band_index in range(self.number_of_bands):
|
288
|
-
results.loc[i, f"band_{band_index}"] =
|
302
|
+
results.loc[i, f"band_{band_index}"] = energy_k[band_index]
|
289
303
|
|
290
304
|
if overlaps is not None:
|
291
305
|
results.loc[i, f"wx_{band_index}"] = (
|
292
|
-
np.abs(np.dot(
|
293
|
-
- np.abs(np.dot(
|
306
|
+
np.abs(np.dot(wavefunction_k[:, band_index], overlaps[0])) ** 2
|
307
|
+
- np.abs(np.dot(wavefunction_k[:, band_index], overlaps[1])) ** 2
|
294
308
|
)
|
295
309
|
|
296
310
|
return results
|
quant_met/mean_field/eg_x.py
CHANGED
@@ -4,10 +4,12 @@
|
|
4
4
|
|
5
5
|
"""Provides the implementation for the EG-X model."""
|
6
6
|
|
7
|
+
from typing import Any
|
8
|
+
|
7
9
|
import numpy as np
|
8
10
|
import numpy.typing as npt
|
9
11
|
|
10
|
-
from ._utils import _validate_float
|
12
|
+
from ._utils import _check_valid_array, _validate_float
|
11
13
|
from .base_hamiltonian import BaseHamiltonian
|
12
14
|
|
13
15
|
|
@@ -24,7 +26,11 @@ class EGXHamiltonian(BaseHamiltonian):
|
|
24
26
|
coloumb_gr: float,
|
25
27
|
coloumb_x: float,
|
26
28
|
delta: npt.NDArray[np.complex64] | None = None,
|
29
|
+
*args: tuple[Any, ...],
|
30
|
+
**kwargs: tuple[dict[str, Any], ...],
|
27
31
|
) -> None:
|
32
|
+
del args
|
33
|
+
del kwargs
|
28
34
|
self.hopping_gr = _validate_float(hopping_gr, "Hopping graphene")
|
29
35
|
self.hopping_x = _validate_float(hopping_x, "Hopping impurity")
|
30
36
|
self.hopping_x_gr_a = _validate_float(hopping_x_gr_a, "Hybridisation")
|
@@ -55,66 +61,113 @@ class EGXHamiltonian(BaseHamiltonian):
|
|
55
61
|
def number_of_bands(self) -> int: # noqa: D102
|
56
62
|
return self._number_of_bands
|
57
63
|
|
58
|
-
def
|
64
|
+
def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
|
65
|
+
"""
|
66
|
+
Return the normal state Hamiltonian in orbital basis.
|
67
|
+
|
68
|
+
Parameters
|
69
|
+
----------
|
70
|
+
k : :class:`numpy.ndarray`
|
71
|
+
List of k points.
|
72
|
+
|
73
|
+
Returns
|
74
|
+
-------
|
75
|
+
:class:`numpy.ndarray`
|
76
|
+
Hamiltonian in matrix form.
|
77
|
+
|
78
|
+
"""
|
79
|
+
assert _check_valid_array(k)
|
80
|
+
|
81
|
+
t_gr = self.hopping_gr
|
82
|
+
t_x = self.hopping_x
|
83
|
+
a = self.lattice_constant
|
84
|
+
v = self.hopping_x_gr_a
|
85
|
+
mu = self.mu
|
86
|
+
if k.ndim == 1:
|
87
|
+
k = np.expand_dims(k, axis=0)
|
88
|
+
|
89
|
+
h = np.zeros((k.shape[0], self.number_of_bands, self.number_of_bands), dtype=np.complex64)
|
90
|
+
|
91
|
+
h[:, 0, 1] = -t_gr * (
|
92
|
+
np.exp(1j * k[:, 1] * a / np.sqrt(3))
|
93
|
+
+ 2 * np.exp(-0.5j * a / np.sqrt(3) * k[:, 1]) * (np.cos(0.5 * a * k[:, 0]))
|
94
|
+
)
|
95
|
+
|
96
|
+
h[:, 1, 0] = h[:, 0, 1].conjugate()
|
97
|
+
|
98
|
+
h[:, 2, 0] = v
|
99
|
+
h[:, 0, 2] = v
|
100
|
+
|
101
|
+
h[:, 2, 2] = (
|
102
|
+
-2
|
103
|
+
* t_x
|
104
|
+
* (
|
105
|
+
np.cos(a * k[:, 0])
|
106
|
+
+ 2 * np.cos(0.5 * a * k[:, 0]) * np.cos(0.5 * np.sqrt(3) * a * k[:, 1])
|
107
|
+
)
|
108
|
+
)
|
109
|
+
h[:, 0, 0] -= mu
|
110
|
+
h[:, 1, 1] -= mu
|
111
|
+
h[:, 2, 2] -= mu
|
112
|
+
|
113
|
+
return h.squeeze()
|
114
|
+
|
115
|
+
def hamiltonian_derivative(
|
59
116
|
self, k: npt.NDArray[np.float64], direction: str
|
60
117
|
) -> npt.NDArray[np.complex64]:
|
118
|
+
"""
|
119
|
+
Deriative of the Hamiltonian.
|
120
|
+
|
121
|
+
Parameters
|
122
|
+
----------
|
123
|
+
k: :class:`numpy.ndarray`
|
124
|
+
List of k points.
|
125
|
+
direction: str
|
126
|
+
Direction for derivative, either 'x' oder 'y'.
|
127
|
+
|
128
|
+
Returns
|
129
|
+
-------
|
130
|
+
:class:`numpy.ndarray`
|
131
|
+
Derivative of Hamiltonian.
|
132
|
+
|
133
|
+
"""
|
134
|
+
assert _check_valid_array(k)
|
61
135
|
assert direction in ["x", "y"]
|
62
136
|
|
63
137
|
t_gr = self.hopping_gr
|
64
138
|
t_x = self.hopping_x
|
65
139
|
a = self.lattice_constant
|
140
|
+
if k.ndim == 1:
|
141
|
+
k = np.expand_dims(k, axis=0)
|
66
142
|
|
67
|
-
h = np.zeros((self.number_of_bands, self.number_of_bands), dtype=np.complex64)
|
143
|
+
h = np.zeros((k.shape[0], self.number_of_bands, self.number_of_bands), dtype=np.complex64)
|
68
144
|
|
69
145
|
if direction == "x":
|
70
|
-
h[0, 1] =
|
71
|
-
|
72
|
-
|
146
|
+
h[:, 0, 1] = (
|
147
|
+
t_gr * a * np.exp(-0.5j * a / np.sqrt(3) * k[:, 1]) * np.sin(0.5 * a * k[:, 0])
|
148
|
+
)
|
149
|
+
h[:, 1, 0] = h[:, 0, 1].conjugate()
|
150
|
+
h[:, 2, 2] = (
|
73
151
|
2
|
74
152
|
* a
|
75
153
|
* t_x
|
76
|
-
* (
|
154
|
+
* (
|
155
|
+
np.sin(a * k[:, 0])
|
156
|
+
+ np.sin(0.5 * a * k[:, 0]) * np.cos(0.5 * np.sqrt(3) * a * k[:, 1])
|
157
|
+
)
|
77
158
|
)
|
78
159
|
else:
|
79
|
-
h[0, 1] = (
|
160
|
+
h[:, 0, 1] = (
|
80
161
|
-t_gr
|
81
162
|
* 1j
|
82
163
|
* a
|
83
164
|
/ np.sqrt(3)
|
84
165
|
* (
|
85
|
-
np.exp(1j * a / np.sqrt(3) * k[1])
|
86
|
-
- np.exp(-0.5j * a / np.sqrt(3) * k[1]) * np.cos(0.5 * a * k[0])
|
166
|
+
np.exp(1j * a / np.sqrt(3) * k[:, 1])
|
167
|
+
- np.exp(-0.5j * a / np.sqrt(3) * k[:, 1]) * np.cos(0.5 * a * k[:, 0])
|
87
168
|
)
|
88
169
|
)
|
89
|
-
h[1, 0] = h[0, 1].conjugate()
|
90
|
-
h[2, 2] = np.sqrt(3) * a * t_x * np.cos(0.5 * np.sqrt(3) * a * k[1])
|
91
|
-
|
92
|
-
return h
|
93
|
-
|
94
|
-
def _hamiltonian_one_point(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
|
95
|
-
t_gr = self.hopping_gr
|
96
|
-
t_x = self.hopping_x
|
97
|
-
a = self.lattice_constant
|
98
|
-
v = self.hopping_x_gr_a
|
99
|
-
mu = self.mu
|
100
|
-
|
101
|
-
h = np.zeros((self.number_of_bands, self.number_of_bands), dtype=np.complex64)
|
102
|
-
|
103
|
-
h[0, 1] = -t_gr * (
|
104
|
-
np.exp(1j * k[1] * a / np.sqrt(3))
|
105
|
-
+ 2 * np.exp(-0.5j * a / np.sqrt(3) * k[1]) * (np.cos(0.5 * a * k[0]))
|
106
|
-
)
|
107
|
-
|
108
|
-
h[1, 0] = h[0, 1].conjugate()
|
109
|
-
|
110
|
-
h[2, 0] = v
|
111
|
-
h[0, 2] = v
|
112
|
-
|
113
|
-
h[2, 2] = (
|
114
|
-
-2
|
115
|
-
* t_x
|
116
|
-
* (np.cos(a * k[0]) + 2 * np.cos(0.5 * a * k[0]) * np.cos(0.5 * np.sqrt(3) * a * k[1]))
|
117
|
-
)
|
118
|
-
h -= mu * np.eye(3, dtype=np.complex64)
|
170
|
+
h[:, 1, 0] = h[:, 0, 1].conjugate()
|
171
|
+
h[:, 2, 2] = np.sqrt(3) * a * t_x * np.cos(0.5 * np.sqrt(3) * a * k[:, 1])
|
119
172
|
|
120
|
-
return h
|
173
|
+
return h.squeeze()
|
quant_met/mean_field/graphene.py
CHANGED
@@ -4,10 +4,12 @@
|
|
4
4
|
|
5
5
|
"""Provides the implementation for Graphene."""
|
6
6
|
|
7
|
+
from typing import Any
|
8
|
+
|
7
9
|
import numpy as np
|
8
10
|
import numpy.typing as npt
|
9
11
|
|
10
|
-
from ._utils import _validate_float
|
12
|
+
from ._utils import _check_valid_array, _validate_float
|
11
13
|
from .base_hamiltonian import BaseHamiltonian
|
12
14
|
|
13
15
|
|
@@ -21,7 +23,11 @@ class GrapheneHamiltonian(BaseHamiltonian):
|
|
21
23
|
mu: float,
|
22
24
|
coulomb_gr: float,
|
23
25
|
delta: npt.NDArray[np.float64] | None = None,
|
26
|
+
*args: tuple[Any, ...],
|
27
|
+
**kwargs: tuple[dict[str, Any], ...],
|
24
28
|
) -> None:
|
29
|
+
del args
|
30
|
+
del kwargs
|
25
31
|
self.t_nn = _validate_float(t_nn, "Hopping")
|
26
32
|
if a <= 0:
|
27
33
|
msg = "Lattice constant must be positive"
|
@@ -52,46 +58,85 @@ class GrapheneHamiltonian(BaseHamiltonian):
|
|
52
58
|
def delta_orbital_basis(self, new_delta: npt.NDArray[np.float64]) -> None:
|
53
59
|
self._delta_orbital_basis = new_delta
|
54
60
|
|
55
|
-
def
|
61
|
+
def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
|
62
|
+
"""
|
63
|
+
Return the normal state Hamiltonian in orbital basis.
|
64
|
+
|
65
|
+
Parameters
|
66
|
+
----------
|
67
|
+
k : :class:`numpy.ndarray`
|
68
|
+
List of k points.
|
69
|
+
|
70
|
+
Returns
|
71
|
+
-------
|
72
|
+
:class:`numpy.ndarray`
|
73
|
+
Hamiltonian in matrix form.
|
74
|
+
|
75
|
+
"""
|
76
|
+
assert _check_valid_array(k)
|
77
|
+
t_nn = self.t_nn
|
78
|
+
a = self.a
|
79
|
+
mu = self.mu
|
80
|
+
if k.ndim == 1:
|
81
|
+
k = np.expand_dims(k, axis=0)
|
82
|
+
|
83
|
+
h = np.zeros((k.shape[0], self.number_of_bands, self.number_of_bands), dtype=np.complex64)
|
84
|
+
|
85
|
+
h[:, 0, 1] = -t_nn * (
|
86
|
+
np.exp(1j * k[:, 1] * a / np.sqrt(3))
|
87
|
+
+ 2 * np.exp(-0.5j * a / np.sqrt(3) * k[:, 1]) * (np.cos(0.5 * a * k[:, 0]))
|
88
|
+
)
|
89
|
+
h[:, 1, 0] = h[:, 0, 1].conjugate()
|
90
|
+
h[:, 0, 0] -= mu
|
91
|
+
h[:, 1, 1] -= mu
|
92
|
+
|
93
|
+
return h.squeeze()
|
94
|
+
|
95
|
+
def hamiltonian_derivative(
|
56
96
|
self, k: npt.NDArray[np.float64], direction: str
|
57
97
|
) -> npt.NDArray[np.complex64]:
|
98
|
+
"""
|
99
|
+
Deriative of the Hamiltonian.
|
100
|
+
|
101
|
+
Parameters
|
102
|
+
----------
|
103
|
+
k: :class:`numpy.ndarray`
|
104
|
+
List of k points.
|
105
|
+
direction: str
|
106
|
+
Direction for derivative, either 'x' oder 'y'.
|
107
|
+
|
108
|
+
Returns
|
109
|
+
-------
|
110
|
+
:class:`numpy.ndarray`
|
111
|
+
Derivative of Hamiltonian.
|
112
|
+
|
113
|
+
"""
|
114
|
+
assert _check_valid_array(k)
|
58
115
|
assert direction in ["x", "y"]
|
59
116
|
|
60
117
|
t_nn = self.t_nn
|
61
118
|
a = self.a
|
119
|
+
if k.ndim == 1:
|
120
|
+
k = np.expand_dims(k, axis=0)
|
62
121
|
|
63
|
-
h = np.zeros((self.number_of_bands, self.number_of_bands), dtype=np.complex64)
|
122
|
+
h = np.zeros((k.shape[0], self.number_of_bands, self.number_of_bands), dtype=np.complex64)
|
64
123
|
|
65
124
|
if direction == "x":
|
66
|
-
h[0, 1] =
|
67
|
-
|
125
|
+
h[:, 0, 1] = (
|
126
|
+
t_nn * a * np.exp(-0.5j * a / np.sqrt(3) * k[:, 1]) * np.sin(0.5 * a * k[:, 0])
|
127
|
+
)
|
128
|
+
h[:, 1, 0] = h[:, 0, 1].conjugate()
|
68
129
|
else:
|
69
|
-
h[0, 1] = (
|
130
|
+
h[:, 0, 1] = (
|
70
131
|
-t_nn
|
71
132
|
* 1j
|
72
133
|
* a
|
73
134
|
/ np.sqrt(3)
|
74
135
|
* (
|
75
|
-
np.exp(1j * a / np.sqrt(3) * k[1])
|
76
|
-
- np.exp(-0.5j * a / np.sqrt(3) * k[1]) * np.cos(0.5 * a * k[0])
|
136
|
+
np.exp(1j * a / np.sqrt(3) * k[:, 1])
|
137
|
+
- np.exp(-0.5j * a / np.sqrt(3) * k[:, 1]) * np.cos(0.5 * a * k[:, 0])
|
77
138
|
)
|
78
139
|
)
|
79
|
-
h[1, 0] = h[0, 1].conjugate()
|
80
|
-
|
81
|
-
return h
|
82
|
-
|
83
|
-
def _hamiltonian_one_point(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
|
84
|
-
t_nn = self.t_nn
|
85
|
-
a = self.a
|
86
|
-
mu = self.mu
|
87
|
-
|
88
|
-
h = np.zeros((self.number_of_bands, self.number_of_bands), dtype=np.complex64)
|
89
|
-
|
90
|
-
h[0, 1] = -t_nn * (
|
91
|
-
np.exp(1j * k[1] * a / np.sqrt(3))
|
92
|
-
+ 2 * np.exp(-0.5j * a / np.sqrt(3) * k[1]) * (np.cos(0.5 * a * k[0]))
|
93
|
-
)
|
94
|
-
h[1, 0] = h[0, 1].conjugate()
|
95
|
-
h -= mu * np.eye(2)
|
140
|
+
h[:, 1, 0] = h[:, 0, 1].conjugate()
|
96
141
|
|
97
|
-
return h
|
142
|
+
return h.squeeze()
|
@@ -44,12 +44,12 @@ def quantum_metric(
|
|
44
44
|
for n in [i for i in range(h.number_of_bands) if i != band]:
|
45
45
|
quantum_geom_tensor[i, j] += (
|
46
46
|
(
|
47
|
-
|
47
|
+
bloch[k_index][:, band].conjugate()
|
48
48
|
@ h_derivative_direction_1[k_index]
|
49
49
|
@ bloch[k_index][:, n]
|
50
50
|
)
|
51
51
|
* (
|
52
|
-
|
52
|
+
bloch[k_index][:, n].conjugate()
|
53
53
|
@ h_derivative_direction_2[k_index]
|
54
54
|
@ bloch[k_index][:, band]
|
55
55
|
)
|
@@ -57,3 +57,53 @@ def quantum_metric(
|
|
57
57
|
)
|
58
58
|
|
59
59
|
return np.real(quantum_geom_tensor) / number_k_points
|
60
|
+
|
61
|
+
|
62
|
+
def quantum_metric_bdg(
|
63
|
+
h: BaseHamiltonian, k_grid: npt.NDArray[np.float64], bands: list[int]
|
64
|
+
) -> npt.NDArray[np.float64]:
|
65
|
+
"""Calculate the quantum metric in the BdG state.
|
66
|
+
|
67
|
+
Parameters
|
68
|
+
----------
|
69
|
+
h : :class:`~quant_met.BaseHamiltonian`
|
70
|
+
Hamiltonian object.
|
71
|
+
k_grid : :class:`numpy.ndarray`
|
72
|
+
List of k points.
|
73
|
+
band : int
|
74
|
+
Index of band for which the quantum metric is calculated.
|
75
|
+
|
76
|
+
Returns
|
77
|
+
-------
|
78
|
+
:class:`numpy.ndarray`
|
79
|
+
Quantum metric in the normal state.
|
80
|
+
|
81
|
+
"""
|
82
|
+
energies, bdg_functions = h.diagonalize_bdg(k_grid)
|
83
|
+
|
84
|
+
number_k_points = len(k_grid)
|
85
|
+
|
86
|
+
quantum_geom_tensor = np.zeros(shape=(2, 2), dtype=np.complex64)
|
87
|
+
|
88
|
+
for band in bands:
|
89
|
+
for i, direction_1 in enumerate(["x", "y"]):
|
90
|
+
h_derivative_dir_1 = h.bdg_hamiltonian_derivative(k=k_grid, direction=direction_1)
|
91
|
+
for j, direction_2 in enumerate(["x", "y"]):
|
92
|
+
h_derivative_dir_2 = h.bdg_hamiltonian_derivative(k=k_grid, direction=direction_2)
|
93
|
+
for k_index in range(len(k_grid)):
|
94
|
+
for n in [i for i in range(h.number_of_bands) if i != band]:
|
95
|
+
quantum_geom_tensor[i, j] += (
|
96
|
+
(
|
97
|
+
bdg_functions[k_index][:, band].conjugate()
|
98
|
+
@ h_derivative_dir_1[k_index]
|
99
|
+
@ bdg_functions[k_index][:, n]
|
100
|
+
)
|
101
|
+
* (
|
102
|
+
bdg_functions[k_index][:, n].conjugate()
|
103
|
+
@ h_derivative_dir_2[k_index]
|
104
|
+
@ bdg_functions[k_index][:, band]
|
105
|
+
)
|
106
|
+
/ (energies[k_index][band] - energies[k_index][n]) ** 2
|
107
|
+
)
|
108
|
+
|
109
|
+
return np.real(quantum_geom_tensor) / number_k_points
|
@@ -63,7 +63,7 @@ def _current_operator(
|
|
63
63
|
for m in range(h.number_of_bands):
|
64
64
|
for n in range(h.number_of_bands):
|
65
65
|
j[m, n] = (
|
66
|
-
|
66
|
+
bloch[:, m].conjugate()
|
67
67
|
@ h.hamiltonian_derivative(direction=direction, k=k)
|
68
68
|
@ bloch[:, n]
|
69
69
|
)
|
@@ -71,34 +71,8 @@ def _current_operator(
|
|
71
71
|
return j
|
72
72
|
|
73
73
|
|
74
|
-
def _w_matrix(
|
75
|
-
h: BaseHamiltonian, k: npt.NDArray[np.float64]
|
76
|
-
) -> tuple[npt.NDArray[np.complex64], npt.NDArray[np.complex64]]:
|
77
|
-
_, bloch = h.diagonalize_nonint(k=k)
|
78
|
-
_, bdg_functions = h.diagonalize_bdg(k=k)
|
79
|
-
|
80
|
-
w_plus = np.zeros((2 * h.number_of_bands, h.number_of_bands), dtype=np.complex64)
|
81
|
-
for i in range(2 * h.number_of_bands):
|
82
|
-
for m in range(h.number_of_bands):
|
83
|
-
w_plus[i, m] = (
|
84
|
-
np.tensordot(bloch[:, m], np.array([1, 0]), axes=0).reshape(-1)
|
85
|
-
@ bdg_functions[:, i]
|
86
|
-
)
|
87
|
-
|
88
|
-
w_minus = np.zeros((2 * h.number_of_bands, h.number_of_bands), dtype=np.complex64)
|
89
|
-
for i in range(2 * h.number_of_bands):
|
90
|
-
for m in range(h.number_of_bands):
|
91
|
-
w_minus[i, m] = (
|
92
|
-
np.tensordot(np.conjugate(bloch[:, m]), np.array([0, 1]), axes=0).reshape(-1)
|
93
|
-
@ bdg_functions[:, i]
|
94
|
-
)
|
95
|
-
|
96
|
-
return w_plus, w_minus
|
97
|
-
|
98
|
-
|
99
74
|
def _c_factor(h: BaseHamiltonian, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
|
100
|
-
bdg_energies,
|
101
|
-
w_plus, w_minus = _w_matrix(h, k)
|
75
|
+
bdg_energies, bdg_functions = h.diagonalize_bdg(k)
|
102
76
|
c_mnpq = np.zeros(
|
103
77
|
shape=(
|
104
78
|
h.number_of_bands,
|
@@ -124,10 +98,10 @@ def _c_factor(h: BaseHamiltonian, k: npt.NDArray[np.float64]) -> npt.NDArray[np.
|
|
124
98
|
c_tmp -= _fermi_dirac_derivative()
|
125
99
|
|
126
100
|
c_tmp *= (
|
127
|
-
|
128
|
-
*
|
129
|
-
*
|
130
|
-
*
|
101
|
+
bdg_functions[i, m].conjugate()
|
102
|
+
* bdg_functions[j, n]
|
103
|
+
* bdg_functions[j, p].conjugate()
|
104
|
+
* bdg_functions[i, q].conjugate()
|
131
105
|
)
|
132
106
|
|
133
107
|
c_mnpq[m, n, p, q] = 2 * c_tmp
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: quant-met
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.5
|
4
4
|
Summary: Calculate superconductivity in flat-band systems.
|
5
5
|
Author: Tjark Sievers
|
6
6
|
Author-email: tsievers@physnet.uni-hamburg.de
|
@@ -9,7 +9,7 @@ Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.11
|
10
10
|
Classifier: Programming Language :: Python :: 3.12
|
11
11
|
Requires-Dist: h5py (>=3.11.0,<4.0.0)
|
12
|
-
Requires-Dist: matplotlib (>=3.9.
|
12
|
+
Requires-Dist: matplotlib (>=3.9.2,<4.0.0)
|
13
13
|
Requires-Dist: numpy (>=2.0.0,<3.0.0)
|
14
14
|
Requires-Dist: pandas (>=2.2.2,<3.0.0)
|
15
15
|
Requires-Dist: scipy (>=1.14.0,<2.0.0)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
quant_met/__init__.py,sha256=ZO1UFz1awUYTI7B9ZkBwucvDz7GMGXnLLUGnEwLBhkc,155
|
2
|
+
quant_met/mean_field/__init__.py,sha256=msHp5Y5cuHjqr_EdC9jS9JKpeAi6CBHggtxrG_psDRk,1182
|
3
|
+
quant_met/mean_field/_utils.py,sha256=plkx6eYjyYV3CT3BWwlulqW7L-Q0t1TzZTLR4k7u0dg,666
|
4
|
+
quant_met/mean_field/base_hamiltonian.py,sha256=7rNBbkoSSaIQVg4GiKDI1WaSZxJiGR26bdidh9uygzw,8812
|
5
|
+
quant_met/mean_field/eg_x.py,sha256=y_DWBoyRaHVIof_itAgHaoaFEEssY_Q9mhvsKC7DxdM,5286
|
6
|
+
quant_met/mean_field/free_energy.py,sha256=FSGCHoBO1myHGwGQ8CqGu7_08whH0Ot3ikZhBu27tyM,3444
|
7
|
+
quant_met/mean_field/graphene.py,sha256=rKD2UjB0blN4ALePk4bQlg0XahHoe_3mCqRAvEUGiqI,4162
|
8
|
+
quant_met/mean_field/quantum_metric.py,sha256=y-ky4bU566TNBxldaYWyloqojfpTODo9gbn4TPe6-4A,3902
|
9
|
+
quant_met/mean_field/superfluid_weight.py,sha256=840Fe3aHOVz1W7hi5GrX69_QxQ3vmdy3H0_B852dZqA,3971
|
10
|
+
quant_met/plotting/__init__.py,sha256=QRQ3TNb0PNQi2lWXY0LHKgYSRuegM1N3dVVs9146Zug,457
|
11
|
+
quant_met/plotting/plotting.py,sha256=iVTFZ9tQz_GalzqbQhxCiNWOhYHJM4wiZPTjXaXnApM,7326
|
12
|
+
quant_met/utils.py,sha256=Tvw_YfqjIWx0FPGSReikSnw9xfN-T2dpQZN-KPMa69A,1709
|
13
|
+
quant_met-0.0.5.dist-info/LICENSE.txt,sha256=QO_duPQihSJlaxSLxPAXo52X3esROP5wBkhxqBd1Z4E,1104
|
14
|
+
quant_met-0.0.5.dist-info/LICENSES/MIT.txt,sha256=QO_duPQihSJlaxSLxPAXo52X3esROP5wBkhxqBd1Z4E,1104
|
15
|
+
quant_met-0.0.5.dist-info/METADATA,sha256=Kh99UUBpu1y3cOU1wYektey2RuA1a5Xd_acXxMQnsyc,2598
|
16
|
+
quant_met-0.0.5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
17
|
+
quant_met-0.0.5.dist-info/RECORD,,
|
quant_met-0.0.3.dist-info/RECORD
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
quant_met/__init__.py,sha256=ZO1UFz1awUYTI7B9ZkBwucvDz7GMGXnLLUGnEwLBhkc,155
|
2
|
-
quant_met/mean_field/__init__.py,sha256=kBkGItunNits1SrSMRIfKkqeSXvzbUJQS-OkcV-0zmc,1136
|
3
|
-
quant_met/mean_field/_utils.py,sha256=plkx6eYjyYV3CT3BWwlulqW7L-Q0t1TzZTLR4k7u0dg,666
|
4
|
-
quant_met/mean_field/base_hamiltonian.py,sha256=YvuUD_RxZVS7yWIJrkylbaOieslz86zrQa7gRWM-6ow,8505
|
5
|
-
quant_met/mean_field/eg_x.py,sha256=hv4gTOnqfLAi_OR3uSZlzph-vrRqnhnCqz3_qJzY8nw,4003
|
6
|
-
quant_met/mean_field/free_energy.py,sha256=FSGCHoBO1myHGwGQ8CqGu7_08whH0Ot3ikZhBu27tyM,3444
|
7
|
-
quant_met/mean_field/graphene.py,sha256=lR_T7TdJiBA_8leG6aUQ4hllxKnjI5qsLVCUUKU-jpw,3025
|
8
|
-
quant_met/mean_field/quantum_metric.py,sha256=ohTs1IzReXFMj03QOKlvlenM94VJjmyAyd4KicHL5gI,2002
|
9
|
-
quant_met/mean_field/superfluid_weight.py,sha256=egW9f3zR_NC5hLTNOdw_GA3fsKOE-L45LDSze2eGcoY,4899
|
10
|
-
quant_met/plotting/__init__.py,sha256=QRQ3TNb0PNQi2lWXY0LHKgYSRuegM1N3dVVs9146Zug,457
|
11
|
-
quant_met/plotting/plotting.py,sha256=iVTFZ9tQz_GalzqbQhxCiNWOhYHJM4wiZPTjXaXnApM,7326
|
12
|
-
quant_met/utils.py,sha256=Tvw_YfqjIWx0FPGSReikSnw9xfN-T2dpQZN-KPMa69A,1709
|
13
|
-
quant_met-0.0.3.dist-info/LICENSE.txt,sha256=QO_duPQihSJlaxSLxPAXo52X3esROP5wBkhxqBd1Z4E,1104
|
14
|
-
quant_met-0.0.3.dist-info/LICENSES/MIT.txt,sha256=QO_duPQihSJlaxSLxPAXo52X3esROP5wBkhxqBd1Z4E,1104
|
15
|
-
quant_met-0.0.3.dist-info/METADATA,sha256=dB9mP1Ytt6ptRbse_R2-8TcNKFWzUJVe0tMsqIQPReI,2598
|
16
|
-
quant_met-0.0.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
17
|
-
quant_met-0.0.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|