quant-met 0.0.6__tar.gz → 0.0.8__tar.gz

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.
Files changed (33) hide show
  1. {quant_met-0.0.6 → quant_met-0.0.8}/PKG-INFO +9 -6
  2. {quant_met-0.0.6 → quant_met-0.0.8}/pyproject.toml +16 -8
  3. quant_met-0.0.8/src/quant_met/cli/__init__.py +22 -0
  4. quant_met-0.0.8/src/quant_met/cli/main.py +34 -0
  5. quant_met-0.0.8/src/quant_met/cli/scf.py +42 -0
  6. {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/geometry/__init__.py +12 -3
  7. {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/geometry/graphene.py +1 -1
  8. quant_met-0.0.8/src/quant_met/mean_field/__init__.py +42 -0
  9. quant_met-0.0.8/src/quant_met/mean_field/hamiltonians/__init__.py +34 -0
  10. {quant_met-0.0.6/src/quant_met/mean_field → quant_met-0.0.8/src/quant_met/mean_field/hamiltonians}/base_hamiltonian.py +125 -16
  11. quant_met-0.0.6/src/quant_met/mean_field/eg_x.py → quant_met-0.0.8/src/quant_met/mean_field/hamiltonians/dressed_graphene.py +48 -25
  12. {quant_met-0.0.6/src/quant_met/mean_field → quant_met-0.0.8/src/quant_met/mean_field/hamiltonians}/graphene.py +42 -20
  13. {quant_met-0.0.6/src/quant_met/mean_field → quant_met-0.0.8/src/quant_met/mean_field/hamiltonians}/one_band_tight_binding.py +39 -19
  14. {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/mean_field/quantum_metric.py +24 -25
  15. quant_met-0.0.8/src/quant_met/mean_field/self_consistency.py +49 -0
  16. {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/mean_field/superfluid_weight.py +1 -1
  17. quant_met-0.0.8/src/quant_met/parameters/__init__.py +21 -0
  18. quant_met-0.0.8/src/quant_met/parameters/hamiltonians.py +47 -0
  19. quant_met-0.0.8/src/quant_met/parameters/main.py +40 -0
  20. {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/utils.py +1 -1
  21. quant_met-0.0.6/src/quant_met/mean_field/__init__.py +0 -65
  22. quant_met-0.0.6/src/quant_met/mean_field/free_energy.py +0 -130
  23. quant_met-0.0.6/src/quant_met/mean_field/self_consistency.py +0 -45
  24. {quant_met-0.0.6 → quant_met-0.0.8}/LICENSE.txt +0 -0
  25. {quant_met-0.0.6 → quant_met-0.0.8}/LICENSES/MIT.txt +0 -0
  26. {quant_met-0.0.6 → quant_met-0.0.8}/README.md +0 -0
  27. {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/__init__.py +0 -0
  28. {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/geometry/base_lattice.py +0 -0
  29. {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/geometry/bz_path.py +0 -0
  30. {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/geometry/square.py +0 -0
  31. {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/mean_field/_utils.py +0 -0
  32. {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/plotting/__init__.py +0 -0
  33. {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/plotting/plotting.py +0 -0
@@ -1,19 +1,22 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quant-met
3
- Version: 0.0.6
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
- Requires-Dist: h5py (>=3.11.0,<4.0.0)
12
+ Requires-Dist: click (>=8.1.7,<9.0.0)
13
+ Requires-Dist: h5py (>=3.12.1,<4.0.0)
13
14
  Requires-Dist: matplotlib (>=3.9.2,<4.0.0)
14
- Requires-Dist: numpy (>=2.0.0,<3.0.0)
15
- Requires-Dist: pandas (>=2.2.2,<3.0.0)
16
- Requires-Dist: scipy (>=1.14.0,<2.0.0)
15
+ Requires-Dist: numpy (>=2.1.2,<3.0.0)
16
+ Requires-Dist: numpydantic (>=1.6.4,<2.0.0)
17
+ Requires-Dist: pandas (>=2.2.3,<3.0.0)
18
+ Requires-Dist: pydantic (>=2.9.2,<3.0.0)
19
+ Requires-Dist: scipy (>=1.14.1,<2.0.0)
17
20
  Project-URL: Repository, https://github.com/Ruberhauptmann/quant-met
18
21
  Description-Content-Type: text/markdown
19
22
 
@@ -4,24 +4,30 @@
4
4
 
5
5
  [project]
6
6
  name = "quant-met"
7
- requires-python = ">=3.12"
7
+ requires-python = ">=3.11,<3.13"
8
8
 
9
9
  [tool.poetry]
10
10
  name = "quant-met"
11
- version = "0.0.6"
11
+ version = "0.0.8"
12
12
  description = "Calculate superconductivity in flat-band systems."
13
13
  authors = ["Tjark Sievers <tsievers@physnet.uni-hamburg.de>"]
14
14
  homepage = "https://quant-met.tjarksievers.de"
15
15
  repository = "https://github.com/Ruberhauptmann/quant-met"
16
16
  readme = "README.md"
17
17
 
18
+ [tool.poetry.scripts]
19
+ quant-met = 'quant_met.cli:cli'
20
+
18
21
  [tool.poetry.dependencies]
19
- python = "^3.11"
20
- numpy = "^2.0.0"
21
- scipy = "^1.14.0"
22
+ python = ">=3.11,<3.13"
23
+ numpy = "^2.1.2"
24
+ scipy = "^1.14.1"
22
25
  matplotlib = "^3.9.2"
23
- pandas = "^2.2.2"
24
- h5py = "^3.11.0"
26
+ pandas = "^2.2.3"
27
+ h5py = "^3.12.1"
28
+ pydantic = "^2.9.2"
29
+ click = "^8.1.7"
30
+ numpydantic = "^1.6.4"
25
31
 
26
32
  [tool.poetry.group.dev.dependencies]
27
33
  pre-commit = "^3.7.0"
@@ -42,6 +48,7 @@ hypothesis = {extras = ["numpy"], version = "^6.103.0"}
42
48
  pytest-regressions = "^2.5.0"
43
49
  numpydoc = "^1.7.0"
44
50
  ruff = "^0.5.0"
51
+ types-pyyaml = "^6.0.12.20240917"
45
52
 
46
53
  [build-system]
47
54
  requires = ["poetry-core"]
@@ -51,7 +58,8 @@ build-backend = "poetry.core.masonry.api"
51
58
  [tool.ruff]
52
59
  line-length = 100
53
60
  force-exclude = true
54
- extend-exclude = ["tests", "docs/source/conf.py"]
61
+ #extend-exclude = ["tests", "docs/source/conf.py"]
62
+ extend-exclude = ["docs/source/conf.py"]
55
63
 
56
64
  [tool.ruff.lint]
57
65
  #select = []
@@ -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
+ ]
@@ -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)
@@ -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:
@@ -0,0 +1,42 @@
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
+ Submodules
10
+ ----------
11
+
12
+ .. autosummary::
13
+ :toctree: generated/
14
+
15
+ hamiltonians
16
+
17
+
18
+ Functions
19
+ ---------
20
+
21
+ .. autosummary::
22
+ :toctree: generated/
23
+
24
+ superfluid_weight
25
+ quantum_metric
26
+ quantum_metric_bdg
27
+ self_consistency_loop
28
+ """ # noqa: D205, D400
29
+
30
+ from quant_met.mean_field import hamiltonians
31
+
32
+ from .quantum_metric import quantum_metric, quantum_metric_bdg
33
+ from .self_consistency import self_consistency_loop
34
+ from .superfluid_weight import superfluid_weight
35
+
36
+ __all__ = [
37
+ "superfluid_weight",
38
+ "quantum_metric",
39
+ "quantum_metric_bdg",
40
+ "self_consistency_loop",
41
+ "hamiltonians",
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
+ """
25
44
  raise NotImplementedError
26
45
 
27
46
  @property
47
+ @abstractmethod
48
+ def lattice(self) -> BaseLattice:
49
+ """Lattice.
50
+
51
+ Returns
52
+ -------
53
+ BaseLattice
54
+
55
+ """
56
+ raise NotImplementedError
57
+
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,8 @@ class BaseHamiltonian(ABC):
312
352
  )
313
353
  delta[i] = (-self.hubbard_int_orbital_basis[i] * sum_tmp / len(k)).conjugate()
314
354
 
315
- return np.abs(delta)
355
+ delta_without_phase: npt.NDArray[np.complex64] = delta * np.exp(-1j * np.angle(delta[-1]))
356
+ return delta_without_phase
316
357
 
317
358
  def calculate_bandstructure(
318
359
  self,
@@ -356,6 +397,74 @@ class BaseHamiltonian(ABC):
356
397
 
357
398
  return results
358
399
 
400
+ def calculate_density_of_states(
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]]:
405
+ """Calculate the density of states.
406
+
407
+ Parameters
408
+ ----------
409
+ q
410
+ k
411
+ energies
412
+
413
+ Returns
414
+ -------
415
+ Density of states.
416
+
417
+ """
418
+ bands, _ = self.diagonalize_bdg(k=k, q=q)
419
+ energies = np.linspace(start=np.min(bands), stop=np.max(bands), num=5000)
420
+ density_of_states = np.zeros(shape=energies.shape, dtype=np.float64)
421
+
422
+ for i, energy in enumerate(energies):
423
+ density_of_states[i] = np.sum(
424
+ _gaussian(x=(energy - bands.flatten()), sigma=1e-2)
425
+ ) / len(k)
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
460
+
461
+
462
+ def _gaussian(x: npt.NDArray[np.float64], sigma: float) -> npt.NDArray[np.float64]:
463
+ gaussian: npt.NDArray[np.float64] = np.exp(-(x**2) / (2 * sigma**2)) / np.sqrt(
464
+ 2 * np.pi * sigma**2
465
+ )
466
+ return gaussian
467
+
359
468
 
360
469
  def _fermi_dirac(energy: np.float64, beta: np.float64) -> np.float64:
361
470
  fermi_dirac: np.float64 = 1 / (1 + np.exp(beta * energy))
@@ -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