def get_left_channels(self, energy, nchan=1): self.initialize() g_s_ii = self.greenfunction.retarded(energy) lambda_l_ii = self.selfenergies[0].get_lambda(energy) lambda_r_ii = self.selfenergies[1].get_lambda(energy) if self.greenfunction.S is not None: s_mm = self.greenfunction.S s_s_i, s_s_ii = linalg.eig(s_mm) s_s_i = np.abs(s_s_i) s_s_sqrt_i = np.sqrt(s_s_i) # sqrt of eigenvalues s_s_sqrt_ii = np.dot(s_s_ii * s_s_sqrt_i, dagger(s_s_ii)) s_s_isqrt_ii = np.dot(s_s_ii / s_s_sqrt_i, dagger(s_s_ii)) lambdab_r_ii = np.dot(np.dot(s_s_isqrt_ii, lambda_r_ii), s_s_isqrt_ii) a_l_ii = np.dot(np.dot(g_s_ii, lambda_l_ii), dagger(g_s_ii)) ab_l_ii = np.dot(np.dot(s_s_sqrt_ii, a_l_ii), s_s_sqrt_ii) lambda_i, u_ii = linalg.eig(ab_l_ii) ut_ii = np.sqrt(lambda_i / (2.0 * np.pi)) * u_ii m_ii = 2 * np.pi * np.dot(np.dot(dagger(ut_ii), lambdab_r_ii), ut_ii) T_i, c_in = linalg.eig(m_ii) T_i = np.abs(T_i) channels = np.argsort(-T_i)[:nchan] c_in = np.take(c_in, channels, axis=1) T_n = np.take(T_i, channels) v_in = np.dot(np.dot(s_s_isqrt_ii, ut_ii), c_in) return T_n, v_in
def get_transmission(self, v_12, v_11_2=None, v_22_1=None): """XXX v_12: coupling between tip and surface v_11_2: correction to "on-site" tip elements due to the surface (eq.16). Is only included to first order. v_22_1: corretion to "on-site" surface elements due to he tip (eq.17). Is only included to first order. """ dim0 = v_12.shape[0] dim1 = v_12.shape[1] nenergies = len(self.energies) T_e = np.empty(nenergies, float) v_21 = dagger(v_12) for e, energy in enumerate(self.energies): gft1 = self.gft1_emm[e] if v_11_2 != None: gf1 = np.dot(v_11_2, np.dot(gft1, v_11_2)) gf1 += gft1 #eq. 16 else: gf1 = gft1 gft2 = self.gft2_emm[e] if v_22_1 != None: gf2 = np.dot(v_22_1, np.dot(gft2, v_22_1)) gf2 += gft2 #eq. 17 else: gf2 = gft2 a1 = (gf1 - dagger(gf1)) a2 = (gf2 - dagger(gf2)) self.v_12 = v_12 self.a2 = a2 self.v_21 = v_21 self.a1 = a1 v12_a2 = np.dot(v_12, a2[:dim1]) v21_a1 = np.dot(v_21, a1[-dim0:]) self.v12_a2 = v12_a2 self.v21_a1 = v21_a1 T = -np.trace(np.dot(v12_a2[:, :dim1], v21_a1[:, -dim0:])) #eq. 11 assert abs(T.imag).max() < 1e-14 T_e[e] = T.real self.T_e = T_e return T_e
def get_transmission(self, v_12, v_11_2=None, v_22_1=None): """XXX v_12: coupling between tip and surface v_11_2: correction to "on-site" tip elements due to the surface (eq.16). Is only included to first order. v_22_1: corretion to "on-site" surface elements due to he tip (eq.17). Is only included to first order. """ dim0 = v_12.shape[0] dim1 = v_12.shape[1] nenergies = len(self.energies) T_e = np.empty(nenergies,float) v_21 = dagger(v_12) for e, energy in enumerate(self.energies): gft1 = self.gft1_emm[e] if v_11_2!=None: gf1 = np.dot(v_11_2, np.dot(gft1, v_11_2)) gf1 += gft1 #eq. 16 else: gf1 = gft1 gft2 = self.gft2_emm[e] if v_22_1!=None: gf2 = np.dot(v_22_1,np.dot(gft2, v_22_1)) gf2 += gft2 #eq. 17 else: gf2 = gft2 a1 = (gf1 - dagger(gf1)) a2 = (gf2 - dagger(gf2)) self.v_12 = v_12 self.a2 = a2 self.v_21 = v_21 self.a1 = a1 v12_a2 = np.dot(v_12, a2[:dim1]) v21_a1 = np.dot(v_21, a1[-dim0:]) self.v12_a2 = v12_a2 self.v21_a1 = v21_a1 T = -np.trace(np.dot(v12_a2[:,:dim1], v21_a1[:,-dim0:])) #eq. 11 assert abs(T.imag).max() < 1e-14 T_e[e] = T.real self.T_e = T_e return T_e
def get_transmission(self, v_12): nenergies = len(self.energies) T_e = np.empty(nenergies, float) v_21 = dagger(v_12) for e, energy in enumerate(self.energies): gft1 = self.gft1_emm[e] gft2 = self.gft2_emm[e] a1 = gft1 - dagger(gft1) a2 = gft2 - dagger(gft2) v12_a2 = np.dot(v_12, a2) v21_a1 = np.dot(v_21, a1) T = -np.trace(np.dot(v12_a2, v21_a1)) T_e[e] = T self.T_e = T_e return T_e
def get_transmission(self, v_12): nenergies = len(self.energies) T_e = np.empty(nenergies,float) v_21 = dagger(v_12) for e, energy in enumerate(self.energies): gft1 = self.gft1_emm[e] gft2 = self.gft2_emm[e] a1 = (gft1 - dagger(gft1)) a2 = (gft2 - dagger(gft2)) v12_a2 = np.dot(v_12, a2) v21_a1 = np.dot(v_21, a1) T = -np.trace(np.dot(v12_a2, v21_a1)) T_e[e] = T self.T_e = T_e return T_e
def test_get_gradients(wan, rng): wanf = wan(nwannier=4, fixedstates=2, kpts=(1, 1, 1), initialwannier='bloch', std_calc=False) # create an anti-hermitian array/matrix step = rng.rand(wanf.get_gradients().size) + \ 1.j * rng.rand(wanf.get_gradients().size) step *= 1e-8 step -= dagger(step) f1 = wanf.get_functional_value() wanf.step(step) f2 = wanf.get_functional_value() assert (np.abs((f2 - f1) / step).ravel() - np.abs(wanf.get_gradients())).max() < 1e-4
def lowdin_rotation(self, apply=False): p = self.input_parameters h_mm = p['h'] s_mm = p['s'] eig, rot_mm = linalg.eigh(s_mm) eig = np.abs(eig) rot_mm = np.dot(rot_mm / np.sqrt(eig), dagger(rot_mm)) if apply: self.uptodate = False h_mm[:] = rotate_matrix(h_mm, rot_mm) # rotate C region s_mm[:] = rotate_matrix(s_mm, rot_mm) for alpha, sigma in enumerate(self.selfenergies): sigma.h_im[:] = np.dot(sigma.h_im, rot_mm) # rotate L-C coupl. sigma.s_im[:] = np.dot(sigma.s_im, rot_mm) return rot_mm
def update(self): if self.uptodate: return p = self.input_parameters self.energies = p['energies'] nepts = len(self.energies) nchan = p['eigenchannels'] pdos = p['pdos'] self.T_e = np.empty(nepts) if p['dos']: self.dos_e = np.empty(nepts) if pdos != []: self.pdos_ne = np.empty((len(pdos), nepts)) if nchan > 0: self.eigenchannels_ne = np.empty((nchan, nepts)) for e, energy in enumerate(self.energies): Ginv_mm = self.greenfunction.retarded(energy, inverse=True) lambda1_mm = self.selfenergies[0].get_lambda(energy) lambda2_mm = self.selfenergies[1].get_lambda(energy) a_mm = linalg.solve(Ginv_mm, lambda1_mm) b_mm = linalg.solve(dagger(Ginv_mm), lambda2_mm) T_mm = np.dot(a_mm, b_mm) if nchan > 0: t_n = linalg.eigvals(T_mm).real self.eigenchannels_ne[:, e] = np.sort(t_n)[-nchan:] self.T_e[e] = np.sum(t_n) else: self.T_e[e] = np.trace(T_mm).real print(energy, self.T_e[e], file=self.log) self.log.flush() if p['dos']: self.dos_e[e] = self.greenfunction.dos(energy) if pdos != []: self.pdos_ne[:, e] = np.take(self.greenfunction.pdos(energy), pdos) self.uptodate = True
def orthonormality_error(matrix): return np.abs(dagger(matrix) @ matrix - np.eye(len(matrix))).max()