Coverage for /builds/ase/ase/ase/transport/greenfunction.py: 82.50%

40 statements  

« prev     ^ index     » next       coverage.py v7.5.3, created at 2025-08-02 00:12 +0000

1# fmt: off 

2 

3import numpy as np 

4 

5 

6class GreenFunction: 

7 """Equilibrium retarded Green function.""" 

8 

9 def __init__(self, H, S=None, selfenergies=[], eta=1e-4): 

10 self.H = H 

11 self.S = S 

12 self.selfenergies = selfenergies 

13 self.eta = eta 

14 self.energy = None 

15 self.Ginv = np.empty(H.shape, complex) 

16 

17 def retarded(self, energy, inverse=False): 

18 """Get retarded Green function at specified energy. 

19 

20 If 'inverse' is True, the inverse Green function is returned (faster). 

21 """ 

22 if energy != self.energy: 

23 self.energy = energy 

24 z = energy + self.eta * 1.j 

25 

26 if self.S is None: 

27 self.Ginv[:] = 0.0 

28 self.Ginv.flat[:: len(self.S) + 1] = z 

29 else: 

30 self.Ginv[:] = z 

31 self.Ginv *= self.S 

32 self.Ginv -= self.H 

33 

34 for selfenergy in self.selfenergies: 

35 self.Ginv -= selfenergy.retarded(energy) 

36 

37 if inverse: 

38 return self.Ginv 

39 else: 

40 return np.linalg.inv(self.Ginv) 

41 

42 def calculate(self, energy, sigma): 

43 """XXX is this really needed""" 

44 ginv = energy * self.S - self.H - sigma 

45 return np.linalg.inv(ginv) 

46 

47 def apply_retarded(self, energy, X): 

48 """Apply retarded Green function to X. 

49 

50 Returns the matrix product G^r(e) . X 

51 """ 

52 return np.linalg.solve(self.retarded(energy, inverse=True), X) 

53 

54 def dos(self, energy): 

55 """Total density of states -1/pi Im(Tr(GS))""" 

56 if self.S is None: 

57 return -self.retarded(energy).imag.trace() / np.pi 

58 else: 

59 GS = self.apply_retarded(energy, self.S) 

60 return -GS.imag.trace() / np.pi 

61 

62 def pdos(self, energy): 

63 """Projected density of states -1/pi Im(SGS/S)""" 

64 if self.S is None: 

65 return -self.retarded(energy).imag.diagonal() / np.pi 

66 else: 

67 S = self.S 

68 SGS = np.dot(S, self.apply_retarded(energy, S)) 

69 return -(SGS.diagonal() / S.diagonal()).imag / np.pi