def pyq1_dft(atomtuples=[(2, (0, 0, 0))], basis='6-31G**', maxit=10, xcname='SVWN'): from PyQuante import Ints, settings, Molecule from PyQuante.dft import getXC from PyQuante.MG2 import MG2 as MolecularGrid from PyQuante.LA2 import mkdens, geigh, trace2 from PyQuante.Ints import getJ print("PyQ1 DFT run") atoms = Molecule('Pyq1', atomlist=atomtuples) bfs = Ints.getbasis(atoms, basis=basis) S, h, Ints = Ints.getints(bfs, atoms) nclosed, nopen = nel // 2, nel % 2 assert nopen == 0 enuke = atoms.get_enuke() grid_nrad = settings.DFTGridRadii grid_fineness = settings.DFTGridFineness gr = MolecularGrid(atoms, grid_nrad, grid_fineness) gr.set_bf_amps(bfs) orbe, orbs = geigh(h, S) eold = 0 for i in range(maxit): D = mkdens(orbs, 0, nclosed) gr.setdens(D) J = getJ(Ints, D) Exc, Vxc = getXC(gr, nel, functional=xcname) F = h + 2 * J + Vxc orbe, orbs = geigh(F, S) Ej = 2 * trace2(D, J) Eone = 2 * trace2(D, h) energy = Eone + Ej + Exc + enuke print(i, energy, Eone, Ej, Exc, enuke) if np.isclose(energy, eold): break eold = energy return energy
def pyq1_dft(atomtuples=[(2,(0,0,0))],basis = '6-31G**',maxit=10, xcname='SVWN'): from PyQuante import Ints,settings,Molecule from PyQuante.dft import getXC from PyQuante.MG2 import MG2 as MolecularGrid from PyQuante.LA2 import mkdens,geigh,trace2 from PyQuante.Ints import getJ print ("PyQ1 DFT run") atoms = Molecule('Pyq1',atomlist=atomtuples) bfs = Ints.getbasis(atoms,basis=basis) S,h,Ints = Ints.getints(bfs,atoms) nclosed,nopen = nel//2,nel%2 assert nopen==0 enuke = atoms.get_enuke() grid_nrad = settings.DFTGridRadii grid_fineness = settings.DFTGridFineness gr = MolecularGrid(atoms,grid_nrad,grid_fineness) gr.set_bf_amps(bfs) orbe,orbs = geigh(h,S) eold = 0 for i in range(maxit): D = mkdens(orbs,0,nclosed) gr.setdens(D) J = getJ(Ints,D) Exc,Vxc = getXC(gr,nel,functional=xcname) F = h+2*J+Vxc orbe,orbs = geigh(F,S) Ej = 2*trace2(D,J) Eone = 2*trace2(D,h) energy = Eone + Ej + Exc + enuke print (i,energy,Eone,Ej,Exc,enuke) if np.isclose(energy,eold): break eold = energy return energy
def GetBasis(gaussResult, quiet=False): """Get PyQuante representation of a basis from a gaussian output file""" # Create representation of molecule within PyQuante PQMol = cclib.bridge.makepyquante(gaussResult.atomcoords[-1], gaussResult.atomnos) # Get PyQuante representation of basis set basis = Ints.getbasis(PQMol, gaussResult.basisname) # Check that PyQuante and g09 have the same basis set ordering nbasis = gaussResult.nbasis assert len(basis.bfs) == nbasis, ( "Gaussian and PyQuante have " "different basis sets. Did you specify the same basis for each?" ) overlap_py = np.array(Ints.getS(basis)) maxdefect = 0.0 if hasattr(gaussResult, "mocoeffs_sao"): sao = gaussResult.mocoeffs_sao else: sao = gaussResult.aooverlaps if not quiet: for i, vals in enumerate(zip(overlap_py.flat, sao.flat)): pq, g9 = vals x, y = np.unravel_index(i, (nbasis, nbasis)) denom = max(pq, g9) if denom < 10 ** -13: continue if min(pq, g9) == 0: denom = 1.0 defect = abs((pq - g9) / denom) if defect > maxdefect: maxdefect = defect if defect > 1e-3 and x <= y: print pq, g9, (x, y), 100 * abs(pq - g9) / denom print "Maximum error between G09 and PyQuante overlap matrices:", maxdefect if maxdefect > 1e-3: print "WARNING!!!! Calculated overlap matrix does not match basis set!" print "Basis sets might not match!\n\n\n" return nbasis, basis
def comp_int(wf1, wf2, wf3, wf4): integral = 0 for j1 in xrange(wf1.N): for j2 in xrange(wf2.N): for j3 in xrange(wf3.N): for j4 in xrange(wf4.N): over0 = overlap_int(wf1.gf[j1], wf2.gf[j2]) over1 = overlap_int(wf1.gf[j1], wf3.gf[j3]) over2 = overlap_int(wf1.gf[j1], wf4.gf[j4]) over3 = overlap_int(wf2.gf[j2], wf4.gf[j4]) over4 = overlap_int(wf3.gf[j3], wf4.gf[j4]) over5 = overlap_int(wf2.gf[j2], wf3.gf[j3]) if min([over0, over1, over2, over3, over4, over5]) >= 1.0: integral += Ints.coulomb_repulsion( (wf1.gf[j1][0], wf1.gf[j1][1], wf1.gf[j1][2]), wf1.gf[j1][4], (0, 0, 0), wf1.gf[j1][3], (wf2.gf[j2][0], wf2.gf[j2][1], wf2.gf[j2][2]), wf2.gf[j2][4], (0, 0, 0), wf2.gf[j2][3], (wf3.gf[j3][0], wf3.gf[j3][1], wf3.gf[j3][2]), wf3.gf[j3][4], (0, 0, 0), wf3.gf[j3][3], (wf4.gf[j4][0], wf4.gf[j4][1], wf4.gf[j4][2]), wf4.gf[j4][4], (0, 0, 0), wf4.gf[j4][3], ) else: integral += 0 return integral
def pyq1_rohf(atomtuples=[(2,(0,0,0))],basis = '6-31G**',maxit=10,mult=3): from PyQuante import Ints,settings,Molecule from PyQuante.hartree_fock import get_energy from PyQuante.MG2 import MG2 as MolecularGrid from PyQuante.LA2 import mkdens,geigh,trace2,simx from PyQuante.Ints import getJ,getK print ("PyQ1 ROHF run") atoms = Molecule('Pyq1',atomlist=atomtuples,multiplicity=mult) bfs = Ints.getbasis(atoms,basis=basis) S,h,I2e = Ints.getints(bfs,atoms) nbf = norbs = len(bfs) nel = atoms.get_nel() nalpha,nbeta = atoms.get_alphabeta() enuke = atoms.get_enuke() orbe,orbs = geigh(h,S) eold = 0 for i in range(maxit): Da = mkdens(orbs,0,nalpha) Db = mkdens(orbs,0,nbeta) Ja = getJ(I2e,Da) Jb = getJ(I2e,Db) Ka = getK(I2e,Da) Kb = getK(I2e,Db) Fa = h+Ja+Jb-Ka Fb = h+Ja+Jb-Kb energya = get_energy(h,Fa,Da) energyb = get_energy(h,Fb,Db) eone = (trace2(Da,h) + trace2(Db,h))/2 etwo = (trace2(Da,Fa) + trace2(Db,Fb))/2 energy = (energya+energyb)/2 + enuke print (i,energy,eone,etwo,enuke) if abs(energy-eold) < 1e-5: break eold = energy Fa = simx(Fa,orbs) Fb = simx(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] orbe,mo_orbs = np.linalg.eigh(F) orbs = np.dot(orbs,mo_orbs) return energy,orbe,orbs
def pyq1_rohf(atomtuples=[(2, (0, 0, 0))], basis='6-31G**', maxit=10, mult=3): from PyQuante import Ints, settings, Molecule from PyQuante.hartree_fock import get_energy from PyQuante.MG2 import MG2 as MolecularGrid from PyQuante.LA2 import mkdens, geigh, trace2, simx from PyQuante.Ints import getJ, getK print("PyQ1 ROHF run") atoms = Molecule('Pyq1', atomlist=atomtuples, multiplicity=mult) bfs = Ints.getbasis(atoms, basis=basis) S, h, I2e = Ints.getints(bfs, atoms) nbf = norbs = len(bfs) nel = atoms.get_nel() nalpha, nbeta = atoms.get_alphabeta() enuke = atoms.get_enuke() orbe, orbs = geigh(h, S) eold = 0 for i in range(maxit): Da = mkdens(orbs, 0, nalpha) Db = mkdens(orbs, 0, nbeta) Ja = getJ(I2e, Da) Jb = getJ(I2e, Db) Ka = getK(I2e, Da) Kb = getK(I2e, Db) Fa = h + Ja + Jb - Ka Fb = h + Ja + Jb - Kb energya = get_energy(h, Fa, Da) energyb = get_energy(h, Fb, Db) eone = (trace2(Da, h) + trace2(Db, h)) / 2 etwo = (trace2(Da, Fa) + trace2(Db, Fb)) / 2 energy = (energya + energyb) / 2 + enuke print(i, energy, eone, etwo, enuke) if abs(energy - eold) < 1e-5: break eold = energy Fa = simx(Fa, orbs) Fb = simx(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] orbe, mo_orbs = np.linalg.eigh(F) orbs = np.dot(orbs, mo_orbs) return energy, orbe, orbs
#Each numbered section refers to coressponding step in Szabo QM Textbook on page 161 from PyQuante import Molecule, Ints from PyQuante import LA2 as linalg from PyQuante.NumWrap import eigh, matrixmultiply from PyQuante import hartree_fock as HF #Global Variables############################ convergenceLimit = 1.0 * pow(10, -6) maxCycle = 50 #Section 1############################ #specify a molecule molecule = Molecule("H2", [(1, (0, 0, 0)), (1, (0, 0, 1)), (8, (-1, 0, 0))]) basisSet = Ints.getbasis(molecule, "sto-3g") #Section 2############################ #Overlap Matrix S = Ints.getS(basisSet) #Follwing Two matrices compose the core Hamiltonian #KE Matrix KE = Ints.getT(basisSet) #External Potential, Nuclear - Electron Attraction Vext = Ints.getV(basisSet, molecule) #Form Hcore Hcore = KE + Vext