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.
- quant_met/__init__.py +2 -7
- quant_met/bdg/__init__.py +26 -0
- quant_met/bdg/bdg_hamiltonian.py +97 -0
- quant_met/bdg/gap_equation.py +127 -0
- quant_met/bdg/sc_current.py +60 -0
- quant_met/bdg/superfluid_weight.py +110 -0
- quant_met/cli/__init__.py +0 -5
- quant_met/cli/crit_temp.py +18 -16
- quant_met/cli/main.py +8 -5
- quant_met/cli/q_analysis.py +60 -0
- quant_met/cli/q_loop.py +95 -0
- quant_met/cli/scf.py +44 -23
- quant_met/parameters/__init__.py +0 -26
- quant_met/parameters/control.py +57 -0
- quant_met/parameters/main.py +2 -55
- quant_met/quantum_geometry/__init__.py +13 -0
- quant_met/quantum_geometry/qgt.py +37 -0
- quant_met/routines/__init__.py +22 -0
- quant_met/routines/analyse_q_data.py +226 -0
- quant_met/routines/loop_over_q.py +154 -0
- quant_met/{mean_field → routines}/search_crit_temp.py +71 -48
- quant_met/{mean_field → routines}/self_consistency.py +32 -28
- quant_met/utils.py +1 -6
- {quant_met-0.0.27.dist-info → quant_met-0.1.1.dist-info}/METADATA +5 -11
- quant_met-0.1.1.dist-info/RECORD +28 -0
- quant_met/cli/_utils.py +0 -32
- quant_met/geometry/__init__.py +0 -36
- quant_met/geometry/base_lattice.py +0 -100
- quant_met/geometry/bz_path.py +0 -90
- quant_met/geometry/graphene.py +0 -48
- quant_met/geometry/square.py +0 -47
- quant_met/mean_field/__init__.py +0 -38
- quant_met/mean_field/_utils.py +0 -17
- quant_met/mean_field/hamiltonians/__init__.py +0 -34
- quant_met/mean_field/hamiltonians/base_hamiltonian.py +0 -793
- quant_met/mean_field/hamiltonians/dressed_graphene.py +0 -118
- quant_met/mean_field/hamiltonians/graphene.py +0 -95
- quant_met/mean_field/hamiltonians/one_band_tight_binding.py +0 -70
- quant_met/mean_field/hamiltonians/three_band_tight_binding.py +0 -85
- quant_met/mean_field/hamiltonians/two_band_tight_binding.py +0 -76
- quant_met/parameters/hamiltonians.py +0 -182
- quant_met/plotting/__init__.py +0 -31
- quant_met/plotting/plotting.py +0 -215
- quant_met-0.0.27.dist-info/RECORD +0 -33
- {quant_met-0.0.27.dist-info → quant_met-0.1.1.dist-info}/WHEEL +0 -0
- {quant_met-0.0.27.dist-info → quant_met-0.1.1.dist-info}/entry_points.txt +0 -0
- {quant_met-0.0.27.dist-info → quant_met-0.1.1.dist-info}/licenses/LICENSE.txt +0 -0
quant_met/cli/scf.py
CHANGED
@@ -1,19 +1,15 @@
|
|
1
|
-
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
-
# SPDX-FileCopyrightText: 2025 Tjark Sievers
|
3
|
-
#
|
4
|
-
# SPDX-License-Identifier: MIT
|
5
|
-
|
6
1
|
"""Functions to run self-consistent calculation for the order parameter."""
|
7
2
|
|
8
3
|
import logging
|
9
4
|
from pathlib import Path
|
10
5
|
|
11
6
|
import h5py
|
7
|
+
import numpy as np
|
8
|
+
import sisl
|
12
9
|
|
13
|
-
from quant_met import
|
10
|
+
from quant_met import bdg, routines
|
14
11
|
from quant_met.parameters import Parameters
|
15
|
-
|
16
|
-
from ._utils import _hamiltonian_factory
|
12
|
+
from quant_met.parameters.control import SCF
|
17
13
|
|
18
14
|
logger = logging.getLogger(__name__)
|
19
15
|
|
@@ -24,41 +20,66 @@ def scf(parameters: Parameters) -> None:
|
|
24
20
|
Parameters
|
25
21
|
----------
|
26
22
|
parameters: Parameters
|
27
|
-
An instance of Parameters containing control settings
|
28
|
-
and k-point specifications for the self-consistency calculation.
|
23
|
+
An instance of Parameters containing control settings.
|
29
24
|
"""
|
25
|
+
if not isinstance(parameters.control, SCF):
|
26
|
+
err_msg = "Wrong parameters for scf."
|
27
|
+
raise TypeError(err_msg)
|
28
|
+
|
30
29
|
result_path = Path(parameters.control.outdir)
|
31
30
|
result_path.mkdir(exist_ok=True, parents=True)
|
31
|
+
result_file = result_path / f"{parameters.control.prefix}.hdf5"
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
hamiltonian = sisl.get_sile(parameters.control.hamiltonian_file).read_hamiltonian()
|
34
|
+
k_grid_obj = sisl.MonkhorstPack(
|
35
|
+
hamiltonian.geometry,
|
36
|
+
[parameters.k_points.nk1, parameters.k_points.nk2, 1],
|
36
37
|
)
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
solved_gap = routines.self_consistency_loop(
|
40
|
+
hamiltonian=hamiltonian,
|
41
|
+
kgrid=k_grid_obj,
|
42
|
+
beta=parameters.control.beta,
|
43
|
+
hubbard_int_orbital_basis=np.array(parameters.control.hubbard_int_orbital_basis),
|
41
44
|
epsilon=parameters.control.conv_treshold,
|
42
45
|
max_iter=parameters.control.max_iter,
|
46
|
+
q=np.array(parameters.control.q),
|
43
47
|
)
|
44
48
|
|
45
49
|
logger.info("Self-consistency loop completed successfully.")
|
46
|
-
logger.debug("Obtained delta values: %s",
|
50
|
+
logger.debug("Obtained delta values: %s", solved_gap)
|
47
51
|
|
48
|
-
result_file
|
49
|
-
|
52
|
+
with h5py.File(result_file, "a") as f:
|
53
|
+
f.create_dataset("delta", data=solved_gap)
|
50
54
|
logger.info("Results saved to %s", result_file)
|
51
55
|
|
52
56
|
if parameters.control.calculate_additional is True:
|
53
57
|
logger.info("Calculating additional things.")
|
54
|
-
|
55
|
-
|
56
|
-
|
58
|
+
|
59
|
+
bdg_energies, bdg_wavefunctions = bdg.diagonalize_bdg(
|
60
|
+
hamiltonian=hamiltonian,
|
61
|
+
kgrid=k_grid_obj,
|
62
|
+
delta_orbital_basis=solved_gap,
|
63
|
+
q=np.array(parameters.control.q),
|
64
|
+
)
|
65
|
+
|
66
|
+
current = bdg.calculate_current_density(
|
67
|
+
hamiltonian=hamiltonian,
|
68
|
+
k=k_grid_obj,
|
69
|
+
bdg_energies=bdg_energies,
|
70
|
+
bdg_wavefunctions=bdg_wavefunctions,
|
71
|
+
beta=parameters.control.beta,
|
72
|
+
)
|
73
|
+
sf_weight_conv, sf_weight_geom = bdg.calculate_superfluid_weight(
|
74
|
+
hamiltonian=hamiltonian,
|
75
|
+
kgrid=k_grid_obj,
|
76
|
+
beta=parameters.control.beta,
|
77
|
+
delta_orbital_basis=solved_gap,
|
78
|
+
)
|
57
79
|
|
58
80
|
with h5py.File(result_file, "a") as f:
|
59
81
|
f.attrs["current_x"] = current[0]
|
60
82
|
f.attrs["current_y"] = current[1]
|
61
|
-
f.attrs["free_energy"] = free_energy
|
62
83
|
f.attrs["sf_weight_conv_xx"] = sf_weight_conv[0, 0]
|
63
84
|
f.attrs["sf_weight_conv_xy"] = sf_weight_conv[0, 1]
|
64
85
|
f.attrs["sf_weight_conv_yx"] = sf_weight_conv[1, 0]
|
quant_met/parameters/__init__.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
|
Parameter Classes
|
8
3
|
=================
|
@@ -11,11 +6,6 @@ Main class holding all the parameters for the calculation.
|
|
11
6
|
|
12
7
|
Classes holding the configuration for the Hamiltonians.
|
13
8
|
|
14
|
-
.. autosummary::
|
15
|
-
:toctree: generated/parameters/hamiltonians
|
16
|
-
|
17
|
-
hamiltonians
|
18
|
-
|
19
9
|
.. autosummary::
|
20
10
|
:toctree: generated/parameters/
|
21
11
|
:template: autosummary/pydantic.rst
|
@@ -25,26 +15,10 @@ Classes holding the configuration for the Hamiltonians.
|
|
25
15
|
KPoints # noqa
|
26
16
|
""" # noqa: D205, D400
|
27
17
|
|
28
|
-
from .hamiltonians import (
|
29
|
-
DressedGrapheneParameters,
|
30
|
-
GenericParameters,
|
31
|
-
GrapheneParameters,
|
32
|
-
HamiltonianParameters,
|
33
|
-
OneBandParameters,
|
34
|
-
ThreeBandParameters,
|
35
|
-
TwoBandParameters,
|
36
|
-
)
|
37
18
|
from .main import Control, KPoints, Parameters
|
38
19
|
|
39
20
|
__all__ = [
|
40
21
|
"Control",
|
41
|
-
"DressedGrapheneParameters",
|
42
|
-
"GenericParameters",
|
43
|
-
"GrapheneParameters",
|
44
|
-
"HamiltonianParameters",
|
45
22
|
"KPoints",
|
46
|
-
"OneBandParameters",
|
47
23
|
"Parameters",
|
48
|
-
"ThreeBandParameters",
|
49
|
-
"TwoBandParameters",
|
50
24
|
]
|
@@ -0,0 +1,57 @@
|
|
1
|
+
"""Control parameters."""
|
2
|
+
|
3
|
+
import pathlib
|
4
|
+
from typing import Annotated, Literal, TypeAlias
|
5
|
+
|
6
|
+
from pydantic import BaseModel, Field
|
7
|
+
|
8
|
+
FloatList: TypeAlias = list[float]
|
9
|
+
|
10
|
+
|
11
|
+
class ControlBase(BaseModel):
|
12
|
+
"""Base class for control parameters."""
|
13
|
+
|
14
|
+
prefix: str
|
15
|
+
hamiltonian_file: pathlib.Path
|
16
|
+
outdir: pathlib.Path
|
17
|
+
conv_treshold: float
|
18
|
+
hubbard_int_orbital_basis: FloatList = Field(..., min_length=1)
|
19
|
+
max_iter: int = 1000
|
20
|
+
|
21
|
+
|
22
|
+
class SCF(ControlBase):
|
23
|
+
"""Parameters for the scf calculation."""
|
24
|
+
|
25
|
+
calculation: Literal["scf"]
|
26
|
+
beta: float
|
27
|
+
calculate_additional: bool = False
|
28
|
+
q: FloatList | None = Field(..., min_length=2, max_length=2)
|
29
|
+
|
30
|
+
|
31
|
+
class CritTemp(ControlBase):
|
32
|
+
"""Parameters for the critical temperature calculation."""
|
33
|
+
|
34
|
+
calculation: Literal["crit-temp"]
|
35
|
+
n_temp_points: int = 50
|
36
|
+
q: FloatList | None = Field(..., min_length=2, max_length=2)
|
37
|
+
|
38
|
+
|
39
|
+
class QLoop(ControlBase):
|
40
|
+
"""Parameters for the q-loop calculation."""
|
41
|
+
|
42
|
+
calculation: Literal["q-loop"]
|
43
|
+
n_q_points: int = 50
|
44
|
+
crit_temp: CritTemp | pathlib.Path
|
45
|
+
|
46
|
+
|
47
|
+
class QAnalysis(BaseModel):
|
48
|
+
"""Parameters for the q-analysis calculation."""
|
49
|
+
|
50
|
+
calculation: Literal["q-analysis"]
|
51
|
+
q_data: pathlib.Path
|
52
|
+
hamiltonian_file: pathlib.Path
|
53
|
+
prefix: str
|
54
|
+
outdir: pathlib.Path
|
55
|
+
|
56
|
+
|
57
|
+
Control = Annotated[SCF | CritTemp | QLoop | QAnalysis, Field(discriminator="calculation")]
|
quant_met/parameters/main.py
CHANGED
@@ -1,54 +1,8 @@
|
|
1
|
-
# SPDX-FileCopyrightText: 2024 Tjark Sievers
|
2
|
-
# SPDX-FileCopyrightText: 2025 Tjark Sievers
|
3
|
-
#
|
4
|
-
# SPDX-License-Identifier: MIT
|
5
|
-
|
6
1
|
"""Pydantic models to hold parameters to run a simulation."""
|
7
2
|
|
8
|
-
import
|
9
|
-
|
10
|
-
from pydantic import BaseModel, Field
|
11
|
-
|
12
|
-
from .hamiltonians import (
|
13
|
-
DressedGrapheneParameters,
|
14
|
-
GrapheneParameters,
|
15
|
-
OneBandParameters,
|
16
|
-
ThreeBandParameters,
|
17
|
-
TwoBandParameters,
|
18
|
-
)
|
19
|
-
|
20
|
-
|
21
|
-
class Control(BaseModel):
|
22
|
-
"""Control for the calculation.
|
23
|
-
|
24
|
-
Attributes
|
25
|
-
----------
|
26
|
-
calculation : str
|
27
|
-
Specifies the type of calculation to be performed.
|
28
|
-
prefix : str
|
29
|
-
A string used as a prefix for naming output files generated by the simulation.
|
30
|
-
outdir : :class:`pathlib.Path`
|
31
|
-
A path indicating the output directory where results will be saved.
|
32
|
-
conv_treshold : float
|
33
|
-
A float value representing the convergence threshold.
|
34
|
-
The calculation will stop when changes in the results drop below this threshold.
|
35
|
-
"""
|
36
|
-
|
37
|
-
calculation: str
|
38
|
-
prefix: str
|
39
|
-
outdir: pathlib.Path
|
40
|
-
conv_treshold: float
|
41
|
-
max_iter: int = 1000
|
42
|
-
n_temp_points: int = 50
|
43
|
-
calculate_additional: bool = False
|
3
|
+
from pydantic import BaseModel
|
44
4
|
|
45
|
-
|
46
|
-
n_success: int = 1
|
47
|
-
wmixing: float = 0.5
|
48
|
-
n_bath: int = 2
|
49
|
-
n_iw: int = 1024
|
50
|
-
n_w: int = 4000
|
51
|
-
broadening: float = 0.005
|
5
|
+
from .control import Control
|
52
6
|
|
53
7
|
|
54
8
|
class KPoints(BaseModel):
|
@@ -81,11 +35,4 @@ class Parameters(BaseModel):
|
|
81
35
|
"""
|
82
36
|
|
83
37
|
control: Control
|
84
|
-
model: (
|
85
|
-
DressedGrapheneParameters
|
86
|
-
| GrapheneParameters
|
87
|
-
| OneBandParameters
|
88
|
-
| TwoBandParameters
|
89
|
-
| ThreeBandParameters
|
90
|
-
) = Field(..., discriminator="name")
|
91
38
|
k_points: KPoints
|
@@ -0,0 +1,37 @@
|
|
1
|
+
"""Calculate the quantum geometric tensor."""
|
2
|
+
|
3
|
+
import numpy as np
|
4
|
+
import numpy.typing as npt
|
5
|
+
import sisl
|
6
|
+
|
7
|
+
|
8
|
+
def calculate_qgt(
|
9
|
+
hamiltonian: sisl.Hamiltonian,
|
10
|
+
k_grid: npt.NDArray[np.floating],
|
11
|
+
bands: list[int],
|
12
|
+
) -> npt.NDArray[np.floating]:
|
13
|
+
"""Calculate the quantum geometric tensor for selected bands."""
|
14
|
+
qgt = np.zeros((2, 2), dtype=np.complex128)
|
15
|
+
|
16
|
+
for k_point in k_grid:
|
17
|
+
# Diagonalize at this k-point
|
18
|
+
hk = hamiltonian.Hk(k=k_point, format="array")
|
19
|
+
energies, bloch = np.linalg.eigh(hk)
|
20
|
+
|
21
|
+
# Derivatives of H at this k-point
|
22
|
+
der_h_k = hamiltonian.dHk(k=k_point, format="array")
|
23
|
+
|
24
|
+
for band in bands:
|
25
|
+
for i, der_h_i in enumerate(der_h_k): # i: x=0, y=1
|
26
|
+
for j, der_h_j in enumerate(der_h_k): # j: x=0, y=1
|
27
|
+
for n in range(len(energies)):
|
28
|
+
if n == band:
|
29
|
+
continue
|
30
|
+
denom = (energies[band] - energies[n]) ** 2
|
31
|
+
if np.isclose(denom, 0.0):
|
32
|
+
continue # avoid division by zero
|
33
|
+
mni = np.vdot(bloch[:, band], der_h_i @ bloch[:, n])
|
34
|
+
mnj = np.vdot(bloch[:, n], der_h_j @ bloch[:, band])
|
35
|
+
qgt[i, j] += mni * mnj / denom
|
36
|
+
|
37
|
+
return np.real(qgt) / len(k_grid)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
"""
|
2
|
+
Routines
|
3
|
+
========
|
4
|
+
|
5
|
+
.. autosummary::
|
6
|
+
:toctree: generated/
|
7
|
+
|
8
|
+
self_consistency_loop
|
9
|
+
""" # noqa: D205, D400
|
10
|
+
|
11
|
+
from .analyse_q_data import get_lengths_vs_temp, get_zero_temperature_values
|
12
|
+
from .loop_over_q import loop_over_q
|
13
|
+
from .search_crit_temp import search_crit_temp
|
14
|
+
from .self_consistency import self_consistency_loop
|
15
|
+
|
16
|
+
__all__ = [
|
17
|
+
"get_lengths_vs_temp",
|
18
|
+
"get_zero_temperature_values",
|
19
|
+
"loop_over_q",
|
20
|
+
"search_crit_temp",
|
21
|
+
"self_consistency_loop",
|
22
|
+
]
|
@@ -0,0 +1,226 @@
|
|
1
|
+
"""Routine to analyse q data."""
|
2
|
+
|
3
|
+
import logging
|
4
|
+
|
5
|
+
import matplotlib.figure
|
6
|
+
import matplotlib.pyplot as plt
|
7
|
+
import numpy as np
|
8
|
+
import numpy.typing as npt
|
9
|
+
import pandas as pd
|
10
|
+
import sisl
|
11
|
+
from scipy.interpolate import CubicSpline
|
12
|
+
from scipy.optimize import curve_fit, minimize_scalar, root_scalar
|
13
|
+
|
14
|
+
logger = logging.getLogger(__name__)
|
15
|
+
|
16
|
+
|
17
|
+
MIN_LENGTH_FIT = 5
|
18
|
+
FIT_CUTOFF = 0.01
|
19
|
+
|
20
|
+
|
21
|
+
def _lambda_from_xi(xi: float, jdp: float) -> float:
|
22
|
+
return np.sqrt(2 / (3 * np.sqrt(3) * xi * jdp))
|
23
|
+
|
24
|
+
|
25
|
+
def _correl_length_temp_dependence(
|
26
|
+
temp: npt.NDArray[np.floating], xi_0: float, crit_temp: float
|
27
|
+
) -> npt.NDArray[np.floating]:
|
28
|
+
return xi_0 / np.sqrt(1 - temp / crit_temp)
|
29
|
+
|
30
|
+
|
31
|
+
def _london_depth_temp_dependence(
|
32
|
+
temp: npt.NDArray[np.floating], lambda_0: float, crit_temp: float
|
33
|
+
) -> npt.NDArray[np.floating]:
|
34
|
+
return lambda_0 / np.sqrt(1 - (temp / crit_temp))
|
35
|
+
|
36
|
+
|
37
|
+
def get_lengths_vs_temp(
|
38
|
+
q_data: dict[str, pd.DataFrame],
|
39
|
+
hamiltonian: sisl.Hamiltonian,
|
40
|
+
) -> tuple[pd.DataFrame, matplotlib.figure.Figure]:
|
41
|
+
"""Calculate SC lengths vs temperature.
|
42
|
+
|
43
|
+
Args:
|
44
|
+
q_data (dict[str, pd.DataFrame]): Dataframe with q data.
|
45
|
+
hamiltonian (sisl.Hamiltonian): Hamiltonian
|
46
|
+
|
47
|
+
Returns
|
48
|
+
-------
|
49
|
+
tuple[pd.DataFrame, matplotlib.figure.Figure]: Results. Figure with fits.
|
50
|
+
"""
|
51
|
+
lengths_row_list = []
|
52
|
+
|
53
|
+
for temperature, data in q_data.items():
|
54
|
+
lengths_dict = {
|
55
|
+
"T": float(temperature.split("_")[-1]),
|
56
|
+
}
|
57
|
+
results_fit = data[
|
58
|
+
np.abs(data["current_abs"]) / np.max(np.abs(data["current_abs"])) > FIT_CUTOFF
|
59
|
+
]
|
60
|
+
results_fit.reset_index(drop=True, inplace=True)
|
61
|
+
|
62
|
+
if len(results_fit) > MIN_LENGTH_FIT:
|
63
|
+
j_spl = CubicSpline(x=results_fit["q_fraction"], y=results_fit["current_abs"])
|
64
|
+
res = minimize_scalar(
|
65
|
+
lambda x, spline=j_spl: -spline(x),
|
66
|
+
bounds=(0, results_fit["q_fraction"].tail(1).item()),
|
67
|
+
)
|
68
|
+
q_j_max = float(res.x)
|
69
|
+
j_dp = float(j_spl(q_j_max))
|
70
|
+
lengths_dict.update({"q_j_max": q_j_max, "j_dp": j_dp})
|
71
|
+
for orbital in range(hamiltonian.no):
|
72
|
+
delta_spl = CubicSpline(
|
73
|
+
x=results_fit["q_fraction"],
|
74
|
+
y=np.abs(results_fit[f"delta_{orbital}"])
|
75
|
+
/ np.abs(data.at[0, f"delta_{orbital}"]),
|
76
|
+
)
|
77
|
+
try:
|
78
|
+
res = root_scalar(
|
79
|
+
lambda x, spline=delta_spl: spline(x) - 1 / np.sqrt(2),
|
80
|
+
bracket=(0, results_fit["q_fraction"].tail(1)),
|
81
|
+
)
|
82
|
+
|
83
|
+
xi = 1 / (np.sqrt(2) * res.root * np.linalg.norm(hamiltonian.geometry.rcell[0]))
|
84
|
+
lengths_dict.update(
|
85
|
+
{
|
86
|
+
f"Q_{orbital}": res.root,
|
87
|
+
f"delta_{orbital}": delta_spl(res.root)
|
88
|
+
* np.abs(data.at[0, f"delta_{orbital}"]),
|
89
|
+
f"xi_{orbital}": xi,
|
90
|
+
},
|
91
|
+
)
|
92
|
+
if j_dp is not None:
|
93
|
+
lambda_london = _lambda_from_xi(xi, j_dp)
|
94
|
+
lengths_dict.update({f"lambda_{orbital}": lambda_london})
|
95
|
+
except ValueError:
|
96
|
+
logger.exception("Value error.")
|
97
|
+
lengths_row_list.append(lengths_dict)
|
98
|
+
|
99
|
+
lengths_vs_temp = pd.DataFrame(lengths_row_list).sort_values("T").reset_index(drop=True)
|
100
|
+
|
101
|
+
gap_and_current_fig, gap_and_current_axs = plt.subplots(
|
102
|
+
ncols=hamiltonian.no + 1,
|
103
|
+
figsize=(7 * hamiltonian.no, 5),
|
104
|
+
)
|
105
|
+
|
106
|
+
for temperature, data in q_data.items():
|
107
|
+
for orbital in range(hamiltonian.no):
|
108
|
+
gap_ax = gap_and_current_axs[orbital]
|
109
|
+
gap_ax.plot(
|
110
|
+
data["q_fraction"],
|
111
|
+
data[f"delta_{orbital}"],
|
112
|
+
"x--",
|
113
|
+
label=f"{float(temperature.split('_')[-1]):.2f}",
|
114
|
+
)
|
115
|
+
gap_ax.plot(lengths_vs_temp[f"Q_{orbital}"], lengths_vs_temp[f"delta_{orbital}"], "o--")
|
116
|
+
gap_ax.legend()
|
117
|
+
current_ax = gap_and_current_axs[hamiltonian.no]
|
118
|
+
current_ax.plot(
|
119
|
+
data["q_fraction"],
|
120
|
+
data["current_abs"],
|
121
|
+
"x--",
|
122
|
+
label=f"{float(temperature.split('_')[-1]):.2f}",
|
123
|
+
)
|
124
|
+
current_ax.legend()
|
125
|
+
|
126
|
+
current_ax = gap_and_current_axs[hamiltonian.no]
|
127
|
+
current_ax.plot(lengths_vs_temp["q_j_max"], lengths_vs_temp["j_dp"], "o--")
|
128
|
+
|
129
|
+
return lengths_vs_temp, gap_and_current_fig
|
130
|
+
|
131
|
+
|
132
|
+
def get_zero_temperature_values(
|
133
|
+
hamiltonian: sisl.Hamiltonian, lengths_vs_temp: pd.DataFrame
|
134
|
+
) -> tuple[pd.DataFrame, matplotlib.figure.Figure]:
|
135
|
+
"""Get zero temperature values for the SC length scales.
|
136
|
+
|
137
|
+
Args:
|
138
|
+
hamiltonian (sisl.Hamiltonian): Hamiltonian.
|
139
|
+
lengths_vs_temp (pd.DataFrame): SC lengths against temperature.
|
140
|
+
|
141
|
+
Returns
|
142
|
+
-------
|
143
|
+
tuple[pd.DataFrame, matplotlib.figure.Figure]: Results, Figure with fits.
|
144
|
+
"""
|
145
|
+
length_vs_temp_fig, length_vs_temp_axs = plt.subplots(
|
146
|
+
nrows=2,
|
147
|
+
ncols=hamiltonian.no,
|
148
|
+
figsize=(7 * hamiltonian.no, 2 * 5),
|
149
|
+
)
|
150
|
+
zero_temp_length_row_list = []
|
151
|
+
zero_temp_length_dict = {}
|
152
|
+
for orbital in range(hamiltonian.no):
|
153
|
+
xi_ax = length_vs_temp_axs[0, orbital]
|
154
|
+
lambda_ax = length_vs_temp_axs[1, orbital]
|
155
|
+
|
156
|
+
if f"xi_{orbital}" in lengths_vs_temp:
|
157
|
+
xi_ax.plot(lengths_vs_temp["T"], lengths_vs_temp[f"xi_{orbital}"], "x--")
|
158
|
+
|
159
|
+
xi_fit = lengths_vs_temp[["T", f"xi_{orbital}"]].dropna().reset_index(drop=True)
|
160
|
+
xi_fit.reset_index(drop=True, inplace=True)
|
161
|
+
|
162
|
+
if len(xi_fit) > MIN_LENGTH_FIT:
|
163
|
+
p0, p0cov = curve_fit(
|
164
|
+
_correl_length_temp_dependence,
|
165
|
+
xi_fit["T"],
|
166
|
+
xi_fit[f"xi_{orbital}"],
|
167
|
+
bounds=([0.0, 0.0], [np.inf, np.inf]),
|
168
|
+
p0=[2.0, 2.0],
|
169
|
+
)
|
170
|
+
xi_0 = p0[0]
|
171
|
+
crit_temp_xi = p0[1]
|
172
|
+
temp_points_interpolate = np.linspace(
|
173
|
+
xi_fit.at[0, "T"],
|
174
|
+
xi_fit.at[len(xi_fit) - 1, "T"],
|
175
|
+
num=500,
|
176
|
+
)
|
177
|
+
xi_ax.plot(
|
178
|
+
temp_points_interpolate,
|
179
|
+
_correl_length_temp_dependence(temp_points_interpolate, xi_0, crit_temp_xi),
|
180
|
+
)
|
181
|
+
xi_ax.axvline(x=crit_temp_xi, ls="--")
|
182
|
+
xi_ax.axhline(y=xi_0, ls="--")
|
183
|
+
xi_ax.set_ylim(bottom=0)
|
184
|
+
zero_temp_length_dict.update(
|
185
|
+
{f"xi0_{orbital}": xi_0, f"T_C_{orbital}_xi": crit_temp_xi},
|
186
|
+
)
|
187
|
+
if f"lambda_{orbital}" in lengths_vs_temp:
|
188
|
+
lambda_ax.plot(lengths_vs_temp["T"], lengths_vs_temp[f"lambda_{orbital}"], "x--")
|
189
|
+
lambda_fit = lengths_vs_temp[["T", f"lambda_{orbital}"]].dropna().reset_index(drop=True)
|
190
|
+
|
191
|
+
if len(lambda_fit) > MIN_LENGTH_FIT:
|
192
|
+
p0, p0cov = curve_fit(
|
193
|
+
_london_depth_temp_dependence,
|
194
|
+
lambda_fit["T"],
|
195
|
+
lambda_fit[f"lambda_{orbital}"],
|
196
|
+
bounds=([0.0, 0.0], [np.inf, np.inf]),
|
197
|
+
p0=[2.0, 2.0],
|
198
|
+
)
|
199
|
+
|
200
|
+
lambda_0 = p0[0]
|
201
|
+
crit_temp_lambda = p0[1]
|
202
|
+
temp_points_interpolate = np.linspace(
|
203
|
+
lambda_fit.at[0, "T"],
|
204
|
+
lambda_fit.at[len(lambda_fit) - 1, "T"],
|
205
|
+
num=500,
|
206
|
+
)
|
207
|
+
lambda_ax.plot(
|
208
|
+
temp_points_interpolate,
|
209
|
+
_london_depth_temp_dependence(
|
210
|
+
temp_points_interpolate, lambda_0, crit_temp_lambda
|
211
|
+
),
|
212
|
+
)
|
213
|
+
lambda_ax.axvline(x=crit_temp_lambda, ls="--")
|
214
|
+
lambda_ax.axhline(y=lambda_0, ls="--")
|
215
|
+
lambda_ax.set_ylim(bottom=0)
|
216
|
+
zero_temp_length_dict.update(
|
217
|
+
{
|
218
|
+
f"lambda0_{orbital}": lambda_0,
|
219
|
+
f"T_C_lambda0_{orbital}": crit_temp_lambda,
|
220
|
+
},
|
221
|
+
)
|
222
|
+
|
223
|
+
zero_temp_length_row_list.append(zero_temp_length_dict)
|
224
|
+
zero_temp_lengths = pd.DataFrame(zero_temp_length_row_list)
|
225
|
+
|
226
|
+
return zero_temp_lengths, length_vs_temp_fig
|