tbkit 0.5.0__tar.gz → 0.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tbkit-0.5.0/tbkit.egg-info → tbkit-0.6.0}/PKG-INFO +22 -8
- {tbkit-0.5.0 → tbkit-0.6.0}/README.md +12 -7
- {tbkit-0.5.0 → tbkit-0.6.0}/pyproject.toml +13 -2
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/__init__.py +3 -3
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/continuum.py +1 -1
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/dos.py +2 -2
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/error_handling.py +39 -1
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/exceptional.py +3 -3
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/floquet.py +35 -12
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/io.py +6 -5
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/kpm.py +3 -1
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/kspace.py +131 -53
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/lattice.py +8 -5
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/lattices.py +2 -1
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/meanfield.py +9 -9
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/moire.py +8 -5
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/neighbours.py +2 -6
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/optics.py +2 -2
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/orbital.py +6 -6
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/plot.py +33 -37
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/propagation.py +9 -10
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/slater_koster.py +5 -5
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/system.py +27 -24
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/topology.py +2 -1
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/transport.py +134 -29
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/values.py +1 -1
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/wannier.py +2 -1
- {tbkit-0.5.0 → tbkit-0.6.0/tbkit.egg-info}/PKG-INFO +22 -8
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_analysis.py +19 -1
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_error_handling.py +14 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_invariants.py +2 -1
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_kspace.py +17 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_regressions.py +26 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_system.py +15 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_transport.py +49 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/LICENSE +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/setup.cfg +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/bdg.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/bridges.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/graphene.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/higher_order.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/occupation.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/py.typed +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/save.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit.egg-info/SOURCES.txt +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit.egg-info/dependency_links.txt +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit.egg-info/requires.txt +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tbkit.egg-info/top_level.txt +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_berry_response.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_bridges.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_continuum.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_correlations.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_dos.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_error_handling_structures.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_exceptional.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_floquet.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_graphene.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_green_occupation.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_hall.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_higher_order.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_interactions.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_io.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_kpm.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_large_lattices.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_lattice.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_lattices.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_magnetic.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_moire.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_neighbours.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_non_hermitian_bands.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_optics.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_orbitals.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_periodic.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_plot.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_propagation.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_save.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_smatrix.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_surface_spectral.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_three_d.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_topology.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_transport_response.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_values.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_wannier90.py +0 -0
- {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_wannier_functions.py +0 -0
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tbkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: A Python package to build and solve Tight-Binding models.
|
|
5
5
|
Author-email: Charles Poli <cpoli374@gmail.com>
|
|
6
6
|
Maintainer-email: Charles Poli <cpoli374@gmail.com>
|
|
7
7
|
License-Expression: BSD-3-Clause
|
|
8
8
|
Project-URL: Homepage, https://github.com/cpoli/tbkit
|
|
9
|
+
Project-URL: Issues, https://github.com/cpoli/tbkit/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/cpoli/tbkit/blob/master/CHANGELOG.md
|
|
11
|
+
Project-URL: Documentation, https://cpoli.github.io/tbkit/
|
|
9
12
|
Classifier: Intended Audience :: Education
|
|
10
13
|
Classifier: Intended Audience :: Science/Research
|
|
11
14
|
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
12
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
13
22
|
Classifier: Typing :: Typed
|
|
14
23
|
Requires-Python: >=3.10
|
|
15
24
|
Description-Content-Type: text/markdown
|
|
@@ -35,11 +44,11 @@ Dynamic: license-file
|
|
|
35
44
|
|
|
36
45
|
| | |
|
|
37
46
|
|:--|:-:|
|
|
38
|
-
| Package | [](https://pypi.org/project/tbkit/) [](https://anaconda.org/conda-forge/tbkit) [](https://pypi.org/project/tbkit/) [](https://zenodo.org/badge/latestdoi/1381398706) |
|
|
48
|
+
| Quality | [](https://github.com/cpoli/tbkit/blob/master/LICENSE) [](https://github.com/cpoli/tbkit/actions/workflows/ci.yml) [](https://codecov.io/gh/cpoli/tbkit) |
|
|
49
|
+
| Documentation | [](https://cpoli.github.io/tbkit/) |
|
|
41
50
|
| Downloads | [](https://pepy.tech/project/tbkit) [](https://pepy.tech/project/tbkit) |
|
|
42
|
-
| Community | [](https://github.com/cpoli/tbkit) [](https://github.com/cpoli/tbkit) [](https://github.com/cpoli/tbkit/graphs/contributors) [](https://github.com/cpoli/tbkit/commits/master) |
|
|
43
52
|
|
|
44
53
|

|
|
45
54
|
|
|
@@ -97,16 +106,20 @@ Wavepacket dynamics, periodically driven (Floquet) lattices, and non-Hermitian b
|
|
|
97
106
|
|
|
98
107
|
## Install
|
|
99
108
|
|
|
100
|
-
Requires Python >= 3.10.
|
|
109
|
+
Requires Python >= 3.10 (tested on 3.10-3.15).
|
|
101
110
|
|
|
102
111
|
```bash
|
|
103
112
|
pip install tbkit
|
|
113
|
+
# or
|
|
114
|
+
conda install -c conda-forge tbkit
|
|
104
115
|
```
|
|
105
116
|
|
|
106
117
|
`tbkit.continuum` (k·p models to tight-binding) also needs sympy:
|
|
107
118
|
|
|
108
119
|
```bash
|
|
109
120
|
pip install "tbkit[continuum]"
|
|
121
|
+
# or
|
|
122
|
+
conda install -c conda-forge tbkit sympy
|
|
110
123
|
```
|
|
111
124
|
|
|
112
125
|
or, for an editable install from a clone (e.g. to run the test suite or
|
|
@@ -228,8 +241,9 @@ Rendered docs (tutorial, API reference, example gallery): https://cpoli.github.i
|
|
|
228
241
|
* [`docs/source/tutorial.rst`](docs/source/tutorial.rst) -- a narrative walkthrough of the
|
|
229
242
|
package, from building a lattice through topology, spin-orbit coupling,
|
|
230
243
|
and edge states.
|
|
231
|
-
* [`docs/source/history
|
|
232
|
-
behind Tight-Binding theory (Bloch's theorem through
|
|
244
|
+
* [`docs/source/history/`](docs/source/history/) -- a chronology of the breakthroughs
|
|
245
|
+
behind Tight-Binding theory (Bloch's theorem through higher-order topology),
|
|
246
|
+
one page per theme,
|
|
233
247
|
each one linked to the corresponding **tbkit** functionality and example
|
|
234
248
|
above.
|
|
235
249
|
* `docs/source/tbkit.rst` -- the API reference (auto-generated from docstrings).
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
| | |
|
|
4
4
|
|:--|:-:|
|
|
5
|
-
| Package | [](https://pypi.org/project/tbkit/) [](https://anaconda.org/conda-forge/tbkit) [](https://pypi.org/project/tbkit/) [](https://zenodo.org/badge/latestdoi/1381398706) |
|
|
6
|
+
| Quality | [](https://github.com/cpoli/tbkit/blob/master/LICENSE) [](https://github.com/cpoli/tbkit/actions/workflows/ci.yml) [](https://codecov.io/gh/cpoli/tbkit) |
|
|
7
|
+
| Documentation | [](https://cpoli.github.io/tbkit/) |
|
|
8
8
|
| Downloads | [](https://pepy.tech/project/tbkit) [](https://pepy.tech/project/tbkit) |
|
|
9
|
-
| Community | [](https://github.com/cpoli/tbkit) [](https://github.com/cpoli/tbkit) [](https://github.com/cpoli/tbkit/graphs/contributors) [](https://github.com/cpoli/tbkit/commits/master) |
|
|
10
10
|
|
|
11
11
|

|
|
12
12
|
|
|
@@ -64,16 +64,20 @@ Wavepacket dynamics, periodically driven (Floquet) lattices, and non-Hermitian b
|
|
|
64
64
|
|
|
65
65
|
## Install
|
|
66
66
|
|
|
67
|
-
Requires Python >= 3.10.
|
|
67
|
+
Requires Python >= 3.10 (tested on 3.10-3.15).
|
|
68
68
|
|
|
69
69
|
```bash
|
|
70
70
|
pip install tbkit
|
|
71
|
+
# or
|
|
72
|
+
conda install -c conda-forge tbkit
|
|
71
73
|
```
|
|
72
74
|
|
|
73
75
|
`tbkit.continuum` (k·p models to tight-binding) also needs sympy:
|
|
74
76
|
|
|
75
77
|
```bash
|
|
76
78
|
pip install "tbkit[continuum]"
|
|
79
|
+
# or
|
|
80
|
+
conda install -c conda-forge tbkit sympy
|
|
77
81
|
```
|
|
78
82
|
|
|
79
83
|
or, for an editable install from a clone (e.g. to run the test suite or
|
|
@@ -195,8 +199,9 @@ Rendered docs (tutorial, API reference, example gallery): https://cpoli.github.i
|
|
|
195
199
|
* [`docs/source/tutorial.rst`](docs/source/tutorial.rst) -- a narrative walkthrough of the
|
|
196
200
|
package, from building a lattice through topology, spin-orbit coupling,
|
|
197
201
|
and edge states.
|
|
198
|
-
* [`docs/source/history
|
|
199
|
-
behind Tight-Binding theory (Bloch's theorem through
|
|
202
|
+
* [`docs/source/history/`](docs/source/history/) -- a chronology of the breakthroughs
|
|
203
|
+
behind Tight-Binding theory (Bloch's theorem through higher-order topology),
|
|
204
|
+
one page per theme,
|
|
200
205
|
each one linked to the corresponding **tbkit** functionality and example
|
|
201
206
|
above.
|
|
202
207
|
* `docs/source/tbkit.rst` -- the API reference (auto-generated from docstrings).
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tbkit"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.6.0"
|
|
8
8
|
description = "A Python package to build and solve Tight-Binding models."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "BSD-3-Clause"
|
|
@@ -21,11 +21,20 @@ classifiers = [
|
|
|
21
21
|
"Intended Audience :: Science/Research",
|
|
22
22
|
"Topic :: Scientific/Engineering :: Physics",
|
|
23
23
|
"Programming Language :: Python :: 3",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Programming Language :: Python :: 3.13",
|
|
28
|
+
"Programming Language :: Python :: 3.14",
|
|
29
|
+
"Programming Language :: Python :: 3.15",
|
|
24
30
|
"Typing :: Typed",
|
|
25
31
|
]
|
|
26
32
|
|
|
27
33
|
[project.urls]
|
|
28
34
|
Homepage = "https://github.com/cpoli/tbkit"
|
|
35
|
+
Issues = "https://github.com/cpoli/tbkit/issues"
|
|
36
|
+
Changelog = "https://github.com/cpoli/tbkit/blob/master/CHANGELOG.md"
|
|
37
|
+
Documentation = "https://cpoli.github.io/tbkit/"
|
|
29
38
|
|
|
30
39
|
[project.optional-dependencies]
|
|
31
40
|
continuum = ["sympy>=1.12"]
|
|
@@ -59,7 +68,9 @@ ignore = ["E741", "E731"]
|
|
|
59
68
|
"tbkit/graphene.py" = ["F403", "F405"]
|
|
60
69
|
|
|
61
70
|
[tool.mypy]
|
|
62
|
-
python_version
|
|
71
|
+
# No python_version pin: the NumPy >= 2.3 stubs use PEP 695 generics,
|
|
72
|
+
# which mypy resolves wrongly when targeting 3.10 (every bare
|
|
73
|
+
# ``arr.max()`` fails to match). Check against the running interpreter.
|
|
63
74
|
ignore_missing_imports = true
|
|
64
75
|
# The type hints are documentation first: check what is annotated, and
|
|
65
76
|
# skip the bodies of unannotated functions.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
"""tbkit: build and solve Tight-Binding models."""
|
|
8
8
|
|
|
9
|
-
__version__ = "0.
|
|
9
|
+
__version__ = "0.6.0"
|
|
10
10
|
|
|
11
11
|
__all__ = [
|
|
12
12
|
"Lattice", "System", "Plot", "Propagation", "Save", "KSpace",
|
|
@@ -51,8 +51,8 @@ __all__ += ["RecursiveTransport"]
|
|
|
51
51
|
from tbkit.topology import WeylPoints, find_weyl_points, bott_index
|
|
52
52
|
__all__ += ["WeylPoints", "find_weyl_points", "bott_index"]
|
|
53
53
|
# Analysis and plotting: standard k-paths
|
|
54
|
-
from tbkit.kspace import high_symmetry_path
|
|
55
|
-
__all__ += ["high_symmetry_path"]
|
|
54
|
+
from tbkit.kspace import high_symmetry_path, cubic_path
|
|
55
|
+
__all__ += ["high_symmetry_path", "cubic_path"]
|
|
56
56
|
# Continuum (k.p) models discretized on a grid; sympy is imported on first use
|
|
57
57
|
from tbkit.continuum import discretize, discretize_symbolic
|
|
58
58
|
__all__ += ["discretize", "discretize_symbolic"]
|
|
@@ -124,7 +124,7 @@ def _discretize(sympy, hamiltonian, dim: int | None):
|
|
|
124
124
|
momenta = [sympy.Symbol(k, real=True) for k in MOMENTA[:dim]]
|
|
125
125
|
a = sympy.Symbol('a')
|
|
126
126
|
norb = ham.shape[0]
|
|
127
|
-
hops = {}
|
|
127
|
+
hops: dict = {}
|
|
128
128
|
for i, j in itertools.product(range(norb), repeat=2):
|
|
129
129
|
entry = sympy.expand(ham[i, j])
|
|
130
130
|
error_handling.continuum_polynomial((i, j), entry.is_polynomial(*momenta))
|
|
@@ -224,8 +224,8 @@ def _plot_dos_curve(
|
|
|
224
224
|
fig, ax = plt.subplots(figsize=figsize)
|
|
225
225
|
ax.plot(e_grid, rho, 'b', lw=lw)
|
|
226
226
|
ax.fill_between(e_grid, rho, color='b', alpha=0.2)
|
|
227
|
-
ax.set_xlim(
|
|
228
|
-
ax.set_ylim(
|
|
227
|
+
ax.set_xlim(e_grid[0], e_grid[-1])
|
|
228
|
+
ax.set_ylim(0., None)
|
|
229
229
|
ax.set_title('Density of states', fontsize=fs)
|
|
230
230
|
ax.set_xlabel('$E$', fontsize=fs)
|
|
231
231
|
ax.set_ylabel(r'$\rho(E)$', fontsize=fs)
|
|
@@ -1711,7 +1711,21 @@ def lead_interface(missing):
|
|
|
1711
1711
|
if missing:
|
|
1712
1712
|
raise ValueError('\n\nThe device lacks lead orbitals {} in its outermost lead cell: '
|
|
1713
1713
|
'extend the device so that it ends with a complete lead '
|
|
1714
|
-
'cell.\n'.format([int(o) for o in missing]))
|
|
1714
|
+
'cell (or pass extend=True).\n'.format([int(o) for o in missing]))
|
|
1715
|
+
|
|
1716
|
+
|
|
1717
|
+
def lead_extension(inside):
|
|
1718
|
+
'''
|
|
1719
|
+
Check that the lead sites added to complete an interface stay within the
|
|
1720
|
+
device's extent along the lead (*inside* False when they would pass the
|
|
1721
|
+
innermost lead cell holding a device site).
|
|
1722
|
+
|
|
1723
|
+
:raises ValueError: The lead cannot be closed against the device.
|
|
1724
|
+
'''
|
|
1725
|
+
if not inside:
|
|
1726
|
+
raise ValueError('\n\nThe lead sites missing from the device reach past its far end: '
|
|
1727
|
+
'the lead is not closed off by the device (wider than it, or '
|
|
1728
|
+
'off its edge).\n')
|
|
1715
1729
|
|
|
1716
1730
|
|
|
1717
1731
|
def lead_index(lead, n_leads):
|
|
@@ -3302,6 +3316,30 @@ def contour_found(n_elements, energy):
|
|
|
3302
3316
|
'constant-energy contour.\n'.format(energy))
|
|
3303
3317
|
|
|
3304
3318
|
|
|
3319
|
+
def cubic_path(points, names, axes):
|
|
3320
|
+
'''
|
|
3321
|
+
Check the parameters of *kspace.cubic_path*.
|
|
3322
|
+
|
|
3323
|
+
:raises TypeError: Parameter points must be a dictionary.
|
|
3324
|
+
:raises ValueError: Each point must have 3 real coordinates.
|
|
3325
|
+
:raises ValueError: Parameter names must list at least two keys of points.
|
|
3326
|
+
:raises ValueError: Parameter axes must be 3 orthonormal rows.
|
|
3327
|
+
'''
|
|
3328
|
+
if not isinstance(points, dict):
|
|
3329
|
+
raise TypeError('\n\nParameter points must be a dictionary (label: point).\n')
|
|
3330
|
+
for key, point in points.items():
|
|
3331
|
+
point = np.asarray(point)
|
|
3332
|
+
if point.shape != (3,) or not np.isrealobj(point) or not np.all(np.isfinite(point)):
|
|
3333
|
+
raise ValueError('\n\nPoint {} must have 3 real coordinates.\n'.format(key))
|
|
3334
|
+
if (not isinstance(names, (list, tuple)) or len(names) < 2
|
|
3335
|
+
or any(n not in points for n in names)):
|
|
3336
|
+
raise ValueError('\n\nParameter names must list at least two keys of points.\n')
|
|
3337
|
+
if axes is not None:
|
|
3338
|
+
axes = np.asarray(axes)
|
|
3339
|
+
if axes.shape != (3, 3) or not np.isrealobj(axes) or not np.allclose(axes @ axes.T, np.eye(3)):
|
|
3340
|
+
raise ValueError('\n\nParameter axes must be 3 orthonormal rows (shape (3, 3)).\n')
|
|
3341
|
+
|
|
3342
|
+
|
|
3305
3343
|
def bravais_lattice(kind, dim):
|
|
3306
3344
|
'''
|
|
3307
3345
|
Check that *kspace.high_symmetry_path* recognized the Bravais lattice.
|
|
@@ -119,11 +119,11 @@ def _loop(loop) -> Callable[[float], NDArray[np.float64]]:
|
|
|
119
119
|
'''
|
|
120
120
|
error_handling.loop(loop)
|
|
121
121
|
if callable(loop):
|
|
122
|
-
def
|
|
122
|
+
def traced(s):
|
|
123
123
|
p = np.asarray(loop(float(s)), dtype='f8')
|
|
124
124
|
error_handling.loop_point(p)
|
|
125
125
|
return p
|
|
126
|
-
return
|
|
126
|
+
return traced
|
|
127
127
|
vert = np.asarray(loop, dtype='f8')
|
|
128
128
|
closed = np.vstack([vert, vert[:1]])
|
|
129
129
|
m = len(vert)
|
|
@@ -670,7 +670,7 @@ def find_exceptional_points(
|
|
|
670
670
|
disc, lambda s, a=a, b=b: kmesh[a] + s * (kmesh[b] - kmesh[a]), 0., 1., d[a], d[b])
|
|
671
671
|
b1, b2 = ks.rec_vec_k
|
|
672
672
|
orient = np.sign(b1[0] * b2[1] - b1[1] * b2[0])
|
|
673
|
-
points = []
|
|
673
|
+
points: list = []
|
|
674
674
|
for i in range(nk):
|
|
675
675
|
for j in range(nk):
|
|
676
676
|
w = (edge[0, i, j] + edge[1, (i + 1) % nk, j]
|
|
@@ -46,7 +46,7 @@ uses the evolution at *all* times of the period, does
|
|
|
46
46
|
from __future__ import annotations
|
|
47
47
|
|
|
48
48
|
import copy
|
|
49
|
-
from typing import Callable
|
|
49
|
+
from typing import TYPE_CHECKING, Callable
|
|
50
50
|
|
|
51
51
|
import numpy as np
|
|
52
52
|
from numpy.typing import ArrayLike, NDArray
|
|
@@ -54,6 +54,10 @@ import scipy.linalg as LA
|
|
|
54
54
|
|
|
55
55
|
import tbkit.error_handling as error_handling
|
|
56
56
|
|
|
57
|
+
if TYPE_CHECKING:
|
|
58
|
+
from tbkit.kspace import KSpace
|
|
59
|
+
from tbkit.lattice import Lattice
|
|
60
|
+
|
|
57
61
|
|
|
58
62
|
def evolution_operator(ham_t: Callable, period: float, n_steps: int = 100) -> NDArray[np.complex128]:
|
|
59
63
|
r'''
|
|
@@ -72,11 +76,10 @@ def evolution_operator(ham_t: Callable, period: float, n_steps: int = 100) -> ND
|
|
|
72
76
|
error_handling.positive_real(period, 'period')
|
|
73
77
|
error_handling.positive_int(n_steps, 'n_steps')
|
|
74
78
|
dt = period / n_steps
|
|
75
|
-
u =
|
|
76
|
-
for m in range(n_steps):
|
|
79
|
+
u = LA.expm(-1j * dt * np.asarray(ham_t(0.5 * dt), dtype='c16'))
|
|
80
|
+
for m in range(1, n_steps):
|
|
77
81
|
h = np.asarray(ham_t((m + 0.5) * dt), dtype='c16')
|
|
78
|
-
|
|
79
|
-
u = step if u is None else step @ u
|
|
82
|
+
u = LA.expm(-1j * dt * h) @ u
|
|
80
83
|
return u
|
|
81
84
|
|
|
82
85
|
|
|
@@ -299,7 +302,7 @@ class StepDrive:
|
|
|
299
302
|
* **H** -- Complex ndarray.
|
|
300
303
|
'''
|
|
301
304
|
error_handling.real_number(t, 't')
|
|
302
|
-
n = np.searchsorted(np.cumsum(self.durations), t % self.period, side='right')
|
|
305
|
+
n = int(np.searchsorted(np.cumsum(self.durations), t % self.period, side='right'))
|
|
303
306
|
return self.hams[min(n, len(self.hams) - 1)]
|
|
304
307
|
|
|
305
308
|
def evolution_operator(self, t: float | None = None) -> NDArray[np.complex128]:
|
|
@@ -443,7 +446,7 @@ def _spectral_derivative(u: NDArray[np.complex128], axis: int) -> NDArray[np.com
|
|
|
443
446
|
return np.fft.ifft(np.fft.fft(u, axis=axis) * (2j * np.pi * m).reshape(shape), axis=axis)
|
|
444
447
|
|
|
445
448
|
|
|
446
|
-
def _winding_density(u: NDArray[np.complex128], a_t: NDArray[np.
|
|
449
|
+
def _winding_density(u: NDArray[np.complex128], a_t: NDArray[np.complexfloating]) -> float:
|
|
447
450
|
r'''
|
|
448
451
|
Private function. Brillouin-zone average of
|
|
449
452
|
Tr(A_t [A_1, A_2]), A_i = U^-1 d U / d f_i along the fractional
|
|
@@ -486,6 +489,22 @@ class DrivenKSpace:
|
|
|
486
489
|
drive = DrivenKSpace(ks, lambda k, t: ks.get_ham(k) + m * np.cos(w * t) * sz, 2 * np.pi / w)
|
|
487
490
|
'''
|
|
488
491
|
|
|
492
|
+
# Set by _copy (and _from_steps or __new__) on an instance whose class
|
|
493
|
+
# also derives from type(ks): the rest is the copied KSpace's.
|
|
494
|
+
static: KSpace
|
|
495
|
+
period: float
|
|
496
|
+
epsilon: float | None
|
|
497
|
+
steps: list | None
|
|
498
|
+
durations: NDArray[np.float64]
|
|
499
|
+
n_steps: int
|
|
500
|
+
ham_kt: Callable
|
|
501
|
+
lat: Lattice
|
|
502
|
+
dim: int
|
|
503
|
+
norb: int
|
|
504
|
+
spin: bool
|
|
505
|
+
rec_vec_k: NDArray[np.float64]
|
|
506
|
+
_plane_orientation: Callable
|
|
507
|
+
|
|
489
508
|
def __new__(cls, ks, ham_kt: Callable, period: float, n_steps: int = 100, epsilon: float | None = None):
|
|
490
509
|
from tbkit.kspace import KSpace
|
|
491
510
|
error_handling.kspace(ks, KSpace)
|
|
@@ -508,7 +527,7 @@ class DrivenKSpace:
|
|
|
508
527
|
Private method. A copy of *ks* whose class also derives from *cls*.
|
|
509
528
|
'''
|
|
510
529
|
driven_cls = type(cls.__name__, (cls, type(ks)), {})
|
|
511
|
-
obj = object.__new__(driven_cls)
|
|
530
|
+
obj: DrivenKSpace = object.__new__(driven_cls)
|
|
512
531
|
obj.__dict__.update(copy.deepcopy(ks.__dict__))
|
|
513
532
|
obj.static = ks
|
|
514
533
|
obj.period = period
|
|
@@ -521,9 +540,10 @@ class DrivenKSpace:
|
|
|
521
540
|
'''
|
|
522
541
|
Private method. The drive of *step_drive*: models[n] for durations[n].
|
|
523
542
|
'''
|
|
524
|
-
|
|
543
|
+
durations = np.array(durations, dtype='f8')
|
|
544
|
+
obj = cls._copy(models[0], float(durations.sum()), epsilon)
|
|
525
545
|
obj.steps = list(models)
|
|
526
|
-
obj.durations =
|
|
546
|
+
obj.durations = durations
|
|
527
547
|
obj.n_steps = len(models)
|
|
528
548
|
obj.ham_kt = obj._step_ham
|
|
529
549
|
return obj
|
|
@@ -532,8 +552,9 @@ class DrivenKSpace:
|
|
|
532
552
|
'''
|
|
533
553
|
Private method. H(k, t) of a step drive.
|
|
534
554
|
'''
|
|
535
|
-
|
|
536
|
-
|
|
555
|
+
steps = self.steps or [] # set by _from_steps, the only caller
|
|
556
|
+
n = int(np.searchsorted(np.cumsum(self.durations), t % self.period, side='right'))
|
|
557
|
+
return steps[min(n, len(steps) - 1)].get_ham(k)
|
|
537
558
|
|
|
538
559
|
def _step_list(self, k: NDArray[np.float64]) -> list:
|
|
539
560
|
'''
|
|
@@ -807,6 +828,8 @@ class FloquetKSpace(DrivenKSpace):
|
|
|
807
828
|
Branch cut of *get_ham*, see *effective_hamiltonian*.
|
|
808
829
|
'''
|
|
809
830
|
|
|
831
|
+
vector_potential: Callable
|
|
832
|
+
|
|
810
833
|
def __new__(cls, ks, vector_potential: Callable, period: float, n_steps: int = 100,
|
|
811
834
|
epsilon: float | None = None):
|
|
812
835
|
from tbkit.kspace import KSpace
|
|
@@ -30,6 +30,7 @@ Archive layout (format ``'tbkit-model'``, version :data:`VERSION`):
|
|
|
30
30
|
from __future__ import annotations
|
|
31
31
|
|
|
32
32
|
import os
|
|
33
|
+
from typing import Any, cast
|
|
33
34
|
|
|
34
35
|
import numpy as np
|
|
35
36
|
from numpy.typing import ArrayLike, NDArray
|
|
@@ -96,20 +97,20 @@ def save_model(model: Lattice | System | KSpace, path: str | os.PathLike) -> str
|
|
|
96
97
|
kind = 'System' if isinstance(model, System) else 'KSpace' if isinstance(model, KSpace) else 'Lattice'
|
|
97
98
|
# only what needs version 2 (a periodic System) is written as such, so
|
|
98
99
|
# that older tbkit versions keep reading everything else
|
|
99
|
-
data = {'format': np.array(FORMAT), 'version': np.array(1), 'kind': np.array(kind),
|
|
100
|
+
data: dict[str, Any] = {'format': np.array(FORMAT), 'version': np.array(1), 'kind': np.array(kind),
|
|
100
101
|
'tbkit_version': np.array(tbkit.__version__),
|
|
101
102
|
'uc_tag': np.array([dic['tag'] for dic in lat.unit_cell], dtype='U1'),
|
|
102
103
|
'uc_r0': np.array([dic['r0'] for dic in lat.unit_cell], dtype='f8'),
|
|
103
104
|
'prim_vec': np.array(lat.prim_vec, dtype='f8'),
|
|
104
105
|
'coor': lat.coor,
|
|
105
106
|
'n_cells': np.array([lat.n1, lat.n2, lat.n3], dtype='i8')}
|
|
106
|
-
if
|
|
107
|
+
if isinstance(model, System):
|
|
107
108
|
data['onsite'] = np.asarray(model.onsite, dtype='c16')
|
|
108
109
|
data['hop'] = model.hop
|
|
109
110
|
if any(model.periodic):
|
|
110
111
|
data['periodic'] = np.array(model.periodic, dtype=bool)
|
|
111
112
|
data['version'] = np.array(VERSION)
|
|
112
|
-
elif
|
|
113
|
+
elif isinstance(model, KSpace):
|
|
113
114
|
data.update({'spin': np.array(model.spin), 'onsite': model.onsite,
|
|
114
115
|
'onsite_offdiag': model._onsite_offdiag,
|
|
115
116
|
'nonreciprocal': np.array(model._nonreciprocal)})
|
|
@@ -324,7 +325,7 @@ def read_wannier90(
|
|
|
324
325
|
num_wann, R, ndegen, ham = read_hr(hr)
|
|
325
326
|
if prim_vec is None:
|
|
326
327
|
error_handling.win_given(win)
|
|
327
|
-
cell = read_win_cell(win)
|
|
328
|
+
cell = read_win_cell(cast('str | os.PathLike', win))
|
|
328
329
|
error_handling.layer_cell(cell, dim)
|
|
329
330
|
prim_vec = [tuple(float(c) for c in a[:dim]) for a in cell[:dim]]
|
|
330
331
|
error_handling.prim_vec(prim_vec)
|
|
@@ -364,7 +365,7 @@ def _hr_kspace(
|
|
|
364
365
|
index = {tuple(r): p for p, r in enumerate(R.tolist())}
|
|
365
366
|
partner = [index.get(tuple(-c for c in r)) for r in R.tolist()]
|
|
366
367
|
hermitian = None not in partner and bool(
|
|
367
|
-
np.abs(ham - ham[partner].conj().transpose(0, 2, 1)).max() <= tol)
|
|
368
|
+
np.abs(ham - ham[np.array(partner)].conj().transpose(0, 2, 1)).max() <= tol)
|
|
368
369
|
list_hop = []
|
|
369
370
|
for r, h in zip(R.tolist(), ham):
|
|
370
371
|
nonzero = [c for c in r if c != 0]
|
|
@@ -94,7 +94,9 @@ def lorentz_kernel(n_moments: int, lam: float = 4.) -> NDArray[np.float64]:
|
|
|
94
94
|
return np.sinh(lam * (1. - np.arange(n_moments) / n_moments)) / np.sinh(lam)
|
|
95
95
|
|
|
96
96
|
|
|
97
|
-
def _setup(
|
|
97
|
+
def _setup(
|
|
98
|
+
ham, n_moments, kernel, bounds, e_grid, n_grid=1001,
|
|
99
|
+
) -> tuple[sparse.csr_matrix, NDArray[np.float64], NDArray[np.float64], float, float]:
|
|
98
100
|
'''
|
|
99
101
|
Private function. Validate, rescale the Hamiltonian, and build the
|
|
100
102
|
coefficients c_m(E) (shape (n_moments, len(e_grid))).
|