diff --git a/kwant/builder.py b/kwant/builder.py index 2ca81a946faf5c9c50201c67a34398a69d46d41c..a8d21d15a5ffa0c163fb2619493f86b7526d7233 100644 --- a/kwant/builder.py +++ b/kwant/builder.py @@ -858,6 +858,10 @@ class Builder: amounts to creating a `Lead` object and appending it to the list of leads accessbile as the `~Builder.leads` attribute. + `conservation_law`, `time_reversal`, `particle_hole`, and `chiral` + affect the basis in which scattering modes derived from the builder + are expressed - see `~kwant.physics.DiscreteSymmetry` for details. + .. warning:: If functions are used to set values in a builder with a symmetry, then diff --git a/kwant/physics/leads.py b/kwant/physics/leads.py index b156f0292c3feafbc0a718d4ca80b73e97786533..30da68c909c8371563939f782b10f9fb8723da1d 100644 --- a/kwant/physics/leads.py +++ b/kwant/physics/leads.py @@ -130,11 +130,10 @@ class PropagatingModes: momentum and velocity, an arbitrary orthonormal basis in the subspace of these modes is chosen. - If a conservation law is specified to block diagonalize the Hamiltonian - to N blocks, then `block_nmodes[i]` is the number of left or right moving - propagating modes in conservation law block `i`. The ordering of blocks - is the same as the ordering of the projectors used to block diagonalize - the Hamiltonian. + If a conservation law is specified to block diagonalize the Hamiltonian, + then `block_nmodes[i]` is the number of left or right moving propagating + modes in conservation law block `i`. The ordering of blocks is the same as + the ordering of the projectors used to block diagonalize the Hamiltonian. """ def __init__(self, wave_functions, velocities, momenta): kwargs = locals() @@ -1046,6 +1045,10 @@ def modes(h_cell, h_hop, tol=1e6, stabilization=None, *, Propagating modes with the same momentum are orthogonalized. All the propagating modes are normalized by current. + `projectors`, `time_reversal`, `particle_hole`, and `chiral` affect the + basis in which the scattering modes are expressed - see + `~kwant.physics.DiscreteSymmetry` for details. + This function uses the most stable and efficient algorithm for calculating the mode decomposition that the Kwant authors are aware about. Its details are to be published. diff --git a/kwant/physics/symmetry.py b/kwant/physics/symmetry.py index 9420f52d4967b66c22cfb971a7b948a10a377581..9e53ab807c71a2f04af587846c2099685077d436 100644 --- a/kwant/physics/symmetry.py +++ b/kwant/physics/symmetry.py @@ -52,22 +52,46 @@ class DiscreteSymmetry: Notes ----- - Whenever one or more discrete symmetry is declared in conjunction with a - conservation law, the symmetry operators and projectors must be declared - in canonical form. This means that each block of the Hamiltonian is - transformed either to itself by a discrete symmetry or to a single - other block. - - More formally, consider a discrete symmetry S. The symmetry projection - that maps from block i to block j of the Hamiltonian with projectors - :math:`P_i` and :math:`P_j` is :math:`S_{ji} = P_j^+ S P_i`. - If :math:`S_{ji}` is nonzero, a symmetry relation exists between - blocks i and j. Canonical form means that for each j, the block - :math:`S_{ji}` is nonzero at most for one i, while all other blocks vanish. - - If the operators are not in canonical form, they can be made so by - further splitting the Hamiltonian into smaller blocks, i.e. by adding - more projectors. + + When computing scattering modes, the representation of the + modes is chosen to reflect declared discrete symmetries and + conservation laws. + + `projectors` block diagonalize the Hamiltonian, and modes are computed + separately in each block. The ordering of blocks is the same as of + `projectors`. If `conservation_law` is declared in + `~kwant.builder.Builder`, `projectors` is computed as the projectors + onto its orthogonal eigensubspaces. The projectors are stored in the + order of ascending eigenvalues of `conservation_law`. + + Symmetrization using discrete symmetries varies depending on whether + a conservation law/projectors are declared. Consider the case with no + conservation law declared. With `time_reversal` declared, the outgoing + modes are chosen as the time-reversed partners of the incoming modes, + i.e. :math:`\psi_{out}(-k) = T \psi_{in}(k)` with k the momentum. + `chiral` also relates incoming and outgoing modes, such that + :math:`\psi_{out}(k) = C \psi_{in}(k)`. `particle_hole` gives symmetric + incoming and outgoing modes separately, such that + :math:`\psi_{in/out}(-k) = P \psi_{in/out}(k)`, except when k=-k, at + k = 0 or :math:`\pi`. In this case, each mode is chosen as an eigenstate + :math:`P \psi = \psi` if :math:`P^2=1`. If :math:`P^2=-1`, we + symmetrize the modes by generating pairs of orthogonal modes + :math:`\psi` and :math:`P\psi`. Because `chiral` and `particle_hole` + flip the sign of energy, they only apply at zero energy. + + Discrete symmetries can be combined with a conservation law if they + leave each block invariant or transform it to another block. With S + a discrete symmetry and :math:`P_i` and :math:`P_j` projectors onto + blocks i and j of the Hamiltonian, :math:`S_{ji} = P_j^+ S P_i` is the + symmetry projection that maps from block i to block j. + :math:`S_{ji} = P_j^+ S P_i` must for each j be nonzero for exactly + one i. If S leaves block i invariant, the modes within block i are + symmetrized using the nonzero projection :math:`S_{ii}`, like in the + case without a conservation law. If S transforms between blocks i and + j, the modes of the block with the larger index are obtained by + transforming the modes of the block with the lower index. Thus, with + :math:`\psi_i` and :math:`\psi_j` the modes of blocks i and j, we have + :math:`\psi_j = S_{ji} \psi_i`. """ def __init__(self, projectors=None, time_reversal=None, particle_hole=None, chiral=None):