quant-met 0.0.7__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.7 → quant_met-0.0.8}/PKG-INFO +5 -3
- {quant_met-0.0.7 → quant_met-0.0.8}/pyproject.toml +12 -4
- 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.7 → quant_met-0.0.8}/src/quant_met/geometry/__init__.py +12 -3
- {quant_met-0.0.7 → 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.7/src/quant_met/mean_field → quant_met-0.0.8/src/quant_met/mean_field/hamiltonians}/base_hamiltonian.py +98 -20
- quant_met-0.0.7/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.7/src/quant_met/mean_field → quant_met-0.0.8/src/quant_met/mean_field/hamiltonians}/graphene.py +42 -20
- {quant_met-0.0.7/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.7 → quant_met-0.0.8}/src/quant_met/mean_field/quantum_metric.py +1 -1
- {quant_met-0.0.7 → quant_met-0.0.8}/src/quant_met/mean_field/self_consistency.py +21 -11
- {quant_met-0.0.7 → 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.7 → quant_met-0.0.8}/src/quant_met/utils.py +1 -1
- quant_met-0.0.7/src/quant_met/mean_field/__init__.py +0 -65
- quant_met-0.0.7/src/quant_met/mean_field/free_energy.py +0 -130
- {quant_met-0.0.7 → quant_met-0.0.8}/LICENSE.txt +0 -0
- {quant_met-0.0.7 → quant_met-0.0.8}/LICENSES/MIT.txt +0 -0
- {quant_met-0.0.7 → quant_met-0.0.8}/README.md +0 -0
- {quant_met-0.0.7 → quant_met-0.0.8}/src/quant_met/__init__.py +0 -0
- {quant_met-0.0.7 → quant_met-0.0.8}/src/quant_met/geometry/base_lattice.py +0 -0
- {quant_met-0.0.7 → quant_met-0.0.8}/src/quant_met/geometry/bz_path.py +0 -0
- {quant_met-0.0.7 → quant_met-0.0.8}/src/quant_met/geometry/square.py +0 -0
- {quant_met-0.0.7 → quant_met-0.0.8}/src/quant_met/mean_field/_utils.py +0 -0
- {quant_met-0.0.7 → quant_met-0.0.8}/src/quant_met/plotting/__init__.py +0 -0
- {quant_met-0.0.7 → quant_met-0.0.8}/src/quant_met/plotting/plotting.py +0 -0
@@ -1,19 +1,21 @@
|
|
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
|
-
|
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
|
@@ -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 = "
|
22
|
+
python = ">=3.11,<3.13"
|
20
23
|
numpy = "^2.1.2"
|
21
24
|
scipy = "^1.14.1"
|
22
25
|
matplotlib = "^3.9.2"
|
23
26
|
pandas = "^2.2.3"
|
24
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
|
+
"""
|
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
|
-
|
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,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[
|
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,
|
362
|
-
|
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
|
-
|
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 .
|
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
|
|
@@ -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 .
|
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
|
21
|
+
class Graphene(BaseHamiltonian):
|
17
22
|
"""Hamiltonian for Graphene."""
|
18
23
|
|
19
24
|
def __init__(
|
20
25
|
self,
|
21
|
-
|
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.
|
32
|
-
|
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.
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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 .
|
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
|
21
|
+
class OneBand(BaseHamiltonian):
|
17
22
|
"""Hamiltonian for Graphene."""
|
18
23
|
|
19
24
|
def __init__(
|
20
25
|
self,
|
21
|
-
|
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.
|
32
|
-
|
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.
|
36
|
-
|
37
|
-
|
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
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
|
@@ -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
|
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,
|
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
|
-
|
27
|
-
|
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.
|
30
|
-
|
31
|
-
|
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.
|
48
|
+
mixing_greed = 0.1
|
39
49
|
h.delta_orbital_basis = mixing_greed * new_gap + (1 - mixing_greed) * h.delta_orbital_basis
|
@@ -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
|
@@ -1,65 +0,0 @@
|
|
1
|
-
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
-
#
|
3
|
-
# SPDX-License-Identifier: MIT
|
4
|
-
|
5
|
-
"""
|
6
|
-
Mean field treatment (:mod:`quant_met.mean_field`)
|
7
|
-
==================================================
|
8
|
-
|
9
|
-
Hamiltonians
|
10
|
-
------------
|
11
|
-
|
12
|
-
Base
|
13
|
-
|
14
|
-
.. autosummary::
|
15
|
-
:toctree: generated/
|
16
|
-
|
17
|
-
BaseHamiltonian
|
18
|
-
|
19
|
-
.. autosummary::
|
20
|
-
:toctree: generated/
|
21
|
-
|
22
|
-
GrapheneHamiltonian
|
23
|
-
EGXHamiltonian
|
24
|
-
|
25
|
-
|
26
|
-
Functions
|
27
|
-
---------
|
28
|
-
|
29
|
-
.. autosummary::
|
30
|
-
:toctree: generated/
|
31
|
-
|
32
|
-
superfluid_weight
|
33
|
-
quantum_metric
|
34
|
-
free_energy
|
35
|
-
free_energy_uniform_pairing
|
36
|
-
""" # noqa: D205, D400
|
37
|
-
|
38
|
-
from .base_hamiltonian import BaseHamiltonian
|
39
|
-
from .eg_x import EGXHamiltonian
|
40
|
-
from .free_energy import (
|
41
|
-
free_energy,
|
42
|
-
free_energy_complex_gap,
|
43
|
-
free_energy_real_gap,
|
44
|
-
free_energy_uniform_pairing,
|
45
|
-
)
|
46
|
-
from .graphene import GrapheneHamiltonian
|
47
|
-
from .one_band_tight_binding import OneBandTightBindingHamiltonian
|
48
|
-
from .quantum_metric import quantum_metric, quantum_metric_bdg
|
49
|
-
from .self_consistency import self_consistency_loop
|
50
|
-
from .superfluid_weight import superfluid_weight
|
51
|
-
|
52
|
-
__all__ = [
|
53
|
-
"superfluid_weight",
|
54
|
-
"quantum_metric",
|
55
|
-
"quantum_metric_bdg",
|
56
|
-
"free_energy",
|
57
|
-
"free_energy_complex_gap",
|
58
|
-
"free_energy_real_gap",
|
59
|
-
"free_energy_uniform_pairing",
|
60
|
-
"self_consistency_loop",
|
61
|
-
"BaseHamiltonian",
|
62
|
-
"GrapheneHamiltonian",
|
63
|
-
"EGXHamiltonian",
|
64
|
-
"OneBandTightBindingHamiltonian",
|
65
|
-
]
|
@@ -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)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|