tbkit 0.4.0__tar.gz → 0.4.1__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.1}/PKG-INFO +25 -8
- {tbkit-0.4.0 → tbkit-0.4.1}/README.md +24 -7
- {tbkit-0.4.0 → tbkit-0.4.1}/pyproject.toml +1 -1
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/__init__.py +15 -1
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/bdg.py +107 -0
- tbkit-0.4.1/tbkit/bridges.py +264 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/error_handling.py +591 -0
- tbkit-0.4.1/tbkit/higher_order.py +428 -0
- tbkit-0.4.1/tbkit/io.py +354 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/kspace.py +25 -2
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/meanfield.py +132 -0
- tbkit-0.4.1/tbkit/moire.py +491 -0
- tbkit-0.4.1/tbkit/neighbours.py +245 -0
- tbkit-0.4.1/tbkit/optics.py +450 -0
- tbkit-0.4.1/tbkit/transport.py +656 -0
- {tbkit-0.4.0 → tbkit-0.4.1/tbkit.egg-info}/PKG-INFO +25 -8
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit.egg-info/SOURCES.txt +17 -1
- tbkit-0.4.1/tests/test_bridges.py +258 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_error_handling.py +111 -0
- tbkit-0.4.1/tests/test_error_handling_structures.py +73 -0
- tbkit-0.4.1/tests/test_higher_order.py +215 -0
- tbkit-0.4.1/tests/test_interactions.py +179 -0
- tbkit-0.4.1/tests/test_io.py +144 -0
- tbkit-0.4.1/tests/test_moire.py +262 -0
- tbkit-0.4.1/tests/test_neighbours.py +233 -0
- tbkit-0.4.1/tests/test_optics.py +335 -0
- tbkit-0.4.1/tests/test_transport_response.py +257 -0
- tbkit-0.4.1/tests/test_wannier90.py +180 -0
- tbkit-0.4.0/tbkit/transport.py +0 -225
- {tbkit-0.4.0 → tbkit-0.4.1}/LICENSE +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/setup.cfg +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/dos.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/exceptional.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/floquet.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/graphene.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/kpm.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/lattice.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/lattices.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/occupation.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/orbital.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/plot.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/propagation.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/save.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/slater_koster.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit/system.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit.egg-info/dependency_links.txt +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit.egg-info/requires.txt +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tbkit.egg-info/top_level.txt +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_correlations.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_dos.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_exceptional.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_floquet.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_graphene.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_green_occupation.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_hall.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_kpm.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_kspace.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_large_lattices.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_lattice.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_lattices.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_magnetic.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_non_hermitian_bands.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_orbitals.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_plot.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_propagation.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_regressions.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_save.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_system.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_three_d.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/tests/test_topology.py +0 -0
- {tbkit-0.4.0 → tbkit-0.4.1}/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.1
|
|
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>
|
|
@@ -130,7 +130,12 @@ topology alongside superconductivity.
|
|
|
130
130
|
| `tbkit.meanfield` | The Hubbard model in (unrestricted Hartree-Fock) mean field. |
|
|
131
131
|
| `tbkit.bdg` | Bogoliubov-de Gennes Hamiltonians and pairings. |
|
|
132
132
|
| `tbkit.exceptional` | Exceptional and diabolical points of 2D bands: vorticity, discriminant winding, EP finder, Fermi arcs, encircling. |
|
|
133
|
+
| `tbkit.higher_order` | Higher-order topology: nested Wilson loops, Wannier-sector polarizations, the BBH quadrupole moment, corner charges. |
|
|
134
|
+
| `tbkit.moire` | Supercells, band unfolding and spectral functions, commensurate twisted bilayers. |
|
|
133
135
|
| `tbkit.floquet` | Floquet theory; `FloquetKSpace`/`DrivenKSpace` for driven Bloch models, `step_drive`, and the winding number of anomalous Floquet phases. |
|
|
136
|
+
| `tbkit.neighbours` | Neighbour shells of a periodic lattice; `KSpace.set_hopping` by neighbour order, angle and sublattice pair, as in `System`. |
|
|
137
|
+
| `tbkit.bridges` | Move a model between `System` and `KSpace` (open samples and tori). |
|
|
138
|
+
| `tbkit.io` | Save and load `Lattice`/`System`/`KSpace` models (`.npz`); import Wannier90 `_hr.dat` models. |
|
|
134
139
|
|
|
135
140
|
## Install
|
|
136
141
|
|
|
@@ -309,10 +314,24 @@ thumbnailed example gallery under `docs/source/api/gallery/`.
|
|
|
309
314
|
| [`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
315
|
| [`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
316
|
| [`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
|
-
|
|
317
|
+
| [`models/plot_neighbour_hoppings.py`](examples/models/plot_neighbour_hoppings.py) | Hoppings by neighbour order in k-space: third-nearest-neighbour graphene with overlaps. |
|
|
318
|
+
| [`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. |
|
|
319
|
+
| [`models/plot_save_load.py`](examples/models/plot_save_load.py) | Saving and reloading models: identical Hamiltonians after a round trip through disk. |
|
|
320
|
+
| [`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. |
|
|
321
|
+
| [`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. |
|
|
322
|
+
| [`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. |
|
|
323
|
+
| [`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. |
|
|
324
|
+
| [`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. |
|
|
325
|
+
| [`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. |
|
|
326
|
+
| [`tight_binding/plot_building_finite_lattices.py`](examples/tight_binding/plot_building_finite_lattices.py) | Building finite lattices: cuts, dangling sites, lattice arithmetic, rotations. |
|
|
327
|
+
| [`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. |
|
|
328
|
+
| [`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. |
|
|
329
|
+
|
|
330
|
+
The five pre-0.2 Jupyter notebooks were replaced by the gallery scripts
|
|
331
|
+
`tight_binding/plot_building_finite_lattices.py`,
|
|
332
|
+
`tight_binding/plot_defects_and_impurities.py` and
|
|
333
|
+
`dynamics/plot_wavepacket_interference.py` (their other content is covered
|
|
334
|
+
by the strain, correlations and non-Hermitian examples).
|
|
316
335
|
|
|
317
336
|
## Documentation
|
|
318
337
|
|
|
@@ -343,9 +362,7 @@ cleaned up the API:
|
|
|
343
362
|
|
|
344
363
|
For continuity, the pre-0.2 lowercase class names (`lattice`, `system`,
|
|
345
364
|
`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.
|
|
365
|
+
classes, so `from tbkit.lattice import lattice` still works.
|
|
349
366
|
|
|
350
367
|
## License
|
|
351
368
|
|
|
@@ -102,7 +102,12 @@ topology alongside superconductivity.
|
|
|
102
102
|
| `tbkit.meanfield` | The Hubbard model in (unrestricted Hartree-Fock) mean field. |
|
|
103
103
|
| `tbkit.bdg` | Bogoliubov-de Gennes Hamiltonians and pairings. |
|
|
104
104
|
| `tbkit.exceptional` | Exceptional and diabolical points of 2D bands: vorticity, discriminant winding, EP finder, Fermi arcs, encircling. |
|
|
105
|
+
| `tbkit.higher_order` | Higher-order topology: nested Wilson loops, Wannier-sector polarizations, the BBH quadrupole moment, corner charges. |
|
|
106
|
+
| `tbkit.moire` | Supercells, band unfolding and spectral functions, commensurate twisted bilayers. |
|
|
105
107
|
| `tbkit.floquet` | Floquet theory; `FloquetKSpace`/`DrivenKSpace` for driven Bloch models, `step_drive`, and the winding number of anomalous Floquet phases. |
|
|
108
|
+
| `tbkit.neighbours` | Neighbour shells of a periodic lattice; `KSpace.set_hopping` by neighbour order, angle and sublattice pair, as in `System`. |
|
|
109
|
+
| `tbkit.bridges` | Move a model between `System` and `KSpace` (open samples and tori). |
|
|
110
|
+
| `tbkit.io` | Save and load `Lattice`/`System`/`KSpace` models (`.npz`); import Wannier90 `_hr.dat` models. |
|
|
106
111
|
|
|
107
112
|
## Install
|
|
108
113
|
|
|
@@ -281,10 +286,24 @@ thumbnailed example gallery under `docs/source/api/gallery/`.
|
|
|
281
286
|
| [`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
287
|
| [`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
288
|
| [`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
|
-
|
|
289
|
+
| [`models/plot_neighbour_hoppings.py`](examples/models/plot_neighbour_hoppings.py) | Hoppings by neighbour order in k-space: third-nearest-neighbour graphene with overlaps. |
|
|
290
|
+
| [`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. |
|
|
291
|
+
| [`models/plot_save_load.py`](examples/models/plot_save_load.py) | Saving and reloading models: identical Hamiltonians after a round trip through disk. |
|
|
292
|
+
| [`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. |
|
|
293
|
+
| [`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. |
|
|
294
|
+
| [`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. |
|
|
295
|
+
| [`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. |
|
|
296
|
+
| [`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. |
|
|
297
|
+
| [`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. |
|
|
298
|
+
| [`tight_binding/plot_building_finite_lattices.py`](examples/tight_binding/plot_building_finite_lattices.py) | Building finite lattices: cuts, dangling sites, lattice arithmetic, rotations. |
|
|
299
|
+
| [`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. |
|
|
300
|
+
| [`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. |
|
|
301
|
+
|
|
302
|
+
The five pre-0.2 Jupyter notebooks were replaced by the gallery scripts
|
|
303
|
+
`tight_binding/plot_building_finite_lattices.py`,
|
|
304
|
+
`tight_binding/plot_defects_and_impurities.py` and
|
|
305
|
+
`dynamics/plot_wavepacket_interference.py` (their other content is covered
|
|
306
|
+
by the strain, correlations and non-Hermitian examples).
|
|
288
307
|
|
|
289
308
|
## Documentation
|
|
290
309
|
|
|
@@ -315,9 +334,7 @@ cleaned up the API:
|
|
|
315
334
|
|
|
316
335
|
For continuity, the pre-0.2 lowercase class names (`lattice`, `system`,
|
|
317
336
|
`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.
|
|
337
|
+
classes, so `from tbkit.lattice import lattice` still works.
|
|
321
338
|
|
|
322
339
|
## License
|
|
323
340
|
|
|
@@ -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.1"
|
|
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
|