def cc_gf_ao (nimp, freqs, delta, cc, mo_coeff): gf = greens_function.greens_function() # Calculate full (p,q) GF matrix in AO basis g_ip = gf.solve_ip_ao(cc, range(nimp), \ freqs.conj(), mo_coeff, delta).conj() g_ea = gf.solve_ea_ao(cc, range(nimp), \ freqs, mo_coeff, delta) return g_ip + g_ea
def tdcc_gf(freqs, delta, cc, mo_coeff, ti=0, tf=40, nobs=800, tmax0=10000, tol=1.e-5): """ I think tf should something like ~2pi * energy width. For example if U=8, then tf=40 works well. tf/nobs defines the smallest frequency. Usually I choose nobs = ~10*tf tmax0 should be left as a large number, I think 10000 must be large enough """ n = mo_coeff.shape[0] times = np.linspace(ti,tf,nobs) deltat = float(tf - ti) / nobs # predict out to long times # note ntotal must be 2**n+1 since # we use romberg integration to do fourier transform integral ntotal0 = tmax0 / deltat nbase2 = np.int(np.log(ntotal0)/np.log(2)) ntotal = 2**nbase2+1 gf = greens_function.greens_function() gip = -gf.td_ip(cc, range(n), range(n), times, re_im="re", tol=tol) gea = -gf.td_ea(cc, range(n), range(n), times, re_im="re", tol=tol) PREDICT = True if PREDICT: # 2*pi/tmax gives a minimum oscillation frequency, so # graph will wiggle at least on this scale print "Total propagation time: ", ntotal * deltat predicted_gf_ip = tools.predict_gf(gip, ntotal) predicted_gf_ea = tools.predict_gf(gea, ntotal) gret = -1j * (predicted_gf_ip + predicted_gf_ea) gret_ao = np.einsum("pi,ijt,jq->pqt", mo_coeff, gret, mo_coeff.T) extrapolated_times = np.array([deltat*i for i in range(ntotal)]) tmax = extrapolated_times[-1] gf_w = tools.get_gfw(gret_ao, extrapolated_times, freqs, delta) else: gret = -1j * (gip + gea) gret_ao = np.einsum("pi,ijt,jq->pqt", mo_coeff, gret, mo_coeff.T) gf_w = tools.get_gfw(gret_ao, times, freqs, delta) return gf_w
def cc_gf_ao (nimp, freqs, delta, cc, mo_coeff): n = mo_coeff.shape[0] nw = len(freqs) #gip = np.zeros((n,n,nw), np.complex128) #gea = np.zeros((n,n,nw), np.complex128) gf = greens_function.greens_function() # Calculate full (p,q) GF matrix in MO basis g_ip = gf.solve_ip_ao(cc, range(nimp), \ freqs.conj(), mo_coeff, delta).conj() g_ea = gf.solve_ea_ao(cc, range(nimp), \ freqs, mo_coeff, delta) return g_ip + g_ea
def cc_gf (freqs, delta, cc, mo_coeff): n = mo_coeff.shape[0] nw = len(freqs) gf = greens_function.greens_function() # Calculate full (p,q) GF matrix in MO basis g_ip = gf.solve_ip(cc, range(n), range(n), \ freqs.conj(), delta).conj() g_ea = gf.solve_ea(cc, range(n), range(n), \ freqs, delta) # Change basis from MO to AO gf = np.zeros([n, n, nw], np.complex128) for iw, w in enumerate(freqs): g_ip_ = np.dot(mo_coeff, np.dot(g_ip[:,:,iw], mo_coeff.T)) g_ea_ = np.dot(mo_coeff, np.dot(g_ea[:,:,iw], mo_coeff.T)) gf[:,:,iw] = g_ip_+g_ea_ return gf
def tdcc_gf_ao(nimp, freqs, delta, cc, mo_coeff, ti=0, tf=40, nobs=800, tmax0=10000, tol=1.e-5): """ See tdcc_gf. """ n = mo_coeff.shape[0] times = np.linspace(ti, tf, nobs) deltat = float(tf - ti) / nobs # predict out to long times # note ntotal must be 2**n+1 since # we use romberg integration to do fourier transform integral ntotal0 = tmax0 / deltat nbase2 = np.int(np.log(ntotal0) / np.log(2)) ntotal = 2**nbase2 + 1 gf = greens_function.greens_function() gip = -gf.td_ip_ao(cc, range(nimp), times, mo_coeff, re_im="re", tol=tol) gea = -gf.td_ea_ao(cc, range(nimp), times, mo_coeff, re_im="re", tol=tol) # 2*pi/tmax gives a minimum oscillation frequency, so # graph will wiggle at least on this scale print "Total propagation time: ", ntotal * deltat predicted_gf_ip = tools.predict_gf(gip, ntotal) predicted_gf_ea = tools.predict_gf(gea, ntotal) gret_ao = -1j * (predicted_gf_ip + predicted_gf_ea) extrapolated_times = np.array([deltat * i for i in range(ntotal)]) tmax = extrapolated_times[-1] gf_w = tools.get_gfw(gret_ao, extrapolated_times, freqs, delta) return gf_w
def cc_gf(freqs, delta, cc, mo_coeff): n = mo_coeff.shape[0] nw = len(freqs) #gip = np.zeros((n,n,nw), np.complex128) #gea = np.zeros((n,n,nw), np.complex128) gf = greens_function.greens_function() # Calculate full (p,q) GF matrix in MO basis g_ip = gf.solve_ip(cc, range(n), range(n), \ freqs.conj(), delta).conj() g_ea = gf.solve_ea(cc, range(n), range(n), \ freqs, delta) # Change basis from MO to AO gf = np.zeros([n, n, nw], np.complex128) for iw, w in enumerate(freqs): g_ip_ = np.dot(mo_coeff, np.dot(g_ip[:, :, iw], mo_coeff.T)) g_ea_ = np.dot(mo_coeff, np.dot(g_ea[:, :, iw], mo_coeff.T)) gf[:, :, iw] = g_ip_ + g_ea_ return gf
def tdcc_gf_ao(nimp, freqs, delta, cc, mo_coeff, ti=0, tf=40, nobs=800, tmax0=10000, tol=1.e-5): """ See tdcc_gf. """ n = mo_coeff.shape[0] times = np.linspace(ti,tf,nobs) deltat = float(tf - ti) / nobs # predict out to long times # note ntotal must be 2**n+1 since # we use romberg integration to do fourier transform integral ntotal0 = tmax0 / deltat nbase2 = np.int(np.log(ntotal0)/np.log(2)) ntotal = 2**nbase2+1 gf = greens_function.greens_function() gip = -gf.td_ip_ao(cc, range(nimp), times, mo_coeff, re_im="re", tol=tol) gea = -gf.td_ea_ao(cc, range(nimp), times, mo_coeff, re_im="re", tol=tol) # 2*pi/tmax gives a minimum oscillation frequency, so # graph will wiggle at least on this scale print "Total propagation time: ", ntotal * deltat predicted_gf_ip = tools.predict_gf(gip, ntotal) predicted_gf_ea = tools.predict_gf(gea, ntotal) gret_ao = -1j * (predicted_gf_ip + predicted_gf_ea) extrapolated_times = np.array([deltat*i for i in range(ntotal)]) tmax = extrapolated_times[-1] gf_w = tools.get_gfw(gret_ao, extrapolated_times, freqs, delta) return gf_w
def get_ea_ao(cc, norbs, times, mo_coeff, tol): gf = greens_function.greens_function() # - sign determined empirically return -gf.td_ea_ao(cc, range(norbs), times, mo_coeff, re_im="re", tol=tol)
def get_ea(cc, norbs, times, tol): gf = greens_function.greens_function() # - sign determined empirically return -gf.td_ea(cc, range(norbs), range(norbs), times, tol)
def main(): args = sys.argv[1:] if len(args) == 2: U = int(args[0]) eta = float(args[1]) else: print "Usage: U/t eta[au]" return -1 nbath = 8 ncorr = 2 nelectron = ncorr + nbath nbas = ncorr + nbath if U == 1: filename = "params/u1.00_6th.mak" elif U == 2: filename = "params/u2.00_10th.mak" elif U == 3: filename = "params/u3.00_13th.mak" elif U == 4: filename = "params/u4.00_12th.mak" elif U == 5: filename = "params/u5.00_11th.mak" elif U == 7: filename = "params/u7.00_10th.mak" elif U == 9: filename = "params/u9.00_12th.mak" else: print "U not coded -- quitting." return -1 U, t, bath_onsite, bath_v = read_hubbard_params(nbath, ncorr, filename) h1 = np.zeros((nbas, nbas)) # Filling in the correlated orbital matrix elements h1[0, 0] = h1[1, 1] = -U / 2. h1[0, 1] = h1[1, 0] = -t # Filling in the bath orbital matrix elements for i in range(nbath): index = ncorr + i h1[index, index] = bath_onsite[i] for j in range(ncorr): h1[j, index] = bath_v[j, i] h1[index, j] = h1[j, index] numpy.set_printoptions(threshold=100, precision=6, linewidth=120) for i in range(-1, nbas): for j in range(nbas): if i == -1: if j < ncorr: print "%7s" % "corr", else: print "%7s" % "bath", else: print "%7.4f" % h1[i, j], print "" print "" eri = numpy.zeros((nbas, nbas, nbas, nbas)) for i in range(ncorr): eri[i, i, i, i] = U # Interfacing with pyscf # ---------------------- mol = gto.M() mol.nelectron = nelectron mol.incore_anyway = True mf = scf.RHF(mol) mf.get_hcore = lambda *args: h1 mf.get_ovlp = lambda *args: numpy.eye(nbas) mf._eri = ao2mo.restore(8, eri, nbas) mf.init_guess = '1e' escf = mf.scf() print "# pyscf HF evals = ", mf.mo_energy print "# pyscf HF evecs = " print mf.mo_coeff cc = pyscf.cc.CCSD(mf) print "cc.mo_energy =", cc.mo_energy ecc, t1, t2 = cc.ccsd() print "CCSD corr : %.15f" % ecc print "CCSD energy : %.15f" % (ecc + escf) print "Solving lambda equations..." conv, l1, l2 = cc.solve_lambda() # Interfacing with EOM pyscf # ---------------------- print "Repeating with EOM CCSD" cc_eom = pyscf.cc.rccsd_eom.RCCSD(mf) def my_ao2mofn(mol, bas, compact): return change_basis_2el(eri, mf.mo_coeff) # Give _ERIS class the eris in the MO basis eris = pyscf.cc.rccsd_eom._ERIS(cc_eom, ao2mofn=my_ao2mofn) ecc_eom, t1_eom, t2_eom = cc_eom.ccsd(eris=eris) print "EOM-CCSD corr : %.15f" % ecc_eom print "EOM-CCSD energy : %.15f" % (ecc_eom + escf) #cc_eom.t1 = cc.t1 #cc_eom.t2 = cc.t2 cc_eom.l1 = cc.l1 cc_eom.l2 = cc.l2 if CISD == True: cc_eom.t1 *= 1e-5 cc_eom.t2 *= 1e-5 cc_eom.l1 *= 1e-5 cc_eom.l2 *= 1e-5 dw = 0.03 wmin = -8.0 wmax = 8.0 nw = int((wmax - wmin) / dw) + 1 omegas = numpy.linspace(wmin, wmax, nw) gip = np.zeros((nbas, nbas, len(omegas)), np.complex) gea = np.zeros((nbas, nbas, len(omegas)), np.complex) gf = greens_function.greens_function() # Calculate full (p,q) GF matrix in MO basis gip, gea = gf.solve_gf(cc_eom, range(nbas), range(nbas), omegas, eta) # Change basis from MO to AO gip_ao = np.einsum('ip,pqw,qj->ijw', mf.mo_coeff, gip, mf.mo_coeff.T) gea_ao = np.einsum('ip,pqw,qj->ijw', mf.mo_coeff, gea, mf.mo_coeff.T) # Save the local GF for the "correlated" impurity orbitals for i in range(ncorr): numpy.savetxt( "gf_U-%.1f_ao-%d%d.dat" % (U, i, i), numpy.column_stack([ omegas, gip_ao[i, i, :].real, gip_ao[i, i, :].imag, gea_ao[i, i, :].real, gea_ao[i, i, :].imag ])) # Make G0 for sigma nocc = nelectron / 2 e, c = eig(h1) #e,c = mf.mo_energy.copy(), mf.mo_coeff.copy() g0ip = np.zeros_like(gip) g0ea = np.zeros_like(gea) for iw, w in enumerate(omegas): for i in range(nocc): g0ip[i, i, iw] = 1. / (w - e[i] - 1j * eta) for a in range(nocc, nbas): g0ea[a, a, iw] = 1. / (w - e[a] + 1j * eta) # Change basis from MO to AO g0ip_ao = np.einsum('ip,pqw,qj->ijw', c, g0ip, c.T) g0ea_ao = np.einsum('ip,pqw,qj->ijw', c, g0ea, c.T) for i in range(1): #for i in range(ncorr): numpy.savetxt( "gf0_U-%.1f_ao-%d%d.dat" % (U, i, i), numpy.column_stack([ omegas, g0ip_ao[i, i, :].real, g0ip_ao[i, i, :].imag, g0ea_ao[i, i, :].real, g0ea_ao[i, i, :].imag ])) g0_ret_ao = g0ip_ao.conj() + g0ea_ao g_ret_ao = gip_ao.conj() + gea_ao sigma = np.zeros_like(g_ret_ao) for iw, w in enumerate(omegas): sigma[:, :, iw] = np.linalg.inv(g0_ret_ao[:, :, iw]) - np.linalg.inv( g_ret_ao[:, :, iw]) for i in range(1): #for i in range(ncorr): numpy.savetxt( "sigma_U-%.1f_ao-%d%d.dat" % (U, i, i), numpy.column_stack( [omegas, sigma[i, i, :].real, sigma[i, i, :].imag]))
def main(): args = sys.argv[1:] if len(args) == 2: U = int(args[0]) eta = float(args[1]) else: print "Usage: U/t eta[au]" return -1 nbath = 8 ncorr = 2 nelectron = ncorr + nbath nbas = ncorr + nbath if U == 1: filename = "params/u1.00_6th.mak" elif U == 2: filename = "params/u2.00_10th.mak" elif U == 3: filename = "params/u3.00_13th.mak" elif U == 4: filename = "params/u4.00_12th.mak" elif U == 5: filename = "params/u5.00_11th.mak" elif U == 7: filename = "params/u7.00_10th.mak" elif U == 9: filename = "params/u9.00_12th.mak" else: print "U not coded -- quitting." return -1 U, t, bath_onsite, bath_v = read_hubbard_params(nbath, ncorr, filename) h1 = np.zeros((nbas,nbas)) # Filling in the correlated orbital matrix elements h1[0,0] = h1[1,1] = -U/2. h1[0,1] = h1[1,0] = -t # Filling in the bath orbital matrix elements for i in range(nbath): index = ncorr + i h1[index,index] = bath_onsite[i] for j in range(ncorr): h1[j,index] = bath_v[j,i] h1[index,j] = h1[j,index] numpy.set_printoptions(threshold=100,precision=6,linewidth=120) for i in range(-1,nbas): for j in range(nbas): if i == -1: if j < ncorr: print "%7s" % "corr", else: print "%7s" % "bath", else: print "%7.4f" % h1[i,j], print "" print "" eri = numpy.zeros((nbas,nbas,nbas,nbas)) for i in range(ncorr): eri[i,i,i,i] = U # Interfacing with pyscf # ---------------------- mol = gto.M() mol.nelectron = nelectron mol.incore_anyway = True mf = scf.RHF(mol) mf.get_hcore = lambda *args: h1 mf.get_ovlp = lambda *args: numpy.eye(nbas) mf._eri = ao2mo.restore(8, eri, nbas) mf.init_guess = '1e' escf = mf.scf() print "# pyscf HF evals = ", mf.mo_energy print "# pyscf HF evecs = " print mf.mo_coeff cc = pyscf.cc.CCSD(mf) print "cc.mo_energy =", cc.mo_energy ecc,t1,t2 = cc.ccsd() print "CCSD corr : %.15f" % ecc print "CCSD energy : %.15f" % (ecc+escf) print "Solving lambda equations..." conv,l1,l2 = cc.solve_lambda() # Interfacing with EOM pyscf # ---------------------- print "Repeating with EOM CCSD" cc_eom = pyscf.cc.rccsd_eom.RCCSD(mf) def my_ao2mofn(mol, bas, compact): return change_basis_2el(eri, mf.mo_coeff) # Give _ERIS class the eris in the MO basis eris = pyscf.cc.rccsd_eom._ERIS(cc_eom, ao2mofn=my_ao2mofn) ecc_eom, t1_eom, t2_eom = cc_eom.ccsd(eris=eris) print "EOM-CCSD corr : %.15f" % ecc_eom print "EOM-CCSD energy : %.15f" % (ecc_eom+escf) #cc_eom.t1 = cc.t1 #cc_eom.t2 = cc.t2 cc_eom.l1 = cc.l1 cc_eom.l2 = cc.l2 if CISD == True: cc_eom.t1 *= 1e-5 cc_eom.t2 *= 1e-5 cc_eom.l1 *= 1e-5 cc_eom.l2 *= 1e-5 dw = 0.03 wmin = -8.0 wmax = 8.0 nw = int((wmax-wmin)/dw) + 1 omegas = numpy.linspace(wmin, wmax, nw) gip = np.zeros((nbas,nbas,len(omegas)),np.complex) gea = np.zeros((nbas,nbas,len(omegas)),np.complex) gf = greens_function.greens_function() # Calculate full (p,q) GF matrix in MO basis gip, gea = gf.solve_gf(cc_eom,range(nbas),range(nbas),omegas,eta) # Change basis from MO to AO gip_ao = np.einsum('ip,pqw,qj->ijw',mf.mo_coeff,gip,mf.mo_coeff.T) gea_ao = np.einsum('ip,pqw,qj->ijw',mf.mo_coeff,gea,mf.mo_coeff.T) # Save the local GF for the "correlated" impurity orbitals for i in range(ncorr): numpy.savetxt("gf_U-%.1f_ao-%d%d.dat"%(U,i,i), numpy.column_stack([omegas, gip_ao[i,i,:].real, gip_ao[i,i,:].imag, gea_ao[i,i,:].real, gea_ao[i,i,:].imag])) # Make G0 for sigma nocc = nelectron/2 e,c = eig(h1) #e,c = mf.mo_energy.copy(), mf.mo_coeff.copy() g0ip = np.zeros_like(gip) g0ea = np.zeros_like(gea) for iw,w in enumerate(omegas): for i in range(nocc): g0ip[i,i,iw] = 1./(w-e[i]-1j*eta) for a in range(nocc,nbas): g0ea[a,a,iw] = 1./(w-e[a]+1j*eta) # Change basis from MO to AO g0ip_ao = np.einsum('ip,pqw,qj->ijw',c,g0ip,c.T) g0ea_ao = np.einsum('ip,pqw,qj->ijw',c,g0ea,c.T) for i in range(1): #for i in range(ncorr): numpy.savetxt("gf0_U-%.1f_ao-%d%d.dat"%(U,i,i), numpy.column_stack([omegas, g0ip_ao[i,i,:].real, g0ip_ao[i,i,:].imag, g0ea_ao[i,i,:].real, g0ea_ao[i,i,:].imag])) g0_ret_ao = g0ip_ao.conj() + g0ea_ao g_ret_ao = gip_ao.conj() + gea_ao sigma = np.zeros_like(g_ret_ao) for iw,w in enumerate(omegas): sigma[:,:,iw] = np.linalg.inv(g0_ret_ao[:,:,iw]) - np.linalg.inv(g_ret_ao[:,:,iw]) for i in range(1): #for i in range(ncorr): numpy.savetxt("sigma_U-%.1f_ao-%d%d.dat"%(U,i,i), numpy.column_stack([omegas, sigma[i,i,:].real, sigma[i,i,:].imag]))