tbkit 0.6.2__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tbkit-0.6.2/tbkit.egg-info → tbkit-0.7.0}/PKG-INFO +2 -2
- {tbkit-0.6.2 → tbkit-0.7.0}/README.md +1 -1
- {tbkit-0.6.2 → tbkit-0.7.0}/pyproject.toml +1 -1
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/__init__.py +1 -1
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/bdg.py +112 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/error_handling.py +55 -6
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/floquet.py +18 -1
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/kspace.py +231 -46
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/transport.py +187 -67
- {tbkit-0.6.2 → tbkit-0.7.0/tbkit.egg-info}/PKG-INFO +2 -2
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_error_handling.py +12 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_error_handling_structures.py +4 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_floquet.py +14 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_interactions.py +58 -1
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_kspace.py +10 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_smatrix.py +69 -1
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_surface_spectral.py +18 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_topology.py +109 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_transport_response.py +45 -6
- {tbkit-0.6.2 → tbkit-0.7.0}/LICENSE +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/setup.cfg +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/bridges.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/continuum.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/dos.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/exceptional.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/graphene.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/higher_order.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/io.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/kpm.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/lattice.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/lattices.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/meanfield.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/moire.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/neighbours.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/occupation.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/optics.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/orbital.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/plot.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/propagation.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/py.typed +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/save.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/slater_koster.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/system.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/topology.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/values.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit/wannier.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit.egg-info/SOURCES.txt +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit.egg-info/dependency_links.txt +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit.egg-info/requires.txt +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tbkit.egg-info/top_level.txt +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_analysis.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_berry_response.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_bridges.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_continuum.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_correlations.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_dos.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_exceptional.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_graphene.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_green_occupation.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_hall.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_higher_order.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_invariants.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_io.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_kpm.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_large_lattices.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_lattice.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_lattices.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_magnetic.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_moire.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_neighbours.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_non_hermitian_bands.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_optics.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_orbitals.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_periodic.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_plot.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_propagation.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_regressions.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_save.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_system.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_three_d.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_transport.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_values.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_wannier90.py +0 -0
- {tbkit-0.6.2 → tbkit-0.7.0}/tests/test_wannier_functions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tbkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.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>
|
|
@@ -47,7 +47,7 @@ Dynamic: license-file
|
|
|
47
47
|
|
|
48
48
|
| | |
|
|
49
49
|
|:--|:-:|
|
|
50
|
-
| Package | [](https://pypi.org/project/tbkit/) [](https://anaconda.org/conda-forge/tbkit) [](https://pypi.org/project/tbkit/) [](https://pypi.org/project/tbkit/) [](https://anaconda.org/conda-forge/tbkit) [](https://pypi.org/project/tbkit/) [](https://doi.org/10.5281/zenodo.23755191) |
|
|
51
51
|
| Quality | [](https://github.com/cpoli/tbkit/blob/master/LICENSE) [](https://github.com/cpoli/tbkit/actions/workflows/ci.yml) [](https://codecov.io/gh/cpoli/tbkit) |
|
|
52
52
|
| Documentation | [](https://cpoli.github.io/tbkit/) |
|
|
53
53
|
| Downloads | [](https://pepy.tech/project/tbkit) [](https://pepy.tech/project/tbkit) |
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
| | |
|
|
4
4
|
|:--|:-:|
|
|
5
|
-
| Package | [](https://pypi.org/project/tbkit/) [](https://anaconda.org/conda-forge/tbkit) [](https://pypi.org/project/tbkit/) [](https://pypi.org/project/tbkit/) [](https://anaconda.org/conda-forge/tbkit) [](https://pypi.org/project/tbkit/) [](https://doi.org/10.5281/zenodo.23755191) |
|
|
6
6
|
| Quality | [](https://github.com/cpoli/tbkit/blob/master/LICENSE) [](https://github.com/cpoli/tbkit/actions/workflows/ci.yml) [](https://codecov.io/gh/cpoli/tbkit) |
|
|
7
7
|
| Documentation | [](https://cpoli.github.io/tbkit/) |
|
|
8
8
|
| Downloads | [](https://pepy.tech/project/tbkit) [](https://pepy.tech/project/tbkit) |
|
|
@@ -395,3 +395,115 @@ def s_wave_gap(
|
|
|
395
395
|
else:
|
|
396
396
|
error_handling.converged(False, 's_wave_gap')
|
|
397
397
|
return GapResult(new, en, vec, it)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def superfluid_weight(
|
|
401
|
+
ks, delta: complex | NDArray, mu: float = 0., nk: int | tuple[int, ...] = 60,
|
|
402
|
+
temperature: float = 0., dq: float = 1e-3,
|
|
403
|
+
) -> NDArray[np.float64]:
|
|
404
|
+
r'''
|
|
405
|
+
Get the superfluid weight of an s-wave superconductor,
|
|
406
|
+
:math:`D_{\mu\nu} = \partial^2\Omega/\partial A_\mu\partial A_\nu` at
|
|
407
|
+
:math:`\mathbf{A} = 0` (:math:`\hbar = e = 1`): the curvature of the
|
|
408
|
+
grand potential per unit volume in a uniform vector potential, which
|
|
409
|
+
gives the supercurrent :math:`j_\mu = -D_{\mu\nu}A_\nu` (London). *ks* is
|
|
410
|
+
the spin-up model; the spin-down electrons are its time-reversed
|
|
411
|
+
partners, :math:`h_\downarrow(\mathbf{k}) = h(-\mathbf{k})^*`, so the
|
|
412
|
+
Kramers pairs :math:`(\mathbf{k}\uparrow, -\mathbf{k}\downarrow)` pair
|
|
413
|
+
even when *ks* is a Chern band (for real hoppings, the spin-independent
|
|
414
|
+
model). In the Nambu basis
|
|
415
|
+
:math:`(c_{\mathbf{k}\uparrow}, c^\dagger_{-\mathbf{k}\downarrow})`,
|
|
416
|
+
|
|
417
|
+
.. math::
|
|
418
|
+
|
|
419
|
+
H_{\mathbf{A}}(\mathbf{k}) = \begin{pmatrix} h_{\mathbf{A}}(\mathbf{k})-\mu & \Delta \\
|
|
420
|
+
\Delta^* & -[h_{-\mathbf{A}}(\mathbf{k})-\mu]\end{pmatrix}\, ,\qquad
|
|
421
|
+
\Omega(\mathbf{A}) = \frac{1}{N_kV}\sum_{\mathbf{k}}\Big[\mathrm{Tr}\,
|
|
422
|
+
[h_{-\mathbf{A}}(\mathbf{k})-\mu] - T\sum_n\ln\big(1 + e^{-E_n/T}\big)\Big]\, ,
|
|
423
|
+
|
|
424
|
+
with :math:`h_{\mathbf{A}}` the Peierls Hamiltonian of
|
|
425
|
+
*get_ham_peierls* (phases on the bond vectors, orbital positions
|
|
426
|
+
included), :math:`\Delta = \mathrm{diag}(\Delta_i)` the onsite pairing,
|
|
427
|
+
:math:`E_n` the eigenvalues and :math:`V` the cell volume.
|
|
428
|
+
:math:`\Delta` is held fixed (not re-solved in the field), which is
|
|
429
|
+
exact when symmetry fixes it, e.g. uniform pairing. The derivatives are
|
|
430
|
+
central differences in :math:`\mathbf{A}`.
|
|
431
|
+
|
|
432
|
+
For a dispersive band it is the conventional :math:`n/m`. For an
|
|
433
|
+
isolated flat band at filling :math:`\nu`, with uniform :math:`\Delta`
|
|
434
|
+
small compared to the band gaps, there is no dispersion, and
|
|
435
|
+
:math:`D` is purely geometric (Peotta and Törmä, Nat. Commun. 6, 8944
|
|
436
|
+
(2015)),
|
|
437
|
+
|
|
438
|
+
.. math::
|
|
439
|
+
|
|
440
|
+
D_{\mu\nu} = 8\Delta\sqrt{\nu(1-\nu)}\int\frac{d^d\mathbf{k}}{(2\pi)^d}\,g_{\mu\nu}(\mathbf{k})
|
|
441
|
+
\, ,\qquad \mathrm{Tr}\,D \ge \frac{4\Delta}{\pi}\sqrt{\nu(1-\nu)}\,|C|\ \ (2D)\, ,
|
|
442
|
+
|
|
443
|
+
with :math:`g` the quantum metric of the band (see
|
|
444
|
+
*KSpace.quantum_geometric_tensor*) and :math:`C` its Chern number.
|
|
445
|
+
|
|
446
|
+
Parameters
|
|
447
|
+
----------
|
|
448
|
+
ks : **KSpace** instance (Hermitian, orthogonal basis, spinless)
|
|
449
|
+
Spin-up model.
|
|
450
|
+
delta : Number, or array of norb numbers
|
|
451
|
+
Onsite pairing :math:`\Delta_i`.
|
|
452
|
+
mu : Real number, default 0
|
|
453
|
+
Chemical potential.
|
|
454
|
+
nk : Positive integer, or tuple of *dim* positive integers, default 60
|
|
455
|
+
k-mesh (see *mesh_grid*).
|
|
456
|
+
temperature : Positive real or zero, default 0
|
|
457
|
+
dq : Positive real, default 1e-3
|
|
458
|
+
Finite-difference step in :math:`\mathbf{A}`.
|
|
459
|
+
|
|
460
|
+
Returns
|
|
461
|
+
-------
|
|
462
|
+
D : Real ndarray, shape (dim, dim), in the k coordinates of *get_ham*
|
|
463
|
+
|
|
464
|
+
Examples
|
|
465
|
+
--------
|
|
466
|
+
Example usage::
|
|
467
|
+
|
|
468
|
+
# BCS chain: D = (1/2 pi) int dk 2t cos k (1 - xi/E)
|
|
469
|
+
chain = KSpace(lattices.chain())
|
|
470
|
+
chain.set_hopping([{'i': 0, 'j': 0, 'R': (1,), 't': -1.}])
|
|
471
|
+
d = superfluid_weight(chain, 0.2, mu=-0.5)
|
|
472
|
+
'''
|
|
473
|
+
from tbkit.kspace import KSpace
|
|
474
|
+
error_handling.kspace(ks, KSpace)
|
|
475
|
+
error_handling.hermitian_kspace(ks.is_hermitian(), ks._overlap_hop)
|
|
476
|
+
error_handling.spin_up_model(ks.spin)
|
|
477
|
+
error_handling.pairing_amplitudes(delta, ks.norb, 'delta')
|
|
478
|
+
error_handling.real_number(mu, 'mu')
|
|
479
|
+
error_handling.nk(nk, ks.dim)
|
|
480
|
+
error_handling.positive_real_zero(temperature, 'temperature')
|
|
481
|
+
error_handling.positive_real(dq, 'dq')
|
|
482
|
+
n, dim = ks.norb, ks.dim
|
|
483
|
+
k_cart = ks.mesh_grid(nk)[1] @ ks.k_basis.T
|
|
484
|
+
diag = np.arange(n)
|
|
485
|
+
pair = np.broadcast_to(np.asarray(delta, dtype='c16'), (n,))
|
|
486
|
+
volume = (2 * np.pi) ** dim / abs(np.linalg.det(ks.rec_vec_k))
|
|
487
|
+
|
|
488
|
+
def omega(q):
|
|
489
|
+
A = ks.k_basis @ q
|
|
490
|
+
hole = ks._bloch_ham(k_cart, A=-A) - mu * np.eye(n)
|
|
491
|
+
big = np.zeros((len(k_cart), 2 * n, 2 * n), 'c16')
|
|
492
|
+
big[:, :n, :n] = ks._bloch_ham(k_cart, A=A) - mu * np.eye(n)
|
|
493
|
+
big[:, n:, n:] = -hole
|
|
494
|
+
big[:, diag, diag + n] = pair
|
|
495
|
+
big[:, diag + n, diag] = pair.conj()
|
|
496
|
+
en = np.linalg.eigvalsh(big)
|
|
497
|
+
free = (-temperature * np.logaddexp(0., -en / temperature) if temperature > 0
|
|
498
|
+
else np.minimum(en, 0.))
|
|
499
|
+
return (np.trace(hole, axis1=1, axis2=2).real.sum() + free.sum()) / (len(k_cart) * volume)
|
|
500
|
+
|
|
501
|
+
step = dq * np.eye(dim)
|
|
502
|
+
w0 = omega(np.zeros(dim))
|
|
503
|
+
d = np.zeros((dim, dim))
|
|
504
|
+
for a in range(dim):
|
|
505
|
+
d[a, a] = (omega(step[a]) - 2 * w0 + omega(-step[a])) / dq ** 2
|
|
506
|
+
for b in range(a):
|
|
507
|
+
d[a, b] = d[b, a] = (omega(step[a] + step[b]) - omega(step[a] - step[b])
|
|
508
|
+
- omega(step[b] - step[a]) + omega(-step[a] - step[b])) / (4 * dq ** 2)
|
|
509
|
+
return d
|
|
@@ -1140,6 +1140,24 @@ def k_vector(vec, var_name, ndim):
|
|
|
1140
1140
|
raise TypeError('\n\nParameter {} must contain real numbers.\n'.format(var_name))
|
|
1141
1141
|
|
|
1142
1142
|
|
|
1143
|
+
def k_points(k, var_name, ndim):
|
|
1144
|
+
'''
|
|
1145
|
+
Check that *k* is one k-point (see *k_vector*) or an array of shape
|
|
1146
|
+
(nk, *ndim*) of real numbers.
|
|
1147
|
+
|
|
1148
|
+
Raises
|
|
1149
|
+
------
|
|
1150
|
+
ValueError
|
|
1151
|
+
Parameter *var_name* must be of shape (nk, ndim).
|
|
1152
|
+
'''
|
|
1153
|
+
if np.ndim(k) != 2:
|
|
1154
|
+
k_vector(k, var_name, ndim)
|
|
1155
|
+
return
|
|
1156
|
+
k = np.asarray(k)
|
|
1157
|
+
if k.shape[1] != ndim or not np.issubdtype(k.dtype, np.number) or np.iscomplexobj(k):
|
|
1158
|
+
raise ValueError('\n\nParameter {} must be a real array of shape (nk, {}).\n'.format(var_name, ndim))
|
|
1159
|
+
|
|
1160
|
+
|
|
1143
1161
|
def ks(ks, ndim):
|
|
1144
1162
|
'''
|
|
1145
1163
|
Check the k-points passed to *kspace.get_bands*: a 2D array of shape
|
|
@@ -1568,6 +1586,23 @@ def is_symmetry(err, tol):
|
|
|
1568
1586
|
'(deviation {:.3g}).\n'.format(err))
|
|
1569
1587
|
|
|
1570
1588
|
|
|
1589
|
+
def symmetry_algebra(u, v, tol):
|
|
1590
|
+
'''
|
|
1591
|
+
Check that two symmetry operators of the same kind agree up to a phase
|
|
1592
|
+
(in *kspace.KSpace.non_hermitian_class*, *v* is a product of others).
|
|
1593
|
+
|
|
1594
|
+
Raises
|
|
1595
|
+
------
|
|
1596
|
+
ValueError
|
|
1597
|
+
The symmetry operators leave a unitary symmetry: block-diagonalize it first.
|
|
1598
|
+
'''
|
|
1599
|
+
phase = np.trace(u.conj().T @ v) / np.trace(u.conj().T @ u)
|
|
1600
|
+
if not np.allclose(v, phase * u, atol=tol):
|
|
1601
|
+
raise ValueError('\n\nThe symmetry operators leave a unitary symmetry (two products of '
|
|
1602
|
+
'the same kind differ by more than a phase): block-diagonalize '
|
|
1603
|
+
'the Hamiltonian first.\n')
|
|
1604
|
+
|
|
1605
|
+
|
|
1571
1606
|
def square(sq, tol):
|
|
1572
1607
|
'''
|
|
1573
1608
|
Check that the square of an antiunitary operator is +-1.
|
|
@@ -3621,21 +3656,35 @@ def interaction(V, n):
|
|
|
3621
3656
|
'numbers (one per site).\n'.format(n))
|
|
3622
3657
|
|
|
3623
3658
|
|
|
3624
|
-
def pairing_amplitudes(delta, n):
|
|
3659
|
+
def pairing_amplitudes(delta, n, var_name='delta0'):
|
|
3625
3660
|
'''
|
|
3626
|
-
Check
|
|
3661
|
+
Check pairing amplitudes: a number, or n numbers.
|
|
3627
3662
|
|
|
3628
3663
|
Raises
|
|
3629
3664
|
------
|
|
3630
3665
|
ValueError
|
|
3631
|
-
Parameter
|
|
3666
|
+
Parameter *var_name* must be a number or n numbers.
|
|
3632
3667
|
'''
|
|
3633
3668
|
if np.ndim(delta) == 0:
|
|
3634
|
-
number(delta,
|
|
3669
|
+
number(delta, var_name)
|
|
3635
3670
|
return
|
|
3636
3671
|
if np.shape(delta) != (n,):
|
|
3637
|
-
raise ValueError('\n\nParameter
|
|
3638
|
-
'(one per site).\n'.format(n))
|
|
3672
|
+
raise ValueError('\n\nParameter {} must be a number, or {} numbers '
|
|
3673
|
+
'(one per site).\n'.format(var_name, n))
|
|
3674
|
+
|
|
3675
|
+
|
|
3676
|
+
def spin_up_model(spin):
|
|
3677
|
+
'''
|
|
3678
|
+
Check that a KSpace model is spinless (the spin-up electrons).
|
|
3679
|
+
|
|
3680
|
+
Raises
|
|
3681
|
+
------
|
|
3682
|
+
ValueError
|
|
3683
|
+
This needs the spinless spin-up model.
|
|
3684
|
+
'''
|
|
3685
|
+
if spin:
|
|
3686
|
+
raise ValueError('\n\nThis needs a spinless model (spin=False): the spin-up '
|
|
3687
|
+
'electrons, whose time-reversed partners are the spin-down ones.\n')
|
|
3639
3688
|
# OPTICAL RESPONSE AND TRANSPORT (tbkit.optics, tbkit.transport)
|
|
3640
3689
|
####################################
|
|
3641
3690
|
|
|
@@ -681,7 +681,24 @@ class DrivenKSpace:
|
|
|
681
681
|
H_F : Complex ndarray, shape (norb, norb)
|
|
682
682
|
'''
|
|
683
683
|
error_handling.k_vector(k, 'k', self.dim)
|
|
684
|
-
return
|
|
684
|
+
return self._hams(np.asarray(k, dtype='f8')[None])[0]
|
|
685
|
+
|
|
686
|
+
def _hams(self, ks: NDArray[np.float64]) -> NDArray[np.complex128]:
|
|
687
|
+
'''
|
|
688
|
+
Private method. *get_ham* at the k-points *ks* (shape (nk, dim)): the
|
|
689
|
+
evolutions of all the k-points advance together, one stacked
|
|
690
|
+
exponential per time step (the steps of *_grid_steps*), in chunks of
|
|
691
|
+
bounded memory.
|
|
692
|
+
'''
|
|
693
|
+
chunk = max(1, 400000 // (self.norb ** 2 * self.n_steps))
|
|
694
|
+
out = []
|
|
695
|
+
for c0 in range(0, len(ks), chunk):
|
|
696
|
+
hams, durations = self._grid_steps(ks[c0:c0 + chunk])
|
|
697
|
+
u = np.broadcast_to(np.eye(self.norb, dtype='c16'), (len(hams), self.norb, self.norb))
|
|
698
|
+
for s, dt in enumerate(durations):
|
|
699
|
+
u = LA.expm(-1j * dt * hams[:, s]) @ u
|
|
700
|
+
out += [_heff(uk, self.period, self.epsilon) for uk in u]
|
|
701
|
+
return np.array(out, dtype='c16').reshape(len(ks), self.norb, self.norb)
|
|
685
702
|
|
|
686
703
|
def is_hermitian(self) -> bool:
|
|
687
704
|
'''
|