def gf(w, U, mu, beta): """Calculate by Lehmann representation the green function""" H, d_up, d_dw = hamiltonian(U, mu) e, v = diagonalize(H.todense()) g_up = gf_lehmann(e, v, d_up.T, beta, w) g_dw = gf_lehmann(e, v, d_dw.T, beta, w) return g_up, g_dw
def test_gf_lehmann2(): """Verifies the lehmann representation of a random Hamiltonian""" w = np.linspace(-1.5, 1.5, 500) d_up = fermion.destruct(6, 0) H = np.random.rand(*d_up.shape) H += H.T e, v = operators.diagonalize(H) g_up_diag = operators.gf_lehmann(e, v, d_up.T, 400, w) g_up_cross = operators.gf_lehmann(e, v, d_up.T, 400, w, d_up) assert np.allclose(g_up_diag, g_up_cross)
def plot_A_ev_utp(beta, urange, mu, tprange): w = np.linspace(-2, 2, 1500) + 1j * 5e-3 for u_int, tp in zip(urange, tprange): h_at, oper = dimer.hamiltonian(u_int, mu, tp) eig_e, eig_v = op.diagonalize(h_at.todense()) gf = op.gf_lehmann(eig_e, eig_v, oper[0].T, beta, w) plt.plot(w.real, u_int + gf.imag / gf.imag.min(), 'k-')
def solve(self, e_c, u_int, hyb): """Solves the impurity problem""" self.update_H(e_c, u_int, hyb) d_up_dag = self.oper[0].T self.GF['Imp G'] = gf_lehmann(self.eig_energies, self.eig_states, d_up_dag, self.beta, self.omega) self.GF['Imp G$_0$'] = self.imp_free_gf(e_c, hyb) self.GF[r'$\Sigma$'] = 1 / self.GF['Imp G$_0$'] - 1 / self.GF['Imp G']
def test_gf_lehmann(U, mu, beta): """Verifies the lehmann representation of the atom""" w = np.linspace(-1.5*U, 1.5*U, 500) d_up, d_dw = [fermion.destruct(2, sigma) for sigma in range(2)] sigma_z = d_up.T*d_up - d_dw.T*d_dw H = - U/2 * sigma_z * sigma_z - mu * (d_up.T*d_up + d_dw.T*d_dw) e, v = operators.diagonalize(H.todense()) g_up = operators.gf_lehmann(e, v, d_up.T, beta, w) g_up_cross = operators.gf_lehmann(e, v, d_up.T, beta, w, d_up) Z = 1+2*np.exp(beta*(U/2+mu)) + np.exp(2*beta*mu) g_up_ref = ((1+np.exp(beta*(U/2+mu)))/(w + mu + U/2.) + (np.exp(beta*(U/2+mu)) + np.exp(2*beta*mu))/(w + mu - U/2.))/Z assert np.allclose(g_up, g_up_ref) assert np.allclose(g_up_cross, g_up_ref)
def solve(self, e_c, u_int, hyb): """Solves the impurity problem""" self.update_H(e_c, u_int, hyb) self.GF['Imp G'] = np.asarray([gf_lehmann(self.eig_energies, self.eig_states, d.T, self.beta, self.omega) for d in self.oper[:2]]) self.GF['Imp G$_0$'] = self.imp_free_gf(e_c, hyb) self.GF[r'$\Sigma$'] = 1/self.GF['Imp G$_0$'] - 1/self.GF['Imp G']
def solve(self, e_c, u_int, hyb): """Solves the impurity problem""" self.update_H(e_c, u_int, hyb) d_up_dag = self.oper[0].T self.GF['Imp G'] = gf_lehmann(self.eig_energies, self.eig_states, d_up_dag, self.beta, self.omega) self.GF['Imp G$_0$'] = self.imp_free_gf(e_c, hyb) self.GF[r'$\Sigma$'] = 1/self.GF['Imp G$_0$'] - 1/self.GF['Imp G']
def test_gf_lehmann(U, mu, beta): """Verifies the lehmann representation of the atom""" w = np.linspace(-1.5 * U, 1.5 * U, 500) d_up, d_dw = [fermion.destruct(2, sigma) for sigma in range(2)] sigma_z = d_up.T * d_up - d_dw.T * d_dw H = -U / 2 * sigma_z * sigma_z - mu * (d_up.T * d_up + d_dw.T * d_dw) e, v = operators.diagonalize(H.todense()) g_up = operators.gf_lehmann(e, v, d_up.T, beta, w) g_up_cross = operators.gf_lehmann(e, v, d_up.T, beta, w, d_up) Z = 1 + 2 * np.exp(beta * (U / 2 + mu)) + np.exp(2 * beta * mu) g_up_ref = ((1 + np.exp(beta * (U / 2 + mu))) / (w + mu + U / 2.) + (np.exp(beta * (U / 2 + mu)) + np.exp(2 * beta * mu)) / (w + mu - U / 2.)) / Z assert np.allclose(g_up, g_up_ref) assert np.allclose(g_up_cross, g_up_ref)
def plot_A_ev_rtp(beta, u_int, mu, tprange): w = np.linspace(-4, 4, 5500) + 1j * 5e-3 for tp in tprange: h_at, oper = dimer.hamiltonian(u_int, mu, tp) eig_e, eig_v = op.diagonalize(h_at.todense()) gfd = op.gf_lehmann(eig_e, eig_v, oper[0].T, beta, w) gfo = op.gf_lehmann(eig_e, eig_v, oper[0].T, beta, w, oper[1]) gf = gfd + gfo plt.plot(w.real, tp + gf.imag / gf.imag.min()) plt.title('Molecule exitation spectral function') plt.xlabel(r'$\omega$') plt.plot(0.5 * np.sqrt(u_int**2 + 16 * tprange**2) - tprange, tprange, '*:', label=r'$|GS\rangle \rightarrow \pm t_\perp + 1/2(U^2+16t^2_\perp)^{1/2}$') plt.plot(0.5 * np.sqrt(u_int**2 + 16 * tprange**2) + tprange, tprange, '*:') plt.plot(u_int / 2 - tprange, tprange, 'x:', label=r'$|T\rangle \rightarrow \pm t_\perp + U/2$') plt.plot(u_int / 2 + tprange, tprange, 'x:') plt.xlim([min(w.real), max(w.real)])
def plot_A_ev_utp(beta, urange, mu, tprange): w = np.linspace(-2, 3.5, 1500) + 1j * 1e-2 Aw = [] for u_int, tp in zip(urange, tprange): h_at, oper = dimer.hamiltonian_diag(u_int, mu, tp) eig_e, eig_v = op.diagonalize(h_at.todense()) gf = op.gf_lehmann(eig_e, eig_v, oper[0].T, beta, w) aw = gf.imag / gf.imag.min() Aw.append(aw) return np.array(Aw)
def solve(self, e_c, u_int, hyb): """Solves the impurity problem""" self.update_H(e_c, u_int, hyb) self.GF['Imp G'] = np.asarray([ gf_lehmann(self.eig_energies, self.eig_states, d.T, self.beta, self.omega) for d in self.oper[:2] ]) self.GF['Imp G$_0$'] = self.imp_free_gf(e_c, hyb) self.GF[r'$\Sigma$'] = 1 / self.GF['Imp G$_0$'] - 1 / self.GF['Imp G']
def test_dimer_energies(u_int, mu, tp, beta=100): h_loc, (a_up, b_up, a_dw, b_dw) = dimer.hamiltonian(u_int, mu, tp) e_imp = (tp * (a_up.T * b_up + a_dw.T * b_dw + b_up.T * a_up + b_dw.T * a_dw)).todense() eig_e, eig_v = op.diagonalize(h_loc.todense()) w_n = gf.matsubara_freq(beta, 2**8) # n=2**7=256 gf_di = op.gf_lehmann(eig_e, eig_v, a_up.T, beta, 1j * w_n) gf_of = op.gf_lehmann(eig_e, eig_v, a_up.T, beta, 1j * w_n, b_up) ekin_gf = dimer.ekin(gf_di, gf_of, w_n, tp, beta, 0) ekin_ed = op.expected_value(e_imp, eig_e, eig_v, beta) assert abs(ekin_ed - ekin_gf) < 5e-4 epot_gf = dimer.epot(gf_di, w_n, beta, u_int**2 / 4 + tp**2, ekin_gf, u_int) docc = (a_up.T * a_up * a_dw.T * a_dw + b_up.T * b_up * b_dw.T * b_dw).todense() epot_ed = op.expected_value(docc, eig_e, eig_v, beta) * u_int assert abs(epot_ed - epot_gf) < 1e-3
def plot_A_ev_ru(beta, urange, mu, tp): w = np.linspace(0, 2, 500) + 1j * 5e-3 for u_int in urange: h_at, oper = dimer.hamiltonian(u_int, mu, tp) eig_e, eig_v = op.diagonalize(h_at.todense()) gf = op.gf_lehmann(eig_e, eig_v, oper[0].T, beta, w) plt.plot(w.real, u_int + gf.imag / gf.imag.min()) plt.plot(0.5 * np.sqrt(urange**2 + 16 * tp**2) - tp, urange, '*:', label=r'$|GS\rangle \rightarrow \pm t_\perp + 1/2(U^2+16t^2_\perp)^{1/2}$') plt.plot(0.5 * np.sqrt(urange**2 + 16 * tp**2) + tp, urange, '*:') plt.plot(urange / 2 - tp, urange, 'x:', label=r'$|T\rangle \rightarrow \pm t_\perp + U/2$') plt.plot(urange / 2 + tp, urange, 'x:') plt.xlim([min(w.real), max(w.real)])
def molecule_sigma_d(omega, U, mu, tp, beta): """Return molecule self-energy in the given frequency axis""" h_at, oper = dimer.hamiltonian_diag(U, mu, tp) oper_pair = [[oper[0], oper[0]], [oper[1], oper[1]]] eig_e, eig_v = op.diagonalize(h_at.todense()) gfsU = np.array([ op.gf_lehmann(eig_e, eig_v, c.T, beta, omega, d) for c, d in oper_pair ]) plt.plot(omega.real, -(gfsU[1]).imag, label='Anti-Bond') plt.plot(omega.real, -(gfsU[0]).imag, label='Bond') plt.xlabel(r'$\omega$') plt.ylabel(r'$A(\omega)$') plt.title(r'Isolated dimer $U={}$, $t_\perp={}$, $\beta={}$'.format( U, tp, beta)) plt.legend(loc=0) return [omega + tp - 1 / gfsU[0], omega - tp - 1 / gfsU[1]]
def molecule_sigma(omega, U, mu, tp, beta): """Return molecule self-energy in the given frequency axis""" h_at, oper = dimer.hamiltonian(U, mu, tp) oper_pair = [[oper[0], oper[0]], [oper[0], oper[1]]] eig_e, eig_v = op.diagonalize(h_at.todense()) gfsU = np.array([ op.gf_lehmann(eig_e, eig_v, c.T, beta, omega, d) for c, d in oper_pair ]) invg = dimer.mat_inv(gfsU[0], gfsU[1]) plt.plot(omega.real, -gfsU[0].imag, label='Interacting') plt.plot(omega.real, -dimer.mat_inv(omega, -tp)[0].imag, label='Free') plt.xlabel(r'$\omega$') plt.ylabel(r'$A(\omega)$') plt.title(r'Isolated dimer $U={}$, $t_\perp={}$, $\beta={}$'.format( U, tp, beta)) plt.legend(loc=0) return [omega - invg[0], -tp - invg[1]]