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.
- {quant_met-0.0.6 → quant_met-0.0.8}/PKG-INFO +9 -6
- {quant_met-0.0.6 → quant_met-0.0.8}/pyproject.toml +16 -8
- quant_met-0.0.8/src/quant_met/cli/__init__.py +22 -0
- quant_met-0.0.8/src/quant_met/cli/main.py +34 -0
- quant_met-0.0.8/src/quant_met/cli/scf.py +42 -0
- {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/geometry/__init__.py +12 -3
- {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/geometry/graphene.py +1 -1
- quant_met-0.0.8/src/quant_met/mean_field/__init__.py +42 -0
- quant_met-0.0.8/src/quant_met/mean_field/hamiltonians/__init__.py +34 -0
- {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
- 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
- {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
- {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
- {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/mean_field/quantum_metric.py +24 -25
- quant_met-0.0.8/src/quant_met/mean_field/self_consistency.py +49 -0
- {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/mean_field/superfluid_weight.py +1 -1
- quant_met-0.0.8/src/quant_met/parameters/__init__.py +21 -0
- quant_met-0.0.8/src/quant_met/parameters/hamiltonians.py +47 -0
- quant_met-0.0.8/src/quant_met/parameters/main.py +40 -0
- {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/utils.py +1 -1
- quant_met-0.0.6/src/quant_met/mean_field/__init__.py +0 -65
- quant_met-0.0.6/src/quant_met/mean_field/free_energy.py +0 -130
- quant_met-0.0.6/src/quant_met/mean_field/self_consistency.py +0 -45
- {quant_met-0.0.6 → quant_met-0.0.8}/LICENSE.txt +0 -0
- {quant_met-0.0.6 → quant_met-0.0.8}/LICENSES/MIT.txt +0 -0
- {quant_met-0.0.6 → quant_met-0.0.8}/README.md +0 -0
- {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/__init__.py +0 -0
- {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/geometry/base_lattice.py +0 -0
- {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/geometry/bz_path.py +0 -0
- {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/geometry/square.py +0 -0
- {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/mean_field/_utils.py +0 -0
- {quant_met-0.0.6 → quant_met-0.0.8}/src/quant_met/plotting/__init__.py +0 -0
- {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.
|
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,<
|
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:
|
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.
|
15
|
-
Requires-Dist:
|
16
|
-
Requires-Dist:
|
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.
|
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.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 = "
|
20
|
-
numpy = "^2.
|
21
|
-
scipy = "^1.14.
|
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.
|
24
|
-
h5py = "^3.
|
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
|
-
|
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
|
32
|
+
from .graphene import GrapheneLattice
|
24
33
|
from .square import SquareLattice
|
25
34
|
|
26
|
-
__all__ = ["generate_bz_path", "BaseLattice", "
|
35
|
+
__all__ = ["generate_bz_path", "BaseLattice", "GrapheneLattice", "SquareLattice"]
|
@@ -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 .
|
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
|
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
|
-
|
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(
|
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
|
-
|
295
|
-
|
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
|
-
|
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 .
|
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
|
21
|
+
class DressedGraphene(BaseHamiltonian):
|
17
22
|
"""Hamiltonian for the EG-X model."""
|
18
23
|
|
19
24
|
def __init__(
|
20
25
|
self,
|
21
|
-
|
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.
|
35
|
-
self.
|
36
|
-
self.
|
37
|
-
|
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.
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
|