quant-met 0.0.8__py3-none-any.whl → 0.0.10__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.
Files changed (31) hide show
  1. quant_met/cli/__init__.py +2 -5
  2. quant_met/cli/main.py +30 -3
  3. quant_met/cli/scf.py +40 -10
  4. quant_met/geometry/__init__.py +1 -1
  5. quant_met/geometry/base_lattice.py +18 -4
  6. quant_met/geometry/graphene.py +10 -2
  7. quant_met/geometry/square.py +11 -3
  8. quant_met/mean_field/__init__.py +3 -5
  9. quant_met/mean_field/_utils.py +0 -11
  10. quant_met/mean_field/hamiltonians/__init__.py +7 -8
  11. quant_met/mean_field/hamiltonians/base_hamiltonian.py +202 -176
  12. quant_met/mean_field/hamiltonians/dressed_graphene.py +21 -108
  13. quant_met/mean_field/hamiltonians/graphene.py +14 -93
  14. quant_met/mean_field/hamiltonians/one_band_tight_binding.py +17 -97
  15. quant_met/mean_field/hamiltonians/three_band_tight_binding.py +84 -0
  16. quant_met/mean_field/hamiltonians/two_band_tight_binding.py +75 -0
  17. quant_met/mean_field/quantum_metric.py +18 -57
  18. quant_met/mean_field/self_consistency.py +54 -20
  19. quant_met/mean_field/superfluid_weight.py +6 -3
  20. quant_met/parameters/__init__.py +28 -5
  21. quant_met/parameters/hamiltonians.py +146 -16
  22. quant_met/parameters/main.py +35 -6
  23. quant_met/plotting/__init__.py +0 -3
  24. quant_met/plotting/plotting.py +0 -34
  25. {quant_met-0.0.8.dist-info → quant_met-0.0.10.dist-info}/METADATA +1 -1
  26. quant_met-0.0.10.dist-info/RECORD +33 -0
  27. quant_met-0.0.8.dist-info/RECORD +0 -31
  28. {quant_met-0.0.8.dist-info → quant_met-0.0.10.dist-info}/LICENSE.txt +0 -0
  29. {quant_met-0.0.8.dist-info → quant_met-0.0.10.dist-info}/LICENSES/MIT.txt +0 -0
  30. {quant_met-0.0.8.dist-info → quant_met-0.0.10.dist-info}/WHEEL +0 -0
  31. {quant_met-0.0.8.dist-info → quant_met-0.0.10.dist-info}/entry_points.txt +0 -0
@@ -2,111 +2,40 @@
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
4
 
5
- """Provides the implementation for the EG-X model."""
5
+ """Provides the implementation for the dressed graphene model."""
6
6
 
7
- import pathlib
8
- from typing import Any
9
-
10
- import h5py
11
7
  import numpy as np
12
8
  import numpy.typing as npt
13
9
 
10
+ from quant_met.geometry import BaseLattice
14
11
  from quant_met.geometry.graphene import GrapheneLattice
15
- from quant_met.mean_field._utils import _check_valid_array, _validate_float
12
+ from quant_met.mean_field._utils import _check_valid_array
16
13
  from quant_met.parameters.hamiltonians import DressedGrapheneParameters
17
14
 
18
15
  from .base_hamiltonian import BaseHamiltonian
19
16
 
20
17
 
21
- class DressedGraphene(BaseHamiltonian):
22
- """Hamiltonian for the EG-X model."""
23
-
24
- def __init__(
25
- self,
26
- parameters: DressedGrapheneParameters,
27
- *args: tuple[Any, ...],
28
- **kwargs: tuple[dict[str, Any], ...],
29
- ) -> None:
30
- del args
31
- del kwargs
32
- self._name = parameters.name
33
- self.hopping_gr = _validate_float(parameters.hopping_gr, "Hopping graphene")
34
- self.hopping_x = _validate_float(parameters.hopping_x, "Hopping impurity")
35
- self.hopping_x_gr_a = _validate_float(parameters.hopping_x_gr_a, "Hybridisation")
36
- if parameters.lattice_constant <= 0:
37
- msg = "Lattice constant must be positive"
38
- raise ValueError(msg)
39
- self._lattice = GrapheneLattice(
40
- lattice_constant=np.float64(
41
- _validate_float(parameters.lattice_constant, "Lattice constant")
42
- )
43
- )
44
- self.lattice_constant = self._lattice.lattice_constant
45
- self.chemical_potential = _validate_float(
46
- parameters.chemical_potential, "Chemical potential"
47
- )
48
- self.hubbard_int_gr = _validate_float(
49
- parameters.hubbard_int_gr, "hubbard_int interaction graphene"
50
- )
51
- self.hubbard_int_x = _validate_float(
52
- parameters.hubbard_int_x, "hubbard_int interaction impurity"
53
- )
54
- self._hubbard_int_orbital_basis = np.array(
55
- [self.hubbard_int_gr, self.hubbard_int_gr, self.hubbard_int_x]
56
- )
57
- self._number_of_bands = 3
58
- if parameters.delta is None:
59
- self._delta_orbital_basis = np.zeros(self.number_of_bands, dtype=np.complex64)
60
- else:
61
- self._delta_orbital_basis = np.astype(parameters.delta, np.complex64)
62
-
63
- @property
64
- def name(self) -> str: # noqa: D102
65
- return self._name
66
-
67
- @property
68
- def hubbard_int_orbital_basis(self) -> npt.NDArray[np.float64]: # noqa: D102
69
- return self._hubbard_int_orbital_basis
18
+ class DressedGraphene(BaseHamiltonian[DressedGrapheneParameters]):
19
+ """Hamiltonian for the dressed graphene model."""
70
20
 
71
- @property
72
- def delta_orbital_basis(self) -> npt.NDArray[np.complex64]: # noqa: D102
73
- return self._delta_orbital_basis
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)
74
30
 
75
- @delta_orbital_basis.setter
76
- def delta_orbital_basis(self, new_delta: npt.NDArray[np.complex64]) -> None:
77
- self._delta_orbital_basis = new_delta
78
-
79
- @property
80
- def number_of_bands(self) -> int: # noqa: D102
81
- return self._number_of_bands
82
-
83
- @property
84
- def lattice(self) -> GrapheneLattice: # noqa: D102
85
- return self._lattice
31
+ def setup_lattice(self, parameters: DressedGrapheneParameters) -> BaseLattice: # noqa: D102
32
+ return GrapheneLattice(lattice_constant=parameters.lattice_constant)
86
33
 
87
34
  @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
-
95
- def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
96
- """
97
- Return the normal state Hamiltonian in orbital basis.
98
-
99
- Parameters
100
- ----------
101
- k : :class:`numpy.ndarray`
102
- List of k points.
103
-
104
- Returns
105
- -------
106
- :class:`numpy.ndarray`
107
- Hamiltonian in matrix form.
108
-
109
- """
35
+ def get_parameters_model(cls) -> type[DressedGrapheneParameters]: # noqa: D102
36
+ return DressedGrapheneParameters
37
+
38
+ def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]: # noqa: D102
110
39
  assert _check_valid_array(k)
111
40
 
112
41
  t_gr = self.hopping_gr
@@ -143,25 +72,9 @@ class DressedGraphene(BaseHamiltonian):
143
72
 
144
73
  return h.squeeze()
145
74
 
146
- def hamiltonian_derivative(
75
+ def hamiltonian_derivative( # noqa: D102
147
76
  self, k: npt.NDArray[np.float64], direction: str
148
77
  ) -> npt.NDArray[np.complex64]:
149
- """
150
- Deriative of the Hamiltonian.
151
-
152
- Parameters
153
- ----------
154
- k: :class:`numpy.ndarray`
155
- List of k points.
156
- direction: str
157
- Direction for derivative, either 'x' oder 'y'.
158
-
159
- Returns
160
- -------
161
- :class:`numpy.ndarray`
162
- Derivative of Hamiltonian.
163
-
164
- """
165
78
  assert _check_valid_array(k)
166
79
  assert direction in ["x", "y"]
167
80
 
@@ -4,100 +4,37 @@
4
4
 
5
5
  """Provides the implementation for Graphene."""
6
6
 
7
- import pathlib
8
- from typing import Any
9
-
10
- import h5py
11
7
  import numpy as np
12
8
  import numpy.typing as npt
13
9
 
14
10
  from quant_met.geometry import GrapheneLattice
15
- from quant_met.mean_field._utils import _check_valid_array, _validate_float
11
+ from quant_met.mean_field._utils import _check_valid_array
16
12
  from quant_met.parameters.hamiltonians import GrapheneParameters
17
13
 
18
14
  from .base_hamiltonian import BaseHamiltonian
19
15
 
20
16
 
21
- class Graphene(BaseHamiltonian):
17
+ class Graphene(BaseHamiltonian[GrapheneParameters]):
22
18
  """Hamiltonian for Graphene."""
23
19
 
24
20
  def __init__(
25
21
  self,
26
22
  parameters: GrapheneParameters,
27
- *args: tuple[Any, ...],
28
- **kwargs: tuple[dict[str, Any], ...],
29
23
  ) -> None:
30
- del args
31
- del kwargs
32
- self._name = parameters.name
33
- self.hopping = _validate_float(parameters.hopping, "Hopping")
34
- if parameters.lattice_constant <= 0:
35
- msg = "Lattice constant must be positive"
36
- raise ValueError(msg)
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])
48
- self._number_of_bands = 2
49
- if parameters.delta is None:
50
- self._delta_orbital_basis = np.zeros(self.number_of_bands, dtype=np.complex64)
51
- else:
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
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)
57
29
 
58
- @property
59
- def lattice(self) -> GrapheneLattice: # noqa: D102
60
- return self._lattice
61
-
62
- @property
63
- def number_of_bands(self) -> int: # noqa: D102
64
- return self._number_of_bands
65
-
66
- @property
67
- def hubbard_int_orbital_basis(self) -> npt.NDArray[np.float64]: # noqa: D102
68
- return self._hubbard_int_orbital_basis
69
-
70
- @property
71
- def delta_orbital_basis(self) -> npt.NDArray[np.complex64]: # noqa: D102
72
- return self._delta_orbital_basis
73
-
74
- @delta_orbital_basis.setter
75
- def delta_orbital_basis(self, new_delta: npt.NDArray[np.complex64]) -> None:
76
- self._delta_orbital_basis = new_delta
30
+ def setup_lattice(self, parameters: GrapheneParameters) -> GrapheneLattice: # noqa: D102
31
+ return GrapheneLattice(lattice_constant=parameters.lattice_constant)
77
32
 
78
33
  @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
-
86
- def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
87
- """
88
- Return the normal state Hamiltonian in orbital basis.
89
-
90
- Parameters
91
- ----------
92
- k : :class:`numpy.ndarray`
93
- List of k points.
94
-
95
- Returns
96
- -------
97
- :class:`numpy.ndarray`
98
- Hamiltonian in matrix form.
99
-
100
- """
34
+ def get_parameters_model(cls) -> type[GrapheneParameters]: # noqa: D102
35
+ return GrapheneParameters
36
+
37
+ def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]: # noqa: D102
101
38
  assert _check_valid_array(k)
102
39
  hopping = self.hopping
103
40
  lattice_constant = self.lattice.lattice_constant
@@ -119,25 +56,9 @@ class Graphene(BaseHamiltonian):
119
56
 
120
57
  return h.squeeze()
121
58
 
122
- def hamiltonian_derivative(
59
+ def hamiltonian_derivative( # noqa: D102
123
60
  self, k: npt.NDArray[np.float64], direction: str
124
61
  ) -> npt.NDArray[np.complex64]:
125
- """
126
- Deriative of the Hamiltonian.
127
-
128
- Parameters
129
- ----------
130
- k: :class:`numpy.ndarray`
131
- List of k points.
132
- direction: str
133
- Direction for derivative, either 'x' oder 'y'.
134
-
135
- Returns
136
- -------
137
- :class:`numpy.ndarray`
138
- Derivative of Hamiltonian.
139
-
140
- """
141
62
  assert _check_valid_array(k)
142
63
  assert direction in ["x", "y"]
143
64
 
@@ -2,100 +2,36 @@
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
4
 
5
- """Provides the implementation for Graphene."""
5
+ """Provides the implementation for a one band tight binding model."""
6
6
 
7
- import pathlib
8
- from typing import Any
9
-
10
- import h5py
11
7
  import numpy as np
12
8
  import numpy.typing as npt
13
9
 
14
10
  from quant_met.geometry import SquareLattice
15
- from quant_met.mean_field._utils import _check_valid_array, _validate_float
11
+ from quant_met.mean_field._utils import _check_valid_array
16
12
  from quant_met.parameters import OneBandParameters
17
13
 
18
14
  from .base_hamiltonian import BaseHamiltonian
19
15
 
20
16
 
21
- class OneBand(BaseHamiltonian):
22
- """Hamiltonian for Graphene."""
23
-
24
- def __init__(
25
- self,
26
- parameters: OneBandParameters,
27
- *args: tuple[Any, ...],
28
- **kwargs: tuple[dict[str, Any], ...],
29
- ) -> None:
30
- del args
31
- del kwargs
32
- self._name = parameters.name
33
- self.hopping = _validate_float(parameters.hopping, "Hopping")
34
- if parameters.lattice_constant <= 0:
35
- msg = "Lattice constant must be positive"
36
- raise ValueError(msg)
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")
45
- self._hubbard_int_orbital_basis = np.array([self.hubbard_int])
46
- self._number_of_bands = 1
47
- if parameters.delta is None:
48
- self._delta_orbital_basis = np.zeros(self.number_of_bands, dtype=np.complex64)
49
- else:
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
17
+ class OneBand(BaseHamiltonian[OneBandParameters]):
18
+ """Hamiltonian for one band tight binding model."""
55
19
 
56
- @property
57
- def lattice(self) -> SquareLattice: # noqa: D102
58
- return self._lattice
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)
59
26
 
60
- @property
61
- def number_of_bands(self) -> int: # noqa: D102
62
- return self._number_of_bands
63
-
64
- @property
65
- def hubbard_int_orbital_basis(self) -> npt.NDArray[np.float64]: # noqa: D102
66
- return self._hubbard_int_orbital_basis
67
-
68
- @property
69
- def delta_orbital_basis(self) -> npt.NDArray[np.complex64]: # noqa: D102
70
- return self._delta_orbital_basis
71
-
72
- @delta_orbital_basis.setter
73
- def delta_orbital_basis(self, new_delta: npt.NDArray[np.complex64]) -> None:
74
- self._delta_orbital_basis = new_delta
27
+ def setup_lattice(self, parameters: OneBandParameters) -> SquareLattice: # noqa: D102
28
+ return SquareLattice(lattice_constant=parameters.lattice_constant)
75
29
 
76
30
  @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
-
84
- def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]:
85
- """
86
- Return the normal state Hamiltonian in orbital basis.
87
-
88
- Parameters
89
- ----------
90
- k : :class:`numpy.ndarray`
91
- List of k points.
92
-
93
- Returns
94
- -------
95
- :class:`numpy.ndarray`
96
- Hamiltonian in matrix form.
97
-
98
- """
31
+ def get_parameters_model(cls) -> type[OneBandParameters]: # noqa: D102
32
+ return OneBandParameters
33
+
34
+ def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]: # noqa: D102
99
35
  assert _check_valid_array(k)
100
36
  hopping = self.hopping
101
37
  lattice_constant = self.lattice.lattice_constant
@@ -112,25 +48,9 @@ class OneBand(BaseHamiltonian):
112
48
 
113
49
  return h
114
50
 
115
- def hamiltonian_derivative(
51
+ def hamiltonian_derivative( # noqa: D102
116
52
  self, k: npt.NDArray[np.float64], direction: str
117
53
  ) -> npt.NDArray[np.complex64]:
118
- """
119
- Deriative of the Hamiltonian.
120
-
121
- Parameters
122
- ----------
123
- k: :class:`numpy.ndarray`
124
- List of k points.
125
- direction: str
126
- Direction for derivative, either 'x' oder 'y'.
127
-
128
- Returns
129
- -------
130
- :class:`numpy.ndarray`
131
- Derivative of Hamiltonian.
132
-
133
- """
134
54
  assert _check_valid_array(k)
135
55
  assert direction in ["x", "y"]
136
56
 
@@ -0,0 +1,84 @@
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """Provides the implementation for a three band tight binding model."""
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: # noqa: D102
28
+ return SquareLattice(lattice_constant=parameters.lattice_constant)
29
+
30
+ @classmethod
31
+ def get_parameters_model(cls) -> type[ThreeBandParameters]: # noqa: D102
32
+ return ThreeBandParameters
33
+
34
+ def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]: # noqa: D102
35
+ assert _check_valid_array(k)
36
+ hopping = self.hopping
37
+ lattice_constant = self.lattice.lattice_constant
38
+ chemical_potential = self.chemical_potential
39
+ if k.ndim == 1:
40
+ k = np.expand_dims(k, axis=0)
41
+
42
+ h = np.zeros((k.shape[0], self.number_of_bands, self.number_of_bands), dtype=np.complex64)
43
+
44
+ h[:, 0, 0] = (
45
+ -2 * hopping * (np.cos(k[:, 1] * lattice_constant) + np.cos(k[:, 0] * lattice_constant))
46
+ )
47
+ h[:, 1, 1] = (
48
+ -2 * hopping * (np.cos(k[:, 1] * lattice_constant) + np.cos(k[:, 0] * lattice_constant))
49
+ )
50
+ h[:, 2, 2] = (
51
+ -2 * hopping * (np.cos(k[:, 1] * lattice_constant) + np.cos(k[:, 0] * lattice_constant))
52
+ )
53
+ h[:, 2, 0] = 0.5
54
+ h[:, 0, 2] = 0.5
55
+
56
+ h[:, 0, 0] -= chemical_potential
57
+ h[:, 1, 1] -= chemical_potential
58
+ h[:, 2, 2] -= chemical_potential
59
+
60
+ return h.squeeze()
61
+
62
+ def hamiltonian_derivative( # noqa: D102
63
+ self, k: npt.NDArray[np.float64], direction: str
64
+ ) -> npt.NDArray[np.complex64]:
65
+ assert _check_valid_array(k)
66
+ assert direction in ["x", "y"]
67
+
68
+ hopping = self.hopping
69
+ lattice_constant = self.lattice.lattice_constant
70
+ if k.ndim == 1:
71
+ k = np.expand_dims(k, axis=0)
72
+
73
+ h = np.zeros((k.shape[0], self.number_of_bands, self.number_of_bands), dtype=np.complex64)
74
+
75
+ if direction == "x":
76
+ h[:, 0, 0] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
77
+ h[:, 1, 1] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
78
+ h[:, 2, 2] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
79
+ else:
80
+ h[:, 0, 0] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
81
+ h[:, 1, 1] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
82
+ h[:, 2, 2] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
83
+
84
+ return h.squeeze()
@@ -0,0 +1,75 @@
1
+ # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """Provides the implementation for a two band tight binding model."""
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: # noqa: D102
28
+ return SquareLattice(lattice_constant=parameters.lattice_constant)
29
+
30
+ @classmethod
31
+ def get_parameters_model(cls) -> type[TwoBandParameters]: # noqa: D102
32
+ return TwoBandParameters
33
+
34
+ def hamiltonian(self, k: npt.NDArray[np.float64]) -> npt.NDArray[np.complex64]: # noqa: D102
35
+ assert _check_valid_array(k)
36
+ hopping = self.hopping
37
+ lattice_constant = self.lattice.lattice_constant
38
+ chemical_potential = self.chemical_potential
39
+ if k.ndim == 1:
40
+ k = np.expand_dims(k, axis=0)
41
+
42
+ h = np.zeros((k.shape[0], self.number_of_bands, self.number_of_bands), dtype=np.complex64)
43
+
44
+ h[:, 0, 0] = (
45
+ -2 * hopping * (np.cos(k[:, 1] * lattice_constant) + np.cos(k[:, 0] * lattice_constant))
46
+ )
47
+ h[:, 1, 1] = (
48
+ -2 * hopping * (np.cos(k[:, 1] * lattice_constant) + np.cos(k[:, 0] * lattice_constant))
49
+ )
50
+ h[:, 0, 0] -= chemical_potential
51
+ h[:, 1, 1] -= chemical_potential
52
+
53
+ return h.squeeze()
54
+
55
+ def hamiltonian_derivative( # noqa: D102
56
+ self, k: npt.NDArray[np.float64], direction: str
57
+ ) -> npt.NDArray[np.complex64]:
58
+ assert _check_valid_array(k)
59
+ assert direction in ["x", "y"]
60
+
61
+ hopping = self.hopping
62
+ lattice_constant = self.lattice.lattice_constant
63
+ if k.ndim == 1:
64
+ k = np.expand_dims(k, axis=0)
65
+
66
+ h = np.zeros((k.shape[0], self.number_of_bands, self.number_of_bands), dtype=np.complex64)
67
+
68
+ if direction == "x":
69
+ h[:, 0, 0] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
70
+ h[:, 1, 1] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
71
+ else:
72
+ h[:, 0, 0] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
73
+ h[:, 1, 1] = -2 * hopping * lattice_constant * np.sin(lattice_constant * k[:, 0])
74
+
75
+ return h.squeeze()