quant-met 0.0.27__py3-none-any.whl → 0.1.1__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 (47) hide show
  1. quant_met/__init__.py +2 -7
  2. quant_met/bdg/__init__.py +26 -0
  3. quant_met/bdg/bdg_hamiltonian.py +97 -0
  4. quant_met/bdg/gap_equation.py +127 -0
  5. quant_met/bdg/sc_current.py +60 -0
  6. quant_met/bdg/superfluid_weight.py +110 -0
  7. quant_met/cli/__init__.py +0 -5
  8. quant_met/cli/crit_temp.py +18 -16
  9. quant_met/cli/main.py +8 -5
  10. quant_met/cli/q_analysis.py +60 -0
  11. quant_met/cli/q_loop.py +95 -0
  12. quant_met/cli/scf.py +44 -23
  13. quant_met/parameters/__init__.py +0 -26
  14. quant_met/parameters/control.py +57 -0
  15. quant_met/parameters/main.py +2 -55
  16. quant_met/quantum_geometry/__init__.py +13 -0
  17. quant_met/quantum_geometry/qgt.py +37 -0
  18. quant_met/routines/__init__.py +22 -0
  19. quant_met/routines/analyse_q_data.py +226 -0
  20. quant_met/routines/loop_over_q.py +154 -0
  21. quant_met/{mean_field → routines}/search_crit_temp.py +71 -48
  22. quant_met/{mean_field → routines}/self_consistency.py +32 -28
  23. quant_met/utils.py +1 -6
  24. {quant_met-0.0.27.dist-info → quant_met-0.1.1.dist-info}/METADATA +5 -11
  25. quant_met-0.1.1.dist-info/RECORD +28 -0
  26. quant_met/cli/_utils.py +0 -32
  27. quant_met/geometry/__init__.py +0 -36
  28. quant_met/geometry/base_lattice.py +0 -100
  29. quant_met/geometry/bz_path.py +0 -90
  30. quant_met/geometry/graphene.py +0 -48
  31. quant_met/geometry/square.py +0 -47
  32. quant_met/mean_field/__init__.py +0 -38
  33. quant_met/mean_field/_utils.py +0 -17
  34. quant_met/mean_field/hamiltonians/__init__.py +0 -34
  35. quant_met/mean_field/hamiltonians/base_hamiltonian.py +0 -793
  36. quant_met/mean_field/hamiltonians/dressed_graphene.py +0 -118
  37. quant_met/mean_field/hamiltonians/graphene.py +0 -95
  38. quant_met/mean_field/hamiltonians/one_band_tight_binding.py +0 -70
  39. quant_met/mean_field/hamiltonians/three_band_tight_binding.py +0 -85
  40. quant_met/mean_field/hamiltonians/two_band_tight_binding.py +0 -76
  41. quant_met/parameters/hamiltonians.py +0 -182
  42. quant_met/plotting/__init__.py +0 -31
  43. quant_met/plotting/plotting.py +0 -215
  44. quant_met-0.0.27.dist-info/RECORD +0 -33
  45. {quant_met-0.0.27.dist-info → quant_met-0.1.1.dist-info}/WHEEL +0 -0
  46. {quant_met-0.0.27.dist-info → quant_met-0.1.1.dist-info}/entry_points.txt +0 -0
  47. {quant_met-0.0.27.dist-info → quant_met-0.1.1.dist-info}/licenses/LICENSE.txt +0 -0
@@ -0,0 +1,154 @@
1
+ """Function to run search for critical temperature."""
2
+
3
+ import logging
4
+ from functools import partial
5
+ from multiprocessing import Pool
6
+ from typing import Any
7
+
8
+ import numpy as np
9
+ import numpy.typing as npt
10
+ import pandas as pd
11
+ import sisl
12
+
13
+ from quant_met import bdg
14
+
15
+ from .self_consistency import self_consistency_loop
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ MAX_Q = 0.5
20
+
21
+
22
+ def is_gap_zero(result: dict[str, float], atol: float = 1e-8) -> bool:
23
+ """Check if all delta values in result are (approximately) zero."""
24
+ deltas = np.array([x for key, x in result.items() if key.startswith("delta")])
25
+ return np.isclose(np.max(np.abs(deltas)), 0, atol=atol)
26
+
27
+
28
+ def adjust_q_upper_bound(
29
+ gap_for_q_partial: partial[dict[str, Any] | None], initial_q: float = 0.5
30
+ ) -> float:
31
+ """
32
+ Adjust q_upper_bound until gap is non-zero or exceeds upper limit.
33
+
34
+ Returns the adjusted q_upper_bound.
35
+ """
36
+ q_upper_bound = initial_q
37
+
38
+ while True:
39
+ result_tmp: dict[str, float] | None = gap_for_q_partial(q_upper_bound)
40
+
41
+ if result_tmp is None or is_gap_zero(result_tmp):
42
+ q_upper_bound /= 2
43
+ else:
44
+ break
45
+
46
+ while True:
47
+ result_tmp = gap_for_q_partial(q_upper_bound)
48
+
49
+ if result_tmp is None or is_gap_zero(result_tmp):
50
+ q_upper_bound *= 1.1
51
+ if q_upper_bound > MAX_Q:
52
+ break
53
+ else:
54
+ break
55
+
56
+ return q_upper_bound
57
+
58
+
59
+ def _gap_for_q( # noqa: PLR0913
60
+ q_fraction: float,
61
+ hamiltonian: sisl.Hamiltonian,
62
+ kgrid: sisl.MonkhorstPack,
63
+ hubbard_int_orbital_basis: npt.NDArray[np.float64],
64
+ epsilon: float,
65
+ temp: float,
66
+ max_iter: int = 1000,
67
+ ) -> dict[str, Any] | None: # pragma: no cover
68
+ beta = np.inf if temp == 0 else 1 / temp
69
+ q = q_fraction * hamiltonian.geometry.rcell[0]
70
+ data_dict: dict[str, Any] = {
71
+ "q_fraction": q_fraction,
72
+ }
73
+ try:
74
+ gap = self_consistency_loop(
75
+ hamiltonian=hamiltonian,
76
+ kgrid=kgrid,
77
+ beta=beta,
78
+ hubbard_int_orbital_basis=hubbard_int_orbital_basis,
79
+ epsilon=epsilon,
80
+ max_iter=max_iter,
81
+ q=q,
82
+ )
83
+ except RuntimeError:
84
+ logger.exception("Did not converge.")
85
+ return None
86
+ else:
87
+ bdg_energies, bdg_wavefunctions = bdg.diagonalize_bdg(
88
+ hamiltonian=hamiltonian,
89
+ kgrid=kgrid,
90
+ delta_orbital_basis=gap,
91
+ q=q,
92
+ )
93
+ current = bdg.calculate_current_density(
94
+ hamiltonian=hamiltonian,
95
+ k=kgrid,
96
+ bdg_energies=bdg_energies,
97
+ bdg_wavefunctions=bdg_wavefunctions,
98
+ beta=beta,
99
+ )
100
+ data_dict.update({f"delta_{orbital}": gap[orbital] for orbital in range(len(gap))})
101
+ data_dict.update(
102
+ {
103
+ "current_x": current[0],
104
+ "current_y": current[1],
105
+ "current_abs": np.linalg.norm(current),
106
+ },
107
+ )
108
+ return data_dict
109
+
110
+
111
+ def loop_over_q( # noqa: PLR0913
112
+ hamiltonian: sisl.Hamiltonian,
113
+ kgrid: sisl.MonkhorstPack,
114
+ hubbard_int_orbital_basis: npt.NDArray[np.float64],
115
+ epsilon: float,
116
+ max_iter: int,
117
+ n_q_points: int,
118
+ crit_temps: npt.NDArray[np.float64],
119
+ ) -> dict[str, pd.DataFrame]: # pragma: no cover
120
+ """Loop over q."""
121
+ logger.info("Start search for upper bound for q.")
122
+
123
+ crit_temp = np.max(crit_temps)
124
+ temp_list = [crit_temp * x for x in [0.65, 0.7, 0.75, 0.8, 0.85, 0.87, 0.89, 0.91, 0.93, 0.95]]
125
+
126
+ delta_vs_q = {}
127
+ for temp in temp_list:
128
+ gap_for_q_partial = partial(
129
+ _gap_for_q,
130
+ hamiltonian=hamiltonian,
131
+ kgrid=kgrid,
132
+ hubbard_int_orbital_basis=hubbard_int_orbital_basis,
133
+ epsilon=epsilon,
134
+ max_iter=max_iter,
135
+ temp=temp,
136
+ )
137
+ q_upper_bound = adjust_q_upper_bound(gap_for_q_partial, initial_q=0.5)
138
+ logger.info("q upper bound: %s", q_upper_bound)
139
+
140
+ q_list = np.linspace(
141
+ 0,
142
+ q_upper_bound,
143
+ num=n_q_points,
144
+ )
145
+
146
+ with Pool() as p:
147
+ delta_vs_q_list = [x for x in p.map(gap_for_q_partial, q_list) if x is not None] # type: ignore[arg-type]
148
+
149
+ delta_vs_q_tmp = (
150
+ pd.DataFrame(delta_vs_q_list).sort_values(by=["q_fraction"]).reset_index(drop=True)
151
+ )
152
+ delta_vs_q[f"{temp}"] = delta_vs_q_tmp
153
+
154
+ return delta_vs_q
@@ -1,8 +1,3 @@
1
- # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
- # SPDX-FileCopyrightText: 2025 Tjark Sievers
3
- #
4
- # SPDX-License-Identifier: MIT
5
-
6
1
  """Function to run search for critical temperature."""
7
2
 
8
3
  import logging
@@ -15,16 +10,16 @@ import matplotlib.pyplot as plt
15
10
  import numpy as np
16
11
  import numpy.typing as npt
17
12
  import pandas as pd
13
+ import sisl
18
14
  from scipy import stats
19
15
 
20
- from quant_met import plotting
21
- from quant_met.parameters import GenericParameters
22
-
23
- from .hamiltonians import BaseHamiltonian
24
16
  from .self_consistency import self_consistency_loop
25
17
 
26
18
  logger = logging.getLogger(__name__)
27
19
 
20
+ MIN_NUMBER_OF_T_POINTS_FITTING = 4
21
+ MAX_ITERATIONS_GET_BOUNDS = 100
22
+
28
23
 
29
24
  def _get_bounds(
30
25
  initial_temp: float,
@@ -38,7 +33,9 @@ def _get_bounds(
38
33
  temp = initial_temp
39
34
  direction = "down"
40
35
  iterations = 0
41
- while (found_zero_gap and found_nonzero_gap) is False and iterations < 100:
36
+ while (
37
+ found_zero_gap and found_nonzero_gap
38
+ ) is False and iterations < MAX_ITERATIONS_GET_BOUNDS:
42
39
  logger.info("Trying temperature: %s", temp)
43
40
  data_dict = gap_for_temp_partial(temp)
44
41
  logger.info("Result: %s", data_dict)
@@ -51,7 +48,9 @@ def _get_bounds(
51
48
  found_zero_gap = True
52
49
  temp = 0.5 * temp
53
50
  elif np.allclose(
54
- gap, zero_temperature_gap, atol=0.10 * np.max(np.abs(zero_temperature_gap))
51
+ gap,
52
+ zero_temperature_gap,
53
+ atol=0.10 * np.max(np.abs(zero_temperature_gap)),
55
54
  ):
56
55
  logger.info("Found temperature with nonzero gap.")
57
56
  nonzero_gap_temp = temp
@@ -62,7 +61,7 @@ def _get_bounds(
62
61
  temp = 0.5 * temp
63
62
  else:
64
63
  logger.info(
65
- "Gap is neither zero nor equal to the zero gap. Increasing temperature."
64
+ "Gap is neither zero nor equal to the zero gap. Increasing temperature.",
66
65
  )
67
66
  temp = 2 * temp
68
67
  elif direction == "down":
@@ -86,7 +85,8 @@ def _get_bounds(
86
85
 
87
86
 
88
87
  def _fit_for_crit_temp(
89
- delta_vs_temp: pd.DataFrame, orbital: int
88
+ delta_vs_temp: pd.DataFrame,
89
+ orbital: int,
90
90
  ) -> tuple[pd.DataFrame | None, pd.DataFrame, float | None, float | None]: # pragma: no cover
91
91
  filtered_results = delta_vs_temp.iloc[
92
92
  np.where(
@@ -104,21 +104,22 @@ def _fit_for_crit_temp(
104
104
  rtol=1e-2,
105
105
  atol=0,
106
106
  ),
107
- )
108
- )
107
+ ),
108
+ ),
109
109
  )
110
110
  ]
111
111
 
112
112
  err = []
113
- if len(filtered_results) <= 4:
113
+ if len(filtered_results) <= MIN_NUMBER_OF_T_POINTS_FITTING:
114
114
  return None, filtered_results, None, None
115
115
 
116
- lengths = range(4, len(filtered_results))
116
+ lengths = range(MIN_NUMBER_OF_T_POINTS_FITTING, len(filtered_results))
117
117
 
118
118
  for length in lengths:
119
119
  range_results = filtered_results.iloc[-length:]
120
120
  linreg = stats.linregress(
121
- range_results["T"], np.abs(range_results[f"delta_{orbital}"]) ** 2
121
+ range_results["T"],
122
+ np.abs(range_results[f"delta_{orbital}"]) ** 2,
122
123
  )
123
124
  err.append(linreg.stderr)
124
125
 
@@ -129,64 +130,83 @@ def _fit_for_crit_temp(
129
130
  return range_results, filtered_results, linreg.intercept, linreg.slope
130
131
 
131
132
 
132
- def _gap_for_temp(
133
+ def _gap_for_temp( # noqa: PLR0913
133
134
  temp: float,
134
- h: BaseHamiltonian[GenericParameters],
135
- k_space_grid: npt.NDArray[np.floating],
135
+ hamiltonian: sisl.Hamiltonian,
136
+ kgrid: sisl.MonkhorstPack,
137
+ hubbard_int_orbital_basis: npt.NDArray[np.float64],
136
138
  epsilon: float,
137
139
  max_iter: int = 1000,
140
+ delta_init: npt.NDArray[np.complex128] | None = None,
141
+ q: npt.NDArray[np.float64] | None = None,
138
142
  ) -> dict[str, Any] | None: # pragma: no cover
139
143
  beta = np.inf if temp == 0 else 1 / temp
140
- h.beta = beta
141
144
  try:
142
- solved_h = self_consistency_loop(h, k_space_grid, epsilon, max_iter)
145
+ gap = self_consistency_loop(
146
+ hamiltonian=hamiltonian,
147
+ kgrid=kgrid,
148
+ beta=beta,
149
+ hubbard_int_orbital_basis=hubbard_int_orbital_basis,
150
+ epsilon=epsilon,
151
+ max_iter=max_iter,
152
+ delta_init=delta_init,
153
+ q=q,
154
+ )
143
155
  except RuntimeError:
144
156
  logger.exception("Did not converge.")
145
157
  return None
146
158
  else:
147
- data_dict = {
159
+ data_dict: dict[str, Any] = {
148
160
  "T": temp,
149
161
  }
150
- zero_temperature_gap = solved_h.delta_orbital_basis
151
- data_dict.update(
152
- {
153
- f"delta_{orbital}": zero_temperature_gap[orbital]
154
- for orbital in range(len(zero_temperature_gap))
155
- }
156
- )
162
+ data_dict.update({f"delta_{orbital}": gap[orbital] for orbital in range(len(gap))})
157
163
  return data_dict
158
164
 
159
165
 
160
- def search_crit_temp(
161
- h: BaseHamiltonian[GenericParameters],
162
- k_space_grid: npt.NDArray[np.floating],
166
+ def search_crit_temp( # noqa: PLR0913
167
+ hamiltonian: sisl.Hamiltonian,
168
+ kgrid: sisl.MonkhorstPack,
169
+ hubbard_int_orbital_basis: npt.NDArray[np.float64],
163
170
  epsilon: float,
164
171
  max_iter: int,
165
172
  n_temp_points: int,
173
+ q: npt.NDArray[np.float64] | None = None,
174
+ beta_init: float | None = None,
166
175
  ) -> tuple[pd.DataFrame, list[float], matplotlib.figure.Figure]: # pragma: no cover
167
176
  """Search for critical temperature."""
168
177
  logger.info("Start search for bounds for T_C")
169
- temp = 1 / h.beta if not np.isinf(h.beta) else 10 * h.hubbard_int_orbital_basis[0]
178
+ beta = 10 * hubbard_int_orbital_basis[0] if beta_init is None else beta_init
179
+ temp = 1 / beta if not np.isinf(beta) else 1e-8
170
180
 
171
181
  delta_vs_temp_list = []
172
182
  critical_temp_list = []
173
183
 
174
184
  gap_for_temp_partial = partial(
175
- _gap_for_temp, h=h, k_space_grid=k_space_grid, epsilon=epsilon, max_iter=max_iter
185
+ _gap_for_temp,
186
+ hamiltonian=hamiltonian,
187
+ kgrid=kgrid,
188
+ hubbard_int_orbital_basis=hubbard_int_orbital_basis,
189
+ epsilon=epsilon,
190
+ max_iter=max_iter,
191
+ q=q,
176
192
  )
177
193
 
178
194
  logger.info("Calculating zero temperature gap")
179
195
  data_dict = gap_for_temp_partial(0)
180
- assert data_dict is not None
196
+ if data_dict is None:
197
+ err_msg = "Calculation for T = 0 did not converge."
198
+ raise ValueError(err_msg)
181
199
  logger.info("Result: %s", data_dict)
182
200
 
183
201
  zero_temperature_gap = np.array(
184
- [data_dict[key] for key in data_dict if key.startswith("delta")]
202
+ [data_dict[key] for key in data_dict if key.startswith("delta")],
185
203
  )
186
204
  delta_vs_temp_list.append(data_dict)
187
205
 
188
206
  delta_vs_temp_list_tmp, zero_gap_temp, nonzero_gap_temp = _get_bounds(
189
- temp, gap_for_temp_partial, zero_temperature_gap
207
+ temp,
208
+ gap_for_temp_partial,
209
+ zero_temperature_gap,
190
210
  )
191
211
  delta_vs_temp_list.extend(delta_vs_temp_list_tmp)
192
212
  logger.info("Temperature bounds: %s to %s", nonzero_gap_temp, zero_gap_temp)
@@ -200,12 +220,18 @@ def search_crit_temp(
200
220
  endpoint=False,
201
221
  ),
202
222
  np.linspace(
203
- nonzero_gap_temp, zero_gap_temp, num=int(0.9 * n_temp_points), endpoint=False
223
+ nonzero_gap_temp,
224
+ zero_gap_temp,
225
+ num=int(0.9 * n_temp_points),
226
+ endpoint=False,
204
227
  ),
205
228
  np.linspace(
206
- zero_gap_temp, 1.2 * zero_gap_temp, num=int(0.05 * n_temp_points), endpoint=True
229
+ zero_gap_temp,
230
+ 1.2 * zero_gap_temp,
231
+ num=int(0.05 * n_temp_points),
232
+ endpoint=True,
207
233
  ),
208
- ]
234
+ ],
209
235
  )
210
236
 
211
237
  with Pool() as p:
@@ -214,14 +240,12 @@ def search_crit_temp(
214
240
 
215
241
  delta_vs_temp = pd.DataFrame(delta_vs_temp_list).sort_values(by=["T"]).reset_index(drop=True)
216
242
 
217
- fit_fig, fit_axs = plt.subplots(
218
- nrows=1, ncols=h.number_of_bands, figsize=(h.number_of_bands * 6, 6)
219
- )
243
+ fit_fig, fit_axs = plt.subplots(nrows=1, ncols=hamiltonian.no, figsize=(hamiltonian.no * 6, 6))
220
244
 
221
- for orbital in range(h.number_of_bands):
245
+ for orbital in range(hamiltonian.no):
222
246
  fit_range, filtered_range, intercept, slope = _fit_for_crit_temp(delta_vs_temp, orbital)
223
247
 
224
- ax = fit_axs if h.number_of_bands == 1 else fit_axs[orbital]
248
+ ax = fit_axs if hamiltonian.no == 1 else fit_axs[orbital]
225
249
 
226
250
  if fit_range is not None and intercept is not None and slope is not None:
227
251
  critical_temp = -intercept / slope
@@ -249,7 +273,6 @@ def search_crit_temp(
249
273
  "--x",
250
274
  color=f"C{orbital}",
251
275
  )
252
- ax = plotting.format_plot(ax)
253
276
  ax.set_ylabel(r"$\vert\Delta\vert^2\ [t^2]$")
254
277
 
255
278
  return delta_vs_temp, critical_temp_list, fit_fig
@@ -1,28 +1,27 @@
1
- # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
- # SPDX-FileCopyrightText: 2025 Tjark Sievers
3
- #
4
- # SPDX-License-Identifier: MIT
5
-
6
1
  """Self-consistency loop."""
7
2
 
8
3
  import logging
9
4
 
10
5
  import numpy as np
11
6
  import numpy.typing as npt
7
+ import sisl
8
+ from numpy import complexfloating, dtype, ndarray
12
9
 
13
- from quant_met.mean_field.hamiltonians.base_hamiltonian import BaseHamiltonian
14
- from quant_met.parameters import GenericParameters
10
+ from quant_met.bdg import gap_equation
15
11
 
16
12
  logger = logging.getLogger(__name__)
17
13
 
18
14
 
19
- def self_consistency_loop(
20
- h: BaseHamiltonian[GenericParameters],
21
- k_space_grid: npt.NDArray[np.floating],
15
+ def self_consistency_loop( # noqa: PLR0913
16
+ hamiltonian: sisl.Hamiltonian,
17
+ kgrid: sisl.MonkhorstPack,
18
+ beta: float,
19
+ hubbard_int_orbital_basis: npt.NDArray[np.float64],
22
20
  epsilon: float,
23
21
  max_iter: int = 1000,
24
22
  delta_init: npt.NDArray[np.complex128] | None = None,
25
- ) -> BaseHamiltonian[GenericParameters]:
23
+ q: npt.NDArray[np.float64] | None = None,
24
+ ) -> ndarray[tuple[int, ...], dtype[complexfloating]]:
26
25
  """Self-consistently solves the gap equation for a given Hamiltonian.
27
26
 
28
27
  This function performs a self-consistency loop to solve the gap equation
@@ -32,11 +31,12 @@ def self_consistency_loop(
32
31
 
33
32
  Parameters
34
33
  ----------
35
- h : :class:`BaseHamiltonian<quant_met.mean_field.hamiltonians.BaseHamiltonian>`
36
- The Hamiltonian object with the parameters for the calculation.
37
-
38
- k_space_grid : :class:`numpy.ndarray`
39
- A grid of points in the Brillouin zone at which the gap equation is evaluated.
34
+ q
35
+ kgrid
36
+ hubbard_int_orbital_basis
37
+ beta
38
+ hamiltonian : sisl.Hamiltonian
39
+ The Hamiltonian object.
40
40
 
41
41
  epsilon : float
42
42
  The convergence criterion. The loop will terminate when the change
@@ -64,12 +64,12 @@ def self_consistency_loop(
64
64
 
65
65
  if delta_init is None:
66
66
  rng = np.random.default_rng()
67
- delta_init = np.zeros(shape=h.delta_orbital_basis.shape, dtype=np.complex128)
68
- delta_init += (0.2 * rng.random(size=h.delta_orbital_basis.shape) - 1) + 1.0j * (
69
- 0.2 * rng.random(size=h.delta_orbital_basis.shape) - 1
67
+ delta_init = np.zeros(shape=hamiltonian.no, dtype=np.complex128)
68
+ delta_init += (0.2 * rng.random(size=hamiltonian.no) - 1) + 1.0j * (
69
+ 0.2 * rng.random(size=hamiltonian.no) - 1
70
70
  )
71
- h.delta_orbital_basis = delta_init # type: ignore[assignment]
72
- logger.debug("Initial gaps set to: %s", h.delta_orbital_basis)
71
+ logger.debug("Initial gaps set to: %s", delta_init)
72
+ delta = delta_init
73
73
 
74
74
  iteration_count = 0
75
75
  while True:
@@ -80,16 +80,20 @@ def self_consistency_loop(
80
80
 
81
81
  logger.debug("Iteration %d: Computing new gaps.", iteration_count)
82
82
 
83
- new_gap = h.gap_equation(k=k_space_grid)
83
+ new_gap = gap_equation(
84
+ hamiltonian=hamiltonian,
85
+ kgrid=kgrid,
86
+ q=q,
87
+ beta=beta,
88
+ hubbard_int_orbital_basis=hubbard_int_orbital_basis,
89
+ delta_orbital_basis=delta,
90
+ )
84
91
 
85
92
  logger.debug("New gaps computed: %s", new_gap)
86
93
 
87
- if np.allclose(h.delta_orbital_basis, new_gap, atol=1e-10, rtol=epsilon):
88
- h.delta_orbital_basis = new_gap # type: ignore[assignment]
94
+ if np.allclose(delta, new_gap, atol=1e-10, rtol=epsilon):
89
95
  logger.info("Convergence achieved after %d iterations.", iteration_count)
90
- return h
96
+ return new_gap
91
97
 
92
98
  mixing_greed = 0.2
93
- h.delta_orbital_basis = mixing_greed * new_gap + (1 - mixing_greed) * h.delta_orbital_basis # type: ignore[assignment]
94
- logger.debug("Updated gaps: %s", h.delta_orbital_basis)
95
- logger.debug("Change in gaps: %s", np.abs(h.delta_orbital_basis - new_gap))
99
+ delta = mixing_greed * new_gap + (1 - mixing_greed) * delta
quant_met/utils.py CHANGED
@@ -1,8 +1,3 @@
1
- # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
- # SPDX-FileCopyrightText: 2025 Tjark Sievers
3
- #
4
- # SPDX-License-Identifier: MIT
5
-
6
1
  """
7
2
  Utility functions (:mod:`quant_met.utils`)
8
3
  ==========================================
@@ -67,7 +62,7 @@ def generate_uniform_grid(
67
62
  num=ncols,
68
63
  )
69
64
  for i in range(nrows)
70
- ]
65
+ ],
71
66
  )
72
67
 
73
68
  return grid
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quant-met
3
- Version: 0.0.27
3
+ Version: 0.1.1
4
4
  Summary: Calculate superconductivity in flat-band systems.
5
- Author-email: Tjark Sievers <tsievers@physnet.uni-hamburg.de>
5
+ Author-email: Tjark Sievers <tjarksievers@icloud.com>
6
6
  License-File: LICENSE.txt
7
7
  Requires-Python: >=3.11
8
8
  Requires-Dist: click>=8.1.8
@@ -10,28 +10,22 @@ Requires-Dist: h5py>=3.12.1
10
10
  Requires-Dist: matplotlib>=3.10.0
11
11
  Requires-Dist: numba>=0.61.0
12
12
  Requires-Dist: numpy>=2.1
13
- Requires-Dist: numpydantic>=1.6.6
13
+ Requires-Dist: numpydantic>=1.6.8
14
14
  Requires-Dist: pandas>=2.2.3
15
15
  Requires-Dist: pydantic>=2.10.4
16
- Requires-Dist: pythtb>=1.8.0
17
16
  Requires-Dist: pyyaml>=6.0.2
18
17
  Requires-Dist: scipy>=1.15.0
18
+ Requires-Dist: sisl[viz]>0.16.0
19
19
  Requires-Dist: tables>=3.10.2
20
+ Requires-Dist: tbmodels>=1.4.3
20
21
  Description-Content-Type: text/markdown
21
22
 
22
- <!--
23
- SPDX-FileCopyrightText: 2024 Tjark Sievers
24
- SPDX-FileCopyrightText: 2025 Tjark Sievers
25
-
26
- SPDX-License-Identifier: MIT
27
- -->
28
23
 
29
24
  # quant-met
30
25
 
31
26
  [![DOI](https://zenodo.org/badge/800628635.svg)](https://zenodo.org/badge/latestdoi/800628635)
32
27
  [![Test](https://github.com/Ruberhauptmann/quant-met/actions/workflows/unit_tests.yml/badge.svg)](https://github.com/Ruberhauptmann/quant-met/actions/workflows/unit_tests.yml)
33
28
  [![Coverage Status](https://coveralls.io/repos/github/Ruberhauptmann/quant-met/badge.svg?branch=main)](https://coveralls.io/github/Ruberhauptmann/quant-met?branch=main)
34
- [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/quant-met)](https://pypi.org/project/quant-met/)
35
29
  [![PyPI - Version](https://img.shields.io/pypi/v/quant-met)](https://pypi.org/project/quant-met/)
36
30
 
37
31
  quant-met is a python package to treat superconductivity in flat-band systems.
@@ -0,0 +1,28 @@
1
+ quant_met/__init__.py,sha256=9WVEpcOuJ6ObayeK9u9Vkm2D-iPyb5Olc4PZdLWPORk,186
2
+ quant_met/utils.py,sha256=pr-J_ElUDKxmSdErxsz4Eclvojoejbaup-Fg12QKMVQ,1989
3
+ quant_met/bdg/__init__.py,sha256=RHxvGyCTDeK4vlIm807K9wJkLOI0jGA3ibuq0YRfo74,605
4
+ quant_met/bdg/bdg_hamiltonian.py,sha256=6zKW_a7XVXYk61RFvJjp_av4Gh7KSMqLUV1Ir8iS1sY,2708
5
+ quant_met/bdg/gap_equation.py,sha256=VyGbQxNxjbUkp-NHzGs3-5vejc6CcBfvmtXREWRS3eI,3372
6
+ quant_met/bdg/sc_current.py,sha256=fRX4KH1J7IY1T8Oxrpd_0RJd8fvPDNeP3yCg-UwRLpI,1840
7
+ quant_met/bdg/superfluid_weight.py,sha256=rLS6fK41Pt8aXxPL0KNVvK0dMWwYdbZ0eAqBEoGvAQ8,4207
8
+ quant_met/cli/__init__.py,sha256=11q_R4KoAKZy2EOuUgnAn4GxbS9yyTA6nSjKpDl-UjI,175
9
+ quant_met/cli/crit_temp.py,sha256=l4jPXY07z75FD7xgACrj_C2B3t3xX-yQeWlcnkEGIAA,2179
10
+ quant_met/cli/main.py,sha256=DNgXguBfVpp-pddmN-RKePeO1R2Dsr_b97BKei1MMG0,2074
11
+ quant_met/cli/q_analysis.py,sha256=H-3o-of_xEv3c1uUqtREGKroY-pk8Yu7RWXmLxi0xpU,1986
12
+ quant_met/cli/q_loop.py,sha256=WIwGAqP00zzePPtU3lrN0M4A4OP9miHbiT32omTVW0c,3696
13
+ quant_met/cli/scf.py,sha256=jpFoIpC0ghf48lK7SfNeTXXADEtyCzv6kzyMvdcBF1Y,3283
14
+ quant_met/parameters/__init__.py,sha256=d1XBoH8siW0fNRz5I8tpI2-JQfiSjadFBcmQANV97Zk,448
15
+ quant_met/parameters/control.py,sha256=ZxtAf35Gnb2LwooazcFrdb1d2b_sipGHIUtF5bZwTIg,1384
16
+ quant_met/parameters/main.py,sha256=P0o7f4o2woHNtLEqYJnO7dXdKEX3t_dsCky8-Sr_W88,977
17
+ quant_met/quantum_geometry/__init__.py,sha256=RMD7pNHPFAJuOtUfNiV4XssA1RjL6h1eZBsh76Fc-8Y,185
18
+ quant_met/quantum_geometry/qgt.py,sha256=jdYUxBOeKYYR96Zex2xIVOVCsT11HZ1NVrUBmmjTlLY,1358
19
+ quant_met/routines/__init__.py,sha256=a8xHRD6j4v8lkrwGSzwmj4BHUg2tgTN0Hp0Vpu4863Y,479
20
+ quant_met/routines/analyse_q_data.py,sha256=8q32GBB2ftYgdjWJ1_EpvcNJO9_Fn1kfKSaWLhIAJeY,8409
21
+ quant_met/routines/loop_over_q.py,sha256=3yYhCf_Xo7ziT5Pj4HmLDvvq8crbb7-MdJOjmyluYao,4460
22
+ quant_met/routines/search_crit_temp.py,sha256=phK2pJTibj8sgtxOghEJkurbG4xt2LRq23MTdfwygAE,9598
23
+ quant_met/routines/self_consistency.py,sha256=nb-gRzyEd24kc6ZU2O53ov07Zg3pN6wSz-9jjo68RCM,3071
24
+ quant_met-0.1.1.dist-info/METADATA,sha256=1b9db_Mgxi_W8tmD0yY4La_6y1MfvBoe7EvJaYPWxtA,1837
25
+ quant_met-0.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
26
+ quant_met-0.1.1.dist-info/entry_points.txt,sha256=1Al3Kt-cMeQxwMp84ZSNL0qFwlbOVBu1o8A19MH8lEU,48
27
+ quant_met-0.1.1.dist-info/licenses/LICENSE.txt,sha256=QO_duPQihSJlaxSLxPAXo52X3esROP5wBkhxqBd1Z4E,1104
28
+ quant_met-0.1.1.dist-info/RECORD,,
quant_met/cli/_utils.py DELETED
@@ -1,32 +0,0 @@
1
- # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
- # SPDX-FileCopyrightText: 2025 Tjark Sievers
3
- #
4
- # SPDX-License-Identifier: MIT
5
-
6
- from quant_met.mean_field.hamiltonians import BaseHamiltonian
7
- from quant_met.parameters import HamiltonianParameters
8
-
9
-
10
- def _hamiltonian_factory(
11
- classname: str, parameters: HamiltonianParameters
12
- ) -> BaseHamiltonian[HamiltonianParameters]:
13
- """Create a Hamiltonian by its class name.
14
-
15
- Parameters
16
- ----------
17
- classname: str
18
- The name of the Hamiltonian class to instantiate.
19
- parameters: HamiltonianParameters
20
- An instance of HamiltonianParameters containing all necessary
21
- configuration for the specific Hamiltonian.
22
-
23
- Returns
24
- -------
25
- BaseHamiltonian[HamiltonianParameters]
26
- An instance of the specified Hamiltonian class.
27
- """
28
- from quant_met.mean_field import hamiltonians
29
-
30
- cls = getattr(hamiltonians, classname)
31
- h: BaseHamiltonian[HamiltonianParameters] = cls(parameters)
32
- return h
@@ -1,36 +0,0 @@
1
- # SPDX-FileCopyrightText: 2024 Tjark Sievers
2
- # SPDX-FileCopyrightText: 2025 Tjark Sievers
3
- #
4
- # SPDX-License-Identifier: MIT
5
-
6
- """
7
- Geometry
8
- ========
9
-
10
- .. currentmodule:: quant_met.geometry
11
-
12
- Functions
13
- ---------
14
-
15
- .. autosummary::
16
- :toctree: generated/
17
-
18
- generate_bz_path
19
-
20
- Classes
21
- -------
22
-
23
- .. autosummary::
24
- :toctree: generated/
25
-
26
- BaseLattice
27
- GrapheneLattice
28
- SquareLattice
29
- """ # noqa: D205, D400
30
-
31
- from .base_lattice import BaseLattice
32
- from .bz_path import generate_bz_path
33
- from .graphene import GrapheneLattice
34
- from .square import SquareLattice
35
-
36
- __all__ = ["BaseLattice", "GrapheneLattice", "SquareLattice", "generate_bz_path"]