Example #1
0
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
Example #2
0
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
Example #3
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
Example #4
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