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 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 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
# a_ij = 0, b_ij = -c_i c_j If i and j are in the same pair for i in range(ncoresh+nopen,ncoresh+nopen+npair): a[i,i+npair] = a[i+npair,i] = 0 b[i,i+npair] = b[i+npair,i] = -coeffs[i]*coeffs[i+npair] return f,a,b if __name__ == '__main__': #import doctest; doctest.testmod() #gvb(h,maxiter=5,verbose=True) # -0.46658 #gvb(lih,maxiter=5,verbose=True) # -7.86073 #gvb(li,maxiter=5,verbose=True) # -7.3155 #gvb(h2,npair=1,verbose=True) # RHF = -1.1171, GVB ?= -1.1373 # # h- example for Rajib: Does not currently work with GVB. # RHF energy is -0.4224, GVB energy is -0.3964 h_m = molecule(atomlist = [(1,0,0,0)],charge=-1,name="H-") from pyquante2.orbman import orbman E,orbs = gvb(h_m,maxiter=10,basisname='6-31g',npair=0,verbose=True, return_orbs=True) o_hf = orbman(orbs,basisset(h_m,'6-31g'),h_m) E,orbs = gvb(h_m,maxiter=10,basisname='6-31g',npair=1,verbose=True, return_orbs=True,input_orbs=orbs) o_gvb = orbman(orbs,basisset(h_m,'6-31g'),h_m) for i in [0,1]: print("Orbital %d after HF" % i) o_hf[i] print(" GVB") o_gvb[i]
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
#gvb(h,maxiter=5,verbose=True) # -0.46658 #gvb(lih,maxiter=5,verbose=True) # -7.86073 #gvb(li,maxiter=5,verbose=True) # -7.3155 #gvb(h2,npair=1,verbose=True) # RHF = -1.1171, GVB ?= -1.1373 # # h- example for Rajib: Does not currently work with GVB. # RHF energy is -0.4224, GVB energy is -0.3964 h_m = molecule(atomlist=[(1, 0, 0, 0)], charge=-1, name="H-") from pyquante2.orbman import orbman E, orbs = gvb(h_m, maxiter=10, basisname='6-31g', npair=0, verbose=True, return_orbs=True) o_hf = orbman(orbs, basisset(h_m, '6-31g'), h_m) E, orbs = gvb(h_m, maxiter=10, basisname='6-31g', npair=1, verbose=True, return_orbs=True, input_orbs=orbs) o_gvb = orbman(orbs, basisset(h_m, '6-31g'), h_m) for i in [0, 1]: print("Orbital %d after HF" % i) o_hf[i] print(" GVB") o_gvb[i]