root / ase / transport / greenfunction.py @ 1
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
|