quant-met 0.0.8__tar.gz → 0.0.9__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.
- {quant_met-0.0.8 → quant_met-0.0.9}/PKG-INFO +1 -1
- {quant_met-0.0.8 → quant_met-0.0.9}/pyproject.toml +1 -1
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/cli/scf.py +5 -7
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/geometry/base_lattice.py +18 -4
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/geometry/graphene.py +10 -2
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/geometry/square.py +11 -3
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/mean_field/_utils.py +0 -11
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/mean_field/hamiltonians/__init__.py +3 -6
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/mean_field/hamiltonians/base_hamiltonian.py +52 -119
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/mean_field/hamiltonians/dressed_graphene.py +20 -75
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/mean_field/hamiltonians/graphene.py +13 -60
- quant_met-0.0.9/src/quant_met/mean_field/hamiltonians/one_band_tight_binding.py +101 -0
- quant_met-0.0.9/src/quant_met/mean_field/hamiltonians/three_band_tight_binding.py +116 -0
- quant_met-0.0.9/src/quant_met/mean_field/hamiltonians/two_band_tight_binding.py +107 -0
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/mean_field/quantum_metric.py +3 -2
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/mean_field/self_consistency.py +8 -17
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/mean_field/superfluid_weight.py +6 -3
- quant_met-0.0.9/src/quant_met/parameters/__init__.py +36 -0
- quant_met-0.0.9/src/quant_met/parameters/hamiltonians.py +147 -0
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/parameters/main.py +0 -3
- quant_met-0.0.8/src/quant_met/mean_field/hamiltonians/one_band_tight_binding.py +0 -149
- quant_met-0.0.8/src/quant_met/parameters/__init__.py +0 -21
- quant_met-0.0.8/src/quant_met/parameters/hamiltonians.py +0 -47
- {quant_met-0.0.8 → quant_met-0.0.9}/LICENSE.txt +0 -0
- {quant_met-0.0.8 → quant_met-0.0.9}/LICENSES/MIT.txt +0 -0
- {quant_met-0.0.8 → quant_met-0.0.9}/README.md +0 -0
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/__init__.py +0 -0
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/cli/__init__.py +0 -0
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/cli/main.py +0 -0
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/geometry/__init__.py +0 -0
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/geometry/bz_path.py +0 -0
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/mean_field/__init__.py +0 -0
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/plotting/__init__.py +0 -0
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/plotting/plotting.py +0 -0
- {quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/utils.py +0 -0
@@ -8,7 +8,7 @@ requires-python = ">=3.11,<3.13"
|
|
8
8
|
|
9
9
|
[tool.poetry]
|
10
10
|
name = "quant-met"
|
11
|
-
version = "0.0.
|
11
|
+
version = "0.0.9"
|
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"
|
@@ -6,20 +6,20 @@
|
|
6
6
|
|
7
7
|
from pathlib import Path
|
8
8
|
|
9
|
-
import numpy as np
|
10
|
-
from pydantic import BaseModel
|
11
|
-
|
12
9
|
from quant_met import mean_field
|
13
10
|
from quant_met.mean_field.hamiltonians import BaseHamiltonian
|
14
11
|
from quant_met.parameters import Parameters
|
12
|
+
from quant_met.parameters.hamiltonians import HamiltonianParameters
|
15
13
|
|
16
14
|
|
17
|
-
def _hamiltonian_factory(
|
15
|
+
def _hamiltonian_factory(
|
16
|
+
classname: str, parameters: HamiltonianParameters
|
17
|
+
) -> BaseHamiltonian[HamiltonianParameters]:
|
18
18
|
"""Create a hamiltonian by its class name."""
|
19
19
|
from quant_met.mean_field import hamiltonians
|
20
20
|
|
21
21
|
cls = getattr(hamiltonians, classname)
|
22
|
-
h: BaseHamiltonian = cls(parameters)
|
22
|
+
h: BaseHamiltonian[HamiltonianParameters] = cls(parameters)
|
23
23
|
return h
|
24
24
|
|
25
25
|
|
@@ -33,9 +33,7 @@ def scf(parameters: Parameters) -> None:
|
|
33
33
|
k_space_grid=h.lattice.generate_bz_grid(
|
34
34
|
ncols=parameters.k_points.nk1, nrows=parameters.k_points.nk2
|
35
35
|
),
|
36
|
-
beta=np.float64(parameters.control.beta),
|
37
36
|
epsilon=parameters.control.conv_treshold,
|
38
|
-
q=parameters.control.q,
|
39
37
|
)
|
40
38
|
print(solved_h.delta_orbital_basis)
|
41
39
|
result_file = result_path / f"{parameters.control.prefix}.hdf5"
|
@@ -19,19 +19,29 @@ class BaseLattice(ABC):
|
|
19
19
|
|
20
20
|
@property
|
21
21
|
@abstractmethod
|
22
|
-
def lattice_constant(self) ->
|
22
|
+
def lattice_constant(self) -> float: # pragma: no cover
|
23
23
|
"""Lattice constant."""
|
24
24
|
raise NotImplementedError
|
25
25
|
|
26
26
|
@property
|
27
27
|
@abstractmethod
|
28
|
-
def bz_corners(self) -> npt.NDArray[np.float64]:
|
28
|
+
def bz_corners(self) -> npt.NDArray[np.float64]: # pragma: no cover
|
29
29
|
"""Corners of the BZ."""
|
30
30
|
raise NotImplementedError
|
31
31
|
|
32
32
|
@property
|
33
33
|
@abstractmethod
|
34
|
-
def
|
34
|
+
def reciprocal_basis(
|
35
|
+
self,
|
36
|
+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]: # pragma: no cover
|
37
|
+
"""Reciprocal basis vectors."""
|
38
|
+
raise NotImplementedError
|
39
|
+
|
40
|
+
@property
|
41
|
+
@abstractmethod
|
42
|
+
def high_symmetry_points(
|
43
|
+
self,
|
44
|
+
) -> tuple[tuple[npt.NDArray[np.float64], str], ...]: # pragma: no cover
|
35
45
|
"""Tuple of high symmetry points and names."""
|
36
46
|
raise NotImplementedError
|
37
47
|
|
@@ -52,7 +62,11 @@ class BaseLattice(ABC):
|
|
52
62
|
|
53
63
|
"""
|
54
64
|
return generate_uniform_grid(
|
55
|
-
ncols,
|
65
|
+
ncols,
|
66
|
+
nrows,
|
67
|
+
self.reciprocal_basis[0],
|
68
|
+
self.reciprocal_basis[1],
|
69
|
+
origin=np.array([0, 0]),
|
56
70
|
)
|
57
71
|
|
58
72
|
def generate_high_symmetry_path(
|
@@ -13,7 +13,7 @@ from .base_lattice import BaseLattice
|
|
13
13
|
class GrapheneLattice(BaseLattice):
|
14
14
|
"""Lattice geometry for Graphene."""
|
15
15
|
|
16
|
-
def __init__(self, lattice_constant:
|
16
|
+
def __init__(self, lattice_constant: float) -> None:
|
17
17
|
self._lattice_constant = lattice_constant
|
18
18
|
self._bz_corners = (
|
19
19
|
4
|
@@ -25,15 +25,23 @@ class GrapheneLattice(BaseLattice):
|
|
25
25
|
self.M = np.pi / self.lattice_constant * np.array([1, 1 / np.sqrt(3)])
|
26
26
|
self.K = 4 * np.pi / (3 * self.lattice_constant) * np.array([1, 0])
|
27
27
|
self._high_symmetry_points = ((self.M, "M"), (self.Gamma, r"\Gamma"), (self.K, "K"))
|
28
|
+
self._reciprocal_basis = (
|
29
|
+
2 * np.pi / self.lattice_constant * np.array([1, 1 / np.sqrt(3)]),
|
30
|
+
2 * np.pi / self.lattice_constant * np.array([1, -1 / np.sqrt(3)]),
|
31
|
+
)
|
28
32
|
|
29
33
|
@property
|
30
|
-
def lattice_constant(self) ->
|
34
|
+
def lattice_constant(self) -> float: # noqa: D102
|
31
35
|
return self._lattice_constant
|
32
36
|
|
33
37
|
@property
|
34
38
|
def bz_corners(self) -> npt.NDArray[np.float64]: # noqa: D102
|
35
39
|
return self._bz_corners
|
36
40
|
|
41
|
+
@property
|
42
|
+
def reciprocal_basis(self) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]: # noqa: D102
|
43
|
+
return self._reciprocal_basis
|
44
|
+
|
37
45
|
@property
|
38
46
|
def high_symmetry_points(self) -> tuple[tuple[npt.NDArray[np.float64], str], ...]: # noqa: D102
|
39
47
|
return self._high_symmetry_points
|
@@ -13,26 +13,34 @@ from .base_lattice import BaseLattice
|
|
13
13
|
class SquareLattice(BaseLattice):
|
14
14
|
"""Lattice geometry for Square Lattice."""
|
15
15
|
|
16
|
-
def __init__(self, lattice_constant:
|
16
|
+
def __init__(self, lattice_constant: float) -> None:
|
17
17
|
self._lattice_constant = lattice_constant
|
18
18
|
self._bz_corners = (
|
19
19
|
np.pi
|
20
20
|
/ lattice_constant
|
21
21
|
* np.array([np.array([1, 1]), np.array([-1, 1]), np.array([1, -1]), np.array([-1, -1])])
|
22
22
|
)
|
23
|
+
self._reciprocal_basis = (
|
24
|
+
2 * np.pi / self.lattice_constant * np.array([1, 0]),
|
25
|
+
2 * np.pi / self.lattice_constant * np.array([0, 1]),
|
26
|
+
)
|
23
27
|
self.Gamma = np.array([0, 0])
|
24
28
|
self.M = np.pi / lattice_constant * np.array([1, 1])
|
25
29
|
self.X = np.pi / lattice_constant * np.array([1, 0])
|
26
30
|
self._high_symmetry_points = ((self.Gamma, r"\Gamma"), (self.M, "M"))
|
27
31
|
|
28
32
|
@property
|
29
|
-
def lattice_constant(self) ->
|
33
|
+
def lattice_constant(self) -> float: # noqa: D102
|
30
34
|
return self._lattice_constant
|
31
35
|
|
32
36
|
@property
|
33
|
-
def bz_corners(self) -> npt.NDArray[np.float64]: # noqa: D102
|
37
|
+
def bz_corners(self) -> npt.NDArray[np.float64]: # noqa: D102 # pragma: no cover
|
34
38
|
return self._bz_corners
|
35
39
|
|
40
|
+
@property
|
41
|
+
def reciprocal_basis(self) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]: # noqa: D102
|
42
|
+
return self._reciprocal_basis
|
43
|
+
|
36
44
|
@property
|
37
45
|
def high_symmetry_points(self) -> tuple[tuple[npt.NDArray[np.float64], str], ...]: # noqa: D102
|
38
46
|
return self._high_symmetry_points
|
@@ -14,14 +14,3 @@ def _check_valid_array(array_in: npt.NDArray[Any]) -> bool:
|
|
14
14
|
raise ValueError(msg)
|
15
15
|
|
16
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
|
@@ -25,10 +25,7 @@ from .base_hamiltonian import BaseHamiltonian
|
|
25
25
|
from .dressed_graphene import DressedGraphene
|
26
26
|
from .graphene import Graphene
|
27
27
|
from .one_band_tight_binding import OneBand
|
28
|
+
from .three_band_tight_binding import ThreeBand
|
29
|
+
from .two_band_tight_binding import TwoBand
|
28
30
|
|
29
|
-
__all__ = [
|
30
|
-
"BaseHamiltonian",
|
31
|
-
"Graphene",
|
32
|
-
"DressedGraphene",
|
33
|
-
"OneBand",
|
34
|
-
]
|
31
|
+
__all__ = ["BaseHamiltonian", "Graphene", "DressedGraphene", "OneBand", "TwoBand", "ThreeBand"]
|
{quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/mean_field/hamiltonians/base_hamiltonian.py
RENAMED
@@ -6,6 +6,7 @@
|
|
6
6
|
|
7
7
|
import pathlib
|
8
8
|
from abc import ABC, abstractmethod
|
9
|
+
from typing import Generic
|
9
10
|
|
10
11
|
import h5py
|
11
12
|
import numpy as np
|
@@ -14,80 +15,35 @@ import pandas as pd
|
|
14
15
|
|
15
16
|
from quant_met.geometry import BaseLattice
|
16
17
|
from quant_met.mean_field._utils import _check_valid_array
|
18
|
+
from quant_met.parameters.hamiltonians import GenericParameters
|
17
19
|
|
18
20
|
|
19
|
-
class BaseHamiltonian(ABC):
|
21
|
+
class BaseHamiltonian(Generic[GenericParameters], ABC):
|
20
22
|
"""Base class for Hamiltonians."""
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
Returns
|
28
|
-
-------
|
29
|
-
str
|
30
|
-
|
31
|
-
"""
|
32
|
-
raise NotImplementedError
|
33
|
-
|
34
|
-
@property
|
35
|
-
@abstractmethod
|
36
|
-
def number_of_bands(self) -> int:
|
37
|
-
"""Number of bands.
|
38
|
-
|
39
|
-
Returns
|
40
|
-
-------
|
41
|
-
int
|
42
|
-
|
43
|
-
"""
|
44
|
-
raise NotImplementedError
|
24
|
+
def __init__(self, parameters: GenericParameters) -> None:
|
25
|
+
self.name = parameters.name
|
26
|
+
self.beta = parameters.beta if parameters.beta else 1000.0
|
27
|
+
self.q = parameters.q if parameters.q is not None else np.zeros(2)
|
45
28
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
Returns
|
52
|
-
-------
|
53
|
-
BaseLattice
|
29
|
+
self.lattice = self.setup_lattice(parameters)
|
30
|
+
self.hubbard_int_orbital_basis = parameters.hubbard_int_orbital_basis
|
31
|
+
self.number_of_bands = len(self.hubbard_int_orbital_basis)
|
32
|
+
self.delta_orbital_basis = np.zeros(self.number_of_bands, dtype=np.complex64)
|
54
33
|
|
55
|
-
"""
|
56
|
-
raise NotImplementedError
|
57
|
-
|
58
|
-
@property
|
59
34
|
@abstractmethod
|
60
|
-
def
|
61
|
-
"""
|
62
|
-
hubbard_int interaction split up in orbitals.
|
63
|
-
|
64
|
-
Returns
|
65
|
-
-------
|
66
|
-
:class:`numpy.ndarray`
|
67
|
-
|
68
|
-
"""
|
69
|
-
raise NotImplementedError
|
35
|
+
def setup_lattice(self, parameters: GenericParameters) -> BaseLattice: # pragma: no cover
|
36
|
+
"""Set up lattice based on parameters."""
|
70
37
|
|
71
|
-
@
|
72
|
-
@abstractmethod
|
73
|
-
def delta_orbital_basis(self) -> npt.NDArray[np.complex64]:
|
74
|
-
"""
|
75
|
-
Order parameter in orbital basis.
|
76
|
-
|
77
|
-
Returns
|
78
|
-
-------
|
79
|
-
:class:`numpy.ndarray`
|
80
|
-
|
81
|
-
"""
|
82
|
-
raise NotImplementedError
|
83
|
-
|
84
|
-
@delta_orbital_basis.setter
|
38
|
+
@classmethod
|
85
39
|
@abstractmethod
|
86
|
-
def
|
87
|
-
|
40
|
+
def get_parameters_model(cls) -> type[GenericParameters]: # pragma: no cover
|
41
|
+
"""Return the specific parameters model for the subclass."""
|
88
42
|
|
89
43
|
@abstractmethod
|
90
|
-
def hamiltonian(
|
44
|
+
def hamiltonian(
|
45
|
+
self, k: npt.NDArray[np.float64]
|
46
|
+
) -> npt.NDArray[np.complex64]: # pragma: no cover
|
91
47
|
"""
|
92
48
|
Return the normal state Hamiltonian in orbital basis.
|
93
49
|
|
@@ -102,12 +58,11 @@ class BaseHamiltonian(ABC):
|
|
102
58
|
Hamiltonian in matrix form.
|
103
59
|
|
104
60
|
"""
|
105
|
-
raise NotImplementedError
|
106
61
|
|
107
62
|
@abstractmethod
|
108
63
|
def hamiltonian_derivative(
|
109
64
|
self, k: npt.NDArray[np.float64], direction: str
|
110
|
-
) -> npt.NDArray[np.complex64]:
|
65
|
+
) -> npt.NDArray[np.complex64]: # pragma: no cover
|
111
66
|
"""
|
112
67
|
Deriative of the Hamiltonian.
|
113
68
|
|
@@ -124,7 +79,6 @@ class BaseHamiltonian(ABC):
|
|
124
79
|
Derivative of Hamiltonian.
|
125
80
|
|
126
81
|
"""
|
127
|
-
raise NotImplementedError
|
128
82
|
|
129
83
|
def save(self, filename: pathlib.Path) -> None:
|
130
84
|
"""
|
@@ -139,32 +93,27 @@ class BaseHamiltonian(ABC):
|
|
139
93
|
with h5py.File(f"{filename.absolute()}", "w") as f:
|
140
94
|
f.create_dataset("delta", data=self.delta_orbital_basis)
|
141
95
|
for key, value in vars(self).items():
|
142
|
-
if
|
143
|
-
f.attrs[key] = value
|
96
|
+
if key != "lattice":
|
97
|
+
f.attrs[key.strip("_")] = value
|
98
|
+
f.attrs["lattice_constant"] = self.lattice.lattice_constant
|
144
99
|
|
145
100
|
@classmethod
|
146
|
-
|
147
|
-
|
148
|
-
""
|
149
|
-
|
150
|
-
|
151
|
-
Parameters
|
152
|
-
----------
|
153
|
-
filename : :class:`pathlib.Path`
|
154
|
-
File to load the Hamiltonian from.
|
101
|
+
def from_file(cls, filename: pathlib.Path) -> "BaseHamiltonian[GenericParameters]":
|
102
|
+
"""Initialize a Hamiltonian from an HDF5 file."""
|
103
|
+
with h5py.File(str(filename), "r") as f:
|
104
|
+
config_dict = dict(f.attrs.items())
|
105
|
+
config_dict["delta"] = f["delta"][()]
|
155
106
|
|
156
|
-
|
157
|
-
|
107
|
+
parameters_model = cls.get_parameters_model()
|
108
|
+
parameters = parameters_model.model_validate(config_dict)
|
109
|
+
return cls(parameters=parameters)
|
158
110
|
|
159
|
-
def bdg_hamiltonian(
|
160
|
-
self, k: npt.NDArray[np.float64], q: npt.NDArray[np.float64] | None = None
|
161
|
-
) -> npt.NDArray[np.complex64]:
|
111
|
+
def bdg_hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
|
162
112
|
"""
|
163
113
|
Bogoliuobov de Genne Hamiltonian.
|
164
114
|
|
165
115
|
Parameters
|
166
116
|
----------
|
167
|
-
q
|
168
117
|
k : :class:`numpy.ndarray`
|
169
118
|
List of k points.
|
170
119
|
|
@@ -177,8 +126,6 @@ class BaseHamiltonian(ABC):
|
|
177
126
|
assert _check_valid_array(k)
|
178
127
|
if k.ndim == 1:
|
179
128
|
k = np.expand_dims(k, axis=0)
|
180
|
-
if q is None:
|
181
|
-
q = np.array([0, 0])
|
182
129
|
|
183
130
|
h = np.zeros(
|
184
131
|
(k.shape[0], 2 * self.number_of_bands, 2 * self.number_of_bands), dtype=np.complex64
|
@@ -189,7 +136,7 @@ class BaseHamiltonian(ABC):
|
|
189
136
|
:,
|
190
137
|
self.number_of_bands : 2 * self.number_of_bands,
|
191
138
|
self.number_of_bands : 2 * self.number_of_bands,
|
192
|
-
] = -self.hamiltonian(q - k).conjugate()
|
139
|
+
] = -self.hamiltonian(self.q - k).conjugate()
|
193
140
|
|
194
141
|
for i in range(self.number_of_bands):
|
195
142
|
h[:, self.number_of_bands + i, i] = self.delta_orbital_basis[i]
|
@@ -276,14 +223,14 @@ class BaseHamiltonian(ABC):
|
|
276
223
|
return band_energies.squeeze(), bloch_wavefunctions.squeeze()
|
277
224
|
|
278
225
|
def diagonalize_bdg(
|
279
|
-
self,
|
226
|
+
self,
|
227
|
+
k: npt.NDArray[np.float64],
|
280
228
|
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.complex64]]:
|
281
229
|
"""
|
282
230
|
Diagonalize the BdG Hamiltonian.
|
283
231
|
|
284
232
|
Parameters
|
285
233
|
----------
|
286
|
-
q
|
287
234
|
k : :class:`numpy.ndarray`
|
288
235
|
List of k points.
|
289
236
|
|
@@ -295,7 +242,7 @@ class BaseHamiltonian(ABC):
|
|
295
242
|
Diagonalising matrix of the BdG Hamiltonian.
|
296
243
|
|
297
244
|
"""
|
298
|
-
bdg_matrix = self.bdg_hamiltonian(k=k
|
245
|
+
bdg_matrix = self.bdg_hamiltonian(k=k)
|
299
246
|
if bdg_matrix.ndim == 2:
|
300
247
|
bdg_matrix = np.expand_dims(bdg_matrix, axis=0)
|
301
248
|
k = np.expand_dims(k, axis=0)
|
@@ -312,14 +259,13 @@ class BaseHamiltonian(ABC):
|
|
312
259
|
return bdg_energies.squeeze(), bdg_wavefunctions.squeeze()
|
313
260
|
|
314
261
|
def gap_equation(
|
315
|
-
self,
|
262
|
+
self,
|
263
|
+
k: npt.NDArray[np.float64],
|
316
264
|
) -> npt.NDArray[np.complex64]:
|
317
265
|
"""Gap equation.
|
318
266
|
|
319
267
|
Parameters
|
320
268
|
----------
|
321
|
-
q
|
322
|
-
beta
|
323
269
|
k
|
324
270
|
|
325
271
|
Returns
|
@@ -329,30 +275,23 @@ class BaseHamiltonian(ABC):
|
|
329
275
|
|
330
276
|
|
331
277
|
"""
|
332
|
-
|
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)
|
278
|
+
bdg_energies, bdg_wavefunctions = self.diagonalize_bdg(k=k)
|
336
279
|
delta = np.zeros(self.number_of_bands, dtype=np.complex64)
|
337
280
|
|
338
281
|
for i in range(self.number_of_bands):
|
339
282
|
sum_tmp = 0
|
340
|
-
for j in range(self.number_of_bands):
|
283
|
+
for j in range(2 * self.number_of_bands):
|
341
284
|
for k_index in range(len(k)):
|
342
|
-
sum_tmp +=
|
343
|
-
k_index, i
|
344
|
-
|
345
|
-
bdg_energies[k_index, j
|
346
|
-
) + np.conjugate(
|
347
|
-
bdg_wavefunctions[k_index, i, j + self.number_of_bands]
|
348
|
-
) * bdg_wavefunctions[
|
349
|
-
k_index, i + self.number_of_bands, j + self.number_of_bands
|
350
|
-
] * _fermi_dirac(
|
351
|
-
-bdg_energies_minus_k[k_index, j + self.number_of_bands].item(), beta
|
285
|
+
sum_tmp += (
|
286
|
+
np.conjugate(bdg_wavefunctions[k_index, i, j])
|
287
|
+
* bdg_wavefunctions[k_index, i + self.number_of_bands, j]
|
288
|
+
* _fermi_dirac(bdg_energies[k_index, j].item(), self.beta)
|
352
289
|
)
|
353
290
|
delta[i] = (-self.hubbard_int_orbital_basis[i] * sum_tmp / len(k)).conjugate()
|
354
291
|
|
355
|
-
delta_without_phase: npt.NDArray[np.complex64] = delta * np.exp(
|
292
|
+
delta_without_phase: npt.NDArray[np.complex64] = delta * np.exp(
|
293
|
+
-1j * np.angle(delta[np.argmax(np.abs(delta))])
|
294
|
+
)
|
356
295
|
return delta_without_phase
|
357
296
|
|
358
297
|
def calculate_bandstructure(
|
@@ -400,22 +339,19 @@ class BaseHamiltonian(ABC):
|
|
400
339
|
def calculate_density_of_states(
|
401
340
|
self,
|
402
341
|
k: npt.NDArray[np.float64],
|
403
|
-
q: npt.NDArray[np.float64] | None = None,
|
404
342
|
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
405
343
|
"""Calculate the density of states.
|
406
344
|
|
407
345
|
Parameters
|
408
346
|
----------
|
409
|
-
q
|
410
347
|
k
|
411
|
-
energies
|
412
348
|
|
413
349
|
Returns
|
414
350
|
-------
|
415
351
|
Density of states.
|
416
352
|
|
417
353
|
"""
|
418
|
-
bands, _ = self.diagonalize_bdg(k=k
|
354
|
+
bands, _ = self.diagonalize_bdg(k=k)
|
419
355
|
energies = np.linspace(start=np.min(bands), stop=np.max(bands), num=5000)
|
420
356
|
density_of_states = np.zeros(shape=energies.shape, dtype=np.float64)
|
421
357
|
|
@@ -425,22 +361,19 @@ class BaseHamiltonian(ABC):
|
|
425
361
|
) / len(k)
|
426
362
|
return energies, density_of_states
|
427
363
|
|
428
|
-
def calculate_spectral_gap(
|
429
|
-
self, k: npt.NDArray[np.float64], q: npt.NDArray[np.float64] | None = None
|
430
|
-
) -> float:
|
364
|
+
def calculate_spectral_gap(self, k: npt.NDArray[np.float64]) -> float:
|
431
365
|
"""Calculate the spectral gap.
|
432
366
|
|
433
367
|
Parameters
|
434
368
|
----------
|
435
369
|
k
|
436
|
-
q
|
437
370
|
|
438
371
|
Returns
|
439
372
|
-------
|
440
373
|
Spectral gap
|
441
374
|
|
442
375
|
"""
|
443
|
-
energies, density_of_states = self.calculate_density_of_states(k=k
|
376
|
+
energies, density_of_states = self.calculate_density_of_states(k=k)
|
444
377
|
|
445
378
|
coherence_peaks = np.where(np.isclose(density_of_states, np.max(density_of_states)))[0]
|
446
379
|
|
@@ -466,6 +399,6 @@ def _gaussian(x: npt.NDArray[np.float64], sigma: float) -> npt.NDArray[np.float6
|
|
466
399
|
return gaussian
|
467
400
|
|
468
401
|
|
469
|
-
def _fermi_dirac(energy:
|
470
|
-
fermi_dirac:
|
402
|
+
def _fermi_dirac(energy: float, beta: float) -> float:
|
403
|
+
fermi_dirac: float = 1 / (1 + np.exp(beta * energy))
|
471
404
|
return fermi_dirac
|
{quant_met-0.0.8 → quant_met-0.0.9}/src/quant_met/mean_field/hamiltonians/dressed_graphene.py
RENAMED
@@ -2,95 +2,40 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MIT
|
4
4
|
|
5
|
-
"""Provides the implementation for the
|
5
|
+
"""Provides the implementation for the dressed graphene model."""
|
6
6
|
|
7
|
-
import pathlib
|
8
|
-
from typing import Any
|
9
|
-
|
10
|
-
import h5py
|
11
7
|
import numpy as np
|
12
8
|
import numpy.typing as npt
|
13
9
|
|
10
|
+
from quant_met.geometry import BaseLattice
|
14
11
|
from quant_met.geometry.graphene import GrapheneLattice
|
15
|
-
from quant_met.mean_field._utils import _check_valid_array
|
12
|
+
from quant_met.mean_field._utils import _check_valid_array
|
16
13
|
from quant_met.parameters.hamiltonians import DressedGrapheneParameters
|
17
14
|
|
18
15
|
from .base_hamiltonian import BaseHamiltonian
|
19
16
|
|
20
17
|
|
21
|
-
class DressedGraphene(BaseHamiltonian):
|
22
|
-
"""Hamiltonian for the
|
23
|
-
|
24
|
-
def __init__(
|
25
|
-
self,
|
26
|
-
parameters: DressedGrapheneParameters,
|
27
|
-
*args: tuple[Any, ...],
|
28
|
-
**kwargs: tuple[dict[str, Any], ...],
|
29
|
-
) -> None:
|
30
|
-
del args
|
31
|
-
del kwargs
|
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:
|
37
|
-
msg = "Lattice constant must be positive"
|
38
|
-
raise ValueError(msg)
|
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
|
-
)
|
54
|
-
self._hubbard_int_orbital_basis = np.array(
|
55
|
-
[self.hubbard_int_gr, self.hubbard_int_gr, self.hubbard_int_x]
|
56
|
-
)
|
57
|
-
self._number_of_bands = 3
|
58
|
-
if parameters.delta is None:
|
59
|
-
self._delta_orbital_basis = np.zeros(self.number_of_bands, dtype=np.complex64)
|
60
|
-
else:
|
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
|
66
|
-
|
67
|
-
@property
|
68
|
-
def hubbard_int_orbital_basis(self) -> npt.NDArray[np.float64]: # noqa: D102
|
69
|
-
return self._hubbard_int_orbital_basis
|
70
|
-
|
71
|
-
@property
|
72
|
-
def delta_orbital_basis(self) -> npt.NDArray[np.complex64]: # noqa: D102
|
73
|
-
return self._delta_orbital_basis
|
74
|
-
|
75
|
-
@delta_orbital_basis.setter
|
76
|
-
def delta_orbital_basis(self, new_delta: npt.NDArray[np.complex64]) -> None:
|
77
|
-
self._delta_orbital_basis = new_delta
|
18
|
+
class DressedGraphene(BaseHamiltonian[DressedGrapheneParameters]):
|
19
|
+
"""Hamiltonian for the dressed graphene model."""
|
78
20
|
|
79
|
-
|
80
|
-
|
81
|
-
|
21
|
+
def __init__(self, parameters: DressedGrapheneParameters) -> None:
|
22
|
+
super().__init__(parameters)
|
23
|
+
self.hopping_gr = parameters.hopping_gr
|
24
|
+
self.hopping_x = parameters.hopping_x
|
25
|
+
self.hopping_x_gr_a = parameters.hopping_x_gr_a
|
26
|
+
self.hubbard_int_orbital_basis = parameters.hubbard_int_orbital_basis
|
27
|
+
self.chemical_potential = parameters.chemical_potential
|
28
|
+
if parameters.delta is not None:
|
29
|
+
self.delta_orbital_basis = np.astype(parameters.delta, np.complex64)
|
82
30
|
|
83
|
-
|
84
|
-
|
85
|
-
return
|
31
|
+
def setup_lattice(self, parameters: DressedGrapheneParameters) -> BaseLattice:
|
32
|
+
"""Set up lattice based on parameters."""
|
33
|
+
return GrapheneLattice(lattice_constant=parameters.lattice_constant)
|
86
34
|
|
87
35
|
@classmethod
|
88
|
-
def
|
89
|
-
|
90
|
-
|
91
|
-
config_dict["delta"] = f["delta"][()]
|
92
|
-
parameters = DressedGrapheneParameters.model_validate(config_dict)
|
93
|
-
return cls(parameters=parameters)
|
36
|
+
def get_parameters_model(cls) -> type[DressedGrapheneParameters]:
|
37
|
+
"""Return the specific parameters model for the subclass."""
|
38
|
+
return DressedGrapheneParameters
|
94
39
|
|
95
40
|
def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
|
96
41
|
"""
|