def __init__(self, mol, mints): rhf = RHF(mol, mints) self.E0 = rhf.computeEnergy() self.docc = rhf.docc self.nbf = len(rhf.S) self.e = rhf.e self.G = rhf.G self.C = rhf.C
def rhf_energy(self): """ Optimize RHF orbitals; return RHF energy, two-electron integrals, and coefficient matrix """ rhf = RHF(self.mol, self.mints) return(rhf.E,rhf.g,rhf.C,rhf.orb_e)
class MP2: def __init__(self,mol,mints): self.docc = get_docc(mol) self.nbf = get_nbf(mints) self.conv = get_conv() self.maxiter = get_maxiter() self.rhf = RHF(mol,mints) self.E_scf = self.rhf.get_energy() self.e = self.rhf.e self.G = self.rhf.G self.C = self.rhf.C def get_energy(self): #rename class variables docc, nbf, conv, maxiter = self.docc, self.nbf, self.conv, self.maxiter E_scf, e = self.E_scf, self.e # Gmo = self.transform_integrals_noddy() # Gmo = self.transform_integrals_einsum() Gmo = self.transform_integrals_einsum_2() Ecorr = 0.0 for i in range(docc): for j in range(docc): for a in range(docc,nbf): for b in range(docc,nbf): Ecorr += (2*Gmo[i,j,a,b]-Gmo[i,j,b,a])*Gmo[i,j,a,b]/(e[i]+e[j]-e[a]-e[b]) return E_scf + Ecorr def transform_integrals_einsum(self): G,C = self.G, self.C return np.einsum("Pqrs,Pp->pqrs", np.einsum("PQrs,Qq->Pqrs", np.einsum("PQRs,Rr->PQrs", np.einsum("PQRS,Ss->PQRs", G, C), C) ,C) ,C) def transform_integrals_einsum_2(self): G,C = self.G, self.C return np.einsum("PQRS,Pp,Qq,Rr,Ss->pqrs",G,C,C,C,C) def transform_integrals_noddy(self): nbf = self.nbf C,G = self.C, self.G Gmo = np.zeros(self.G.shape) for p in range(nbf): for q in range(nbf): for r in range(nbf): for s in range(nbf): for i in range(nbf): for j in range(nbf): for k in range(nbf): for l in range(nbf): Gmo[p,q,r,s] += C[i,p]*C[j,q]*C[k,r]*C[l,s]*G[i,j,k,l] return Gmo
def __init__(self,mol,mints): self.docc = get_docc(mol) self.nbf = get_nbf(mints) self.conv = get_conv() self.maxiter = get_maxiter() self.rhf = RHF(mol,mints) self.E_scf = self.rhf.get_energy() self.e = self.rhf.e self.G = self.rhf.G self.C = self.rhf.C
return np.einsum('pqrs, pP, qQ, rR, sS-> PQRS', G, C, C, C, C) def get_energy(self): # MP2 energy correction e, E0, ndocc, ntot = self.e, self.E0, self.ndocc, self.ntot g_mo = self.transform_integrals( rhf.C, rhf.G) # calls transform_integrals function E = 0.0 for i in range( ndocc): # i and j over occupied orbitals, a and b over virtual for j in range(ndocc): for a in range(ndocc, ntot): for b in range(ndocc, ntot): E += (g_mo[i, a, j, b] * (2 * g_mo[i, a, j, b] - g_mo[i, b, j, a])) / ( e[i] + e[j] - e[a] - e[b] ) # MP2 energy expression print('The second order energy correction is {:20.14f}'.format(E)) print('The total RMP2 energy is {:20.14f}'.format(E0 + E)) return E # testing if __name__ == '__main__': rhf = RHF('../../3/bz3wp/Options.ini') rhf.get_energy() rmp2 = RMP2(rhf) rmp2.get_energy()
for i in range(nocc): for j in range(nocc): for a in range(nocc, ntot): for b in range(nocc, ntot): Ec += gmo[i, a, j, b]*(2*gmo[i, a, j, b] - gmo[i, b, j, a])/\ (e[i] + e[j] - e[a] - e[b]) self.Ec = Ec self.E_mp2 = Ec + self.E_scf print('@MP2 correlation energy: {:15.10f}\n'.format(self.Ec)) print('@Total MP2 energy: {:15.10f}\n'.format(self.E_mp2)) return self.E_mp2 if __name__ == "__main__": import sys sys.path.insert(0, '../../3/jevandezande') from rhf import RHF rhf = RHF('../../3/jevandezande/Options.ini') rhf.energy() rmp2 = RMP2(rhf) e = rmp2.energy() dfrmp2 = RMP2(rhf, 'cc-pVDZ-RI') df_e = dfrmp2.energy() print("Energy Error: {:7.5e}".format(df_e - e)) print("norm(UMP2.gmo - DFUMP2.gmo): {:7.5E}".format(np.linalg.norm(rmp2.gmo - dfrmp2.gmo)))
for j in range(nocc): for a in range(nocc, ntot): for b in range(nocc, ntot): Ec += gmo[i, a, j, b]*(2*gmo[i, a, j, b] - gmo[i, b, j, a])/\ (e[i] + e[j] - e[a] - e[b]) self.Ec = Ec self.E_mp2 = Ec + self.E_scf print('@MP2 correlation energy: {:15.10f}\n'.format(self.Ec)) print('@Total MP2 energy: {:15.10f}\n'.format(self.E_mp2)) return self.E_mp2 if __name__ == "__main__": import sys sys.path.insert(0, '../../3/jevandezande') from rhf import RHF rhf = RHF('../../3/jevandezande/Options.ini') rhf.energy() rmp2 = RMP2(rhf) e = rmp2.energy() dfrmp2 = RMP2(rhf, 'cc-pVDZ-RI') df_e = dfrmp2.energy() print("Energy Error: {:7.5e}".format(df_e - e)) print("norm(UMP2.gmo - DFUMP2.gmo): {:7.5E}".format( np.linalg.norm(rmp2.gmo - dfrmp2.gmo)))