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 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 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 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 two_electron_solve(atomic_number, maximum_order, spin): Z = atomic_number H, S = pekeris(Z, maximum_order, spin) E, V = geigh(H, S) epsilon = E[0] E2 = [-Ei**2 for Ei in E] #print "Energy (h) for order %d: %15.12f %15.12f" % (len(E),E2[0],epsilon) return E2[0]
def two_electron_solve(atomic_number,maximum_order,spin): Z = atomic_number H,S = pekeris(Z,maximum_order,spin) E,V = geigh(H,S) epsilon = E[0] E2 = [-Ei**2 for Ei in E] #print "Energy (h) for order %d: %15.12f %15.12f" % (len(E),E2[0],epsilon) return E2[0]
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 __init__(self,H,c=None,tol=1e-5,maxiters=100): self.H = H self.Eold = 0 if c is None: orbe,self.c = geigh(H.i1.T+H.i1.V,H.i1.S) else: self.c = c self.maxiters = maxiters self.tol = tol self.converged = False self.iterations = 0 return
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 eigenv(self, Fa, Fb): orbea, orbsa = geigh(Fa, self.i1.S) orbeb, orbsb = geigh(Fb, self.i1.S) return (orbea, orbsa), (orbeb, orbsb)
def eigenv(self, F): """ Eigenvalues and Eigenvectors""" orbe, orbs = geigh(F, self.i1.S) return orbe, orbs
def gvb(geo, npair=0, basisname='sto3g', maxiter=25, verbose=False, return_orbs=False, input_orbs=None): """\ This is a trivial test for the gvb module, because other pyquante modules are simpler if you're doing closed shell rhf, and should give the same results. # -0.46658184546856041 from uhf/sto3g >>> gvb(h) # doctest: +ELLIPSIS -0.4665818... # -1.117099582955609 from rhf/sto3g >>> gvb(h2) # doctest: +ELLIPSIS -1.117099... >>> gvb(lih,maxiter=5) # doctest: +ELLIPSIS -7.86073... >>> gvb(li,maxiter=5) # doctest: +ELLIPSIS -7.31552... >>> gvb(h2,npair=1) # doctest: +ELLIPSIS -1.13730... """ # Get the basis set and the integrals bfs = basisset(geo, basisname) i1 = onee_integrals(bfs, geo) i2 = twoe_integrals(bfs) h = i1.T + i1.V # Get a guess for the orbitals if input_orbs is not None: U = input_orbs else: E, U = geigh(h, i1.S) # Set the parameters based on the molecule nopen = geo.nopen() ncore = geo.nclosed() - npair nocc = ncore + nopen + 2 * npair norb = len(bfs) virt = range(nocc, norb) orbs_per_shell = get_orbs_per_shell(ncore, nopen, npair) nsh = len(orbs_per_shell) shell = orbital_to_shell_mapping(ncore, nopen, npair) Enuke = geo.nuclear_repulsion() f, a, b = fab(ncore, nopen, npair) if verbose: np.set_printoptions(precision=4) print("**** PyQuante GVB ****") print(geo) print("Nuclear repulsion energy: %.3f" % Enuke) print("Basis set: %s" % basisname) print(" ncore/open/pair: %d,%d,%d" % (ncore, nopen, npair)) print(" occ/bf/orb: %d,%d,%d" % (nocc, len(bfs), norb)) for i in range(nsh): print("Shell %d" % i) print(" occupation = %.2f" % f[i]) print(" orbitals in shell %s" % orbs_per_shell[i]) print(" couplings to other shells %s" % zip(a[i, :], b[i, :])) print("Starting guess at orbitals:\n%s" % U) print("Shell array: %s" % shell) print("****") Eold = 0 for it in range(maxiter): # Make all of the density matrices: Ds = [dmat_gen(U, orbs) for orbs in orbs_per_shell] # Compute the required Hamiltonian matrices: Js = [i2.get_j(D) for D in Ds] Ks = [i2.get_k(D) for D in Ds] # Perform the ROTION step and compute the energy Eel, Eone, Uocc = ROTION(U[:, :nocc], h, Js, Ks, f, a, b, nocc, shell, verbose=verbose) if nsh > 1: U[:, :nocc] = Uocc # Perform the OCBSE step U = OCBSE(U, h, Js, Ks, f, a, b, orbs_per_shell, virt) #E = Enuke+Eone+Etwo E = Enuke + Eel Etwo = Eel - 2 * Eone # Update CI coefs coeffs = update_gvb_ci_coeffs(Uocc, h, Js, Ks, f, a, b, ncore, nopen, npair, orbs_per_shell, verbose) f, a, b = fab(ncore, nopen, npair, coeffs) if verbose: print("---- %d : %10.4f %10.4f %10.4f %10.4f" % ((it + 1), E, Enuke, Eone, Etwo)) if np.isclose(E, Eold): if verbose: print("Energy converged") break Eold = E else: print("Maximum iterations (%d) reached without convergence" % (maxiter)) if return_orbs: return E, U return E
def gvb(geo,npair=0,basisname='sto3g',maxiter=25,verbose=False, return_orbs=False, input_orbs=None): """\ This is a trivial test for the gvb module, because other pyquante modules are simpler if you're doing closed shell rhf, and should give the same results. # -0.46658184546856041 from uhf/sto3g >>> gvb(h) # doctest: +ELLIPSIS -0.4665818... # -1.117099582955609 from rhf/sto3g >>> gvb(h2) # doctest: +ELLIPSIS -1.117099... >>> gvb(lih,maxiter=5) # doctest: +ELLIPSIS -7.86073... >>> gvb(li,maxiter=5) # doctest: +ELLIPSIS -7.31552... >>> gvb(h2,npair=1) # doctest: +ELLIPSIS -1.13730... """ # Get the basis set and the integrals bfs = basisset(geo,basisname) i1 = onee_integrals(bfs,geo) i2 = twoe_integrals(bfs) h = i1.T + i1.V # Get a guess for the orbitals if input_orbs is not None: U = input_orbs else: E,U = geigh(h,i1.S) # Set the parameters based on the molecule nopen = geo.nopen() ncore = geo.nclosed() - npair nocc = ncore + nopen + 2*npair norb = len(bfs) virt = range(nocc,norb) orbs_per_shell = get_orbs_per_shell(ncore,nopen,npair) nsh = len(orbs_per_shell) shell = orbital_to_shell_mapping(ncore,nopen,npair) Enuke = geo.nuclear_repulsion() f,a,b = fab(ncore,nopen,npair) if verbose: np.set_printoptions(precision=4) print("**** PyQuante GVB ****") print(geo) print("Nuclear repulsion energy: %.3f" % Enuke) print("Basis set: %s" % basisname) print(" ncore/open/pair: %d,%d,%d" % (ncore,nopen,npair)) print(" occ/bf/orb: %d,%d,%d" % (nocc,len(bfs),norb)) for i in range(nsh): print("Shell %d" % i) print(" occupation = %.2f" % f[i]) print(" orbitals in shell %s" % orbs_per_shell[i]) print(" couplings to other shells %s" % zip(a[i,:],b[i,:])) print("Starting guess at orbitals:\n%s"%U) print("Shell array: %s" % shell) print("****") Eold = 0 for it in range(maxiter): # Make all of the density matrices: Ds = [dmat_gen(U,orbs) for orbs in orbs_per_shell] # Compute the required Hamiltonian matrices: Js = [i2.get_j(D) for D in Ds] Ks = [i2.get_k(D) for D in Ds] # Perform the ROTION step and compute the energy Eel,Eone,Uocc = ROTION(U[:,:nocc],h,Js,Ks,f,a,b,nocc,shell, verbose=verbose) if nsh > 1: U[:,:nocc] = Uocc # Perform the OCBSE step U = OCBSE(U,h,Js,Ks,f,a,b,orbs_per_shell,virt) #E = Enuke+Eone+Etwo E = Enuke+Eel Etwo = Eel-2*Eone # Update CI coefs coeffs = update_gvb_ci_coeffs(Uocc,h,Js,Ks,f,a,b,ncore,nopen,npair, orbs_per_shell,verbose) f,a,b = fab(ncore,nopen,npair,coeffs) if verbose: print ("---- %d : %10.4f %10.4f %10.4f %10.4f" % ((it+1),E,Enuke,Eone,Etwo)) if np.isclose(E,Eold): if verbose: print("Energy converged") break Eold = E else: print("Maximum iterations (%d) reached without convergence" % (maxiter)) if return_orbs: return E,U return E