Esempio n. 1
0
    def update(self, **kwargs):
        from PyQuante.Ints import getJ, getK
        from PyQuante.LA2 import geigh, mkdens
        from PyQuante.rohf import ao2mo
        from PyQuante.hartree_fock import get_energy
        from PyQuante.NumWrap import eigh, matrixmultiply

        if self.orbs is None:
            self.orbe, self.orbs = geigh(self.h, self.S)
        Da = mkdens(self.orbs, 0, self.nalpha)
        Db = mkdens(self.orbs, 0, self.nbeta)

        Ja = getJ(self.ERI, Da)
        Jb = getJ(self.ERI, Db)
        Ka = getK(self.ERI, Da)
        Kb = getK(self.ERI, Db)
        Fa = self.h + Ja + Jb - Ka
        Fb = self.h + Ja + Jb - Kb
        energya = get_energy(self.h, Fa, Da)
        energyb = get_energy(self.h, Fb, Db)
        self.energy = (energya + energyb) / 2 + self.Enuke

        Fa = ao2mo(Fa, self.orbs)
        Fb = ao2mo(Fb, self.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, self.nbeta)
        so = slice(self.nbeta, self.nalpha)
        uo = slice(self.nalpha, self.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]

        self.orbe, mo_orbs = eigh(F)
        self.orbs = matrixmultiply(self.orbs, mo_orbs)

        return
Esempio n. 2
0
    def update(self,**opts):
        from PyQuante.Ints import getJ,getK
        from PyQuante.LA2 import geigh,mkdens
        from PyQuante.rohf import ao2mo
        from PyQuante.hartree_fock import get_energy
        from PyQuante.NumWrap import eigh,matrixmultiply

        if self.orbs is None:
            self.orbe,self.orbs = geigh(self.h, self.S)
        Da = mkdens(self.orbs,0,self.nalpha)
        Db = mkdens(self.orbs,0,self.nbeta)

        Ja = getJ(self.ERI,Da)
        Jb = getJ(self.ERI,Db)
        Ka = getK(self.ERI,Da)
        Kb = getK(self.ERI,Db)
        Fa = self.h+Ja+Jb-Ka
        Fb = self.h+Ja+Jb-Kb
        energya = get_energy(self.h,Fa,Da)
        energyb = get_energy(self.h,Fb,Db)
        self.energy = (energya+energyb)/2 + self.Enuke

        Fa = ao2mo(Fa,self.orbs)
        Fb = ao2mo(Fb,self.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,self.nbeta)
        so = slice(self.nbeta,self.nalpha)
        uo = slice(self.nalpha,self.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]

        self.orbe,mo_orbs = eigh(F)
        self.orbs = matrixmultiply(self.orbs,mo_orbs)
        
        return
Esempio n. 3
0
def simple_hf(atoms,S,h,Ints):
    from PyQuante.LA2 import mkdens
    from PyQuante.hartree_fock import get_energy
    orbe,orbs = geigh(h,S)
    nclosed,nopen = atoms.get_closedopen()
    enuke = atoms.get_enuke()
    nocc = nclosed
    eold = 0
    for i in range(15):
        D = mkdens(orbs,0,nocc)
        G = get2JmK(Ints,D)
        F = h+G
        orbe,orbs = geigh(F,S)
        energy = get_energy(h,F,D,enuke)
        print "%d %f" % (i,energy)
        if abs(energy-eold) < 1e-4: break
        eold = energy
    print "Final HF energy for system %s is %f" % (atoms.name,energy)
    return energy,orbe,orbs
Esempio n. 4
0
def simple_hf(atoms, S, h, Ints):
    from PyQuante.LA2 import mkdens
    from PyQuante.hartree_fock import get_energy
    orbe, orbs = geigh(h, S)
    nclosed, nopen = atoms.get_closedopen()
    enuke = atoms.get_enuke()
    nocc = nclosed
    eold = 0
    for i in range(15):
        D = mkdens(orbs, 0, nocc)
        G = get2JmK(Ints, D)
        F = h + G
        orbe, orbs = geigh(F, S)
        energy = get_energy(h, F, D, enuke)
        print "%d %f" % (i, energy)
        if abs(energy - eold) < 1e-4: break
        eold = energy
    print "Final HF energy for system %s is %f" % (atoms.name, energy)
    return energy, orbe, orbs
Esempio n. 5
0
def rohf(atoms,**opts):
    """\
    rohf(atoms,**opts) - Restriced Open Shell Hartree Fock
    atoms       A Molecule object containing the molecule
    """

    ConvCriteria = opts.get('ConvCriteria',1e-5)
    MaxIter = opts.get('MaxIter',40)
    DoAveraging = opts.get('DoAveraging',True)
    averaging = opts.get('averaging',0.95)
    verbose = opts.get('verbose',True)

    bfs = opts.get('bfs',None)
    if not bfs:
        basis_data = opts.get('basis_data',None)
        bfs = getbasis(atoms,basis_data)
    nbf = len(bfs)

    integrals = opts.get('integrals', None)
    if integrals:
        S,h,Ints = integrals
    else:
        S,h,Ints = getints(bfs,atoms)

    nel = atoms.get_nel()

    nalpha,nbeta = atoms.get_alphabeta()
    S,h,Ints = getints(bfs,atoms)

    orbs = opts.get('orbs',None)
    if orbs is None:
        orbe,orbs = geigh(h,S)
    norbs = nbf

    enuke = atoms.get_enuke()
    eold = 0.

    if verbose: print "ROHF calculation on %s" % atoms.name
    if verbose: print "Nbf = %d" % nbf
    if verbose: print "Nalpha = %d" % nalpha
    if verbose: print "Nbeta = %d" % nbeta
    if verbose: print "Averaging = %s" % DoAveraging
    print "Optimization of HF orbitals"

    for i in xrange(MaxIter):
        if verbose: print "SCF Iteration:",i,"Starting Energy:",eold
        Da = mkdens(orbs,0,nalpha)
        Db = mkdens(orbs,0,nbeta)
        if DoAveraging:
            if i: 
                Da = averaging*Da + (1-averaging)*Da0
                Db = averaging*Db + (1-averaging)*Db0
            Da0 = Da
            Db0 = Db

        Ja = getJ(Ints,Da)
        Jb = getJ(Ints,Db)
        Ka = getK(Ints,Da)
        Kb = getK(Ints,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) < ConvCriteria: break
        eold = energy

        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]

        orbe,mo_orbs = eigh(F)
        orbs = matrixmultiply(orbs,mo_orbs)
        
    if verbose:
        print "Final ROHF energy for system %s is %f" % (atoms.name,energy)
    return energy,orbe,orbs
Esempio n. 6
0
from PyQuante.Ints import get2JmK,getbasis,getints
from PyQuante.Convergence import DIIS
from PyQuante.hartree_fock import get_energy

bfs = getbasis(h2,basis="3-21g")
nclosed,nopen = h2.get_closedopen()
nocc = nclosed
nel = h2.get_nel()
S,h,Ints = getints(bfs,h2)

orbe,orbs = geigh(h,S)

enuke = h2.get_enuke()
eold = 0

avg = DIIS(S)

for i in range(20):
    D = mkdens(orbs,0,nocc)
    G = get2JmK(Ints,D)
    F = h+G
    F = avg.getF(F,D)
    orbe,orbs = geigh(F,S)
    energy = get_energy(h,F,D,enuke)
    print i,energy,energy-eold
    if abs(energy-eold)<1e-5:
        break
    eold = energy
print "Converged"
print energy, "(benchmark = -1.122956)"
Esempio n. 7
0
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
Esempio n. 8
0
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
Esempio n. 9
0
    #get eigen values and vectors of transformed Fock matrix
    eVal, eVec = eigh(Fmo)

    #Section 9############################
    #transform eigen vectors back to AO basis to get C
    C = matrixmultiply(X, eVec)

    #Section 10############################
    #calculate a new density matrix from C
    D = HF.mkdens(C, 0, molecule.get_closedopen()[0])

    #Section 11############################
    #check convergence critera,
    #which for this particular program is checking
    #the delta energy of the system
    E = HF.get_energy(Hcore, F, D, molecule.get_enuke())

    #append to energy list
    energy.append(E)

    #increment cycle counter
    cycle += 1

    #if the change in energy from one iteration to the next
    #is less than the specfied convergence difference, then end SCF procedure
    if (abs(energy[cycle] - energy[cycle - 1]) <= convergenceLimit):
        break

#End of SCF procedure,
#print important information
print("Emergy: " + str(energy[cycle]) + " Hartrees")