Source code for gauNEGF.protocols

"""Protocol definitions for the surfG interface.

SurfGProtocol: the single interface that density.py and integrate.py
interact with.

Implemented by: surfG, surfG3, surfGB, surfGTest, surfGAt3D, surfGBAt

These are structural (duck-typed) protocols -- classes do NOT need to
inherit from them. They exist for documentation and optional type-checking
with isinstance() via @runtime_checkable.

Limitation: @runtime_checkable only verifies that methods and attributes
exist on the instance. It does not check signatures, return types, or
attribute types. For full correctness, see test_cross_term.py and
test_jit_fermi_shift.py which test functional behavior.
"""

from typing import Protocol, Optional, runtime_checkable
import numpy as np


[docs] @runtime_checkable class SurfGProtocol(Protocol): """Protocol for surface Green's function calculators. This is the interface that density.py and integrate.py interact with. Implemented by: surfG, surfG3, surfGB, surfGTest, surfGAt3D, surfGBAt Note: Parameter names for setF() vary across implementations (mu1/mu2 vs muL/muR). This does not affect structural typing. """ F: np.ndarray # Fock matrix (N x N) S: np.ndarray # Overlap matrix (N x N) eta: float # broadening num_contacts: int # Number of contacts
[docs] def sigma(self, E: complex, i: int, conv: float = ...) -> np.ndarray: """Self-energy for contact i in full device basis (N x N).""" ...
[docs] def sigmaTot(self, E: complex, conv: float = ...) -> np.ndarray: """Total self-energy from all contacts (N x N).""" ...
[docs] def setF(self, F: np.ndarray, mu1: float, mu2: float) -> None: """Update Fock matrix and contact chemical potentials.""" ...
[docs] def crossTermQ(self, E: complex, i: int, conv: float = ..., dFermi: Optional[float] = None ) -> Optional[tuple]: """Cross-term matrices (Q_fwd, Q_rev, Q_sym) for contact i, each in the full device basis; None if contact i is orthogonal. Q_fwd = tau_Di g_i S_iD ; Q_rev = S_Di g_i taubar_iD ; Q_sym = (Q_fwd + Q_rev) / 2. Sign conventions for the cross-term count: forward real axis: delta_N = +(1/pi) * Im INT f Tr[Gr Q_sym_tot] dE closed contour: delta_N = contour integral of Tr[Gr Q_sym_tot]; orientation carried by traversal, no Im taken. """ ...
[docs] def crossTermQTot(self, E: complex, conv: float = ..., dFermi: Optional[float] = None ) -> Optional[np.ndarray]: """Sum of Q_sym over all contacts, or None if all orthogonal.""" ...