quant-met 0.0.7__py3-none-any.whl → 0.0.8__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.
@@ -0,0 +1,22 @@
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """
6
+ Command-Line-Interface (:mod:`quant_met.cli`)
7
+ =============================================
8
+
9
+ Functions
10
+ ---------
11
+
12
+ .. autosummary::
13
+ :toctree: generated/
14
+
15
+ cli
16
+ """ # noqa: D205, D400
17
+
18
+ from .main import cli
19
+
20
+ __all__ = [
21
+ "cli",
22
+ ]
quant_met/cli/main.py ADDED
@@ -0,0 +1,34 @@
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """Command line interface."""
6
+
7
+ import sys
8
+ from typing import TextIO
9
+
10
+ import click
11
+ import yaml
12
+
13
+ from quant_met.parameters import Parameters
14
+
15
+ from .scf import scf
16
+
17
+
18
+ @click.command()
19
+ @click.argument("input-file", type=click.File("r"))
20
+ def cli(input_file: TextIO) -> None:
21
+ """Command line interface for quant-met.
22
+
23
+ Parameters
24
+ ----------
25
+ input_file
26
+ """
27
+ params = Parameters(**yaml.safe_load(input_file))
28
+
29
+ match params.control.calculation:
30
+ case "scf":
31
+ scf(params)
32
+ case _:
33
+ print(f"Calculation {params.control.calculation} not found.")
34
+ sys.exit(1)
quant_met/cli/scf.py ADDED
@@ -0,0 +1,42 @@
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
+ from pathlib import Path
8
+
9
+ import numpy as np
10
+ from pydantic import BaseModel
11
+
12
+ from quant_met import mean_field
13
+ from quant_met.mean_field.hamiltonians import BaseHamiltonian
14
+ from quant_met.parameters import Parameters
15
+
16
+
17
+ def _hamiltonian_factory(classname: str, parameters: BaseModel) -> BaseHamiltonian:
18
+ """Create a hamiltonian by its class name."""
19
+ from quant_met.mean_field import hamiltonians
20
+
21
+ cls = getattr(hamiltonians, classname)
22
+ h: BaseHamiltonian = cls(parameters)
23
+ return h
24
+
25
+
26
+ def scf(parameters: Parameters) -> None:
27
+ """Self-consistent calculation for the order parameter."""
28
+ result_path = Path(parameters.control.outdir)
29
+ result_path.mkdir(exist_ok=True, parents=True)
30
+ h = _hamiltonian_factory(parameters=parameters.model, classname=parameters.model.name)
31
+ solved_h = mean_field.self_consistency_loop(
32
+ h=h,
33
+ k_space_grid=h.lattice.generate_bz_grid(
34
+ ncols=parameters.k_points.nk1, nrows=parameters.k_points.nk2
35
+ ),
36
+ beta=np.float64(parameters.control.beta),
37
+ epsilon=parameters.control.conv_treshold,
38
+ q=parameters.control.q,
39
+ )
40
+ print(solved_h.delta_orbital_basis)
41
+ result_file = result_path / f"{parameters.control.prefix}.hdf5"
42
+ solved_h.save(filename=result_file)
@@ -15,12 +15,21 @@ Functions
15
15
  :toctree: generated/
16
16
 
17
17
  generate_bz_path
18
- Graphene
18
+
19
+ Classes
20
+ -------
21
+
22
+ .. autosummary::
23
+ :toctree: generated/
24
+
25
+ BaseLattice
26
+ GrapheneLattice
27
+ SquareLattice
19
28
  """ # noqa: D205, D400
20
29
 
21
30
  from .base_lattice import BaseLattice
22
31
  from .bz_path import generate_bz_path
23
- from .graphene import Graphene
32
+ from .graphene import GrapheneLattice
24
33
  from .square import SquareLattice
25
34
 
26
- __all__ = ["generate_bz_path", "BaseLattice", "Graphene", "SquareLattice"]
35
+ __all__ = ["generate_bz_path", "BaseLattice", "GrapheneLattice", "SquareLattice"]
@@ -10,7 +10,7 @@ import numpy.typing as npt
10
10
  from .base_lattice import BaseLattice
11
11
 
12
12
 
13
- class Graphene(BaseLattice):
13
+ class GrapheneLattice(BaseLattice):
14
14
  """Lattice geometry for Graphene."""
15
15
 
16
16
  def __init__(self, lattice_constant: np.float64) -> None:
@@ -6,21 +6,13 @@
6
6
  Mean field treatment (:mod:`quant_met.mean_field`)
7
7
  ==================================================
8
8
 
9
- Hamiltonians
10
- ------------
11
-
12
- Base
9
+ Submodules
10
+ ----------
13
11
 
14
12
  .. autosummary::
15
- :toctree: generated/
13
+ :toctree: generated/
16
14
 
17
- BaseHamiltonian
18
-
19
- .. autosummary::
20
- :toctree: generated/
21
-
22
- GrapheneHamiltonian
23
- EGXHamiltonian
15
+ hamiltonians
24
16
 
25
17
 
26
18
  Functions
@@ -31,20 +23,12 @@ Functions
31
23
 
32
24
  superfluid_weight
33
25
  quantum_metric
34
- free_energy
35
- free_energy_uniform_pairing
26
+ quantum_metric_bdg
27
+ self_consistency_loop
36
28
  """ # noqa: D205, D400
37
29
 
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 .one_band_tight_binding import OneBandTightBindingHamiltonian
30
+ from quant_met.mean_field import hamiltonians
31
+
48
32
  from .quantum_metric import quantum_metric, quantum_metric_bdg
49
33
  from .self_consistency import self_consistency_loop
50
34
  from .superfluid_weight import superfluid_weight
@@ -53,13 +37,6 @@ __all__ = [
53
37
  "superfluid_weight",
54
38
  "quantum_metric",
55
39
  "quantum_metric_bdg",
56
- "free_energy",
57
- "free_energy_complex_gap",
58
- "free_energy_real_gap",
59
- "free_energy_uniform_pairing",
60
40
  "self_consistency_loop",
61
- "BaseHamiltonian",
62
- "GrapheneHamiltonian",
63
- "EGXHamiltonian",
64
- "OneBandTightBindingHamiltonian",
41
+ "hamiltonians",
65
42
  ]
@@ -0,0 +1,34 @@
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """
6
+ Hamiltonians (:mod:`quant_met.mean_field.hamiltonians`)
7
+ =======================================================
8
+
9
+ Base
10
+
11
+ .. autosummary::
12
+ :toctree: hamiltonians/
13
+
14
+ BaseHamiltonian
15
+
16
+ .. autosummary::
17
+ :toctree: hamiltonians/
18
+
19
+ Graphene
20
+ DressedGraphene
21
+ OneBand
22
+ """ # noqa: D205, D400
23
+
24
+ from .base_hamiltonian import BaseHamiltonian
25
+ from .dressed_graphene import DressedGraphene
26
+ from .graphene import Graphene
27
+ from .one_band_tight_binding import OneBand
28
+
29
+ __all__ = [
30
+ "BaseHamiltonian",
31
+ "Graphene",
32
+ "DressedGraphene",
33
+ "OneBand",
34
+ ]
@@ -12,19 +12,51 @@ import numpy as np
12
12
  import numpy.typing as npt
13
13
  import pandas as pd
14
14
 
15
- from ._utils import _check_valid_array
15
+ from quant_met.geometry import BaseLattice
16
+ from quant_met.mean_field._utils import _check_valid_array
16
17
 
17
18
 
18
19
  class BaseHamiltonian(ABC):
19
20
  """Base class for Hamiltonians."""
20
21
 
22
+ @property
23
+ @abstractmethod
24
+ def name(self) -> str:
25
+ """Name of the model.
26
+
27
+ Returns
28
+ -------
29
+ str
30
+
31
+ """
32
+ raise NotImplementedError
33
+
21
34
  @property
22
35
  @abstractmethod
23
36
  def number_of_bands(self) -> int:
24
- """Number of bands in the model."""
37
+ """Number of bands.
38
+
39
+ Returns
40
+ -------
41
+ int
42
+
43
+ """
44
+ raise NotImplementedError
45
+
46
+ @property
47
+ @abstractmethod
48
+ def lattice(self) -> BaseLattice:
49
+ """Lattice.
50
+
51
+ Returns
52
+ -------
53
+ BaseLattice
54
+
55
+ """
25
56
  raise NotImplementedError
26
57
 
27
58
  @property
59
+ @abstractmethod
28
60
  def hubbard_int_orbital_basis(self) -> npt.NDArray[np.float64]:
29
61
  """
30
62
  hubbard_int interaction split up in orbitals.
@@ -37,6 +69,7 @@ class BaseHamiltonian(ABC):
37
69
  raise NotImplementedError
38
70
 
39
71
  @property
72
+ @abstractmethod
40
73
  def delta_orbital_basis(self) -> npt.NDArray[np.complex64]:
41
74
  """
42
75
  Order parameter in orbital basis.
@@ -103,13 +136,14 @@ class BaseHamiltonian(ABC):
103
136
  Filename to save the Hamiltonian to, should end in .hdf5
104
137
 
105
138
  """
106
- with h5py.File(f"{filename}", "w") as f:
139
+ with h5py.File(f"{filename.absolute()}", "w") as f:
107
140
  f.create_dataset("delta", data=self.delta_orbital_basis)
108
141
  for key, value in vars(self).items():
109
142
  if not key.startswith("_"):
110
143
  f.attrs[key] = value
111
144
 
112
145
  @classmethod
146
+ @abstractmethod
113
147
  def from_file(cls, filename: pathlib.Path) -> "BaseHamiltonian":
114
148
  """
115
149
  Initialise a Hamiltonian from a HDF5 file.
@@ -120,18 +154,17 @@ class BaseHamiltonian(ABC):
120
154
  File to load the Hamiltonian from.
121
155
 
122
156
  """
123
- with h5py.File(f"{filename}", "r") as f:
124
- config_dict = dict(f.attrs.items())
125
- config_dict["delta"] = f["delta"][()]
126
-
127
- return cls(**config_dict)
157
+ raise NotImplementedError
128
158
 
129
- def bdg_hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
159
+ def bdg_hamiltonian(
160
+ self, k: npt.NDArray[np.float64], q: npt.NDArray[np.float64] | None = None
161
+ ) -> npt.NDArray[np.complex64]:
130
162
  """
131
163
  Bogoliuobov de Genne Hamiltonian.
132
164
 
133
165
  Parameters
134
166
  ----------
167
+ q
135
168
  k : :class:`numpy.ndarray`
136
169
  List of k points.
137
170
 
@@ -144,6 +177,8 @@ class BaseHamiltonian(ABC):
144
177
  assert _check_valid_array(k)
145
178
  if k.ndim == 1:
146
179
  k = np.expand_dims(k, axis=0)
180
+ if q is None:
181
+ q = np.array([0, 0])
147
182
 
148
183
  h = np.zeros(
149
184
  (k.shape[0], 2 * self.number_of_bands, 2 * self.number_of_bands), dtype=np.complex64
@@ -154,10 +189,11 @@ class BaseHamiltonian(ABC):
154
189
  :,
155
190
  self.number_of_bands : 2 * self.number_of_bands,
156
191
  self.number_of_bands : 2 * self.number_of_bands,
157
- ] = -self.hamiltonian(-k).conjugate()
192
+ ] = -self.hamiltonian(q - k).conjugate()
158
193
 
159
194
  for i in range(self.number_of_bands):
160
195
  h[:, self.number_of_bands + i, i] = self.delta_orbital_basis[i]
196
+
161
197
  h[:, 0 : self.number_of_bands, self.number_of_bands : self.number_of_bands * 2] = (
162
198
  h[:, self.number_of_bands : self.number_of_bands * 2, 0 : self.number_of_bands]
163
199
  .copy()
@@ -240,13 +276,14 @@ class BaseHamiltonian(ABC):
240
276
  return band_energies.squeeze(), bloch_wavefunctions.squeeze()
241
277
 
242
278
  def diagonalize_bdg(
243
- self, k: npt.NDArray[np.float64]
279
+ self, k: npt.NDArray[np.float64], q: npt.NDArray[np.float64] | None = None
244
280
  ) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.complex64]]:
245
281
  """
246
282
  Diagonalize the BdG Hamiltonian.
247
283
 
248
284
  Parameters
249
285
  ----------
286
+ q
250
287
  k : :class:`numpy.ndarray`
251
288
  List of k points.
252
289
 
@@ -258,7 +295,7 @@ class BaseHamiltonian(ABC):
258
295
  Diagonalising matrix of the BdG Hamiltonian.
259
296
 
260
297
  """
261
- bdg_matrix = self.bdg_hamiltonian(k)
298
+ bdg_matrix = self.bdg_hamiltonian(k=k, q=q)
262
299
  if bdg_matrix.ndim == 2:
263
300
  bdg_matrix = np.expand_dims(bdg_matrix, axis=0)
264
301
  k = np.expand_dims(k, axis=0)
@@ -275,12 +312,13 @@ class BaseHamiltonian(ABC):
275
312
  return bdg_energies.squeeze(), bdg_wavefunctions.squeeze()
276
313
 
277
314
  def gap_equation(
278
- self, k: npt.NDArray[np.float64], beta: np.float64
315
+ self, k: npt.NDArray[np.float64], beta: np.float64, q: npt.NDArray[np.float64] | None = None
279
316
  ) -> npt.NDArray[np.complex64]:
280
317
  """Gap equation.
281
318
 
282
319
  Parameters
283
320
  ----------
321
+ q
284
322
  beta
285
323
  k
286
324
 
@@ -291,8 +329,10 @@ class BaseHamiltonian(ABC):
291
329
 
292
330
 
293
331
  """
294
- bdg_energies, bdg_wavefunctions = self.diagonalize_bdg(k)
295
- bdg_energies_minus_k, _ = self.diagonalize_bdg(-k)
332
+ if q is None:
333
+ q = np.array([0, 0])
334
+ bdg_energies, bdg_wavefunctions = self.diagonalize_bdg(k=k, q=q)
335
+ bdg_energies_minus_k, _ = self.diagonalize_bdg(k=-k, q=-q)
296
336
  delta = np.zeros(self.number_of_bands, dtype=np.complex64)
297
337
 
298
338
  for i in range(self.number_of_bands):
@@ -312,7 +352,7 @@ class BaseHamiltonian(ABC):
312
352
  )
313
353
  delta[i] = (-self.hubbard_int_orbital_basis[i] * sum_tmp / len(k)).conjugate()
314
354
 
315
- delta_without_phase: npt.NDArray[np.complex64] = delta * np.exp(-1j * np.angle(delta[0]))
355
+ delta_without_phase: npt.NDArray[np.complex64] = delta * np.exp(-1j * np.angle(delta[-1]))
316
356
  return delta_without_phase
317
357
 
318
358
  def calculate_bandstructure(
@@ -358,12 +398,15 @@ class BaseHamiltonian(ABC):
358
398
  return results
359
399
 
360
400
  def calculate_density_of_states(
361
- self, k: npt.NDArray[np.float64], energies: npt.NDArray[np.float64]
362
- ) -> npt.NDArray[np.float64]:
401
+ self,
402
+ k: npt.NDArray[np.float64],
403
+ q: npt.NDArray[np.float64] | None = None,
404
+ ) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
363
405
  """Calculate the density of states.
364
406
 
365
407
  Parameters
366
408
  ----------
409
+ q
367
410
  k
368
411
  energies
369
412
 
@@ -372,13 +415,48 @@ class BaseHamiltonian(ABC):
372
415
  Density of states.
373
416
 
374
417
  """
418
+ bands, _ = self.diagonalize_bdg(k=k, q=q)
419
+ energies = np.linspace(start=np.min(bands), stop=np.max(bands), num=5000)
375
420
  density_of_states = np.zeros(shape=energies.shape, dtype=np.float64)
376
- bands, _ = self.diagonalize_bdg(k=k)
421
+
377
422
  for i, energy in enumerate(energies):
378
423
  density_of_states[i] = np.sum(
379
424
  _gaussian(x=(energy - bands.flatten()), sigma=1e-2)
380
425
  ) / len(k)
381
- return density_of_states
426
+ return energies, density_of_states
427
+
428
+ def calculate_spectral_gap(
429
+ self, k: npt.NDArray[np.float64], q: npt.NDArray[np.float64] | None = None
430
+ ) -> float:
431
+ """Calculate the spectral gap.
432
+
433
+ Parameters
434
+ ----------
435
+ k
436
+ q
437
+
438
+ Returns
439
+ -------
440
+ Spectral gap
441
+
442
+ """
443
+ energies, density_of_states = self.calculate_density_of_states(k=k, q=q)
444
+
445
+ coherence_peaks = np.where(np.isclose(density_of_states, np.max(density_of_states)))[0]
446
+
447
+ gap_region = density_of_states[coherence_peaks[0] : coherence_peaks[1] + 1] / np.max(
448
+ density_of_states
449
+ )
450
+ energies_gap_region = energies[coherence_peaks[0] : coherence_peaks[1] + 1]
451
+ zero_indeces = np.where(gap_region <= 1e-10)[0]
452
+ if len(zero_indeces) == 0:
453
+ gap = 0
454
+ else:
455
+ gap = (
456
+ energies_gap_region[zero_indeces[-1]] - energies_gap_region[zero_indeces[0]]
457
+ ).item()
458
+
459
+ return gap
382
460
 
383
461
 
384
462
  def _gaussian(x: npt.NDArray[np.float64], sigma: float) -> npt.NDArray[np.float64]:
@@ -4,54 +4,65 @@
4
4
 
5
5
  """Provides the implementation for the EG-X model."""
6
6
 
7
+ import pathlib
7
8
  from typing import Any
8
9
 
10
+ import h5py
9
11
  import numpy as np
10
12
  import numpy.typing as npt
11
13
 
12
- from ._utils import _check_valid_array, _validate_float
14
+ from quant_met.geometry.graphene import GrapheneLattice
15
+ from quant_met.mean_field._utils import _check_valid_array, _validate_float
16
+ from quant_met.parameters.hamiltonians import DressedGrapheneParameters
17
+
13
18
  from .base_hamiltonian import BaseHamiltonian
14
19
 
15
20
 
16
- class EGXHamiltonian(BaseHamiltonian):
21
+ class DressedGraphene(BaseHamiltonian):
17
22
  """Hamiltonian for the EG-X model."""
18
23
 
19
24
  def __init__(
20
25
  self,
21
- hopping_gr: float,
22
- hopping_x: float,
23
- hopping_x_gr_a: float,
24
- lattice_constant: float,
25
- chemical_potential: float,
26
- hubbard_int_gr: float,
27
- hubbard_int_x: float,
28
- delta: npt.NDArray[np.complex64] | None = None,
26
+ parameters: DressedGrapheneParameters,
29
27
  *args: tuple[Any, ...],
30
28
  **kwargs: tuple[dict[str, Any], ...],
31
29
  ) -> None:
32
30
  del args
33
31
  del kwargs
34
- self.hopping_gr = _validate_float(hopping_gr, "Hopping graphene")
35
- self.hopping_x = _validate_float(hopping_x, "Hopping impurity")
36
- self.hopping_x_gr_a = _validate_float(hopping_x_gr_a, "Hybridisation")
37
- if lattice_constant <= 0:
32
+ self._name = parameters.name
33
+ self.hopping_gr = _validate_float(parameters.hopping_gr, "Hopping graphene")
34
+ self.hopping_x = _validate_float(parameters.hopping_x, "Hopping impurity")
35
+ self.hopping_x_gr_a = _validate_float(parameters.hopping_x_gr_a, "Hybridisation")
36
+ if parameters.lattice_constant <= 0:
38
37
  msg = "Lattice constant must be positive"
39
38
  raise ValueError(msg)
40
- self.lattice_constant = _validate_float(lattice_constant, "Lattice constant")
41
- self.chemical_potential = _validate_float(chemical_potential, "Chemical potential")
42
- self.hubbard_int_gr = _validate_float(hubbard_int_gr, "hubbard_int interaction graphene")
43
- self.hubbard_int_x = _validate_float(hubbard_int_x, "hubbard_int interaction impurity")
39
+ self._lattice = GrapheneLattice(
40
+ lattice_constant=np.float64(
41
+ _validate_float(parameters.lattice_constant, "Lattice constant")
42
+ )
43
+ )
44
+ self.lattice_constant = self._lattice.lattice_constant
45
+ self.chemical_potential = _validate_float(
46
+ parameters.chemical_potential, "Chemical potential"
47
+ )
48
+ self.hubbard_int_gr = _validate_float(
49
+ parameters.hubbard_int_gr, "hubbard_int interaction graphene"
50
+ )
51
+ self.hubbard_int_x = _validate_float(
52
+ parameters.hubbard_int_x, "hubbard_int interaction impurity"
53
+ )
44
54
  self._hubbard_int_orbital_basis = np.array(
45
55
  [self.hubbard_int_gr, self.hubbard_int_gr, self.hubbard_int_x]
46
56
  )
47
57
  self._number_of_bands = 3
48
- if delta is None:
58
+ if parameters.delta is None:
49
59
  self._delta_orbital_basis = np.zeros(self.number_of_bands, dtype=np.complex64)
50
60
  else:
51
- if delta.shape != (self.number_of_bands,):
52
- msg = "Invalid input value for gaps."
53
- raise ValueError(msg)
54
- self._delta_orbital_basis = np.astype(delta, np.complex64)
61
+ self._delta_orbital_basis = np.astype(parameters.delta, np.complex64)
62
+
63
+ @property
64
+ def name(self) -> str: # noqa: D102
65
+ return self._name
55
66
 
56
67
  @property
57
68
  def hubbard_int_orbital_basis(self) -> npt.NDArray[np.float64]: # noqa: D102
@@ -69,6 +80,18 @@ class EGXHamiltonian(BaseHamiltonian):
69
80
  def number_of_bands(self) -> int: # noqa: D102
70
81
  return self._number_of_bands
71
82
 
83
+ @property
84
+ def lattice(self) -> GrapheneLattice: # noqa: D102
85
+ return self._lattice
86
+
87
+ @classmethod
88
+ def from_file(cls, filename: pathlib.Path) -> "BaseHamiltonian": # noqa: D102
89
+ with h5py.File(f"{filename}", "r") as f:
90
+ config_dict = dict(f.attrs.items())
91
+ config_dict["delta"] = f["delta"][()]
92
+ parameters = DressedGrapheneParameters.model_validate(config_dict)
93
+ return cls(parameters=parameters)
94
+
72
95
  def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
73
96
  """
74
97
  Return the normal state Hamiltonian in orbital basis.
@@ -88,7 +111,7 @@ class EGXHamiltonian(BaseHamiltonian):
88
111
 
89
112
  t_gr = self.hopping_gr
90
113
  t_x = self.hopping_x
91
- a = self.lattice_constant
114
+ a = self.lattice.lattice_constant
92
115
  v = self.hopping_x_gr_a
93
116
  chemical_potential = self.chemical_potential
94
117
  if k.ndim == 1:
@@ -144,7 +167,7 @@ class EGXHamiltonian(BaseHamiltonian):
144
167
 
145
168
  t_gr = self.hopping_gr
146
169
  t_x = self.hopping_x
147
- a = self.lattice_constant
170
+ a = self.lattice.lattice_constant
148
171
  if k.ndim == 1:
149
172
  k = np.expand_dims(k, axis=0)
150
173
 
@@ -4,46 +4,60 @@
4
4
 
5
5
  """Provides the implementation for Graphene."""
6
6
 
7
+ import pathlib
7
8
  from typing import Any
8
9
 
10
+ import h5py
9
11
  import numpy as np
10
12
  import numpy.typing as npt
11
13
 
12
- from ._utils import _check_valid_array, _validate_float
14
+ from quant_met.geometry import GrapheneLattice
15
+ from quant_met.mean_field._utils import _check_valid_array, _validate_float
16
+ from quant_met.parameters.hamiltonians import GrapheneParameters
17
+
13
18
  from .base_hamiltonian import BaseHamiltonian
14
19
 
15
20
 
16
- class GrapheneHamiltonian(BaseHamiltonian):
21
+ class Graphene(BaseHamiltonian):
17
22
  """Hamiltonian for Graphene."""
18
23
 
19
24
  def __init__(
20
25
  self,
21
- hopping: float,
22
- lattice_constant: float,
23
- chemical_potential: float,
24
- hubbard_int_gr: float,
25
- delta: npt.NDArray[np.float64] | None = None,
26
+ parameters: GrapheneParameters,
26
27
  *args: tuple[Any, ...],
27
28
  **kwargs: tuple[dict[str, Any], ...],
28
29
  ) -> None:
29
30
  del args
30
31
  del kwargs
31
- self.hopping = _validate_float(hopping, "Hopping")
32
- if lattice_constant <= 0:
32
+ self._name = parameters.name
33
+ self.hopping = _validate_float(parameters.hopping, "Hopping")
34
+ if parameters.lattice_constant <= 0:
33
35
  msg = "Lattice constant must be positive"
34
36
  raise ValueError(msg)
35
- self.lattice_constant = _validate_float(lattice_constant, "Lattice constant")
36
- self.chemical_potential = _validate_float(chemical_potential, "Chemical potential")
37
- self.hubbard_int_gr = _validate_float(hubbard_int_gr, "hubbard_int interaction")
38
- self._hubbard_int_orbital_basis = np.array([self.hubbard_int_gr, self.hubbard_int_gr])
37
+ self._lattice = GrapheneLattice(
38
+ lattice_constant=np.float64(
39
+ _validate_float(parameters.lattice_constant, "Lattice constant")
40
+ )
41
+ )
42
+ self.lattice_constant = self._lattice.lattice_constant
43
+ self.chemical_potential = _validate_float(
44
+ parameters.chemical_potential, "Chemical potential"
45
+ )
46
+ self.hubbard_int = _validate_float(parameters.hubbard_int, "Hubbard interaction")
47
+ self._hubbard_int_orbital_basis = np.array([self.hubbard_int, self.hubbard_int])
39
48
  self._number_of_bands = 2
40
- if delta is None:
49
+ if parameters.delta is None:
41
50
  self._delta_orbital_basis = np.zeros(self.number_of_bands, dtype=np.complex64)
42
51
  else:
43
- if delta.shape != (self.number_of_bands,):
44
- msg = "Invalid input value for gaps."
45
- raise ValueError(msg)
46
- self._delta_orbital_basis = np.astype(delta, np.complex64)
52
+ self._delta_orbital_basis = np.astype(parameters.delta, np.complex64)
53
+
54
+ @property
55
+ def name(self) -> str: # noqa: D102
56
+ return self._name
57
+
58
+ @property
59
+ def lattice(self) -> GrapheneLattice: # noqa: D102
60
+ return self._lattice
47
61
 
48
62
  @property
49
63
  def number_of_bands(self) -> int: # noqa: D102
@@ -61,6 +75,14 @@ class GrapheneHamiltonian(BaseHamiltonian):
61
75
  def delta_orbital_basis(self, new_delta: npt.NDArray[np.complex64]) -> None:
62
76
  self._delta_orbital_basis = new_delta
63
77
 
78
+ @classmethod
79
+ def from_file(cls, filename: pathlib.Path) -> "BaseHamiltonian": # noqa: D102
80
+ with h5py.File(f"{filename}", "r") as f:
81
+ config_dict = dict(f.attrs.items())
82
+ config_dict["delta"] = f["delta"][()]
83
+ parameters = GrapheneParameters.model_validate(config_dict)
84
+ return cls(parameters=parameters)
85
+
64
86
  def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
65
87
  """
66
88
  Return the normal state Hamiltonian in orbital basis.
@@ -78,7 +100,7 @@ class GrapheneHamiltonian(BaseHamiltonian):
78
100
  """
79
101
  assert _check_valid_array(k)
80
102
  hopping = self.hopping
81
- lattice_constant = self.lattice_constant
103
+ lattice_constant = self.lattice.lattice_constant
82
104
  chemical_potential = self.chemical_potential
83
105
  if k.ndim == 1:
84
106
  k = np.expand_dims(k, axis=0)
@@ -120,7 +142,7 @@ class GrapheneHamiltonian(BaseHamiltonian):
120
142
  assert direction in ["x", "y"]
121
143
 
122
144
  hopping = self.hopping
123
- lattice_constant = self.lattice_constant
145
+ lattice_constant = self.lattice.lattice_constant
124
146
  if k.ndim == 1:
125
147
  k = np.expand_dims(k, axis=0)
126
148
 
@@ -4,46 +4,58 @@
4
4
 
5
5
  """Provides the implementation for Graphene."""
6
6
 
7
+ import pathlib
7
8
  from typing import Any
8
9
 
10
+ import h5py
9
11
  import numpy as np
10
12
  import numpy.typing as npt
11
13
 
12
- from ._utils import _check_valid_array, _validate_float
14
+ from quant_met.geometry import SquareLattice
15
+ from quant_met.mean_field._utils import _check_valid_array, _validate_float
16
+ from quant_met.parameters import OneBandParameters
17
+
13
18
  from .base_hamiltonian import BaseHamiltonian
14
19
 
15
20
 
16
- class OneBandTightBindingHamiltonian(BaseHamiltonian):
21
+ class OneBand(BaseHamiltonian):
17
22
  """Hamiltonian for Graphene."""
18
23
 
19
24
  def __init__(
20
25
  self,
21
- hopping: float,
22
- lattice_constant: float,
23
- chemical_potential: float,
24
- hubbard_int: float,
25
- delta: npt.NDArray[np.float64] | None = None,
26
+ parameters: OneBandParameters,
26
27
  *args: tuple[Any, ...],
27
28
  **kwargs: tuple[dict[str, Any], ...],
28
29
  ) -> None:
29
30
  del args
30
31
  del kwargs
31
- self.hopping = _validate_float(hopping, "Hopping")
32
- if lattice_constant <= 0:
32
+ self._name = parameters.name
33
+ self.hopping = _validate_float(parameters.hopping, "Hopping")
34
+ if parameters.lattice_constant <= 0:
33
35
  msg = "Lattice constant must be positive"
34
36
  raise ValueError(msg)
35
- self.lattice_constant = _validate_float(lattice_constant, "Lattice constant")
36
- self.chemical_potential = _validate_float(chemical_potential, "Chemical potential")
37
- self.hubbard_int = _validate_float(hubbard_int, "hubbard_int interaction")
37
+ self._lattice = SquareLattice(
38
+ np.float64(_validate_float(parameters.lattice_constant, "Lattice constant"))
39
+ )
40
+ self.lattice_constant = self._lattice.lattice_constant
41
+ self.chemical_potential = _validate_float(
42
+ parameters.chemical_potential, "Chemical potential"
43
+ )
44
+ self.hubbard_int = _validate_float(parameters.hubbard_int, "Hubbard interaction")
38
45
  self._hubbard_int_orbital_basis = np.array([self.hubbard_int])
39
46
  self._number_of_bands = 1
40
- if delta is None:
47
+ if parameters.delta is None:
41
48
  self._delta_orbital_basis = np.zeros(self.number_of_bands, dtype=np.complex64)
42
49
  else:
43
- if delta.shape != (self.number_of_bands,):
44
- msg = "Invalid input value for gaps."
45
- raise ValueError(msg)
46
- self._delta_orbital_basis = np.astype(delta, np.complex64)
50
+ self._delta_orbital_basis = np.astype(parameters.delta, np.complex64)
51
+
52
+ @property
53
+ def name(self) -> str: # noqa: D102
54
+ return self._name
55
+
56
+ @property
57
+ def lattice(self) -> SquareLattice: # noqa: D102
58
+ return self._lattice
47
59
 
48
60
  @property
49
61
  def number_of_bands(self) -> int: # noqa: D102
@@ -61,6 +73,14 @@ class OneBandTightBindingHamiltonian(BaseHamiltonian):
61
73
  def delta_orbital_basis(self, new_delta: npt.NDArray[np.complex64]) -> None:
62
74
  self._delta_orbital_basis = new_delta
63
75
 
76
+ @classmethod
77
+ def from_file(cls, filename: pathlib.Path) -> "BaseHamiltonian": # noqa: D102
78
+ with h5py.File(f"{filename}", "r") as f:
79
+ config_dict = dict(f.attrs.items())
80
+ config_dict["delta"] = f["delta"][()]
81
+ parameters = OneBandParameters.model_validate(config_dict)
82
+ return cls(parameters=parameters)
83
+
64
84
  def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
65
85
  """
66
86
  Return the normal state Hamiltonian in orbital basis.
@@ -78,7 +98,7 @@ class OneBandTightBindingHamiltonian(BaseHamiltonian):
78
98
  """
79
99
  assert _check_valid_array(k)
80
100
  hopping = self.hopping
81
- lattice_constant = self.lattice_constant
101
+ lattice_constant = self.lattice.lattice_constant
82
102
  chemical_potential = self.chemical_potential
83
103
  if k.ndim == 1:
84
104
  k = np.expand_dims(k, axis=0)
@@ -115,7 +135,7 @@ class OneBandTightBindingHamiltonian(BaseHamiltonian):
115
135
  assert direction in ["x", "y"]
116
136
 
117
137
  hopping = self.hopping
118
- lattice_constant = self.lattice_constant
138
+ lattice_constant = self.lattice.lattice_constant
119
139
  if k.ndim == 1:
120
140
  k = np.expand_dims(k, axis=0)
121
141
 
@@ -7,7 +7,7 @@
7
7
  import numpy as np
8
8
  import numpy.typing as npt
9
9
 
10
- from .base_hamiltonian import BaseHamiltonian
10
+ from quant_met.mean_field.hamiltonians.base_hamiltonian import BaseHamiltonian
11
11
 
12
12
 
13
13
  def quantum_metric(
@@ -5,35 +5,45 @@
5
5
  """Self-consistency loop."""
6
6
 
7
7
  import numpy as np
8
+ import numpy.typing as npt
8
9
 
9
- from quant_met import geometry
10
-
11
- from .base_hamiltonian import BaseHamiltonian
10
+ from quant_met.mean_field.hamiltonians.base_hamiltonian import BaseHamiltonian
12
11
 
13
12
 
14
13
  def self_consistency_loop(
15
- h: BaseHamiltonian, beta: np.float64, number_of_k_points: int, epsilon: float
14
+ h: BaseHamiltonian,
15
+ k_space_grid: npt.NDArray[np.float64],
16
+ beta: np.float64,
17
+ epsilon: float,
18
+ q: npt.NDArray[np.float64] | None = None,
16
19
  ) -> BaseHamiltonian:
17
20
  """Self-consistency loop.
18
21
 
19
22
  Parameters
20
23
  ----------
24
+ lattice
25
+ q
21
26
  beta
22
27
  number_of_k_points
23
28
  h
24
29
  epsilon
25
30
  """
26
- lattice = geometry.Graphene(lattice_constant=np.sqrt(3))
27
- k_space_grid = lattice.generate_bz_grid(ncols=number_of_k_points, nrows=number_of_k_points)
31
+ if q is None:
32
+ q = np.array([0, 0])
33
+
28
34
  rng = np.random.default_rng()
29
- delta_init = np.zeros(shape=h.delta_orbital_basis.shape, dtype=np.float64)
30
- rng.random(size=h.delta_orbital_basis.shape, out=delta_init)
31
- h.delta_orbital_basis = delta_init.astype(np.complex64)
35
+ delta_init = np.zeros(shape=h.delta_orbital_basis.shape, dtype=np.complex64)
36
+ delta_init += (
37
+ 2 * rng.random(size=h.delta_orbital_basis.shape)
38
+ - 1
39
+ + 1.0j * (2 * rng.random(size=h.delta_orbital_basis.shape) - 1)
40
+ )
41
+ h.delta_orbital_basis = delta_init
32
42
 
33
43
  while True:
34
- new_gap = h.gap_equation(k=k_space_grid, beta=beta)
44
+ new_gap = h.gap_equation(k=k_space_grid, q=q, beta=beta)
35
45
  if (np.abs(h.delta_orbital_basis - new_gap) < epsilon).all():
36
46
  h.delta_orbital_basis = new_gap
37
47
  return h
38
- mixing_greed = 0.2
48
+ mixing_greed = 0.1
39
49
  h.delta_orbital_basis = mixing_greed * new_gap + (1 - mixing_greed) * h.delta_orbital_basis
@@ -7,7 +7,7 @@
7
7
  import numpy as np
8
8
  import numpy.typing as npt
9
9
 
10
- from .base_hamiltonian import BaseHamiltonian
10
+ from quant_met.mean_field.hamiltonians.base_hamiltonian import BaseHamiltonian
11
11
 
12
12
 
13
13
  def superfluid_weight(
@@ -0,0 +1,21 @@
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """
6
+ Parameters (:mod:`quant_met.parameters`)
7
+ ========================================
8
+
9
+ .. autosummary::
10
+ :toctree: generated/parameters/
11
+
12
+ DressedGrapheneParameters
13
+ GrapheneParameters
14
+ OneBandParameters
15
+ Parameters
16
+ """ # noqa: D205, D400
17
+
18
+ from .hamiltonians import DressedGrapheneParameters, GrapheneParameters, OneBandParameters
19
+ from .main import Parameters
20
+
21
+ __all__ = ["Parameters", "DressedGrapheneParameters", "GrapheneParameters", "OneBandParameters"]
@@ -0,0 +1,47 @@
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """Pydantic models to hold parameters for Hamiltonians."""
6
+
7
+ from typing import Literal
8
+
9
+ import numpy as np
10
+ from numpydantic import NDArray, Shape
11
+ from pydantic import BaseModel
12
+
13
+
14
+ class DressedGrapheneParameters(BaseModel):
15
+ """Parameters for the dressed Graphene model."""
16
+
17
+ name: Literal["DressedGraphene"] = "DressedGraphene"
18
+ hopping_gr: float
19
+ hopping_x: float
20
+ hopping_x_gr_a: float
21
+ lattice_constant: float
22
+ chemical_potential: float
23
+ hubbard_int_gr: float
24
+ hubbard_int_x: float
25
+ delta: NDArray[Shape["3"], np.complex64] | None = None
26
+
27
+
28
+ class GrapheneParameters(BaseModel):
29
+ """Parameters for Graphene model."""
30
+
31
+ name: Literal["Graphene"] = "Graphene"
32
+ hopping: float
33
+ lattice_constant: float
34
+ chemical_potential: float
35
+ hubbard_int: float
36
+ delta: NDArray[Shape["2"], np.complex64] | None = None
37
+
38
+
39
+ class OneBandParameters(BaseModel):
40
+ """Parameters for Graphene model."""
41
+
42
+ name: Literal["OneBand"] = "OneBand"
43
+ hopping: float
44
+ lattice_constant: float
45
+ chemical_potential: float
46
+ hubbard_int: float
47
+ delta: NDArray[Shape["1"], np.complex64] | None = None
@@ -0,0 +1,40 @@
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """Pydantic models to hold parameters to run a simulation."""
6
+
7
+ import pathlib
8
+
9
+ from numpydantic import NDArray, Shape
10
+ from pydantic import BaseModel, Field
11
+
12
+ from .hamiltonians import DressedGrapheneParameters, GrapheneParameters, OneBandParameters
13
+
14
+
15
+ class Control(BaseModel):
16
+ """Control for the calculation."""
17
+
18
+ calculation: str
19
+ prefix: str
20
+ outdir: pathlib.Path
21
+ conv_treshold: float
22
+ beta: float
23
+ q: NDArray[Shape["2"], int | float] | None = None
24
+
25
+
26
+ class KPoints(BaseModel):
27
+ """Control for k points."""
28
+
29
+ nk1: int
30
+ nk2: int
31
+
32
+
33
+ class Parameters(BaseModel):
34
+ """Class to hold the parameters for a calculation."""
35
+
36
+ control: Control
37
+ model: DressedGrapheneParameters | GrapheneParameters | OneBandParameters = Field(
38
+ ..., discriminator="name"
39
+ )
40
+ k_points: KPoints
quant_met/utils.py CHANGED
@@ -14,7 +14,7 @@ Functions
14
14
  .. autosummary::
15
15
  :toctree: generated/
16
16
 
17
- generate_uniform_grid - Generate a uniform grid of points in 2D.
17
+ generate_uniform_grid
18
18
  """ # noqa: D205, D400
19
19
 
20
20
  import numpy as np
@@ -1,19 +1,21 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quant-met
3
- Version: 0.0.7
3
+ Version: 0.0.8
4
4
  Summary: Calculate superconductivity in flat-band systems.
5
5
  Home-page: https://quant-met.tjarksievers.de
6
6
  Author: Tjark Sievers
7
7
  Author-email: tsievers@physnet.uni-hamburg.de
8
- Requires-Python: >=3.11,<4.0
8
+ Requires-Python: >=3.11,<3.13
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: Programming Language :: Python :: 3.11
11
11
  Classifier: Programming Language :: Python :: 3.12
12
- Classifier: Programming Language :: Python :: 3.13
12
+ Requires-Dist: click (>=8.1.7,<9.0.0)
13
13
  Requires-Dist: h5py (>=3.12.1,<4.0.0)
14
14
  Requires-Dist: matplotlib (>=3.9.2,<4.0.0)
15
15
  Requires-Dist: numpy (>=2.1.2,<3.0.0)
16
+ Requires-Dist: numpydantic (>=1.6.4,<2.0.0)
16
17
  Requires-Dist: pandas (>=2.2.3,<3.0.0)
18
+ Requires-Dist: pydantic (>=2.9.2,<3.0.0)
17
19
  Requires-Dist: scipy (>=1.14.1,<2.0.0)
18
20
  Project-URL: Repository, https://github.com/Ruberhauptmann/quant-met
19
21
  Description-Content-Type: text/markdown
@@ -0,0 +1,31 @@
1
+ quant_met/__init__.py,sha256=ZO1UFz1awUYTI7B9ZkBwucvDz7GMGXnLLUGnEwLBhkc,155
2
+ quant_met/cli/__init__.py,sha256=If5Jdi7mG-5PbIyjQGxnt9o2bsY5VyE3qtdcO5yTGnQ,321
3
+ quant_met/cli/main.py,sha256=EZTRRTfrN3z-srgbG2BoDg64iYBjzZLuuMtrxTdZU8s,698
4
+ quant_met/cli/scf.py,sha256=x9qxjQizXAKH7217dBuHTlA26eGenzcC2LDpN1q7030,1435
5
+ quant_met/geometry/__init__.py,sha256=uCLEDBrYuMUkEgJmPnLAvR2WlmvoM9X9_cV_Q2zMzoA,620
6
+ quant_met/geometry/base_lattice.py,sha256=QVHuZVy6bOvBSITY_mKhr7hYW1jHJ5UAm3sMCFClYZ0,2276
7
+ quant_met/geometry/bz_path.py,sha256=q_eNhKYjhKLeFNjio8BdKVsseO6slQKlwKKSQQYTVJQ,2497
8
+ quant_met/geometry/graphene.py,sha256=86C1LiYFunoSGSS1_A79dPq24FiiOxpHvOLUVrdRq_E,1271
9
+ quant_met/geometry/square.py,sha256=1fSrHab07uB6ildNzlbTwINJvPa5C2Az0B0uuOVJmMc,1216
10
+ quant_met/mean_field/__init__.py,sha256=yH_UovKDaP5c06cb1uWPtvIO2WQ76pi6ZTsNBzE8oso,793
11
+ quant_met/mean_field/_utils.py,sha256=plkx6eYjyYV3CT3BWwlulqW7L-Q0t1TzZTLR4k7u0dg,666
12
+ quant_met/mean_field/hamiltonians/__init__.py,sha256=FcqhV5fG_gzngVuiVfBucripdbNTzOxPRafu7sZ4ueA,644
13
+ quant_met/mean_field/hamiltonians/base_hamiltonian.py,sha256=fL1dl1ZX3I_4gzARiQl5o2eCTIr-udRA23qZo4VWq0k,13622
14
+ quant_met/mean_field/hamiltonians/dressed_graphene.py,sha256=zzHRVmp8749I2ll5N-wjks8l5dJLdtmhWR7smR7ezM0,6542
15
+ quant_met/mean_field/hamiltonians/graphene.py,sha256=Zg_S9xTMYi_7v_6PBK7NUdiwgmyqyCPElUfezuiozm0,5611
16
+ quant_met/mean_field/hamiltonians/one_band_tight_binding.py,sha256=kBYqthKUPby754PhOwf0mzHLTHNVbdKZbtJhvp2yc3E,4766
17
+ quant_met/mean_field/quantum_metric.py,sha256=5FC3NU_ObbHlUUZMCAP1DyZuyifgnEr3s2cSH6cA8-8,3903
18
+ quant_met/mean_field/self_consistency.py,sha256=xkZIWkOopekhDufJnSGK6ARsro6XaIuVhhrnJmb6sk8,1291
19
+ quant_met/mean_field/superfluid_weight.py,sha256=m_x2uVYcEVdbItwEV3-Ml80Qad7X-YWLgb38fJKLJsY,4004
20
+ quant_met/parameters/__init__.py,sha256=DvzEtTAnHcRcJufZV7bwYGZUeA-0Q2B8N9syGA9uNRM,552
21
+ quant_met/parameters/hamiltonians.py,sha256=Q5uGTzxM8kIdUnRuIpEJNPmSHF27Zj7LBV3kgKd5dP4,1213
22
+ quant_met/parameters/main.py,sha256=yrDME_KfDZ_9xf3ofTt7V8kw_8qbgD9EfVlxLcymcNE,899
23
+ quant_met/plotting/__init__.py,sha256=s-DS22impzozKiS7p-v3yCmeccDQfXmBbtPiYMKwH0Y,620
24
+ quant_met/plotting/plotting.py,sha256=_SqL8GrDqlBtccHnUWpZPqdSJy0Yd_4dhFdUOxOzPpY,7447
25
+ quant_met/utils.py,sha256=JG_tShSL1JIi-Fn-N6mVD6J0sl7Egf-zuHnOSEKu7VA,1666
26
+ quant_met-0.0.8.dist-info/LICENSE.txt,sha256=QO_duPQihSJlaxSLxPAXo52X3esROP5wBkhxqBd1Z4E,1104
27
+ quant_met-0.0.8.dist-info/LICENSES/MIT.txt,sha256=QO_duPQihSJlaxSLxPAXo52X3esROP5wBkhxqBd1Z4E,1104
28
+ quant_met-0.0.8.dist-info/METADATA,sha256=vh99nVcyAhUECV32kkXxfDjne2LvBufs6ekW60m8pYs,2953
29
+ quant_met-0.0.8.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
30
+ quant_met-0.0.8.dist-info/entry_points.txt,sha256=fuVnEk5wiqPMEhn-Cc7q0Hdk2s_OniOn0zfdFPicH4Y,47
31
+ quant_met-0.0.8.dist-info/RECORD,,
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ quant-met=quant_met.cli:cli
3
+
@@ -1,130 +0,0 @@
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.hubbard_int_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)
@@ -1,24 +0,0 @@
1
- quant_met/__init__.py,sha256=ZO1UFz1awUYTI7B9ZkBwucvDz7GMGXnLLUGnEwLBhkc,155
2
- quant_met/geometry/__init__.py,sha256=dWT4yYDBKsJUI9Hv1DDCGtqx-lDLQF6mH7xSRLomvD4,508
3
- quant_met/geometry/base_lattice.py,sha256=QVHuZVy6bOvBSITY_mKhr7hYW1jHJ5UAm3sMCFClYZ0,2276
4
- quant_met/geometry/bz_path.py,sha256=q_eNhKYjhKLeFNjio8BdKVsseO6slQKlwKKSQQYTVJQ,2497
5
- quant_met/geometry/graphene.py,sha256=37CZXj_NpFsnR1pPE_jFbrAiiMFhs1Q3FLlcgqG2pwM,1264
6
- quant_met/geometry/square.py,sha256=1fSrHab07uB6ildNzlbTwINJvPa5C2Az0B0uuOVJmMc,1216
7
- quant_met/mean_field/__init__.py,sha256=sXKp572huLdcqYEj0b9ojgefLiOiIHV7CH2XN54WU7E,1368
8
- quant_met/mean_field/_utils.py,sha256=plkx6eYjyYV3CT3BWwlulqW7L-Q0t1TzZTLR4k7u0dg,666
9
- quant_met/mean_field/base_hamiltonian.py,sha256=kUZ6-eU525l_9e3YoSA66HsE9c5isUNjNqOh6T71OGk,11773
10
- quant_met/mean_field/eg_x.py,sha256=w-6UcSVYPC-B58152aJpp0HDNoxyy46c6eXNZCGHi6Q,5805
11
- quant_met/mean_field/free_energy.py,sha256=59GPLJhyllyAJEZteAr6iYqCbHGFsmV1zcYxJ8Aw9Ao,3448
12
- quant_met/mean_field/graphene.py,sha256=8xMR43ndL5oJ7BbYBVGxWTLU5BscsE8ixTpPlCZzKO8,4917
13
- quant_met/mean_field/one_band_tight_binding.py,sha256=ZfZQZxcqoKRtx3oomQyXwuong81K5vKKg0cyjs5JJ48,4138
14
- quant_met/mean_field/quantum_metric.py,sha256=3OiwSDxz_Pw4uioGO18lYyYb_myK2kSCwF9AloUZIt4,3870
15
- quant_met/mean_field/self_consistency.py,sha256=r2J9mEEcgWkI92exEol0tkwoWlM9ithodgNzdKEQpfs,1193
16
- quant_met/mean_field/superfluid_weight.py,sha256=840Fe3aHOVz1W7hi5GrX69_QxQ3vmdy3H0_B852dZqA,3971
17
- quant_met/plotting/__init__.py,sha256=s-DS22impzozKiS7p-v3yCmeccDQfXmBbtPiYMKwH0Y,620
18
- quant_met/plotting/plotting.py,sha256=_SqL8GrDqlBtccHnUWpZPqdSJy0Yd_4dhFdUOxOzPpY,7447
19
- quant_met/utils.py,sha256=Tvw_YfqjIWx0FPGSReikSnw9xfN-T2dpQZN-KPMa69A,1709
20
- quant_met-0.0.7.dist-info/LICENSE.txt,sha256=QO_duPQihSJlaxSLxPAXo52X3esROP5wBkhxqBd1Z4E,1104
21
- quant_met-0.0.7.dist-info/LICENSES/MIT.txt,sha256=QO_duPQihSJlaxSLxPAXo52X3esROP5wBkhxqBd1Z4E,1104
22
- quant_met-0.0.7.dist-info/METADATA,sha256=eq-LGEGvKZsMw_MC5guVaJvrfvF24OmMkNLj6l74CRo,2880
23
- quant_met-0.0.7.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
24
- quant_met-0.0.7.dist-info/RECORD,,