root / ase / transport / selfenergy.py @ 1
Historique | Voir | Annoter | Télécharger (2,79 ko)
1 | 1 | tkerber | import numpy as np |
---|---|---|---|
2 | 1 | tkerber | |
3 | 1 | tkerber | |
4 | 1 | tkerber | class LeadSelfEnergy: |
5 | 1 | tkerber | conv = 1e-8 # Convergence criteria for surface Green function |
6 | 1 | tkerber | |
7 | 1 | tkerber | def __init__(self, hs_dii, hs_dij, hs_dim, eta=1e-4): |
8 | 1 | tkerber | self.h_ii, self.s_ii = hs_dii # onsite principal layer |
9 | 1 | tkerber | self.h_ij, self.s_ij = hs_dij # coupling between principal layers |
10 | 1 | tkerber | self.h_im, self.s_im = hs_dim # coupling to the central region |
11 | 1 | tkerber | self.nbf = self.h_im.shape[1] # nbf for the scattering region |
12 | 1 | tkerber | self.eta = eta
|
13 | 1 | tkerber | self.energy = None |
14 | 1 | tkerber | self.bias = 0 |
15 | 1 | tkerber | self.sigma_mm = np.empty((self.nbf, self.nbf), complex) |
16 | 1 | tkerber | |
17 | 1 | tkerber | def retarded(self, energy): |
18 | 1 | tkerber | """Return self-energy (sigma) evaluated at specified energy."""
|
19 | 1 | tkerber | if energy != self.energy: |
20 | 1 | tkerber | self.energy = energy
|
21 | 1 | tkerber | z = energy - self.bias + self.eta * 1.j |
22 | 1 | tkerber | tau_im = z * self.s_im - self.h_im |
23 | 1 | tkerber | a_im = np.linalg.solve(self.get_sgfinv(energy), tau_im)
|
24 | 1 | tkerber | tau_mi = z * self.s_im.T.conj() - self.h_im.T.conj() |
25 | 1 | tkerber | self.sigma_mm[:] = np.dot(tau_mi, a_im)
|
26 | 1 | tkerber | |
27 | 1 | tkerber | return self.sigma_mm |
28 | 1 | tkerber | |
29 | 1 | tkerber | def set_bias(self, bias): |
30 | 1 | tkerber | self.bias = bias
|
31 | 1 | tkerber | |
32 | 1 | tkerber | def get_lambda(self, energy): |
33 | 1 | tkerber | """Return the lambda (aka Gamma) defined by i(S-S^d).
|
34 | 1 | tkerber |
|
35 | 1 | tkerber | Here S is the retarded selfenergy, and d denotes the hermitian
|
36 | 1 | tkerber | conjugate.
|
37 | 1 | tkerber | """
|
38 | 1 | tkerber | sigma_mm = self.retarded(energy)
|
39 | 1 | tkerber | return 1.j * (sigma_mm - sigma_mm.T.conj()) |
40 | 1 | tkerber | |
41 | 1 | tkerber | def get_sgfinv(self, energy): |
42 | 1 | tkerber | """The inverse of the retarded surface Green function"""
|
43 | 1 | tkerber | z = energy - self.bias + self.eta * 1.j |
44 | 1 | tkerber | |
45 | 1 | tkerber | v_00 = z * self.s_ii.T.conj() - self.h_ii.T.conj() |
46 | 1 | tkerber | v_11 = v_00.copy() |
47 | 1 | tkerber | v_10 = z * self.s_ij - self.h_ij |
48 | 1 | tkerber | v_01 = z * self.s_ij.T.conj() - self.h_ij.T.conj() |
49 | 1 | tkerber | |
50 | 1 | tkerber | delta = self.conv + 1 |
51 | 1 | tkerber | while delta > self.conv: |
52 | 1 | tkerber | a = np.linalg.solve(v_11, v_01) |
53 | 1 | tkerber | b = np.linalg.solve(v_11, v_10) |
54 | 1 | tkerber | v_01_dot_b = np.dot(v_01, b) |
55 | 1 | tkerber | v_00 -= v_01_dot_b |
56 | 1 | tkerber | v_11 -= np.dot(v_10, a) |
57 | 1 | tkerber | v_11 -= v_01_dot_b |
58 | 1 | tkerber | v_01 = -np.dot(v_01, a) |
59 | 1 | tkerber | v_10 = -np.dot(v_10, b) |
60 | 1 | tkerber | delta = abs(v_01).max()
|
61 | 1 | tkerber | |
62 | 1 | tkerber | return v_00
|
63 | 1 | tkerber | |
64 | 1 | tkerber | |
65 | 1 | tkerber | class BoxProbe: |
66 | 1 | tkerber | """Box shaped Buttinger probe.
|
67 | 1 | tkerber |
|
68 | 1 | tkerber | Kramers-kroning: real = H(imag); imag = -H(real)
|
69 | 1 | tkerber | """
|
70 | 1 | tkerber | def __init__(self, eta, a, b, energies, S, T=0.3): |
71 | 1 | tkerber | from Transport.Hilbert import hilbert |
72 | 1 | tkerber | se = np.empty(len(energies), complex) |
73 | 1 | tkerber | se.imag = .5 * (np.tanh(.5 * (energies - a) / T) - |
74 | 1 | tkerber | np.tanh(.5 * (energies - b) / T))
|
75 | 1 | tkerber | se.real = hilbert(se.imag) |
76 | 1 | tkerber | se.imag -= 1
|
77 | 1 | tkerber | self.selfenergy_e = eta * se
|
78 | 1 | tkerber | self.energies = energies
|
79 | 1 | tkerber | self.S = S
|
80 | 1 | tkerber | |
81 | 1 | tkerber | def retarded(self, energy): |
82 | 1 | tkerber | return self.selfenergy_e[self.energies.searchsorted(energy)] * self.S |