root / ase / transport / greenfunction.py @ 7
Historique | Voir | Annoter | Télécharger (2,06 ko)
| 1 |
import numpy as np |
|---|---|
| 2 |
|
| 3 |
class GreenFunction: |
| 4 |
"""Equilibrium retarded Green function."""
|
| 5 |
|
| 6 |
def __init__(self, H, S=None, selfenergies=[], eta=1e-4): |
| 7 |
self.H = H
|
| 8 |
self.S = S
|
| 9 |
self.selfenergies = selfenergies
|
| 10 |
self.eta = eta
|
| 11 |
self.energy = None |
| 12 |
self.Ginv = np.empty(H.shape, complex) |
| 13 |
|
| 14 |
def retarded(self, energy, inverse=False): |
| 15 |
"""Get retarded Green function at specified energy.
|
| 16 |
|
| 17 |
If 'inverse' is True, the inverse Green function is returned (faster).
|
| 18 |
"""
|
| 19 |
if energy != self.energy: |
| 20 |
self.energy = energy
|
| 21 |
z = energy + self.eta * 1.j |
| 22 |
|
| 23 |
if self.S is None: |
| 24 |
self.Ginv[:] = 0.0 |
| 25 |
self.Ginv.flat[:: len(self.S) + 1] = z |
| 26 |
else:
|
| 27 |
self.Ginv[:] = z
|
| 28 |
self.Ginv *= self.S |
| 29 |
self.Ginv -= self.H |
| 30 |
|
| 31 |
for selfenergy in self.selfenergies: |
| 32 |
self.Ginv -= selfenergy.retarded(energy)
|
| 33 |
|
| 34 |
if inverse:
|
| 35 |
return self.Ginv |
| 36 |
else:
|
| 37 |
return np.linalg.inv(self.Ginv) |
| 38 |
|
| 39 |
def calculate(self, energy, sigma): |
| 40 |
"""XXX is this really needed"""
|
| 41 |
ginv = energy * self.S - self.H - sigma |
| 42 |
return np.linalg.inv(ginv)
|
| 43 |
|
| 44 |
def apply_retarded(self, energy, X): |
| 45 |
"""Apply retarded Green function to X.
|
| 46 |
|
| 47 |
Returns the matrix product G^r(e) . X
|
| 48 |
"""
|
| 49 |
return np.linalg.solve(self.retarded(energy, inverse=True), X) |
| 50 |
|
| 51 |
def dos(self, energy): |
| 52 |
"""Total density of states -1/pi Im(Tr(GS))"""
|
| 53 |
if self.S is None: |
| 54 |
return -self(energy).imag.trace() / np.pi |
| 55 |
else:
|
| 56 |
GS = self.apply_retarded(energy, self.S) |
| 57 |
return -GS.imag.trace() / np.pi
|
| 58 |
|
| 59 |
def pdos(self, energy): |
| 60 |
"""Projected density of states -1/pi Im(SGS/S)"""
|
| 61 |
if self.S is None: |
| 62 |
return -self.retarded(energy).imag.diagonal() / np.pi |
| 63 |
else:
|
| 64 |
S = self.S
|
| 65 |
SGS = np.dot(S, self.apply_retarded(energy, S))
|
| 66 |
return -(SGS.diagonal() / S.diagonal()).imag / np.pi
|