tbkit 0.4.0__tar.gz → 0.4.2__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.4.0/tbkit.egg-info → tbkit-0.4.2}/PKG-INFO +32 -9
- {tbkit-0.4.0 → tbkit-0.4.2}/README.md +31 -8
- {tbkit-0.4.0 → tbkit-0.4.2}/pyproject.toml +1 -1
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/__init__.py +15 -1
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/bdg.py +107 -0
- tbkit-0.4.2/tbkit/bridges.py +264 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/error_handling.py +601 -0
- tbkit-0.4.2/tbkit/higher_order.py +428 -0
- tbkit-0.4.2/tbkit/io.py +354 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/kspace.py +121 -2
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/meanfield.py +132 -0
- tbkit-0.4.2/tbkit/moire.py +491 -0
- tbkit-0.4.2/tbkit/neighbours.py +245 -0
- tbkit-0.4.2/tbkit/optics.py +450 -0
- tbkit-0.4.2/tbkit/transport.py +717 -0
- {tbkit-0.4.0 → tbkit-0.4.2/tbkit.egg-info}/PKG-INFO +32 -9
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit.egg-info/SOURCES.txt +18 -1
- tbkit-0.4.2/tests/test_bridges.py +258 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_error_handling.py +111 -0
- tbkit-0.4.2/tests/test_error_handling_structures.py +73 -0
- tbkit-0.4.2/tests/test_higher_order.py +215 -0
- tbkit-0.4.2/tests/test_interactions.py +179 -0
- tbkit-0.4.2/tests/test_io.py +144 -0
- tbkit-0.4.2/tests/test_moire.py +262 -0
- tbkit-0.4.2/tests/test_neighbours.py +233 -0
- tbkit-0.4.2/tests/test_optics.py +335 -0
- tbkit-0.4.2/tests/test_surface_spectral.py +182 -0
- tbkit-0.4.2/tests/test_transport_response.py +257 -0
- tbkit-0.4.2/tests/test_wannier90.py +180 -0
- tbkit-0.4.0/tbkit/transport.py +0 -225
- {tbkit-0.4.0 → tbkit-0.4.2}/LICENSE +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/setup.cfg +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/dos.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/exceptional.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/floquet.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/graphene.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/kpm.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/lattice.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/lattices.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/occupation.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/orbital.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/plot.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/propagation.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/save.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/slater_koster.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit/system.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit.egg-info/dependency_links.txt +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit.egg-info/requires.txt +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tbkit.egg-info/top_level.txt +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_correlations.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_dos.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_exceptional.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_floquet.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_graphene.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_green_occupation.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_hall.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_kpm.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_kspace.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_large_lattices.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_lattice.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_lattices.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_magnetic.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_non_hermitian_bands.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_orbitals.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_plot.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_propagation.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_regressions.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_save.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_system.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_three_d.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_topology.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.2}/tests/test_transport.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tbkit
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
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: cpoli <cpoli374@gmail.com>
|
|
@@ -97,6 +97,9 @@ topology alongside superconductivity.
|
|
|
97
97
|
Kane-Mele) and Zeeman splitting.
|
|
98
98
|
* **Edge states**: cut a ribbon (periodic in one direction, finite in the
|
|
99
99
|
other) out of any periodic model, to see edge/surface physics.
|
|
100
|
+
* **Surface spectral functions** of semi-infinite crystals (iterative
|
|
101
|
+
surface Green's function): edge and surface states, e.g. the surface
|
|
102
|
+
Dirac cone of a 3D topological insulator, without a finite slab.
|
|
100
103
|
* **Density of states**, Gaussian- or Lorentzian-broadened, from either a
|
|
101
104
|
real-space spectrum or a Brillouin-zone mesh.
|
|
102
105
|
* A small library of ready-made lattices (chain, square, triangular,
|
|
@@ -116,7 +119,7 @@ topology alongside superconductivity.
|
|
|
116
119
|
|----------------------------|---------------------------------------------------------|
|
|
117
120
|
| `tbkit.Lattice` | Define and manipulate site positions and sublattices. |
|
|
118
121
|
| `tbkit.System` | Build the real-space Hamiltonian from a `Lattice` and solve it. |
|
|
119
|
-
| `tbkit.KSpace` | Build and solve the Bloch Hamiltonian of a periodic `Lattice`; bands, Berry curvature/Chern numbers, anomalous and spin Hall conductivities, ribbons, DOS. |
|
|
122
|
+
| `tbkit.KSpace` | Build and solve the Bloch Hamiltonian of a periodic `Lattice`; bands, Berry curvature/Chern numbers, anomalous and spin Hall conductivities, ribbons, surface spectral functions, DOS. |
|
|
120
123
|
| `tbkit.Plot` | Plot lattices, spectra, eigenstates, and the density of states. |
|
|
121
124
|
| `tbkit.Propagation` | Time-evolve a wavepacket. |
|
|
122
125
|
| `tbkit.Save` | Save figures/animations to disk. |
|
|
@@ -130,7 +133,12 @@ topology alongside superconductivity.
|
|
|
130
133
|
| `tbkit.meanfield` | The Hubbard model in (unrestricted Hartree-Fock) mean field. |
|
|
131
134
|
| `tbkit.bdg` | Bogoliubov-de Gennes Hamiltonians and pairings. |
|
|
132
135
|
| `tbkit.exceptional` | Exceptional and diabolical points of 2D bands: vorticity, discriminant winding, EP finder, Fermi arcs, encircling. |
|
|
136
|
+
| `tbkit.higher_order` | Higher-order topology: nested Wilson loops, Wannier-sector polarizations, the BBH quadrupole moment, corner charges. |
|
|
137
|
+
| `tbkit.moire` | Supercells, band unfolding and spectral functions, commensurate twisted bilayers. |
|
|
133
138
|
| `tbkit.floquet` | Floquet theory; `FloquetKSpace`/`DrivenKSpace` for driven Bloch models, `step_drive`, and the winding number of anomalous Floquet phases. |
|
|
139
|
+
| `tbkit.neighbours` | Neighbour shells of a periodic lattice; `KSpace.set_hopping` by neighbour order, angle and sublattice pair, as in `System`. |
|
|
140
|
+
| `tbkit.bridges` | Move a model between `System` and `KSpace` (open samples and tori). |
|
|
141
|
+
| `tbkit.io` | Save and load `Lattice`/`System`/`KSpace` models (`.npz`); import Wannier90 `_hr.dat` models. |
|
|
134
142
|
|
|
135
143
|
## Install
|
|
136
144
|
|
|
@@ -287,6 +295,7 @@ thumbnailed example gallery under `docs/source/api/gallery/`.
|
|
|
287
295
|
| [`topology/plot_tknn_hofstadter.py`](examples/topology/plot_tknn_hofstadter.py) | TKNN: Chern numbers of the Hofstadter bands from magnetic supercells, and the Diophantine equation. |
|
|
288
296
|
| [`topology/plot_kane_mele_z2.py`](examples/topology/plot_kane_mele_z2.py) | The Kane-Mele Z2 invariant from Wannier-centre flow. |
|
|
289
297
|
| [`topology/plot_fu_kane_parity.py`](examples/topology/plot_fu_kane_parity.py) | The Fu-Kane parity criterion on the BHZ model, checked against the Wannier flow. |
|
|
298
|
+
| [`topology/plot_3d_topological_insulator.py`](examples/topology/plot_3d_topological_insulator.py) | 3D topological insulators: the strong index and the surface Dirac cone, from the surface spectral function of a semi-infinite crystal. |
|
|
290
299
|
| [`topology/plot_quantum_geometry.py`](examples/topology/plot_quantum_geometry.py) | The quantum metric and Berry curvature of a Bloch band. |
|
|
291
300
|
| [`topology/plot_tenfold_way.py`](examples/topology/plot_tenfold_way.py) | Symmetry classes of tight-binding models: the tenfold way. |
|
|
292
301
|
| [`topology/plot_local_chern_marker.py`](examples/topology/plot_local_chern_marker.py) | The local Chern marker of a finite, disordered Haldane flake. |
|
|
@@ -309,10 +318,24 @@ thumbnailed example gallery under `docs/source/api/gallery/`.
|
|
|
309
318
|
| [`hall_effects/plot_anomalous_hall_effect.py`](examples/hall_effects/plot_anomalous_hall_effect.py) | The anomalous Hall effect: sigma_xy(E_F) of the Haldane model, quantized at C in the gap, not in the bands. |
|
|
310
319
|
| [`hall_effects/plot_anomalous_hall_disorder.py`](examples/hall_effects/plot_anomalous_hall_disorder.py) | The anomalous Hall plateau of a disordered Haldane torus, by the Kubo-Bastin kernel polynomial method. |
|
|
311
320
|
| [`hall_effects/plot_intrinsic_spin_hall_effect.py`](examples/hall_effects/plot_intrinsic_spin_hall_effect.py) | The intrinsic spin Hall effect: the Kane-Mele plateau at e/2pi, and its departure from quantization under Rashba coupling. |
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
321
|
+
| [`models/plot_neighbour_hoppings.py`](examples/models/plot_neighbour_hoppings.py) | Hoppings by neighbour order in k-space: third-nearest-neighbour graphene with overlaps. |
|
|
322
|
+
| [`models/plot_pipeline_bridges.py`](examples/models/plot_pipeline_bridges.py) | From real space to k-space and back: the Haldane model's torus spectrum equals its mesh bands. |
|
|
323
|
+
| [`models/plot_save_load.py`](examples/models/plot_save_load.py) | Saving and reloading models: identical Hamiltonians after a round trip through disk. |
|
|
324
|
+
| [`models/plot_maximally_localized_wannier_functions.py`](examples/models/plot_maximally_localized_wannier_functions.py) | Maximally localized Wannier functions: graphene's pi bands from a Wannier90 `_hr.dat` file. |
|
|
325
|
+
| [`higher_order/plot_quadrupole_insulator.py`](examples/higher_order/plot_quadrupole_insulator.py) | The BBH quadrupole insulator: nested Wilson loop, q_xy = 1/2, four corner states and corner charges +-1/2. |
|
|
326
|
+
| [`moire/plot_band_unfolding.py`](examples/moire/plot_band_unfolding.py) | Band unfolding: exact for a pristine supercell, coherence factors, and A(k, omega) of a disordered graphene supercell. |
|
|
327
|
+
| [`moire/plot_magic_angle_twisted_bilayer.py`](examples/moire/plot_magic_angle_twisted_bilayer.py) | Twisted bilayer graphene: Bistritzer-MacDonald velocity and flat bands at the magic alpha. |
|
|
328
|
+
| [`superconductivity/plot_bcs_gap_equation.py`](examples/superconductivity/plot_bcs_gap_equation.py) | The real-space BCS gap equation: Delta(T), Delta(0)/T_c = 1.764, and the proximity effect. |
|
|
329
|
+
| [`correlations/plot_noncollinear_120_degree_order.py`](examples/correlations/plot_noncollinear_120_degree_order.py) | Non-collinear mean field: the 120-degree order of the half-filled triangular Hubbard model. |
|
|
330
|
+
| [`tight_binding/plot_building_finite_lattices.py`](examples/tight_binding/plot_building_finite_lattices.py) | Building finite lattices: cuts, dangling sites, lattice arithmetic, rotations. |
|
|
331
|
+
| [`tight_binding/plot_defects_and_impurities.py`](examples/tight_binding/plot_defects_and_impurities.py) | A vacancy zero mode and an impurity bound state in a graphene flake. |
|
|
332
|
+
| [`dynamics/plot_wavepacket_interference.py`](examples/dynamics/plot_wavepacket_interference.py) | Wave propagation: Aharonov-Bohm caging on a ring and a state trapped at a domain wall. |
|
|
333
|
+
|
|
334
|
+
The five pre-0.2 Jupyter notebooks were replaced by the gallery scripts
|
|
335
|
+
`tight_binding/plot_building_finite_lattices.py`,
|
|
336
|
+
`tight_binding/plot_defects_and_impurities.py` and
|
|
337
|
+
`dynamics/plot_wavepacket_interference.py` (their other content is covered
|
|
338
|
+
by the strain, correlations and non-Hermitian examples).
|
|
316
339
|
|
|
317
340
|
## Documentation
|
|
318
341
|
|
|
@@ -326,6 +349,8 @@ Rendered docs (tutorial, API reference, example gallery): https://cpoli.github.i
|
|
|
326
349
|
each one linked to the corresponding **tbkit** functionality and example
|
|
327
350
|
above.
|
|
328
351
|
* `docs/source/tbkit.rst` -- the API reference (auto-generated from docstrings).
|
|
352
|
+
* [`ROADMAP.md`](ROADMAP.md) -- what is planned next, and what tbkit
|
|
353
|
+
does not do yet (compared with Kwant and PythTB).
|
|
329
354
|
|
|
330
355
|
Build the HTML docs with `cd docs && make html` (output in `docs/build/html`).
|
|
331
356
|
|
|
@@ -343,9 +368,7 @@ cleaned up the API:
|
|
|
343
368
|
|
|
344
369
|
For continuity, the pre-0.2 lowercase class names (`lattice`, `system`,
|
|
345
370
|
`plot`, `propagation`, `save`) remain available as aliases of the new
|
|
346
|
-
classes, so `from tbkit.lattice import lattice` still works.
|
|
347
|
-
notebooks predating 0.2 still use byte-string tags (`b'a'`) and will need
|
|
348
|
-
that one mechanical change to run on the current version.
|
|
371
|
+
classes, so `from tbkit.lattice import lattice` still works.
|
|
349
372
|
|
|
350
373
|
## License
|
|
351
374
|
|
|
@@ -69,6 +69,9 @@ topology alongside superconductivity.
|
|
|
69
69
|
Kane-Mele) and Zeeman splitting.
|
|
70
70
|
* **Edge states**: cut a ribbon (periodic in one direction, finite in the
|
|
71
71
|
other) out of any periodic model, to see edge/surface physics.
|
|
72
|
+
* **Surface spectral functions** of semi-infinite crystals (iterative
|
|
73
|
+
surface Green's function): edge and surface states, e.g. the surface
|
|
74
|
+
Dirac cone of a 3D topological insulator, without a finite slab.
|
|
72
75
|
* **Density of states**, Gaussian- or Lorentzian-broadened, from either a
|
|
73
76
|
real-space spectrum or a Brillouin-zone mesh.
|
|
74
77
|
* A small library of ready-made lattices (chain, square, triangular,
|
|
@@ -88,7 +91,7 @@ topology alongside superconductivity.
|
|
|
88
91
|
|----------------------------|---------------------------------------------------------|
|
|
89
92
|
| `tbkit.Lattice` | Define and manipulate site positions and sublattices. |
|
|
90
93
|
| `tbkit.System` | Build the real-space Hamiltonian from a `Lattice` and solve it. |
|
|
91
|
-
| `tbkit.KSpace` | Build and solve the Bloch Hamiltonian of a periodic `Lattice`; bands, Berry curvature/Chern numbers, anomalous and spin Hall conductivities, ribbons, DOS. |
|
|
94
|
+
| `tbkit.KSpace` | Build and solve the Bloch Hamiltonian of a periodic `Lattice`; bands, Berry curvature/Chern numbers, anomalous and spin Hall conductivities, ribbons, surface spectral functions, DOS. |
|
|
92
95
|
| `tbkit.Plot` | Plot lattices, spectra, eigenstates, and the density of states. |
|
|
93
96
|
| `tbkit.Propagation` | Time-evolve a wavepacket. |
|
|
94
97
|
| `tbkit.Save` | Save figures/animations to disk. |
|
|
@@ -102,7 +105,12 @@ topology alongside superconductivity.
|
|
|
102
105
|
| `tbkit.meanfield` | The Hubbard model in (unrestricted Hartree-Fock) mean field. |
|
|
103
106
|
| `tbkit.bdg` | Bogoliubov-de Gennes Hamiltonians and pairings. |
|
|
104
107
|
| `tbkit.exceptional` | Exceptional and diabolical points of 2D bands: vorticity, discriminant winding, EP finder, Fermi arcs, encircling. |
|
|
108
|
+
| `tbkit.higher_order` | Higher-order topology: nested Wilson loops, Wannier-sector polarizations, the BBH quadrupole moment, corner charges. |
|
|
109
|
+
| `tbkit.moire` | Supercells, band unfolding and spectral functions, commensurate twisted bilayers. |
|
|
105
110
|
| `tbkit.floquet` | Floquet theory; `FloquetKSpace`/`DrivenKSpace` for driven Bloch models, `step_drive`, and the winding number of anomalous Floquet phases. |
|
|
111
|
+
| `tbkit.neighbours` | Neighbour shells of a periodic lattice; `KSpace.set_hopping` by neighbour order, angle and sublattice pair, as in `System`. |
|
|
112
|
+
| `tbkit.bridges` | Move a model between `System` and `KSpace` (open samples and tori). |
|
|
113
|
+
| `tbkit.io` | Save and load `Lattice`/`System`/`KSpace` models (`.npz`); import Wannier90 `_hr.dat` models. |
|
|
106
114
|
|
|
107
115
|
## Install
|
|
108
116
|
|
|
@@ -259,6 +267,7 @@ thumbnailed example gallery under `docs/source/api/gallery/`.
|
|
|
259
267
|
| [`topology/plot_tknn_hofstadter.py`](examples/topology/plot_tknn_hofstadter.py) | TKNN: Chern numbers of the Hofstadter bands from magnetic supercells, and the Diophantine equation. |
|
|
260
268
|
| [`topology/plot_kane_mele_z2.py`](examples/topology/plot_kane_mele_z2.py) | The Kane-Mele Z2 invariant from Wannier-centre flow. |
|
|
261
269
|
| [`topology/plot_fu_kane_parity.py`](examples/topology/plot_fu_kane_parity.py) | The Fu-Kane parity criterion on the BHZ model, checked against the Wannier flow. |
|
|
270
|
+
| [`topology/plot_3d_topological_insulator.py`](examples/topology/plot_3d_topological_insulator.py) | 3D topological insulators: the strong index and the surface Dirac cone, from the surface spectral function of a semi-infinite crystal. |
|
|
262
271
|
| [`topology/plot_quantum_geometry.py`](examples/topology/plot_quantum_geometry.py) | The quantum metric and Berry curvature of a Bloch band. |
|
|
263
272
|
| [`topology/plot_tenfold_way.py`](examples/topology/plot_tenfold_way.py) | Symmetry classes of tight-binding models: the tenfold way. |
|
|
264
273
|
| [`topology/plot_local_chern_marker.py`](examples/topology/plot_local_chern_marker.py) | The local Chern marker of a finite, disordered Haldane flake. |
|
|
@@ -281,10 +290,24 @@ thumbnailed example gallery under `docs/source/api/gallery/`.
|
|
|
281
290
|
| [`hall_effects/plot_anomalous_hall_effect.py`](examples/hall_effects/plot_anomalous_hall_effect.py) | The anomalous Hall effect: sigma_xy(E_F) of the Haldane model, quantized at C in the gap, not in the bands. |
|
|
282
291
|
| [`hall_effects/plot_anomalous_hall_disorder.py`](examples/hall_effects/plot_anomalous_hall_disorder.py) | The anomalous Hall plateau of a disordered Haldane torus, by the Kubo-Bastin kernel polynomial method. |
|
|
283
292
|
| [`hall_effects/plot_intrinsic_spin_hall_effect.py`](examples/hall_effects/plot_intrinsic_spin_hall_effect.py) | The intrinsic spin Hall effect: the Kane-Mele plateau at e/2pi, and its departure from quantization under Rashba coupling. |
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
293
|
+
| [`models/plot_neighbour_hoppings.py`](examples/models/plot_neighbour_hoppings.py) | Hoppings by neighbour order in k-space: third-nearest-neighbour graphene with overlaps. |
|
|
294
|
+
| [`models/plot_pipeline_bridges.py`](examples/models/plot_pipeline_bridges.py) | From real space to k-space and back: the Haldane model's torus spectrum equals its mesh bands. |
|
|
295
|
+
| [`models/plot_save_load.py`](examples/models/plot_save_load.py) | Saving and reloading models: identical Hamiltonians after a round trip through disk. |
|
|
296
|
+
| [`models/plot_maximally_localized_wannier_functions.py`](examples/models/plot_maximally_localized_wannier_functions.py) | Maximally localized Wannier functions: graphene's pi bands from a Wannier90 `_hr.dat` file. |
|
|
297
|
+
| [`higher_order/plot_quadrupole_insulator.py`](examples/higher_order/plot_quadrupole_insulator.py) | The BBH quadrupole insulator: nested Wilson loop, q_xy = 1/2, four corner states and corner charges +-1/2. |
|
|
298
|
+
| [`moire/plot_band_unfolding.py`](examples/moire/plot_band_unfolding.py) | Band unfolding: exact for a pristine supercell, coherence factors, and A(k, omega) of a disordered graphene supercell. |
|
|
299
|
+
| [`moire/plot_magic_angle_twisted_bilayer.py`](examples/moire/plot_magic_angle_twisted_bilayer.py) | Twisted bilayer graphene: Bistritzer-MacDonald velocity and flat bands at the magic alpha. |
|
|
300
|
+
| [`superconductivity/plot_bcs_gap_equation.py`](examples/superconductivity/plot_bcs_gap_equation.py) | The real-space BCS gap equation: Delta(T), Delta(0)/T_c = 1.764, and the proximity effect. |
|
|
301
|
+
| [`correlations/plot_noncollinear_120_degree_order.py`](examples/correlations/plot_noncollinear_120_degree_order.py) | Non-collinear mean field: the 120-degree order of the half-filled triangular Hubbard model. |
|
|
302
|
+
| [`tight_binding/plot_building_finite_lattices.py`](examples/tight_binding/plot_building_finite_lattices.py) | Building finite lattices: cuts, dangling sites, lattice arithmetic, rotations. |
|
|
303
|
+
| [`tight_binding/plot_defects_and_impurities.py`](examples/tight_binding/plot_defects_and_impurities.py) | A vacancy zero mode and an impurity bound state in a graphene flake. |
|
|
304
|
+
| [`dynamics/plot_wavepacket_interference.py`](examples/dynamics/plot_wavepacket_interference.py) | Wave propagation: Aharonov-Bohm caging on a ring and a state trapped at a domain wall. |
|
|
305
|
+
|
|
306
|
+
The five pre-0.2 Jupyter notebooks were replaced by the gallery scripts
|
|
307
|
+
`tight_binding/plot_building_finite_lattices.py`,
|
|
308
|
+
`tight_binding/plot_defects_and_impurities.py` and
|
|
309
|
+
`dynamics/plot_wavepacket_interference.py` (their other content is covered
|
|
310
|
+
by the strain, correlations and non-Hermitian examples).
|
|
288
311
|
|
|
289
312
|
## Documentation
|
|
290
313
|
|
|
@@ -298,6 +321,8 @@ Rendered docs (tutorial, API reference, example gallery): https://cpoli.github.i
|
|
|
298
321
|
each one linked to the corresponding **tbkit** functionality and example
|
|
299
322
|
above.
|
|
300
323
|
* `docs/source/tbkit.rst` -- the API reference (auto-generated from docstrings).
|
|
324
|
+
* [`ROADMAP.md`](ROADMAP.md) -- what is planned next, and what tbkit
|
|
325
|
+
does not do yet (compared with Kwant and PythTB).
|
|
301
326
|
|
|
302
327
|
Build the HTML docs with `cd docs && make html` (output in `docs/build/html`).
|
|
303
328
|
|
|
@@ -315,9 +340,7 @@ cleaned up the API:
|
|
|
315
340
|
|
|
316
341
|
For continuity, the pre-0.2 lowercase class names (`lattice`, `system`,
|
|
317
342
|
`plot`, `propagation`, `save`) remain available as aliases of the new
|
|
318
|
-
classes, so `from tbkit.lattice import lattice` still works.
|
|
319
|
-
notebooks predating 0.2 still use byte-string tags (`b'a'`) and will need
|
|
320
|
-
that one mechanical change to run on the current version.
|
|
343
|
+
classes, so `from tbkit.lattice import lattice` still works.
|
|
321
344
|
|
|
322
345
|
## License
|
|
323
346
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
"""tbkit: build and solve Tight-Binding models."""
|
|
8
8
|
|
|
9
|
-
__version__ = "0.4.
|
|
9
|
+
__version__ = "0.4.2"
|
|
10
10
|
|
|
11
11
|
__all__ = [
|
|
12
12
|
"Lattice", "System", "Plot", "Propagation", "Save", "KSpace",
|
|
@@ -33,3 +33,17 @@ from tbkit.floquet import FloquetKSpace, DrivenKSpace, StepDrive, step_drive
|
|
|
33
33
|
from tbkit.meanfield import MeanFieldResult, hubbard_mean_field
|
|
34
34
|
from tbkit.exceptional import ExceptionalPoints, Encircling, find_exceptional_points
|
|
35
35
|
import tbkit.error_handling
|
|
36
|
+
# Model I/O (tbkit.io): appended here to keep the list above untouched.
|
|
37
|
+
from tbkit.io import save_model, load_model, read_wannier90
|
|
38
|
+
__all__ += ["save_model", "load_model", "read_wannier90"]
|
|
39
|
+
|
|
40
|
+
# Higher-order topology, moire supercells, self-consistent interactions
|
|
41
|
+
from tbkit.higher_order import CornerCharges, quadrupole_moment, corner_charges
|
|
42
|
+
__all__ += ["CornerCharges", "quadrupole_moment", "corner_charges"]
|
|
43
|
+
from tbkit.moire import SupercellKSpace, MoireKSpace, supercell, twisted_bilayer
|
|
44
|
+
__all__ += ["SupercellKSpace", "MoireKSpace", "supercell", "twisted_bilayer"]
|
|
45
|
+
from tbkit.meanfield import NonCollinearResult, hubbard_mean_field_noncollinear
|
|
46
|
+
from tbkit.bdg import GapResult, s_wave_gap
|
|
47
|
+
__all__ += ["NonCollinearResult", "hubbard_mean_field_noncollinear", "GapResult", "s_wave_gap"]
|
|
48
|
+
from tbkit.transport import RecursiveTransport
|
|
49
|
+
__all__ += ["RecursiveTransport"]
|
|
@@ -161,3 +161,110 @@ def particle_hole(n: int) -> NDArray[np.float64]:
|
|
|
161
161
|
'''
|
|
162
162
|
error_handling.positive_int(n, 'n')
|
|
163
163
|
return np.kron(np.array([[0., 1.], [1., 0.]]), np.eye(n))
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class GapResult():
|
|
167
|
+
r'''
|
|
168
|
+
Self-consistent s-wave pairing of *s_wave_gap*.
|
|
169
|
+
|
|
170
|
+
:ivar delta: Complex ndarray. Gap :math:`\Delta_i` on every site.
|
|
171
|
+
:ivar energies: Real ndarray, shape (2N,). Spectrum of the reduced BdG
|
|
172
|
+
Hamiltonian (symmetric, :math:`\pm E_n`).
|
|
173
|
+
:ivar states: Complex ndarray, shape (2N, 2N). Its eigenvectors
|
|
174
|
+
:math:`(u_n, v_n)` (columns).
|
|
175
|
+
:ivar iterations: Integer. Number of iterations.
|
|
176
|
+
'''
|
|
177
|
+
|
|
178
|
+
def __init__(self, delta, energies, states, iterations) -> None:
|
|
179
|
+
self.delta = delta
|
|
180
|
+
self.energies = energies
|
|
181
|
+
self.states = states
|
|
182
|
+
self.iterations = iterations
|
|
183
|
+
|
|
184
|
+
@property
|
|
185
|
+
def mean_gap(self) -> float:
|
|
186
|
+
r'''
|
|
187
|
+
Average :math:`|\Delta_i|` over the sites.
|
|
188
|
+
'''
|
|
189
|
+
return float(np.mean(np.abs(self.delta)))
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def s_wave_gap(
|
|
193
|
+
ham, V: float | NDArray, mu: float = 0., temperature: float = 0., delta0: complex | NDArray = 0.1,
|
|
194
|
+
mixing: float = 1., tol: float = 1e-8, max_iter: int = 10000,
|
|
195
|
+
) -> GapResult:
|
|
196
|
+
r'''
|
|
197
|
+
Solve the real-space gap equation of an s-wave superconductor
|
|
198
|
+
self-consistently (the attractive Hubbard model
|
|
199
|
+
:math:`-\sum_iV_in_{i\uparrow}n_{i\downarrow}` in the BCS mean-field
|
|
200
|
+
approximation, de Gennes 1966). For a spin-independent *ham* the singlet
|
|
201
|
+
BdG Hamiltonian reduces to the Nambu basis
|
|
202
|
+
:math:`(c_{i\uparrow}, c^\dagger_{i\downarrow})`,
|
|
203
|
+
|
|
204
|
+
.. math::
|
|
205
|
+
|
|
206
|
+
H = \begin{pmatrix} h-\mu & \Delta\\ \Delta^* & -(h-\mu)^*\end{pmatrix}\, ,
|
|
207
|
+
\qquad \Delta = \mathrm{diag}(\Delta_i)\, ,
|
|
208
|
+
|
|
209
|
+
whose eigenvectors :math:`(u_n, v_n)`, :math:`E_n > 0`, give the gap
|
|
210
|
+
equation
|
|
211
|
+
|
|
212
|
+
.. math::
|
|
213
|
+
|
|
214
|
+
\Delta_i = V_i\,\langle c_{i\downarrow}c_{i\uparrow}\rangle
|
|
215
|
+
= V_i\sum_{E_n>0}u_n(i)\,v_n^*(i)\tanh\frac{E_n}{2T}\, ,
|
|
216
|
+
|
|
217
|
+
iterated (with linear mixing) until self-consistent. On a clean lattice
|
|
218
|
+
it is the BCS gap equation :math:`1 = \frac{V}{N}\sum_{\mathbf{k}}
|
|
219
|
+
\tanh(E_{\mathbf{k}}/2T)/2E_{\mathbf{k}}`, with
|
|
220
|
+
:math:`\Delta(T_c) = 0` at :math:`T_c \approx \Delta(0)/1.764` at weak
|
|
221
|
+
coupling. The chemical potential is fixed (the Hartree shift
|
|
222
|
+
:math:`-V_in_i/2` is left out, i.e. absorbed in :math:`\mu`). Near
|
|
223
|
+
:math:`T_c` the iteration slows down (the linearized map has an
|
|
224
|
+
eigenvalue close to 1): raise *max_iter* there.
|
|
225
|
+
|
|
226
|
+
:param ham: Square Hermitian matrix, (N, N), spin independent (e.g. *System.ham*).
|
|
227
|
+
:param V: Positive real, or array of N non-negative reals. Attraction.
|
|
228
|
+
:param mu: Real number. Default value 0. Chemical potential.
|
|
229
|
+
:param temperature: Positive real or zero. Default value 0.
|
|
230
|
+
:param delta0: Number, or array of N numbers. Default value 0.1.
|
|
231
|
+
Initial gap.
|
|
232
|
+
:param mixing: Real in (0, 1]. Default value 1 (plain iteration).
|
|
233
|
+
:param tol: Positive real. Default value 1e-8. Convergence threshold
|
|
234
|
+
on the largest change of :math:`\Delta_i`.
|
|
235
|
+
:param max_iter: Positive integer. Default value 10000.
|
|
236
|
+
|
|
237
|
+
:returns:
|
|
238
|
+
* **result** -- :class:`GapResult`.
|
|
239
|
+
'''
|
|
240
|
+
h = ham.toarray() if hasattr(ham, 'toarray') else np.asarray(ham)
|
|
241
|
+
error_handling.square_matrix(h, 'ham')
|
|
242
|
+
error_handling.hermitian_dense(h)
|
|
243
|
+
n = len(h)
|
|
244
|
+
error_handling.interaction(V, n)
|
|
245
|
+
error_handling.real_number(mu, 'mu')
|
|
246
|
+
error_handling.positive_real_zero(temperature, 'temperature')
|
|
247
|
+
error_handling.pairing_amplitudes(delta0, n)
|
|
248
|
+
error_handling.mixing(mixing)
|
|
249
|
+
error_handling.positive_real(tol, 'tol')
|
|
250
|
+
error_handling.positive_int(max_iter, 'max_iter')
|
|
251
|
+
V = np.broadcast_to(np.asarray(V, dtype='f8'), (n,))
|
|
252
|
+
delta = np.broadcast_to(np.asarray(delta0, dtype='c16'), (n,)).copy()
|
|
253
|
+
xi = h.astype('c16') - mu * np.eye(n)
|
|
254
|
+
big = np.zeros((2 * n, 2 * n), 'c16')
|
|
255
|
+
big[:n, :n], big[n:, n:] = xi, -xi.conj()
|
|
256
|
+
diag = np.arange(n)
|
|
257
|
+
for it in range(1, max_iter + 1):
|
|
258
|
+
big[diag, diag + n] = delta
|
|
259
|
+
big[diag + n, diag] = delta.conj()
|
|
260
|
+
en, vec = np.linalg.eigh(big)
|
|
261
|
+
pos = en > 0
|
|
262
|
+
weight = np.tanh(en[pos] / (2 * temperature)) if temperature > 0 else np.ones(pos.sum())
|
|
263
|
+
new = V * np.einsum('in,in,n->i', vec[:n, pos], vec[n:, pos].conj(), weight)
|
|
264
|
+
change = np.max(np.abs(new - delta))
|
|
265
|
+
delta = (1 - mixing) * delta + mixing * new
|
|
266
|
+
if change < tol:
|
|
267
|
+
break
|
|
268
|
+
else:
|
|
269
|
+
error_handling.converged(False, 's_wave_gap')
|
|
270
|
+
return GapResult(new, en, vec, it)
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
r'''
|
|
2
|
+
Bridges between the two pipelines of tbkit: the real-space *System* (a
|
|
3
|
+
finite lattice, its sparse Hamiltonian) and the reciprocal-space *KSpace*
|
|
4
|
+
(the Bloch Hamiltonian :math:`H(\mathbf{k})` of the infinite lattice).
|
|
5
|
+
|
|
6
|
+
* *kspace_from_system* reads the Bloch model off a translation-invariant
|
|
7
|
+
*System* built the real-space way (*get_lattice*, *set_hopping* by
|
|
8
|
+
neighbour order, *set_onsite*, ...).
|
|
9
|
+
* *finite_model* and *finite_system* cut a finite sample (open boundaries,
|
|
10
|
+
or a torus) out of a *KSpace* model: its sparse Hamiltonian with the site
|
|
11
|
+
positions, or a ready-to-use *System*.
|
|
12
|
+
|
|
13
|
+
Both use the convention of *KSpace.finite_ham*: the hopping
|
|
14
|
+
:math:`t_{ij}(\mathbf{R}) = \langle i,\mathbf{0}|H|j,\mathbf{R}\rangle`
|
|
15
|
+
joins orbital *i* of every cell to orbital *j* of the cell :math:`\mathbf{R}`
|
|
16
|
+
further. So, for the same model, the spectrum of a System on an
|
|
17
|
+
:math:`N_1\times N_2` torus is the set of KSpace bands on the
|
|
18
|
+
:math:`N_1\times N_2` Brillouin-zone mesh.
|
|
19
|
+
'''
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import numpy as np
|
|
23
|
+
from numpy.typing import NDArray
|
|
24
|
+
import scipy.sparse as sp
|
|
25
|
+
|
|
26
|
+
import tbkit.error_handling as error_handling
|
|
27
|
+
import tbkit.neighbours as neighbours
|
|
28
|
+
from tbkit.kspace import KSpace
|
|
29
|
+
from tbkit.lattice import Lattice
|
|
30
|
+
from tbkit.orbital import OrbitalSystem
|
|
31
|
+
from tbkit.system import System, HOP_DTYPE, ATOL, _upper
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _coords(lat: Lattice) -> NDArray[np.float64]:
|
|
35
|
+
'''
|
|
36
|
+
Private function. Site coordinates of a finite lattice, shape (sites, space_dim).
|
|
37
|
+
'''
|
|
38
|
+
return np.stack([lat.coor[f] for f in ('x', 'y', 'z')[:lat.space_dim]], axis=1)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def cell_orbitals(lat: Lattice) -> tuple[NDArray[np.int64], NDArray[np.int64]]:
|
|
42
|
+
r'''
|
|
43
|
+
Get, for every site of a finite lattice (*lat.coor*), the unit-cell
|
|
44
|
+
orbital it is a copy of and its cell: site *s* sits at
|
|
45
|
+
:math:`\boldsymbol\tau_{o_s} + \sum_k n_{s,k}\mathbf{a}_k`, with the tag
|
|
46
|
+
of orbital :math:`o_s` (within ``ATOL``).
|
|
47
|
+
|
|
48
|
+
:param lat: **Lattice** instance, after *get_lattice* (sites may have
|
|
49
|
+
been removed, but not moved).
|
|
50
|
+
|
|
51
|
+
:returns:
|
|
52
|
+
* **cells** -- Integer ndarray, shape (sites, dim). :math:`n_{s,k}`.
|
|
53
|
+
* **orbitals** -- Integer ndarray, shape (sites,). :math:`o_s`.
|
|
54
|
+
'''
|
|
55
|
+
error_handling.lat(lat)
|
|
56
|
+
error_handling.empty_coor(lat.coor)
|
|
57
|
+
a, tau, tags = neighbours._geometry(lat)
|
|
58
|
+
pos = _coords(lat)
|
|
59
|
+
pinv = np.linalg.pinv(a)
|
|
60
|
+
match = np.zeros((lat.sites, len(tau)), bool)
|
|
61
|
+
cells = np.zeros((lat.sites, len(tau), len(a)), int)
|
|
62
|
+
for o in range(len(tau)):
|
|
63
|
+
rel = pos - tau[o]
|
|
64
|
+
n = np.rint(rel @ pinv).astype(int)
|
|
65
|
+
match[:, o] = (np.linalg.norm(n @ a - rel, axis=1) < ATOL) & (lat.coor['tag'] == tags[o])
|
|
66
|
+
cells[:, o] = n
|
|
67
|
+
error_handling.lattice_sites(match.sum(axis=1))
|
|
68
|
+
orb = np.argmax(match, axis=1)
|
|
69
|
+
return cells[np.arange(lat.sites), orb], orb
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def kspace_from_system(sys: System, periodic: bool = False, tol: float = 1e-9) -> KSpace:
|
|
73
|
+
r'''
|
|
74
|
+
Get the Bloch Hamiltonian of a periodic model defined the real-space
|
|
75
|
+
way: every matrix element :math:`H_{ab}` of the finite *System* (built
|
|
76
|
+
by *get_ham*) joins orbital :math:`o_a` of cell :math:`\mathbf{n}_a` to
|
|
77
|
+
orbital :math:`o_b` of cell :math:`\mathbf{n}_b` (see *cell_orbitals*),
|
|
78
|
+
i.e. is the hopping :math:`t_{o_ao_b}(\mathbf{n}_b-\mathbf{n}_a)` of the
|
|
79
|
+
infinite lattice. Each such hopping must take the same value in every
|
|
80
|
+
cell where it appears (bonds cut by the boundary are simply missing).
|
|
81
|
+
The lattice must be large enough to hold every bond of the model.
|
|
82
|
+
|
|
83
|
+
A System on a torus (*periodic*, e.g. from *finite_system*) has bonds
|
|
84
|
+
that wrap around: their lattice vectors are then taken modulo the
|
|
85
|
+
:math:`N_1\times N_2\times\dots` cells of *get_lattice*, as the shortest
|
|
86
|
+
image (so the model's range must stay below half the torus).
|
|
87
|
+
|
|
88
|
+
A Hermitian hopping matrix gives a Hermitian model (one representative
|
|
89
|
+
per bond, *set_hopping* adding the conjugate); otherwise every matrix
|
|
90
|
+
element is kept, with ``hermitian=False``. Onsite energies are taken
|
|
91
|
+
orbital by orbital.
|
|
92
|
+
|
|
93
|
+
:param sys: **System** instance with its hoppings set (one orbital per site).
|
|
94
|
+
:param periodic: Boolean. Default value False. The System is a torus
|
|
95
|
+
of the *lat.n1* x *lat.n2* (x *lat.n3*) cells of *get_lattice*.
|
|
96
|
+
:param tol: Positive real number. Default value 1e-9. Largest allowed
|
|
97
|
+
difference between equivalent matrix elements.
|
|
98
|
+
|
|
99
|
+
:returns:
|
|
100
|
+
* **ks** -- **KSpace** instance (spinless), on a new **Lattice**
|
|
101
|
+
with the *unit_cell* and *prim_vec* of *sys.lat*.
|
|
102
|
+
|
|
103
|
+
Example usage::
|
|
104
|
+
|
|
105
|
+
lat = lattices.honeycomb()
|
|
106
|
+
lat.get_lattice(6, 6)
|
|
107
|
+
sys = System(lat)
|
|
108
|
+
sys.set_hopping([{'n': 1, 't': -1.}, {'n': 2, 't': 0.1}])
|
|
109
|
+
gra = kspace_from_system(sys) # the Bloch model of the same graphene
|
|
110
|
+
'''
|
|
111
|
+
error_handling.sys(sys)
|
|
112
|
+
error_handling.not_orbital_system(sys, OrbitalSystem)
|
|
113
|
+
error_handling.boolean(periodic, 'periodic')
|
|
114
|
+
error_handling.positive_real(tol, 'tol')
|
|
115
|
+
sys.get_ham()
|
|
116
|
+
cells, orb = cell_orbitals(sys.lat)
|
|
117
|
+
ham = sys.ham.tocoo()
|
|
118
|
+
rows, cols, vals = ham.row, ham.col, ham.data.astype('c16')
|
|
119
|
+
R = cells[cols] - cells[rows]
|
|
120
|
+
if periodic:
|
|
121
|
+
sizes = np.array((sys.lat.n1, sys.lat.n2, sys.lat.n3)[:R.shape[1]])
|
|
122
|
+
R = (R + sizes // 2) % sizes - sizes // 2 # shortest image, in [-N/2, N/2)
|
|
123
|
+
error_handling.torus_range(R, sizes)
|
|
124
|
+
keys = np.column_stack([orb[rows], orb[cols], R])
|
|
125
|
+
uniq, first, inv = np.unique(keys, axis=0, return_index=True, return_inverse=True)
|
|
126
|
+
inv = inv.ravel()
|
|
127
|
+
values = vals[first]
|
|
128
|
+
error_handling.translation_invariant(float(np.abs(vals - values[inv]).max()), tol)
|
|
129
|
+
off = ham - sp.diags(ham.diagonal())
|
|
130
|
+
hermitian = bool(abs(off - off.conj().T).max() <= tol)
|
|
131
|
+
lat = Lattice(unit_cell=list(sys.lat.unit_cell), prim_vec=list(sys.lat.prim_vec))
|
|
132
|
+
ks = KSpace(lat)
|
|
133
|
+
list_hop = []
|
|
134
|
+
for key, t in zip(uniq, values):
|
|
135
|
+
i, j, R = int(key[0]), int(key[1]), tuple(int(n) for n in key[2:])
|
|
136
|
+
if i == j and not any(R):
|
|
137
|
+
ks.onsite[i] = t
|
|
138
|
+
continue
|
|
139
|
+
nonzero = [n for n in R if n != 0]
|
|
140
|
+
if hermitian and not ((nonzero and nonzero[0] > 0) or (not nonzero and i < j)):
|
|
141
|
+
continue # the conjugate of a kept representative
|
|
142
|
+
list_hop.append({'i': i, 'j': j, 'R': R, 't': complex(t)})
|
|
143
|
+
ks.set_hopping(list_hop, hermitian=hermitian)
|
|
144
|
+
return ks
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _finite_sites(ks: KSpace, n_cells: tuple[int, ...]) -> tuple[NDArray[np.float64], NDArray]:
|
|
148
|
+
'''
|
|
149
|
+
Private function. Positions and tags of the rows of *ks.finite_ham(n_cells)*.
|
|
150
|
+
'''
|
|
151
|
+
n_tot = int(np.prod(n_cells))
|
|
152
|
+
cells = np.array(np.unravel_index(np.arange(n_tot), n_cells, order='F')).T
|
|
153
|
+
a = np.array(ks.lat.prim_vec, dtype='f8')
|
|
154
|
+
pos = (cells @ a)[:, None, :] + ks.orbital_positions()[None, :, :]
|
|
155
|
+
tags = np.repeat(ks.tags, 2) if ks.spin else ks.tags
|
|
156
|
+
return pos.reshape(n_tot * ks.norb, ks.space_dim), np.tile(tags, n_tot)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def finite_model(
|
|
160
|
+
ks: KSpace, n_cells: int | tuple[int, ...], periodic: bool = False,
|
|
161
|
+
) -> tuple[sp.csr_matrix, NDArray[np.float64], NDArray]:
|
|
162
|
+
r'''
|
|
163
|
+
Get a finite sample of a *KSpace* model: its sparse Hamiltonian (that of
|
|
164
|
+
*KSpace.finite_ham*, open or periodic boundaries), with the position
|
|
165
|
+
and tag of every row. Spinful models are supported (the two spin
|
|
166
|
+
components of a site share its position).
|
|
167
|
+
|
|
168
|
+
:param ks: **KSpace** instance.
|
|
169
|
+
:param n_cells: Positive integer, or tuple of *dim* positive integers.
|
|
170
|
+
Number of unit cells along each primitive vector.
|
|
171
|
+
:param periodic: Boolean. Default value False. Periodic boundaries (a torus).
|
|
172
|
+
|
|
173
|
+
:returns:
|
|
174
|
+
* **ham** -- Complex CSR matrix, shape (N*norb, N*norb).
|
|
175
|
+
* **positions** -- Real ndarray, shape (N*norb, space_dim). Row
|
|
176
|
+
:math:`c\,\mathrm{norb}+o` sits at :math:`\boldsymbol\tau_o + \sum_k n_k\mathbf{a}_k`
|
|
177
|
+
(cell *c* has :math:`c = n_1 + N_1 n_2 + N_1N_2 n_3`).
|
|
178
|
+
* **tags** -- String ndarray, shape (N*norb,). Sublattice tags.
|
|
179
|
+
'''
|
|
180
|
+
error_handling.kspace(ks, KSpace)
|
|
181
|
+
error_handling.nk(n_cells, ks.dim)
|
|
182
|
+
error_handling.boolean(periodic, 'periodic')
|
|
183
|
+
n_cells = (n_cells,) * ks.dim if isinstance(n_cells, int) else n_cells
|
|
184
|
+
pos, tags = _finite_sites(ks, n_cells)
|
|
185
|
+
return ks.finite_ham(n_cells, periodic=periodic, sparse=True), pos, tags
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def finite_system(ks: KSpace, n_cells: int | tuple[int, ...], periodic: bool = False) -> System:
|
|
189
|
+
r'''
|
|
190
|
+
Build a finite *System* out of a (spinless) *KSpace* model: *lat.coor*
|
|
191
|
+
holds the sites of :math:`N_1\times N_2\times\dots` unit cells (in the
|
|
192
|
+
order of *finite_model*), and *sys.hop* / *sys.onsite* the model's
|
|
193
|
+
hoppings and onsite energies, so that *sys.get_ham()* gives
|
|
194
|
+
*ks.finite_ham(n_cells, periodic)*. Every real-space tool (*get_eig*,
|
|
195
|
+
*get_ldos*, *Plot*, disorder, ...) then applies.
|
|
196
|
+
|
|
197
|
+
In *sys.hop*, each bond is stored with the conventions of
|
|
198
|
+
*System.set_hopping*: a Hermitian model keeps one orientation per bond
|
|
199
|
+
(angle in [0, 180), *get_ham* adds the conjugate); a non-reciprocal
|
|
200
|
+
one keeps both, the missing direction with a zero amplitude. 'n' is the
|
|
201
|
+
neighbour order of the bond (0 for coinciding orbitals), 'tag' the
|
|
202
|
+
sublattice pair. On a torus, a bond that wraps around keeps its short
|
|
203
|
+
bond vector for its angle, and a hopping that wraps onto its own site
|
|
204
|
+
is added to the onsite energy.
|
|
205
|
+
|
|
206
|
+
:param ks: **KSpace** instance, with ``spin=False``.
|
|
207
|
+
:param n_cells: Positive integer, or tuple of *dim* positive integers.
|
|
208
|
+
:param periodic: Boolean. Default value False. Periodic boundaries (a torus).
|
|
209
|
+
|
|
210
|
+
:returns:
|
|
211
|
+
* **sys** -- **System** instance, with its hoppings set.
|
|
212
|
+
|
|
213
|
+
Example usage::
|
|
214
|
+
|
|
215
|
+
sys = finite_system(gra, (30, 30), periodic=True)
|
|
216
|
+
sys.get_ham()
|
|
217
|
+
sys.get_eig() # = gra.mesh_bands((30, 30)), sorted
|
|
218
|
+
'''
|
|
219
|
+
error_handling.kspace(ks, KSpace)
|
|
220
|
+
error_handling.nk(n_cells, ks.dim)
|
|
221
|
+
error_handling.boolean(periodic, 'periodic')
|
|
222
|
+
error_handling.spinless(ks.spin)
|
|
223
|
+
n_cells = (n_cells,) * ks.dim if isinstance(n_cells, int) else n_cells
|
|
224
|
+
pos, tags = _finite_sites(ks, n_cells)
|
|
225
|
+
lat = Lattice(unit_cell=list(ks.lat.unit_cell), prim_vec=list(ks.lat.prim_vec))
|
|
226
|
+
coor = np.zeros(len(pos), dtype=lat.dtype)
|
|
227
|
+
for c, f in enumerate(('x', 'y', 'z')[:ks.space_dim]):
|
|
228
|
+
coor[f] = pos[:, c]
|
|
229
|
+
coor['tag'] = tags
|
|
230
|
+
lat.coor, lat.sites = coor, len(coor)
|
|
231
|
+
lat.n1, lat.n2, lat.n3 = (tuple(n_cells) + (1, 1))[:3]
|
|
232
|
+
sys = System(lat)
|
|
233
|
+
_, n_tot, entries = ks._finite_entries(n_cells, periodic)
|
|
234
|
+
tau = ks.orbital_positions()
|
|
235
|
+
rows = np.concatenate([np.zeros(0, int)] + [e[0] for e in entries])
|
|
236
|
+
cols = np.concatenate([np.zeros(0, int)] + [e[1] for e in entries])
|
|
237
|
+
t = np.concatenate([np.zeros(0, 'c16')] + [np.full(len(e[0]), e[6], 'c16') for e in entries])
|
|
238
|
+
d = np.concatenate([np.zeros((0, ks.space_dim))]
|
|
239
|
+
+ [np.repeat((e[5] + tau[e[3]] - tau[e[2]])[None], len(e[0]), axis=0)
|
|
240
|
+
for e in entries])
|
|
241
|
+
n_sites = len(pos)
|
|
242
|
+
diag = rows == cols
|
|
243
|
+
sys.onsite = np.tile(ks.onsite, n_tot) + (np.bincount(rows[diag], t[diag].real, n_sites)
|
|
244
|
+
+ 1j * np.bincount(rows[diag], t[diag].imag, n_sites))
|
|
245
|
+
rows, cols, t, d = rows[~diag], cols[~diag], t[~diag], d[~diag]
|
|
246
|
+
dist = np.linalg.norm(d, axis=1)
|
|
247
|
+
zero = dist <= ATOL
|
|
248
|
+
ang = neighbours._bond_angles(d)
|
|
249
|
+
up = np.where(zero, rows < cols, _upper(ang))
|
|
250
|
+
ang_up = np.where(zero, 0., np.maximum(np.where(up, ang, neighbours._bond_angles(-d)), 0.))
|
|
251
|
+
if ks._nonreciprocal:
|
|
252
|
+
i = np.concatenate([rows, cols])
|
|
253
|
+
j = np.concatenate([cols, rows])
|
|
254
|
+
t = np.concatenate([t, np.zeros(len(t), 'c16')])
|
|
255
|
+
ang = np.concatenate([np.where(up, ang_up, ang_up - 180.), np.where(up, ang_up - 180., ang_up)])
|
|
256
|
+
dist = np.concatenate([dist, dist])
|
|
257
|
+
else:
|
|
258
|
+
i, j, t, ang, dist = rows[up], cols[up], t[up], ang_up[up], dist[up]
|
|
259
|
+
hop = np.zeros(len(i), dtype=HOP_DTYPE)
|
|
260
|
+
hop['n'] = neighbours.shell_index(ks.lat, dist)
|
|
261
|
+
hop['i'], hop['j'], hop['t'], hop['ang'] = i, j, t, ang
|
|
262
|
+
hop['tag'] = np.char.add(tags[i], tags[j])
|
|
263
|
+
sys.hop = hop
|
|
264
|
+
return sys
|