quant-met 0.0.7__py3-none-any.whl → 0.0.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- quant_met/cli/__init__.py +22 -0
- quant_met/cli/main.py +34 -0
- quant_met/cli/scf.py +40 -0
- quant_met/geometry/__init__.py +12 -3
- quant_met/geometry/base_lattice.py +18 -4
- quant_met/geometry/graphene.py +11 -3
- quant_met/geometry/square.py +11 -3
- quant_met/mean_field/__init__.py +9 -32
- quant_met/mean_field/_utils.py +0 -11
- quant_met/mean_field/hamiltonians/__init__.py +31 -0
- quant_met/mean_field/{base_hamiltonian.py → hamiltonians/base_hamiltonian.py} +88 -77
- quant_met/mean_field/{eg_x.py → hamiltonians/dressed_graphene.py} +26 -58
- quant_met/mean_field/{graphene.py → hamiltonians/graphene.py} +20 -45
- quant_met/mean_field/{one_band_tight_binding.py → hamiltonians/one_band_tight_binding.py} +20 -48
- quant_met/mean_field/hamiltonians/three_band_tight_binding.py +116 -0
- quant_met/mean_field/hamiltonians/two_band_tight_binding.py +107 -0
- quant_met/mean_field/quantum_metric.py +4 -3
- quant_met/mean_field/self_consistency.py +15 -14
- quant_met/mean_field/superfluid_weight.py +7 -4
- quant_met/parameters/__init__.py +36 -0
- quant_met/parameters/hamiltonians.py +147 -0
- quant_met/parameters/main.py +37 -0
- quant_met/utils.py +1 -1
- {quant_met-0.0.7.dist-info → quant_met-0.0.9.dist-info}/METADATA +5 -3
- quant_met-0.0.9.dist-info/RECORD +33 -0
- quant_met-0.0.9.dist-info/entry_points.txt +3 -0
- quant_met/mean_field/free_energy.py +0 -130
- quant_met-0.0.7.dist-info/RECORD +0 -24
- {quant_met-0.0.7.dist-info → quant_met-0.0.9.dist-info}/LICENSE.txt +0 -0
- {quant_met-0.0.7.dist-info → quant_met-0.0.9.dist-info}/LICENSES/MIT.txt +0 -0
- {quant_met-0.0.7.dist-info → quant_met-0.0.9.dist-info}/WHEEL +0 -0
@@ -2,72 +2,40 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MIT
|
4
4
|
|
5
|
-
"""Provides the implementation for the
|
6
|
-
|
7
|
-
from typing import Any
|
5
|
+
"""Provides the implementation for the dressed graphene model."""
|
8
6
|
|
9
7
|
import numpy as np
|
10
8
|
import numpy.typing as npt
|
11
9
|
|
12
|
-
from .
|
13
|
-
from .
|
10
|
+
from quant_met.geometry import BaseLattice
|
11
|
+
from quant_met.geometry.graphene import GrapheneLattice
|
12
|
+
from quant_met.mean_field._utils import _check_valid_array
|
13
|
+
from quant_met.parameters.hamiltonians import DressedGrapheneParameters
|
14
14
|
|
15
|
+
from .base_hamiltonian import BaseHamiltonian
|
15
16
|
|
16
|
-
class EGXHamiltonian(BaseHamiltonian):
|
17
|
-
"""Hamiltonian for the EG-X model."""
|
18
|
-
|
19
|
-
def __init__(
|
20
|
-
self,
|
21
|
-
hopping_gr: float,
|
22
|
-
hopping_x: float,
|
23
|
-
hopping_x_gr_a: float,
|
24
|
-
lattice_constant: float,
|
25
|
-
chemical_potential: float,
|
26
|
-
hubbard_int_gr: float,
|
27
|
-
hubbard_int_x: float,
|
28
|
-
delta: npt.NDArray[np.complex64] | None = None,
|
29
|
-
*args: tuple[Any, ...],
|
30
|
-
**kwargs: tuple[dict[str, Any], ...],
|
31
|
-
) -> None:
|
32
|
-
del args
|
33
|
-
del kwargs
|
34
|
-
self.hopping_gr = _validate_float(hopping_gr, "Hopping graphene")
|
35
|
-
self.hopping_x = _validate_float(hopping_x, "Hopping impurity")
|
36
|
-
self.hopping_x_gr_a = _validate_float(hopping_x_gr_a, "Hybridisation")
|
37
|
-
if lattice_constant <= 0:
|
38
|
-
msg = "Lattice constant must be positive"
|
39
|
-
raise ValueError(msg)
|
40
|
-
self.lattice_constant = _validate_float(lattice_constant, "Lattice constant")
|
41
|
-
self.chemical_potential = _validate_float(chemical_potential, "Chemical potential")
|
42
|
-
self.hubbard_int_gr = _validate_float(hubbard_int_gr, "hubbard_int interaction graphene")
|
43
|
-
self.hubbard_int_x = _validate_float(hubbard_int_x, "hubbard_int interaction impurity")
|
44
|
-
self._hubbard_int_orbital_basis = np.array(
|
45
|
-
[self.hubbard_int_gr, self.hubbard_int_gr, self.hubbard_int_x]
|
46
|
-
)
|
47
|
-
self._number_of_bands = 3
|
48
|
-
if delta is None:
|
49
|
-
self._delta_orbital_basis = np.zeros(self.number_of_bands, dtype=np.complex64)
|
50
|
-
else:
|
51
|
-
if delta.shape != (self.number_of_bands,):
|
52
|
-
msg = "Invalid input value for gaps."
|
53
|
-
raise ValueError(msg)
|
54
|
-
self._delta_orbital_basis = np.astype(delta, np.complex64)
|
55
17
|
|
56
|
-
|
57
|
-
|
58
|
-
return self._hubbard_int_orbital_basis
|
18
|
+
class DressedGraphene(BaseHamiltonian[DressedGrapheneParameters]):
|
19
|
+
"""Hamiltonian for the dressed graphene model."""
|
59
20
|
|
60
|
-
|
61
|
-
|
62
|
-
|
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)
|
63
30
|
|
64
|
-
|
65
|
-
|
66
|
-
|
31
|
+
def setup_lattice(self, parameters: DressedGrapheneParameters) -> BaseLattice:
|
32
|
+
"""Set up lattice based on parameters."""
|
33
|
+
return GrapheneLattice(lattice_constant=parameters.lattice_constant)
|
67
34
|
|
68
|
-
@
|
69
|
-
def
|
70
|
-
|
35
|
+
@classmethod
|
36
|
+
def get_parameters_model(cls) -> type[DressedGrapheneParameters]:
|
37
|
+
"""Return the specific parameters model for the subclass."""
|
38
|
+
return DressedGrapheneParameters
|
71
39
|
|
72
40
|
def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
|
73
41
|
"""
|
@@ -88,7 +56,7 @@ class EGXHamiltonian(BaseHamiltonian):
|
|
88
56
|
|
89
57
|
t_gr = self.hopping_gr
|
90
58
|
t_x = self.hopping_x
|
91
|
-
a = self.lattice_constant
|
59
|
+
a = self.lattice.lattice_constant
|
92
60
|
v = self.hopping_x_gr_a
|
93
61
|
chemical_potential = self.chemical_potential
|
94
62
|
if k.ndim == 1:
|
@@ -144,7 +112,7 @@ class EGXHamiltonian(BaseHamiltonian):
|
|
144
112
|
|
145
113
|
t_gr = self.hopping_gr
|
146
114
|
t_x = self.hopping_x
|
147
|
-
a = self.lattice_constant
|
115
|
+
a = self.lattice.lattice_constant
|
148
116
|
if k.ndim == 1:
|
149
117
|
k = np.expand_dims(k, axis=0)
|
150
118
|
|
@@ -4,62 +4,37 @@
|
|
4
4
|
|
5
5
|
"""Provides the implementation for Graphene."""
|
6
6
|
|
7
|
-
from typing import Any
|
8
|
-
|
9
7
|
import numpy as np
|
10
8
|
import numpy.typing as npt
|
11
9
|
|
12
|
-
from .
|
10
|
+
from quant_met.geometry import GrapheneLattice
|
11
|
+
from quant_met.mean_field._utils import _check_valid_array
|
12
|
+
from quant_met.parameters.hamiltonians import GrapheneParameters
|
13
|
+
|
13
14
|
from .base_hamiltonian import BaseHamiltonian
|
14
15
|
|
15
16
|
|
16
|
-
class
|
17
|
+
class Graphene(BaseHamiltonian[GrapheneParameters]):
|
17
18
|
"""Hamiltonian for Graphene."""
|
18
19
|
|
19
20
|
def __init__(
|
20
21
|
self,
|
21
|
-
|
22
|
-
lattice_constant: float,
|
23
|
-
chemical_potential: float,
|
24
|
-
hubbard_int_gr: float,
|
25
|
-
delta: npt.NDArray[np.float64] | None = None,
|
26
|
-
*args: tuple[Any, ...],
|
27
|
-
**kwargs: tuple[dict[str, Any], ...],
|
22
|
+
parameters: GrapheneParameters,
|
28
23
|
) -> None:
|
29
|
-
|
30
|
-
|
31
|
-
self.
|
32
|
-
if
|
33
|
-
|
34
|
-
raise ValueError(msg)
|
35
|
-
self.lattice_constant = _validate_float(lattice_constant, "Lattice constant")
|
36
|
-
self.chemical_potential = _validate_float(chemical_potential, "Chemical potential")
|
37
|
-
self.hubbard_int_gr = _validate_float(hubbard_int_gr, "hubbard_int interaction")
|
38
|
-
self._hubbard_int_orbital_basis = np.array([self.hubbard_int_gr, self.hubbard_int_gr])
|
39
|
-
self._number_of_bands = 2
|
40
|
-
if delta is None:
|
41
|
-
self._delta_orbital_basis = np.zeros(self.number_of_bands, dtype=np.complex64)
|
42
|
-
else:
|
43
|
-
if delta.shape != (self.number_of_bands,):
|
44
|
-
msg = "Invalid input value for gaps."
|
45
|
-
raise ValueError(msg)
|
46
|
-
self._delta_orbital_basis = np.astype(delta, np.complex64)
|
47
|
-
|
48
|
-
@property
|
49
|
-
def number_of_bands(self) -> int: # noqa: D102
|
50
|
-
return self._number_of_bands
|
51
|
-
|
52
|
-
@property
|
53
|
-
def hubbard_int_orbital_basis(self) -> npt.NDArray[np.float64]: # noqa: D102
|
54
|
-
return self._hubbard_int_orbital_basis
|
24
|
+
super().__init__(parameters)
|
25
|
+
self.hopping = parameters.hopping
|
26
|
+
self.chemical_potential = parameters.chemical_potential
|
27
|
+
if parameters.delta is not None:
|
28
|
+
self.delta_orbital_basis = np.astype(parameters.delta, np.complex64)
|
55
29
|
|
56
|
-
|
57
|
-
|
58
|
-
return
|
30
|
+
def setup_lattice(self, parameters: GrapheneParameters) -> GrapheneLattice:
|
31
|
+
"""Set up lattice based on parameters."""
|
32
|
+
return GrapheneLattice(lattice_constant=parameters.lattice_constant)
|
59
33
|
|
60
|
-
@
|
61
|
-
def
|
62
|
-
|
34
|
+
@classmethod
|
35
|
+
def get_parameters_model(cls) -> type[GrapheneParameters]:
|
36
|
+
"""Return the specific parameters model for the subclass."""
|
37
|
+
return GrapheneParameters
|
63
38
|
|
64
39
|
def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
|
65
40
|
"""
|
@@ -78,7 +53,7 @@ class GrapheneHamiltonian(BaseHamiltonian):
|
|
78
53
|
"""
|
79
54
|
assert _check_valid_array(k)
|
80
55
|
hopping = self.hopping
|
81
|
-
lattice_constant = self.lattice_constant
|
56
|
+
lattice_constant = self.lattice.lattice_constant
|
82
57
|
chemical_potential = self.chemical_potential
|
83
58
|
if k.ndim == 1:
|
84
59
|
k = np.expand_dims(k, axis=0)
|
@@ -120,7 +95,7 @@ class GrapheneHamiltonian(BaseHamiltonian):
|
|
120
95
|
assert direction in ["x", "y"]
|
121
96
|
|
122
97
|
hopping = self.hopping
|
123
|
-
lattice_constant = self.lattice_constant
|
98
|
+
lattice_constant = self.lattice.lattice_constant
|
124
99
|
if k.ndim == 1:
|
125
100
|
k = np.expand_dims(k, axis=0)
|
126
101
|
|
@@ -4,62 +4,34 @@
|
|
4
4
|
|
5
5
|
"""Provides the implementation for Graphene."""
|
6
6
|
|
7
|
-
from typing import Any
|
8
|
-
|
9
7
|
import numpy as np
|
10
8
|
import numpy.typing as npt
|
11
9
|
|
12
|
-
from .
|
10
|
+
from quant_met.geometry import SquareLattice
|
11
|
+
from quant_met.mean_field._utils import _check_valid_array
|
12
|
+
from quant_met.parameters import OneBandParameters
|
13
|
+
|
13
14
|
from .base_hamiltonian import BaseHamiltonian
|
14
15
|
|
15
16
|
|
16
|
-
class
|
17
|
+
class OneBand(BaseHamiltonian[OneBandParameters]):
|
17
18
|
"""Hamiltonian for Graphene."""
|
18
19
|
|
19
|
-
def __init__(
|
20
|
-
|
21
|
-
hopping
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
delta: npt.NDArray[np.float64] | None = None,
|
26
|
-
*args: tuple[Any, ...],
|
27
|
-
**kwargs: tuple[dict[str, Any], ...],
|
28
|
-
) -> None:
|
29
|
-
del args
|
30
|
-
del kwargs
|
31
|
-
self.hopping = _validate_float(hopping, "Hopping")
|
32
|
-
if lattice_constant <= 0:
|
33
|
-
msg = "Lattice constant must be positive"
|
34
|
-
raise ValueError(msg)
|
35
|
-
self.lattice_constant = _validate_float(lattice_constant, "Lattice constant")
|
36
|
-
self.chemical_potential = _validate_float(chemical_potential, "Chemical potential")
|
37
|
-
self.hubbard_int = _validate_float(hubbard_int, "hubbard_int interaction")
|
38
|
-
self._hubbard_int_orbital_basis = np.array([self.hubbard_int])
|
39
|
-
self._number_of_bands = 1
|
40
|
-
if delta is None:
|
41
|
-
self._delta_orbital_basis = np.zeros(self.number_of_bands, dtype=np.complex64)
|
42
|
-
else:
|
43
|
-
if delta.shape != (self.number_of_bands,):
|
44
|
-
msg = "Invalid input value for gaps."
|
45
|
-
raise ValueError(msg)
|
46
|
-
self._delta_orbital_basis = np.astype(delta, np.complex64)
|
47
|
-
|
48
|
-
@property
|
49
|
-
def number_of_bands(self) -> int: # noqa: D102
|
50
|
-
return self._number_of_bands
|
51
|
-
|
52
|
-
@property
|
53
|
-
def hubbard_int_orbital_basis(self) -> npt.NDArray[np.float64]: # noqa: D102
|
54
|
-
return self._hubbard_int_orbital_basis
|
20
|
+
def __init__(self, parameters: OneBandParameters) -> None:
|
21
|
+
super().__init__(parameters)
|
22
|
+
self.hopping = parameters.hopping
|
23
|
+
self.chemical_potential = parameters.chemical_potential
|
24
|
+
if parameters.delta is not None:
|
25
|
+
self.delta_orbital_basis = np.astype(parameters.delta, np.complex64)
|
55
26
|
|
56
|
-
|
57
|
-
|
58
|
-
return
|
27
|
+
def setup_lattice(self, parameters: OneBandParameters) -> SquareLattice:
|
28
|
+
"""Set up lattice based on parameters."""
|
29
|
+
return SquareLattice(lattice_constant=parameters.lattice_constant)
|
59
30
|
|
60
|
-
@
|
61
|
-
def
|
62
|
-
|
31
|
+
@classmethod
|
32
|
+
def get_parameters_model(cls) -> type[OneBandParameters]:
|
33
|
+
"""Return the specific parameters model for the subclass."""
|
34
|
+
return OneBandParameters
|
63
35
|
|
64
36
|
def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
|
65
37
|
"""
|
@@ -78,7 +50,7 @@ class OneBandTightBindingHamiltonian(BaseHamiltonian):
|
|
78
50
|
"""
|
79
51
|
assert _check_valid_array(k)
|
80
52
|
hopping = self.hopping
|
81
|
-
lattice_constant = self.lattice_constant
|
53
|
+
lattice_constant = self.lattice.lattice_constant
|
82
54
|
chemical_potential = self.chemical_potential
|
83
55
|
if k.ndim == 1:
|
84
56
|
k = np.expand_dims(k, axis=0)
|
@@ -115,7 +87,7 @@ class OneBandTightBindingHamiltonian(BaseHamiltonian):
|
|
115
87
|
assert direction in ["x", "y"]
|
116
88
|
|
117
89
|
hopping = self.hopping
|
118
|
-
lattice_constant = self.lattice_constant
|
90
|
+
lattice_constant = self.lattice.lattice_constant
|
119
91
|
if k.ndim == 1:
|
120
92
|
k = np.expand_dims(k, axis=0)
|
121
93
|
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
|
5
|
+
"""Provides the implementation for Graphene."""
|
6
|
+
|
7
|
+
import numpy as np
|
8
|
+
import numpy.typing as npt
|
9
|
+
|
10
|
+
from quant_met.geometry import SquareLattice
|
11
|
+
from quant_met.mean_field._utils import _check_valid_array
|
12
|
+
from quant_met.parameters import ThreeBandParameters
|
13
|
+
|
14
|
+
from .base_hamiltonian import BaseHamiltonian
|
15
|
+
|
16
|
+
|
17
|
+
class ThreeBand(BaseHamiltonian[ThreeBandParameters]):
|
18
|
+
"""Hamiltonian for Graphene."""
|
19
|
+
|
20
|
+
def __init__(self, parameters: ThreeBandParameters) -> None:
|
21
|
+
super().__init__(parameters)
|
22
|
+
self.hopping = parameters.hopping
|
23
|
+
self.chemical_potential = parameters.chemical_potential
|
24
|
+
if parameters.delta is not None:
|
25
|
+
self.delta_orbital_basis = np.astype(parameters.delta, np.complex64)
|
26
|
+
|
27
|
+
def setup_lattice(self, parameters: ThreeBandParameters) -> SquareLattice:
|
28
|
+
"""Set up lattice based on parameters."""
|
29
|
+
return SquareLattice(lattice_constant=parameters.lattice_constant)
|
30
|
+
|
31
|
+
@classmethod
|
32
|
+
def get_parameters_model(cls) -> type[ThreeBandParameters]:
|
33
|
+
"""Return the specific parameters model for the subclass."""
|
34
|
+
return ThreeBandParameters
|
35
|
+
|
36
|
+
def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
|
37
|
+
"""
|
38
|
+
Return the normal state Hamiltonian in orbital basis.
|
39
|
+
|
40
|
+
Parameters
|
41
|
+
----------
|
42
|
+
k : :class:`numpy.ndarray`
|
43
|
+
List of k points.
|
44
|
+
|
45
|
+
Returns
|
46
|
+
-------
|
47
|
+
:class:`numpy.ndarray`
|
48
|
+
Hamiltonian in matrix form.
|
49
|
+
|
50
|
+
"""
|
51
|
+
assert _check_valid_array(k)
|
52
|
+
hopping = self.hopping
|
53
|
+
lattice_constant = self.lattice.lattice_constant
|
54
|
+
chemical_potential = self.chemical_potential
|
55
|
+
if k.ndim == 1:
|
56
|
+
k = np.expand_dims(k, axis=0)
|
57
|
+
|
58
|
+
h = np.zeros((k.shape[0], self.number_of_bands, self.number_of_bands), dtype=np.complex64)
|
59
|
+
|
60
|
+
h[:, 0, 0] = (
|
61
|
+
-2 * hopping * (np.cos(k[:, 1] * lattice_constant) + np.cos(k[:, 0] * lattice_constant))
|
62
|
+
)
|
63
|
+
h[:, 1, 1] = (
|
64
|
+
-2 * hopping * (np.cos(k[:, 1] * lattice_constant) + np.cos(k[:, 0] * lattice_constant))
|
65
|
+
)
|
66
|
+
h[:, 2, 2] = (
|
67
|
+
-2 * hopping * (np.cos(k[:, 1] * lattice_constant) + np.cos(k[:, 0] * lattice_constant))
|
68
|
+
)
|
69
|
+
h[:, 2, 0] = 0.5
|
70
|
+
h[:, 0, 2] = 0.5
|
71
|
+
|
72
|
+
h[:, 0, 0] -= chemical_potential
|
73
|
+
h[:, 1, 1] -= chemical_potential
|
74
|
+
h[:, 2, 2] -= chemical_potential
|
75
|
+
|
76
|
+
return h.squeeze()
|
77
|
+
|
78
|
+
def hamiltonian_derivative(
|
79
|
+
self, k: npt.NDArray[np.float64], direction: str
|
80
|
+
) -> npt.NDArray[np.complex64]:
|
81
|
+
"""
|
82
|
+
Deriative of the Hamiltonian.
|
83
|
+
|
84
|
+
Parameters
|
85
|
+
----------
|
86
|
+
k: :class:`numpy.ndarray`
|
87
|
+
List of k points.
|
88
|
+
direction: str
|
89
|
+
Direction for derivative, either 'x' oder 'y'.
|
90
|
+
|
91
|
+
Returns
|
92
|
+
-------
|
93
|
+
:class:`numpy.ndarray`
|
94
|
+
Derivative of Hamiltonian.
|
95
|
+
|
96
|
+
"""
|
97
|
+
assert _check_valid_array(k)
|
98
|
+
assert direction in ["x", "y"]
|
99
|
+
|
100
|
+
hopping = self.hopping
|
101
|
+
lattice_constant = self.lattice.lattice_constant
|
102
|
+
if k.ndim == 1:
|
103
|
+
k = np.expand_dims(k, axis=0)
|
104
|
+
|
105
|
+
h = np.zeros((k.shape[0], self.number_of_bands, self.number_of_bands), dtype=np.complex64)
|
106
|
+
|
107
|
+
if direction == "x":
|
108
|
+
h[:, 0, 0] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
|
109
|
+
h[:, 1, 1] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
|
110
|
+
h[:, 2, 2] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
|
111
|
+
else:
|
112
|
+
h[:, 0, 0] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
|
113
|
+
h[:, 1, 1] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
|
114
|
+
h[:, 2, 2] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
|
115
|
+
|
116
|
+
return h.squeeze()
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
|
5
|
+
"""Provides the implementation for Graphene."""
|
6
|
+
|
7
|
+
import numpy as np
|
8
|
+
import numpy.typing as npt
|
9
|
+
|
10
|
+
from quant_met.geometry import SquareLattice
|
11
|
+
from quant_met.mean_field._utils import _check_valid_array
|
12
|
+
from quant_met.parameters import TwoBandParameters
|
13
|
+
|
14
|
+
from .base_hamiltonian import BaseHamiltonian
|
15
|
+
|
16
|
+
|
17
|
+
class TwoBand(BaseHamiltonian[TwoBandParameters]):
|
18
|
+
"""Hamiltonian for Graphene."""
|
19
|
+
|
20
|
+
def __init__(self, parameters: TwoBandParameters) -> None:
|
21
|
+
super().__init__(parameters)
|
22
|
+
self.hopping = parameters.hopping
|
23
|
+
self.chemical_potential = parameters.chemical_potential
|
24
|
+
if parameters.delta is not None:
|
25
|
+
self.delta_orbital_basis = np.astype(parameters.delta, np.complex64)
|
26
|
+
|
27
|
+
def setup_lattice(self, parameters: TwoBandParameters) -> SquareLattice:
|
28
|
+
"""Set up lattice based on parameters."""
|
29
|
+
return SquareLattice(lattice_constant=parameters.lattice_constant)
|
30
|
+
|
31
|
+
@classmethod
|
32
|
+
def get_parameters_model(cls) -> type[TwoBandParameters]:
|
33
|
+
"""Return the specific parameters model for the subclass."""
|
34
|
+
return TwoBandParameters
|
35
|
+
|
36
|
+
def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
|
37
|
+
"""
|
38
|
+
Return the normal state Hamiltonian in orbital basis.
|
39
|
+
|
40
|
+
Parameters
|
41
|
+
----------
|
42
|
+
k : :class:`numpy.ndarray`
|
43
|
+
List of k points.
|
44
|
+
|
45
|
+
Returns
|
46
|
+
-------
|
47
|
+
:class:`numpy.ndarray`
|
48
|
+
Hamiltonian in matrix form.
|
49
|
+
|
50
|
+
"""
|
51
|
+
assert _check_valid_array(k)
|
52
|
+
hopping = self.hopping
|
53
|
+
lattice_constant = self.lattice.lattice_constant
|
54
|
+
chemical_potential = self.chemical_potential
|
55
|
+
if k.ndim == 1:
|
56
|
+
k = np.expand_dims(k, axis=0)
|
57
|
+
|
58
|
+
h = np.zeros((k.shape[0], self.number_of_bands, self.number_of_bands), dtype=np.complex64)
|
59
|
+
|
60
|
+
h[:, 0, 0] = (
|
61
|
+
-2 * hopping * (np.cos(k[:, 1] * lattice_constant) + np.cos(k[:, 0] * lattice_constant))
|
62
|
+
)
|
63
|
+
h[:, 1, 1] = (
|
64
|
+
-2 * hopping * (np.cos(k[:, 1] * lattice_constant) + np.cos(k[:, 0] * lattice_constant))
|
65
|
+
)
|
66
|
+
h[:, 0, 0] -= chemical_potential
|
67
|
+
h[:, 1, 1] -= chemical_potential
|
68
|
+
|
69
|
+
return h.squeeze()
|
70
|
+
|
71
|
+
def hamiltonian_derivative(
|
72
|
+
self, k: npt.NDArray[np.float64], direction: str
|
73
|
+
) -> npt.NDArray[np.complex64]:
|
74
|
+
"""
|
75
|
+
Deriative of the Hamiltonian.
|
76
|
+
|
77
|
+
Parameters
|
78
|
+
----------
|
79
|
+
k: :class:`numpy.ndarray`
|
80
|
+
List of k points.
|
81
|
+
direction: str
|
82
|
+
Direction for derivative, either 'x' oder 'y'.
|
83
|
+
|
84
|
+
Returns
|
85
|
+
-------
|
86
|
+
:class:`numpy.ndarray`
|
87
|
+
Derivative of Hamiltonian.
|
88
|
+
|
89
|
+
"""
|
90
|
+
assert _check_valid_array(k)
|
91
|
+
assert direction in ["x", "y"]
|
92
|
+
|
93
|
+
hopping = self.hopping
|
94
|
+
lattice_constant = self.lattice.lattice_constant
|
95
|
+
if k.ndim == 1:
|
96
|
+
k = np.expand_dims(k, axis=0)
|
97
|
+
|
98
|
+
h = np.zeros((k.shape[0], self.number_of_bands, self.number_of_bands), dtype=np.complex64)
|
99
|
+
|
100
|
+
if direction == "x":
|
101
|
+
h[:, 0, 0] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
|
102
|
+
h[:, 1, 1] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
|
103
|
+
else:
|
104
|
+
h[:, 0, 0] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
|
105
|
+
h[:, 1, 1] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
|
106
|
+
|
107
|
+
return h.squeeze()
|
@@ -7,11 +7,12 @@
|
|
7
7
|
import numpy as np
|
8
8
|
import numpy.typing as npt
|
9
9
|
|
10
|
-
from .base_hamiltonian import BaseHamiltonian
|
10
|
+
from quant_met.mean_field.hamiltonians.base_hamiltonian import BaseHamiltonian
|
11
|
+
from quant_met.parameters import GenericParameters
|
11
12
|
|
12
13
|
|
13
14
|
def quantum_metric(
|
14
|
-
h: BaseHamiltonian, k_grid: npt.NDArray[np.float64], bands: list[int]
|
15
|
+
h: BaseHamiltonian[GenericParameters], k_grid: npt.NDArray[np.float64], bands: list[int]
|
15
16
|
) -> npt.NDArray[np.float64]:
|
16
17
|
"""Calculate the quantum metric in the normal state.
|
17
18
|
|
@@ -60,7 +61,7 @@ def quantum_metric(
|
|
60
61
|
|
61
62
|
|
62
63
|
def quantum_metric_bdg(
|
63
|
-
h: BaseHamiltonian, k_grid: npt.NDArray[np.float64], bands: list[int]
|
64
|
+
h: BaseHamiltonian[GenericParameters], k_grid: npt.NDArray[np.float64], bands: list[int]
|
64
65
|
) -> npt.NDArray[np.float64]:
|
65
66
|
"""Calculate the quantum metric in the BdG state.
|
66
67
|
|
@@ -5,35 +5,36 @@
|
|
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
|
11
|
+
from quant_met.parameters import GenericParameters
|
12
12
|
|
13
13
|
|
14
14
|
def self_consistency_loop(
|
15
|
-
h: BaseHamiltonian,
|
16
|
-
|
15
|
+
h: BaseHamiltonian[GenericParameters],
|
16
|
+
k_space_grid: npt.NDArray[np.float64],
|
17
|
+
epsilon: float,
|
18
|
+
) -> BaseHamiltonian[GenericParameters]:
|
17
19
|
"""Self-consistency loop.
|
18
20
|
|
19
21
|
Parameters
|
20
22
|
----------
|
21
|
-
|
22
|
-
number_of_k_points
|
23
|
+
k_space_grid
|
23
24
|
h
|
24
25
|
epsilon
|
25
26
|
"""
|
26
|
-
lattice = geometry.Graphene(lattice_constant=np.sqrt(3))
|
27
|
-
k_space_grid = lattice.generate_bz_grid(ncols=number_of_k_points, nrows=number_of_k_points)
|
28
27
|
rng = np.random.default_rng()
|
29
|
-
delta_init = np.zeros(shape=h.delta_orbital_basis.shape, dtype=np.
|
30
|
-
rng.random(size=h.delta_orbital_basis.shape
|
31
|
-
|
28
|
+
delta_init = np.zeros(shape=h.delta_orbital_basis.shape, dtype=np.complex64)
|
29
|
+
delta_init += (0.2 * rng.random(size=h.delta_orbital_basis.shape) - 1) + 1.0j * (
|
30
|
+
0.2 * rng.random(size=h.delta_orbital_basis.shape) - 1
|
31
|
+
)
|
32
|
+
h.delta_orbital_basis = delta_init
|
32
33
|
|
33
34
|
while True:
|
34
|
-
new_gap = h.gap_equation(k=k_space_grid
|
35
|
+
new_gap = h.gap_equation(k=k_space_grid)
|
35
36
|
if (np.abs(h.delta_orbital_basis - new_gap) < epsilon).all():
|
36
37
|
h.delta_orbital_basis = new_gap
|
37
38
|
return h
|
38
|
-
mixing_greed = 0.
|
39
|
+
mixing_greed = 0.5
|
39
40
|
h.delta_orbital_basis = mixing_greed * new_gap + (1 - mixing_greed) * h.delta_orbital_basis
|
@@ -7,11 +7,12 @@
|
|
7
7
|
import numpy as np
|
8
8
|
import numpy.typing as npt
|
9
9
|
|
10
|
-
from .base_hamiltonian import BaseHamiltonian
|
10
|
+
from quant_met.mean_field.hamiltonians.base_hamiltonian import BaseHamiltonian
|
11
|
+
from quant_met.parameters import GenericParameters
|
11
12
|
|
12
13
|
|
13
14
|
def superfluid_weight(
|
14
|
-
h: BaseHamiltonian,
|
15
|
+
h: BaseHamiltonian[GenericParameters],
|
15
16
|
k_grid: npt.NDArray[np.float64],
|
16
17
|
) -> tuple[npt.NDArray[np.complex64], npt.NDArray[np.complex64]]:
|
17
18
|
"""Calculate the superfluid weight.
|
@@ -54,7 +55,7 @@ def superfluid_weight(
|
|
54
55
|
|
55
56
|
|
56
57
|
def _current_operator(
|
57
|
-
h: BaseHamiltonian, direction: str, k: npt.NDArray[np.float64]
|
58
|
+
h: BaseHamiltonian[GenericParameters], direction: str, k: npt.NDArray[np.float64]
|
58
59
|
) -> npt.NDArray[np.complex64]:
|
59
60
|
j = np.zeros(shape=(h.number_of_bands, h.number_of_bands), dtype=np.complex64)
|
60
61
|
|
@@ -71,7 +72,9 @@ def _current_operator(
|
|
71
72
|
return j
|
72
73
|
|
73
74
|
|
74
|
-
def _c_factor(
|
75
|
+
def _c_factor(
|
76
|
+
h: BaseHamiltonian[GenericParameters], k: npt.NDArray[np.float64]
|
77
|
+
) -> npt.NDArray[np.complex64]:
|
75
78
|
bdg_energies, bdg_functions = h.diagonalize_bdg(k)
|
76
79
|
c_mnpq = np.zeros(
|
77
80
|
shape=(
|