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 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