quant-met 0.0.2__py3-none-any.whl → 0.0.3__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 CHANGED
@@ -1,7 +1,5 @@
1
- # SPDX-FileCopyrightText: 2024-present Tjark <tjarksievers@icloud.com>
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
4
 
5
- import numpy as np
6
-
7
- np.seterr(all="ignore")
5
+ """quant-met, a package to treat superconductivity in flat-band systems."""
@@ -0,0 +1,60 @@
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """
6
+ Mean field treatment (:mod:`quant_met.mean_field`)
7
+ ==================================================
8
+
9
+ Hamiltonians
10
+ ------------
11
+
12
+ Base
13
+
14
+ .. autosummary::
15
+ :toctree: generated/
16
+
17
+ BaseHamiltonian
18
+
19
+ .. autosummary::
20
+ :toctree: generated/
21
+
22
+ GrapheneHamiltonian
23
+ EGXHamiltonian
24
+
25
+
26
+ Functions
27
+ ---------
28
+
29
+ .. autosummary::
30
+ :toctree: generated/
31
+
32
+ superfluid_weight
33
+ quantum_metric
34
+ free_energy
35
+ free_energy_uniform_pairing
36
+ """ # noqa: D205, D400
37
+
38
+ from .base_hamiltonian import BaseHamiltonian
39
+ from .eg_x import EGXHamiltonian
40
+ from .free_energy import (
41
+ free_energy,
42
+ free_energy_complex_gap,
43
+ free_energy_real_gap,
44
+ free_energy_uniform_pairing,
45
+ )
46
+ from .graphene import GrapheneHamiltonian
47
+ from .quantum_metric import quantum_metric
48
+ from .superfluid_weight import superfluid_weight
49
+
50
+ __all__ = [
51
+ "superfluid_weight",
52
+ "quantum_metric",
53
+ "free_energy",
54
+ "free_energy_complex_gap",
55
+ "free_energy_real_gap",
56
+ "free_energy_uniform_pairing",
57
+ "BaseHamiltonian",
58
+ "GrapheneHamiltonian",
59
+ "EGXHamiltonian",
60
+ ]
@@ -0,0 +1,27 @@
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ from typing import Any
6
+
7
+ import numpy as np
8
+ import numpy.typing as npt
9
+
10
+
11
+ def _check_valid_array(array_in: npt.NDArray[Any]) -> bool:
12
+ if np.isnan(array_in).any() or np.isinf(array_in).any():
13
+ msg = "k is NaN or Infinity"
14
+ raise ValueError(msg)
15
+
16
+ return True
17
+
18
+
19
+ def _validate_float(float_in: float, parameter_name: str) -> float:
20
+ if np.isinf(float_in):
21
+ msg = f"{parameter_name} must not be Infinity"
22
+ raise ValueError(msg)
23
+ if np.isnan(float_in):
24
+ msg = f"{parameter_name} must not be NaN"
25
+ raise ValueError(msg)
26
+
27
+ return float_in
@@ -1,3 +1,9 @@
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """Provides the base class for Hamiltonians."""
6
+
1
7
  import pathlib
2
8
  from abc import ABC, abstractmethod
3
9
 
@@ -6,6 +12,8 @@ import numpy as np
6
12
  import numpy.typing as npt
7
13
  import pandas as pd
8
14
 
15
+ from ._utils import _check_valid_array
16
+
9
17
 
10
18
  class BaseHamiltonian(ABC):
11
19
  """Base class for Hamiltonians."""
@@ -13,26 +21,40 @@ class BaseHamiltonian(ABC):
13
21
  @property
14
22
  @abstractmethod
15
23
  def number_of_bands(self) -> int:
24
+ """Number of bands in the model."""
16
25
  raise NotImplementedError
17
26
 
18
27
  @property
19
- @abstractmethod
20
28
  def coloumb_orbital_basis(self) -> npt.NDArray[np.float64]:
29
+ """
30
+ Coloumb interaction split up in orbitals.
31
+
32
+ Returns
33
+ -------
34
+ :class:`numpy.ndarray`
35
+
36
+ """
21
37
  raise NotImplementedError
22
38
 
23
39
  @property
24
- def delta_orbital_basis(self) -> npt.NDArray[np.float64]:
40
+ def delta_orbital_basis(self) -> npt.NDArray[np.complex64]:
41
+ """
42
+ Order parameter in orbital basis.
43
+
44
+ Returns
45
+ -------
46
+ :class:`numpy.ndarray`
47
+
48
+ """
25
49
  raise NotImplementedError
26
50
 
27
51
  @delta_orbital_basis.setter
28
52
  @abstractmethod
29
- def delta_orbital_basis(self, new_delta: npt.NDArray[np.float64]) -> None:
53
+ def delta_orbital_basis(self, new_delta: npt.NDArray[np.complex64]) -> None:
30
54
  raise NotImplementedError
31
55
 
32
56
  @abstractmethod
33
- def _hamiltonian_one_point(
34
- self, k_point: npt.NDArray[np.float64]
35
- ) -> npt.NDArray[np.complex64]:
57
+ def _hamiltonian_one_point(self, k_point: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
36
58
  raise NotImplementedError
37
59
 
38
60
  @abstractmethod
@@ -49,15 +71,23 @@ class BaseHamiltonian(ABC):
49
71
  )
50
72
  np.fill_diagonal(delta_matrix, self.delta_orbital_basis)
51
73
 
52
- h = np.block(
74
+ return np.block(
53
75
  [
54
76
  [self.hamiltonian(k_point), delta_matrix],
55
77
  [np.conjugate(delta_matrix), -np.conjugate(self.hamiltonian(-k_point))],
56
78
  ]
57
79
  )
58
- return h
59
80
 
60
81
  def save(self, filename: pathlib.Path) -> None:
82
+ """
83
+ Save the Hamiltonian as a HDF5 file.
84
+
85
+ Parameters
86
+ ----------
87
+ filename : :class:`pathlib.Path`
88
+ Filename to save the Hamiltonian to, should end in .hdf5
89
+
90
+ """
61
91
  with h5py.File(f"{filename}", "a") as f:
62
92
  f.create_dataset("delta", data=self.delta_orbital_basis)
63
93
  for key, value in vars(self).items():
@@ -66,17 +96,39 @@ class BaseHamiltonian(ABC):
66
96
 
67
97
  @classmethod
68
98
  def from_file(cls, filename: pathlib.Path) -> "BaseHamiltonian":
69
- config_dict = {}
99
+ """
100
+ Initialise a Hamiltonian from a HDF5 file.
101
+
102
+ Parameters
103
+ ----------
104
+ filename : :class:`pathlib.Path`
105
+ File to load the Hamiltonian from.
106
+
107
+ """
70
108
  with h5py.File(f"{filename}", "r") as f:
109
+ config_dict = dict(f.attrs.items())
71
110
  config_dict["delta"] = f["delta"][()]
72
- for key, value in f.attrs.items():
73
- config_dict[key] = value
74
111
 
75
112
  return cls(**config_dict)
76
113
 
77
114
  def bdg_hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
115
+ """
116
+ Bogoliuobov de Genne Hamiltonian.
117
+
118
+ Parameters
119
+ ----------
120
+ k : :class:`numpy.ndarray`
121
+ List of k points.
122
+
123
+ Returns
124
+ -------
125
+ :class:`numpy.ndarray`
126
+ BdG Hamiltonian.
127
+
128
+ """
78
129
  if np.isnan(k).any() or np.isinf(k).any():
79
- raise ValueError("k is NaN or Infinity")
130
+ msg = "k is NaN or Infinity"
131
+ raise ValueError(msg)
80
132
  if k.ndim == 1:
81
133
  h = self._bdg_hamiltonian_one_point(k)
82
134
  else:
@@ -84,8 +136,21 @@ class BaseHamiltonian(ABC):
84
136
  return h
85
137
 
86
138
  def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
87
- if np.isnan(k).any() or np.isinf(k).any():
88
- raise ValueError("k is NaN or Infinity")
139
+ """
140
+ Return the normal state Hamiltonian in orbital basis.
141
+
142
+ Parameters
143
+ ----------
144
+ k : :class:`numpy.ndarray`
145
+ List of k points.
146
+
147
+ Returns
148
+ -------
149
+ :class:`numpy.ndarray`
150
+ Hamiltonian in matrix form.
151
+
152
+ """
153
+ assert _check_valid_array(k)
89
154
  if k.ndim == 1:
90
155
  h = self._hamiltonian_one_point(k)
91
156
  else:
@@ -95,19 +160,48 @@ class BaseHamiltonian(ABC):
95
160
  def hamiltonian_derivative(
96
161
  self, k: npt.NDArray[np.float64], direction: str
97
162
  ) -> npt.NDArray[np.complex64]:
98
- if np.isnan(k).any() or np.isinf(k).any():
99
- raise ValueError("k is NaN or Infinity")
163
+ """
164
+ Deriative of the Hamiltonian.
165
+
166
+ Parameters
167
+ ----------
168
+ k: :class:`numpy.ndarray`
169
+ List of k points.
170
+ direction: str
171
+ Direction for derivative, either 'x' oder 'y'.
172
+
173
+ Returns
174
+ -------
175
+ :class:`numpy.ndarray`
176
+ Derivative of Hamiltonian.
177
+
178
+ """
179
+ assert _check_valid_array(k)
100
180
  if k.ndim == 1:
101
181
  h = self._hamiltonian_derivative_one_point(k, direction)
102
182
  else:
103
- h = np.array(
104
- [self._hamiltonian_derivative_one_point(k, direction) for k in k]
105
- )
183
+ h = np.array([self._hamiltonian_derivative_one_point(k, direction) for k in k])
106
184
  return h
107
185
 
108
186
  def diagonalize_nonint(
109
187
  self, k: npt.NDArray[np.float64]
110
188
  ) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
189
+ """
190
+ Diagonalize the normal state Hamiltonian.
191
+
192
+ Parameters
193
+ ----------
194
+ k : :class:`numpy.ndarray`
195
+ List of k points.
196
+
197
+ Returns
198
+ -------
199
+ :class:`numpy.ndarray`
200
+ Eigenvalues of the normal state Hamiltonian.
201
+ :class:`numpy.ndarray`
202
+ Diagonalising matrix of the normal state Hamiltonian.
203
+
204
+ """
111
205
  k_point_matrix = self.hamiltonian(k)
112
206
 
113
207
  if k.ndim == 1:
@@ -119,16 +213,30 @@ class BaseHamiltonian(ABC):
119
213
  )
120
214
  band_energies = np.zeros((len(k), self.number_of_bands))
121
215
 
122
- for i, k in enumerate(k):
123
- band_energies[i], bloch_wavefunctions[i] = np.linalg.eigh(
124
- k_point_matrix[i]
125
- )
216
+ for i in range(len(k)):
217
+ band_energies[i], bloch_wavefunctions[i] = np.linalg.eigh(k_point_matrix[i])
126
218
 
127
219
  return band_energies, bloch_wavefunctions
128
220
 
129
221
  def diagonalize_bdg(
130
222
  self, k: npt.NDArray[np.float64]
131
223
  ) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.complex64]]:
224
+ """
225
+ Diagonalize the BdG Hamiltonian.
226
+
227
+ Parameters
228
+ ----------
229
+ k : :class:`numpy.ndarray`
230
+ List of k points.
231
+
232
+ Returns
233
+ -------
234
+ :class:`numpy.ndarray`
235
+ Eigenvalues of the BdG Hamiltonian.
236
+ :class:`numpy.ndarray`
237
+ Diagonalising matrix of the BdG Hamiltonian.
238
+
239
+ """
132
240
  bdg_matrix = self.bdg_hamiltonian(k)
133
241
 
134
242
  if k.ndim == 1:
@@ -140,7 +248,7 @@ class BaseHamiltonian(ABC):
140
248
  )
141
249
  bdg_energies = np.zeros((len(k), 2 * self.number_of_bands))
142
250
 
143
- for i, k in enumerate(k):
251
+ for i in range(len(k)):
144
252
  bdg_energies[i], bdg_wavefunctions[i] = np.linalg.eigh(bdg_matrix[i])
145
253
 
146
254
  return bdg_energies, bdg_wavefunctions
@@ -150,6 +258,22 @@ class BaseHamiltonian(ABC):
150
258
  k: npt.NDArray[np.float64],
151
259
  overlaps: tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]] | None = None,
152
260
  ) -> pd.DataFrame:
261
+ """
262
+ Calculate the band structure.
263
+
264
+ Parameters
265
+ ----------
266
+ k : :class:`numpy.ndarray`
267
+ List of k points.
268
+ overlaps : tuple(:class:`numpy.ndarray`, :class:`numpy.ndarray`), optional
269
+ Overlaps.
270
+
271
+ Returns
272
+ -------
273
+ `pandas.DataFrame`
274
+ Band structure.
275
+
276
+ """
153
277
  k_point_matrix = self.hamiltonian(k)
154
278
 
155
279
  results = pd.DataFrame(
@@ -157,14 +281,14 @@ class BaseHamiltonian(ABC):
157
281
  dtype=float,
158
282
  )
159
283
 
160
- for i, k in enumerate(k):
284
+ for i in range(len(k)):
161
285
  energies, eigenvectors = np.linalg.eigh(k_point_matrix[i])
162
286
 
163
287
  for band_index in range(self.number_of_bands):
164
- results.at[i, f"band_{band_index}"] = energies[band_index]
288
+ results.loc[i, f"band_{band_index}"] = energies[band_index]
165
289
 
166
290
  if overlaps is not None:
167
- results.at[i, f"wx_{band_index}"] = (
291
+ results.loc[i, f"wx_{band_index}"] = (
168
292
  np.abs(np.dot(eigenvectors[:, band_index], overlaps[0])) ** 2
169
293
  - np.abs(np.dot(eigenvectors[:, band_index], overlaps[1])) ** 2
170
294
  )
@@ -0,0 +1,120 @@
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """Provides the implementation for the EG-X model."""
6
+
7
+ import numpy as np
8
+ import numpy.typing as npt
9
+
10
+ from ._utils import _validate_float
11
+ from .base_hamiltonian import BaseHamiltonian
12
+
13
+
14
+ class EGXHamiltonian(BaseHamiltonian):
15
+ """Hamiltonian for the EG-X model."""
16
+
17
+ def __init__(
18
+ self,
19
+ hopping_gr: float,
20
+ hopping_x: float,
21
+ hopping_x_gr_a: float,
22
+ lattice_constant: float,
23
+ mu: float,
24
+ coloumb_gr: float,
25
+ coloumb_x: float,
26
+ delta: npt.NDArray[np.complex64] | None = None,
27
+ ) -> None:
28
+ self.hopping_gr = _validate_float(hopping_gr, "Hopping graphene")
29
+ self.hopping_x = _validate_float(hopping_x, "Hopping impurity")
30
+ self.hopping_x_gr_a = _validate_float(hopping_x_gr_a, "Hybridisation")
31
+ self.lattice_constant = _validate_float(lattice_constant, "Lattice constant")
32
+ self.mu = _validate_float(mu, "Chemical potential")
33
+ self.coloumb_gr = _validate_float(coloumb_gr, "Coloumb interaction graphene")
34
+ self.coloumb_x = _validate_float(coloumb_x, "Coloumb interaction impurity")
35
+ self._coloumb_orbital_basis = np.array([self.coloumb_gr, self.coloumb_gr, self.coloumb_x])
36
+ self._number_of_bands = 3
37
+ if delta is None:
38
+ self._delta_orbital_basis = np.zeros(3, dtype=np.complex64)
39
+ else:
40
+ self._delta_orbital_basis = delta
41
+
42
+ @property
43
+ def coloumb_orbital_basis(self) -> npt.NDArray[np.float64]: # noqa: D102
44
+ return self._coloumb_orbital_basis
45
+
46
+ @property
47
+ def delta_orbital_basis(self) -> npt.NDArray[np.complex64]: # noqa: D102
48
+ return self._delta_orbital_basis
49
+
50
+ @delta_orbital_basis.setter
51
+ def delta_orbital_basis(self, new_delta: npt.NDArray[np.complex64]) -> None:
52
+ self._delta_orbital_basis = new_delta
53
+
54
+ @property
55
+ def number_of_bands(self) -> int: # noqa: D102
56
+ return self._number_of_bands
57
+
58
+ def _hamiltonian_derivative_one_point(
59
+ self, k: npt.NDArray[np.float64], direction: str
60
+ ) -> npt.NDArray[np.complex64]:
61
+ assert direction in ["x", "y"]
62
+
63
+ t_gr = self.hopping_gr
64
+ t_x = self.hopping_x
65
+ a = self.lattice_constant
66
+
67
+ h = np.zeros((self.number_of_bands, self.number_of_bands), dtype=np.complex64)
68
+
69
+ if direction == "x":
70
+ h[0, 1] = t_gr * a * np.exp(-0.5j * a / np.sqrt(3) * k[1]) * np.sin(0.5 * a * k[0])
71
+ h[1, 0] = h[0, 1].conjugate()
72
+ h[2, 2] = (
73
+ 2
74
+ * a
75
+ * t_x
76
+ * (np.sin(a * k[0]) + np.sin(0.5 * a * k[0]) * np.cos(0.5 * np.sqrt(3) * a * k[1]))
77
+ )
78
+ else:
79
+ h[0, 1] = (
80
+ -t_gr
81
+ * 1j
82
+ * a
83
+ / np.sqrt(3)
84
+ * (
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])
87
+ )
88
+ )
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)
119
+
120
+ return h
@@ -0,0 +1,130 @@
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """Functions to calculate the free energy of a BdG Hamiltonian."""
6
+
7
+ import numpy as np
8
+ import numpy.typing as npt
9
+
10
+ from .base_hamiltonian import BaseHamiltonian
11
+
12
+
13
+ def free_energy(
14
+ hamiltonian: BaseHamiltonian,
15
+ k_points: npt.NDArray[np.float64],
16
+ ) -> float:
17
+ """Calculate the free energy of a BdG Hamiltonian.
18
+
19
+ Parameters
20
+ ----------
21
+ hamiltonian : :class:`BaseHamiltonian`
22
+ Hamiltonian to be evaluated.
23
+ k_points : :class:`numpy.ndarray`
24
+ List of k points
25
+
26
+ Returns
27
+ -------
28
+ float
29
+ Free energy from the BdG Hamiltonian.
30
+
31
+ """
32
+ number_k_points = len(k_points)
33
+ bdg_energies, _ = hamiltonian.diagonalize_bdg(k_points)
34
+
35
+ k_array = np.array(
36
+ [
37
+ np.sum(np.abs(bdg_energies[k_index][0 : hamiltonian.number_of_bands]))
38
+ for k_index in range(number_k_points)
39
+ ]
40
+ )
41
+
42
+ integral: float = -np.sum(k_array, axis=-1) / number_k_points + np.sum(
43
+ np.power(np.abs(hamiltonian.delta_orbital_basis), 2) / hamiltonian.coloumb_orbital_basis
44
+ )
45
+
46
+ return integral
47
+
48
+
49
+ def free_energy_complex_gap(
50
+ delta_vector: npt.NDArray[np.float64],
51
+ hamiltonian: BaseHamiltonian,
52
+ k_points: npt.NDArray[np.float64],
53
+ ) -> float:
54
+ """Calculate the free energy of a BdG Hamiltonian, with a complex order parameter.
55
+
56
+ Parameters
57
+ ----------
58
+ delta_vector : :class:`numpy.ndarray`
59
+ Delta in orbital basis, with consecutive floats getting converted into one complex number,
60
+ so [a, b, c, d] -> [a+b*j, c+d*j].
61
+ hamiltonian : :class:`BaseHamiltonian`
62
+ Hamiltonian to be evaluated.
63
+ k_points : :class:`numpy.ndarray`
64
+ List of k points
65
+
66
+ Returns
67
+ -------
68
+ float
69
+ Free energy from the BdG Hamiltonian.
70
+
71
+ """
72
+ hamiltonian.delta_orbital_basis = delta_vector[0::2] + 1j * delta_vector[1::2]
73
+
74
+ return free_energy(hamiltonian=hamiltonian, k_points=k_points)
75
+
76
+
77
+ def free_energy_real_gap(
78
+ delta_vector: npt.NDArray[np.float64],
79
+ hamiltonian: BaseHamiltonian,
80
+ k_points: npt.NDArray[np.float64],
81
+ ) -> float:
82
+ """Calculate the free energy of a BdG Hamiltonian, with a real order parameter.
83
+
84
+ Parameters
85
+ ----------
86
+ delta_vector : :class:`numpy.ndarray`
87
+ Delta in orbital basis.
88
+ hamiltonian : :class:`BaseHamiltonian`
89
+ Hamiltonian to be evaluated.
90
+ k_points : :class:`numpy.ndarray`
91
+ List of k points
92
+
93
+ Returns
94
+ -------
95
+ float
96
+ Free energy from the BdG Hamiltonian.
97
+
98
+ """
99
+ hamiltonian.delta_orbital_basis = delta_vector.astype(np.complex64)
100
+
101
+ return free_energy(hamiltonian=hamiltonian, k_points=k_points)
102
+
103
+
104
+ def free_energy_uniform_pairing(
105
+ delta: float,
106
+ hamiltonian: BaseHamiltonian,
107
+ k_points: npt.NDArray[np.float64],
108
+ ) -> float:
109
+ """Calculate the free energy of a BdG Hamiltonian, with uniform pairing constraint.
110
+
111
+ Parameters
112
+ ----------
113
+ delta : float
114
+ Delta.
115
+ hamiltonian : :class:`BaseHamiltonian`
116
+ Hamiltonian to be evaluated.
117
+ k_points : :class:`numpy.ndarray`
118
+ List of k points
119
+
120
+ Returns
121
+ -------
122
+ float
123
+ Free energy from the BdG Hamiltonian.
124
+
125
+ """
126
+ hamiltonian.delta_orbital_basis = np.full(
127
+ hamiltonian.number_of_bands, fill_value=delta, dtype=np.float64
128
+ ).astype(np.complex64)
129
+
130
+ return free_energy(hamiltonian=hamiltonian, k_points=k_points)