def uhf_simple(geo,basisname='sto3g',maxiter=25,verbose=False): if geo.nopen() == 0: return scf_simple(geo,basisname,maxiter,verbose) bfs = basisset(geo,basisname) i1 = onee_integrals(bfs,geo) i2 = twoe_integrals(bfs) h = i1.T + i1.V E,U = geigh(h,i1.S) Enuke = geo.nuclear_repulsion() Eold = Energy = 0 ca = cb = U na,nb = geo.nup(),geo.ndown() for i in xrange(maxiter): Energy = Enuke Da = dmat(ca,na) Db = dmat(cb,nb) h = i1.T + i1.V Energy += trace2(Da+Db,h)/2 Ja,Ka = i2.get_j(Da),i2.get_k(Da) Jb,Kb = i2.get_j(Db),i2.get_k(Db) Fa = h + Ja + Jb - Ka Fb = h + Ja + Jb - Kb orbea,ca = geigh(Fa,i1.S) orbeb,cb = geigh(Fb,i1.S) Energy += trace2(Fa,Da)/2 + trace2(Fb,Db)/2 print ("UHF: %d %10.4f : %10.4f" % ((i+1),Energy,Enuke)) if np.isclose(Energy,Eold): break Eold = Energy else: print ("Warning: Maxiter %d hit in scf_simple" % maxiter) return Energy,E,U
def fock_energy(self, Da, Db): # Fock h = self.h J = self.i2.get_j(Da + Db) Ka, Kb = self.i2.get_k(Da), self.i2.get_k(Db) Ga = J - Ka Gb = J - Kb Fa = h + Ga Fb = h + Gb # Energy Eone = trace2(Da + Db, h) Etwo = trace2(Ga, Da) / 2 + trace2(Gb, Db) / 2 E = self.Enuc + Eone + Etwo # Create Effective Fock Matrixs P = (Da + Db) / 2 # charge density matrix M = (Da - Db) / 2 # spin density matrix # obtain Cno - natural orbitals Fc = (Fa + Fb) / 2.0 c = slice(0, self.ndown) o = slice(self.ndown, self.nup) v = slice(self.nup, self.norb) Fa[c, v] = Fc[c, v] Fb[v, c] = Fc[v, c] return Fa, Fb, E
def scf_simple(geo,basisname='sto-3g',maxiter=25,verbose=False): bfs = basisset(geo,basisname) i1 = onee_integrals(bfs,geo) i2 = twoe_integrals(bfs) if verbose: print ("S=\n%s" % i1.S) h = i1.T + i1.V if verbose: print ("h=\n%s" % h) if verbose: print ("T=\n%s" % i1.T) if verbose: print ("V=\n%s" % i1.V) E,U = geigh(h,i1.S) if verbose: print ("E=\n%s" % E) if verbose: print ("U=\n%s" % U) Enuke = geo.nuclear_repulsion() nocc = geo.nocc() Eold = Energy = 0 if verbose: print ("2e ints\n%s" % i2) for i in xrange(maxiter): D = dmat(U,nocc) if verbose: print ("D=\n%s" % D) Eone = trace2(h,D) G = i2.get_2jk(D) H = h+G Etwo = trace2(H,D) E,U = geigh(H,i1.S) Energy = Enuke+Eone+Etwo print ("HF: %d %10.4f : %10.4f %10.4f %10.4f" % ((i+1),Energy,Enuke,Eone,Etwo)) if np.isclose(Energy,Eold): break Eold = Energy else: print ("Warning: Maxiter %d hit in scf_simple" % maxiter) return Energy,E,U
def rhf_simple(geo,basisname='sto3g',maxiter=25,verbose=False): bfs = basisset(geo,basisname) i1 = onee_integrals(bfs,geo) i2 = twoe_integrals(bfs) if verbose: print ("S=\n%s" % i1.S) h = i1.T + i1.V if verbose: print ("h=\n%s" % h) if verbose: print ("T=\n%s" % i1.T) if verbose: print ("V=\n%s" % i1.V) E,U = geigh(h,i1.S) if verbose: print ("E=\n%s" % E) if verbose: print ("U=\n%s" % U) Enuke = geo.nuclear_repulsion() nocc = geo.nocc() Eold = Energy = 0 if verbose: print ("2e ints\n%s" % i2) for i in xrange(maxiter): D = dmat(U,nocc) if verbose: print ("D=\n%s" % D) Eone = trace2(h,D) G = i2.get_2jk(D) H = h+G Etwo = trace2(H,D) E,U = geigh(H,i1.S) Energy = Enuke+Eone+Etwo print ("HF: %d %10.4f : %10.4f %10.4f %10.4f" % ((i+1),Energy,Enuke,Eone,Etwo)) if np.isclose(Energy,Eold): break Eold = Energy else: print ("Warning: Maxiter %d hit in scf_simple" % maxiter) return Energy,E,U
def update(self,D): self.energy = self.geo.nuclear_repulsion() H = self.i1.T + self.i1.V self.energy += trace2(H,D) JK = self.i2.get_2jk(D) H = H + JK self.energy += trace2(H,D) E,c = geigh(H,self.i1.S) self.orbe = E self.orbs = c return c
def update(self, Da, Db, orbs): from pyquante2.utils import ao2mo nalpha = self.geo.nup() nbeta = self.geo.ndown() norbs = len(orbs) # Da.shape[0] E0 = self.geo.nuclear_repulsion() h = self.i1.T + self.i1.V E1 = 0.5 * trace2(Da + Db, h) Ja, Ka = self.i2.get_j(Da), self.i2.get_k(Da) Jb, Kb = self.i2.get_j(Db), self.i2.get_k(Db) Fa = h + Ja + Jb - Ka Fb = h + Ja + Jb - Kb E2 = 0.5 * (trace2(Fa, Da) + trace2(Fb, Db)) self.energy = E0 + E1 + E2 # print (self.energy,E1,E2,E0) Fa = ao2mo(Fa, orbs) Fb = ao2mo(Fb, orbs) # Building the approximate Fock matrices in the MO basis F = 0.5 * (Fa + Fb) K = Fb - Fa # The Fock matrix now looks like # F-K | F + K/2 | F # --------------------------------- # F + K/2 | F | F - K/2 # --------------------------------- # F | F - K/2 | F + K # Make explicit slice objects to simplify this do = slice(0, nbeta) so = slice(nbeta, nalpha) uo = slice(nalpha, norbs) F[do, do] -= K[do, do] F[uo, uo] += K[uo, uo] F[do, so] += 0.5 * K[do, so] F[so, do] += 0.5 * K[so, do] F[so, uo] -= 0.5 * K[so, uo] F[uo, so] -= 0.5 * K[uo, so] E, cmo = np.linalg.eigh(F) c = np.dot(orbs, cmo) self.orbe = E self.orbs = c return c
def update(self,Da,Db,orbs): from pyquante2.utils import ao2mo nalpha = self.geo.nup() nbeta = self.geo.ndown() norbs = len(orbs) # Da.shape[0] E0 = self.geo.nuclear_repulsion() h = self.i1.T + self.i1.V E1 = 0.5*trace2(Da+Db,h) Ja,Ka = self.i2.get_j(Da),self.i2.get_k(Da) Jb,Kb = self.i2.get_j(Db),self.i2.get_k(Db) Fa = h + Ja + Jb - Ka Fb = h + Ja + Jb - Kb E2 = 0.5*(trace2(Fa,Da)+trace2(Fb,Db)) self.energy = E0+E1+E2 #print (self.energy,E1,E2,E0) Fa = ao2mo(Fa,orbs) Fb = ao2mo(Fb,orbs) # Building the approximate Fock matrices in the MO basis F = 0.5*(Fa+Fb) K = Fb-Fa # The Fock matrix now looks like # F-K | F + K/2 | F # --------------------------------- # F + K/2 | F | F - K/2 # --------------------------------- # F | F - K/2 | F + K # Make explicit slice objects to simplify this do = slice(0,nbeta) so = slice(nbeta,nalpha) uo = slice(nalpha,norbs) F[do,do] -= K[do,do] F[uo,uo] += K[uo,uo] F[do,so] += 0.5*K[do,so] F[so,do] += 0.5*K[so,do] F[so,uo] -= 0.5*K[so,uo] F[uo,so] -= 0.5*K[uo,so] E,cmo = np.linalg.eigh(F) c = np.dot(orbs,cmo) self.orbe = E self.orbs = c return c
def update(self,Da,Db): self.energy = self.geo.nuclear_repulsion() h = self.i1.T + self.i1.V self.energy += trace2(Da+Db,h)/2 Ja,Ka = self.i2.get_j(Da),self.i2.get_k(Da) Jb,Kb = self.i2.get_j(Db),self.i2.get_k(Db) Fa = h + Ja + Jb - Ka Fb = h + Ja + Jb - Kb orbea,ca = geigh(Fa,self.i1.S) orbeb,cb = geigh(Fb,self.i1.S) self.energy += trace2(Fa,Da)/2 + trace2(Fb,Db)/2 self.orbea = orbea self.orbsa = ca self.orbeb = orbeb self.orbsb = cb return ca,cb
def update(self,D): from pyquante2.dft.dft import get_xc E0 = self.geo.nuclear_repulsion() self.energy = E0 H = self.i1.T + self.i1.V E1 = 2*trace2(H,D) self.energy += E1 J = self.i2.get_j(D) Ej = 2*trace2(J,D) # The 0.5 before the D comes from making the alpha density from the total density Exc,Vxc = get_xc(self.grid,0.5*D,xcname=self.xcname) H = H + 2*J + Vxc self.energy += Ej+Exc if self.verbose: print(self.energy,E1,Ej,Exc,E0) E,c = geigh(H,self.i1.S) self.orbe = E self.orbs = c return c
def energy(self, Da, Db, Fa, Fb): """ Energy""" Ea = trace2(self.h + Fa, Da) Eb = trace2(self.h + Fb, Db) return self.Enuc + (Ea + Eb) / 2
def energy(self, D, F): """ Energy""" Exc = 0.0 # TODO: not implemented return self.Enuc + trace2(self.h + F, D) + Exc
def energy(self, D, F): """ Energy""" return self.Enuc + trace2(self.h + F, D)