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.
Files changed (84) hide show
  1. {tbkit-0.5.0/tbkit.egg-info → tbkit-0.6.0}/PKG-INFO +22 -8
  2. {tbkit-0.5.0 → tbkit-0.6.0}/README.md +12 -7
  3. {tbkit-0.5.0 → tbkit-0.6.0}/pyproject.toml +13 -2
  4. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/__init__.py +3 -3
  5. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/continuum.py +1 -1
  6. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/dos.py +2 -2
  7. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/error_handling.py +39 -1
  8. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/exceptional.py +3 -3
  9. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/floquet.py +35 -12
  10. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/io.py +6 -5
  11. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/kpm.py +3 -1
  12. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/kspace.py +131 -53
  13. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/lattice.py +8 -5
  14. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/lattices.py +2 -1
  15. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/meanfield.py +9 -9
  16. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/moire.py +8 -5
  17. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/neighbours.py +2 -6
  18. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/optics.py +2 -2
  19. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/orbital.py +6 -6
  20. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/plot.py +33 -37
  21. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/propagation.py +9 -10
  22. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/slater_koster.py +5 -5
  23. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/system.py +27 -24
  24. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/topology.py +2 -1
  25. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/transport.py +134 -29
  26. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/values.py +1 -1
  27. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/wannier.py +2 -1
  28. {tbkit-0.5.0 → tbkit-0.6.0/tbkit.egg-info}/PKG-INFO +22 -8
  29. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_analysis.py +19 -1
  30. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_error_handling.py +14 -0
  31. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_invariants.py +2 -1
  32. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_kspace.py +17 -0
  33. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_regressions.py +26 -0
  34. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_system.py +15 -0
  35. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_transport.py +49 -0
  36. {tbkit-0.5.0 → tbkit-0.6.0}/LICENSE +0 -0
  37. {tbkit-0.5.0 → tbkit-0.6.0}/setup.cfg +0 -0
  38. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/bdg.py +0 -0
  39. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/bridges.py +0 -0
  40. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/graphene.py +0 -0
  41. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/higher_order.py +0 -0
  42. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/occupation.py +0 -0
  43. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/py.typed +0 -0
  44. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit/save.py +0 -0
  45. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit.egg-info/SOURCES.txt +0 -0
  46. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit.egg-info/dependency_links.txt +0 -0
  47. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit.egg-info/requires.txt +0 -0
  48. {tbkit-0.5.0 → tbkit-0.6.0}/tbkit.egg-info/top_level.txt +0 -0
  49. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_berry_response.py +0 -0
  50. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_bridges.py +0 -0
  51. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_continuum.py +0 -0
  52. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_correlations.py +0 -0
  53. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_dos.py +0 -0
  54. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_error_handling_structures.py +0 -0
  55. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_exceptional.py +0 -0
  56. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_floquet.py +0 -0
  57. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_graphene.py +0 -0
  58. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_green_occupation.py +0 -0
  59. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_hall.py +0 -0
  60. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_higher_order.py +0 -0
  61. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_interactions.py +0 -0
  62. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_io.py +0 -0
  63. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_kpm.py +0 -0
  64. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_large_lattices.py +0 -0
  65. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_lattice.py +0 -0
  66. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_lattices.py +0 -0
  67. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_magnetic.py +0 -0
  68. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_moire.py +0 -0
  69. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_neighbours.py +0 -0
  70. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_non_hermitian_bands.py +0 -0
  71. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_optics.py +0 -0
  72. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_orbitals.py +0 -0
  73. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_periodic.py +0 -0
  74. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_plot.py +0 -0
  75. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_propagation.py +0 -0
  76. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_save.py +0 -0
  77. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_smatrix.py +0 -0
  78. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_surface_spectral.py +0 -0
  79. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_three_d.py +0 -0
  80. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_topology.py +0 -0
  81. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_transport_response.py +0 -0
  82. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_values.py +0 -0
  83. {tbkit-0.5.0 → tbkit-0.6.0}/tests/test_wannier90.py +0 -0
  84. {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.5.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 | [![PyPI version](https://img.shields.io/pypi/v/tbkit)](https://pypi.org/project/tbkit/) [![Python versions](https://img.shields.io/pypi/pyversions/tbkit)](https://pypi.org/project/tbkit/) [![DOI](https://zenodo.org/badge/1381398706.svg)](https://zenodo.org/badge/latestdoi/1381398706) |
39
- | Quality | [![License](https://img.shields.io/github/license/cpoli/tbkit)](https://github.com/cpoli/tbkit/blob/master/LICENSE) [![CI](https://github.com/cpoli/tbkit/actions/workflows/tests.yml/badge.svg)](https://github.com/cpoli/tbkit/actions/workflows/tests.yml) [![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)](https://cpoli.github.io/tbkit/coverage/) |
40
- | Documentation | [![Docs](https://img.shields.io/badge/docs-cpoli.github.io%2Ftbkit-blue)](https://cpoli.github.io/tbkit/) |
47
+ | Package | [![PyPI version](https://badgen.net/pypi/v/tbkit)](https://pypi.org/project/tbkit/) [![conda-forge](https://img.shields.io/conda/vn/conda-forge/tbkit)](https://anaconda.org/conda-forge/tbkit) [![Python versions](https://badgen.net/pypi/python/tbkit)](https://pypi.org/project/tbkit/) [![DOI](https://zenodo.org/badge/1381398706.svg)](https://zenodo.org/badge/latestdoi/1381398706) |
48
+ | Quality | [![License](https://badgen.net/github/license/cpoli/tbkit)](https://github.com/cpoli/tbkit/blob/master/LICENSE) [![CI](https://github.com/cpoli/tbkit/actions/workflows/ci.yml/badge.svg)](https://github.com/cpoli/tbkit/actions/workflows/ci.yml) [![Coverage](https://codecov.io/gh/cpoli/tbkit/branch/master/graph/badge.svg)](https://codecov.io/gh/cpoli/tbkit) |
49
+ | Documentation | [![Docs](https://badgen.net/badge/docs/cpoli.github.io%2Ftbkit/blue)](https://cpoli.github.io/tbkit/) |
41
50
  | Downloads | [![Downloads](https://static.pepy.tech/badge/tbkit)](https://pepy.tech/project/tbkit) [![Downloads/Month](https://static.pepy.tech/badge/tbkit/month)](https://pepy.tech/project/tbkit) |
42
- | Community | [![GitHub Stars](https://img.shields.io/github/stars/cpoli/tbkit?style=social)](https://github.com/cpoli/tbkit) [![GitHub Forks](https://img.shields.io/github/forks/cpoli/tbkit?style=social)](https://github.com/cpoli/tbkit) [![Contributors](https://img.shields.io/github/contributors/cpoli/tbkit)](https://github.com/cpoli/tbkit/graphs/contributors) [![Last Commit](https://img.shields.io/github/last-commit/cpoli/tbkit)](https://github.com/cpoli/tbkit/commits/master) |
51
+ | Community | [![GitHub Stars](https://badgen.net/github/stars/cpoli/tbkit)](https://github.com/cpoli/tbkit) [![GitHub Forks](https://badgen.net/github/forks/cpoli/tbkit)](https://github.com/cpoli/tbkit) [![Contributors](https://badgen.net/github/contributors/cpoli/tbkit)](https://github.com/cpoli/tbkit/graphs/contributors) [![Last Commit](https://badgen.net/github/last-commit/cpoli/tbkit/master)](https://github.com/cpoli/tbkit/commits/master) |
43
52
 
44
53
  ![tbkit logo](https://raw.githubusercontent.com/cpoli/tbkit/master/docs/source/_static/image/tbkit_logo.png)
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.rst`](docs/source/history.rst) -- a chronology of the breakthroughs
232
- behind Tight-Binding theory (Bloch's theorem through the Kane-Mele model),
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 | [![PyPI version](https://img.shields.io/pypi/v/tbkit)](https://pypi.org/project/tbkit/) [![Python versions](https://img.shields.io/pypi/pyversions/tbkit)](https://pypi.org/project/tbkit/) [![DOI](https://zenodo.org/badge/1381398706.svg)](https://zenodo.org/badge/latestdoi/1381398706) |
6
- | Quality | [![License](https://img.shields.io/github/license/cpoli/tbkit)](https://github.com/cpoli/tbkit/blob/master/LICENSE) [![CI](https://github.com/cpoli/tbkit/actions/workflows/tests.yml/badge.svg)](https://github.com/cpoli/tbkit/actions/workflows/tests.yml) [![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)](https://cpoli.github.io/tbkit/coverage/) |
7
- | Documentation | [![Docs](https://img.shields.io/badge/docs-cpoli.github.io%2Ftbkit-blue)](https://cpoli.github.io/tbkit/) |
5
+ | Package | [![PyPI version](https://badgen.net/pypi/v/tbkit)](https://pypi.org/project/tbkit/) [![conda-forge](https://img.shields.io/conda/vn/conda-forge/tbkit)](https://anaconda.org/conda-forge/tbkit) [![Python versions](https://badgen.net/pypi/python/tbkit)](https://pypi.org/project/tbkit/) [![DOI](https://zenodo.org/badge/1381398706.svg)](https://zenodo.org/badge/latestdoi/1381398706) |
6
+ | Quality | [![License](https://badgen.net/github/license/cpoli/tbkit)](https://github.com/cpoli/tbkit/blob/master/LICENSE) [![CI](https://github.com/cpoli/tbkit/actions/workflows/ci.yml/badge.svg)](https://github.com/cpoli/tbkit/actions/workflows/ci.yml) [![Coverage](https://codecov.io/gh/cpoli/tbkit/branch/master/graph/badge.svg)](https://codecov.io/gh/cpoli/tbkit) |
7
+ | Documentation | [![Docs](https://badgen.net/badge/docs/cpoli.github.io%2Ftbkit/blue)](https://cpoli.github.io/tbkit/) |
8
8
  | Downloads | [![Downloads](https://static.pepy.tech/badge/tbkit)](https://pepy.tech/project/tbkit) [![Downloads/Month](https://static.pepy.tech/badge/tbkit/month)](https://pepy.tech/project/tbkit) |
9
- | Community | [![GitHub Stars](https://img.shields.io/github/stars/cpoli/tbkit?style=social)](https://github.com/cpoli/tbkit) [![GitHub Forks](https://img.shields.io/github/forks/cpoli/tbkit?style=social)](https://github.com/cpoli/tbkit) [![Contributors](https://img.shields.io/github/contributors/cpoli/tbkit)](https://github.com/cpoli/tbkit/graphs/contributors) [![Last Commit](https://img.shields.io/github/last-commit/cpoli/tbkit)](https://github.com/cpoli/tbkit/commits/master) |
9
+ | Community | [![GitHub Stars](https://badgen.net/github/stars/cpoli/tbkit)](https://github.com/cpoli/tbkit) [![GitHub Forks](https://badgen.net/github/forks/cpoli/tbkit)](https://github.com/cpoli/tbkit) [![Contributors](https://badgen.net/github/contributors/cpoli/tbkit)](https://github.com/cpoli/tbkit/graphs/contributors) [![Last Commit](https://badgen.net/github/last-commit/cpoli/tbkit/master)](https://github.com/cpoli/tbkit/commits/master) |
10
10
 
11
11
  ![tbkit logo](https://raw.githubusercontent.com/cpoli/tbkit/master/docs/source/_static/image/tbkit_logo.png)
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.rst`](docs/source/history.rst) -- a chronology of the breakthroughs
199
- behind Tight-Binding theory (Bloch's theorem through the Kane-Mele model),
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.5.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 = "3.10"
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.5.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([e_grid[0], e_grid[-1]])
228
- ax.set_ylim([0., None])
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 path(s):
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 path
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 = None
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
- step = LA.expm(-1j * dt * h)
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.complex128]) -> float:
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
- obj = cls._copy(models[0], float(np.sum(durations)), epsilon)
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 = np.array(durations, dtype='f8')
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
- n = np.searchsorted(np.cumsum(self.durations), t % self.period, side='right')
536
- return self.steps[min(n, len(self.steps) - 1)].get_ham(k)
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 kind == 'System':
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 kind == 'KSpace':
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(ham, n_moments, kernel, bounds, e_grid, n_grid=1001):
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))).