Beispiel #1
0
def MP2(aoints,orbs,orbe,nclosed,nvirt):
    #moints = TransformInts(aoints,orbs)
    moints = TransformIntsMP2(aoints,orbs,nclosed)
    occs = range(nclosed)
    unoccs = range(nclosed,nclosed+nvirt)
    nocc = len(occs)

    Epairs = zeros((nocc,nocc),'d')

    Emp2 = 0
    for a in occs:
        for b in occs:
            for r in unoccs:
                for s in unoccs:
                    arbs = moints[ijkl2intindex(a,r,b,s)]
                    asbr = moints[ijkl2intindex(a,s,b,r)]
                    Epairs[a,b] += arbs*(2*arbs-asbr)/\
                                   (orbe[a]+orbe[b]-orbe[r]-orbe[s])
    if VERBOSE:
        print "MP2 pair energies"
        for a in range(nocc):
            for b in range(a):
                print a,b,Epairs[a,b]+Epairs[b,a]
            print a,a,Epairs[a,a]
    return sum(sum(Epairs))
Beispiel #2
0
def MP2(aoints, orbs, orbe, nclosed, nvirt):
    #moints = TransformInts(aoints,orbs)
    moints = TransformIntsMP2(aoints, orbs, nclosed)
    occs = range(nclosed)
    unoccs = range(nclosed, nclosed + nvirt)
    nocc = len(occs)

    Epairs = zeros((nocc, nocc), 'd')

    Emp2 = 0
    for a in occs:
        for b in occs:
            for r in unoccs:
                for s in unoccs:
                    arbs = moints[ijkl2intindex(a, r, b, s)]
                    asbr = moints[ijkl2intindex(a, s, b, r)]
                    Epairs[a,b] += arbs*(2*arbs-asbr)/\
                                   (orbe[a]+orbe[b]-orbe[r]-orbe[s])
    if VERBOSE:
        print "MP2 pair energies"
        for a in xrange(nocc):
            for b in xrange(a):
                print a, b, Epairs[a, b] + Epairs[b, a]
            print a, a, Epairs[a, a]
    return sum(sum(Epairs))
Beispiel #3
0
def derK(D, d2Ints_dXa, d2Ints_dYa, d2Ints_dZa):
    #modified from Ints.py -> getK
    "Form the exchange operator corresponding to a density matrix D"
    nbf = D.shape[0]
    D1d = reshape(D, (nbf * nbf, ))  #1D version of Dens
    dKx = zeros((nbf, nbf), 'd')
    dKy = zeros((nbf, nbf), 'd')
    dKz = zeros((nbf, nbf), 'd')
    for i in xrange(nbf):
        for j in xrange(i + 1):
            xtemp = zeros(nbf * nbf, 'd')
            ytemp = zeros(nbf * nbf, 'd')
            ztemp = zeros(nbf * nbf, 'd')
            kl = 0
            for k in xrange(nbf):
                for l in xrange(nbf):
                    index_k1 = ijkl2intindex(i, k, j, l)
                    index_k2 = ijkl2intindex(i, l, k, j)
                    xtemp[kl] = 0.5 * (d2Ints_dXa[index_k1] +
                                       d2Ints_dXa[index_k2])
                    ytemp[kl] = 0.5 * (d2Ints_dYa[index_k1] +
                                       d2Ints_dYa[index_k2])
                    ztemp[kl] = 0.5 * (d2Ints_dZa[index_k1] +
                                       d2Ints_dZa[index_k2])
                    kl += 1
            dKx[i, j] = dot(xtemp, D1d)
            dKx[j, i] = dKx[i, j]

            dKy[i, j] = dot(ytemp, D1d)
            dKy[j, i] = dKy[i, j]

            dKz[i, j] = dot(ztemp, D1d)
            dKz[j, i] = dKz[i, j]
    return dKx, dKy, dKz
Beispiel #4
0
def derK(D,d2Ints_dXa,d2Ints_dYa,d2Ints_dZa):
    #modified from Ints.py -> getK
    "Form the exchange operator corresponding to a density matrix D"
    nbf = D.shape[0]
    D1d = reshape(D,(nbf*nbf,)) #1D version of Dens
    dKx = zeros((nbf,nbf),'d')
    dKy = zeros((nbf,nbf),'d')
    dKz = zeros((nbf,nbf),'d')
    for i in xrange(nbf):
        for j in xrange(i+1):
            xtemp = zeros(nbf*nbf,'d')
            ytemp = zeros(nbf*nbf,'d')
            ztemp = zeros(nbf*nbf,'d')
            kl = 0
            for k in xrange(nbf):
                for l in xrange(nbf):
                    index_k1 = ijkl2intindex(i,k,j,l)
                    index_k2 = ijkl2intindex(i,l,k,j)
                    xtemp[kl] = 0.5*(d2Ints_dXa[index_k1]+d2Ints_dXa[index_k2])
                    ytemp[kl] = 0.5*(d2Ints_dYa[index_k1]+d2Ints_dYa[index_k2])
                    ztemp[kl] = 0.5*(d2Ints_dZa[index_k1]+d2Ints_dZa[index_k2])
                    kl += 1
            dKx[i,j] = dot(xtemp,D1d)
            dKx[j,i] = dKx[i,j]
            
            dKy[i,j] = dot(ytemp,D1d)
            dKy[j,i] = dKy[i,j]
            
            dKz[i,j] = dot(ztemp,D1d)
            dKz[j,i] = dKz[i,j]
    return dKx,dKy,dKz
Beispiel #5
0
def TransformInts(Ints,orbs):
    """O(N^5) 4-index transformation of the two-electron integrals. Not as
    efficient as it could be, since it inflates to the full rectangular
    matrices rather than keeping them compressed. But at least it gets the
    correct result."""

    from time import time

    t0 = time()

    nbf,nmo = orbs.shape
    totlen = nmo*(nmo+1)*(nmo*nmo+nmo+2)/8

    temp = zeros((nbf,nbf,nbf,nmo),'d')
    tempvec = zeros(nbf,'d')
    temp2 = zeros((nbf,nbf,nmo,nmo),'d')

    mos = range(nmo) # preform so we don't form inside loops
    bfs = range(nbf)

    # Start with (mu,nu|sigma,eta)
    # Unpack aoints and transform eta -> l
    for mu in bfs:
        for nu in bfs:
            for sigma in bfs:
                for l in mos:
                    for eta in bfs:
                        tempvec[eta] = Ints[ijkl2intindex(mu,nu,sigma,eta)]
                    temp[mu,nu,sigma,l] = dot(orbs[:,l],tempvec)

    # Transform sigma -> k
    for mu in bfs:
        for nu in bfs:
            for l in mos:
                for k in mos:
                    temp2[mu,nu,k,l] = dot(orbs[:,k],temp[mu,nu,:,l])

    # Transform nu -> j
    for mu in bfs:
        for k in mos:
            for l in mos:
                for j in mos:
                    temp[mu,j,k,l] = dot(orbs[:,j],temp2[mu,:,k,l])

    # Transform mu -> i and repack integrals:
    MOInts = zeros(totlen,'d')
    for i in mos:
        for j in xrange(i+1):
            ij = i*(i+1)/2+j
            for k in mos:
                for l in xrange(k+1):
                    kl = k*(k+1)/2+l
                    if ij >= kl:
                        ijkl = ijkl2intindex(i,j,k,l)
                        MOInts[ijkl] = dot(orbs[:,i],temp[:,j,k,l])

    del temp,temp2,tempvec #force garbage collection now
    return MOInts
Beispiel #6
0
def TransformInts(Ints, orbs):
    """O(N^5) 4-index transformation of the two-electron integrals. Not as
    efficient as it could be, since it inflates to the full rectangular
    matrices rather than keeping them compressed. But at least it gets the
    correct result."""

    from time import time

    t0 = time()

    nbf, nmo = orbs.shape
    totlen = nmo * (nmo + 1) * (nmo * nmo + nmo + 2) / 8

    temp = zeros((nbf, nbf, nbf, nmo), 'd')
    tempvec = zeros(nbf, 'd')
    temp2 = zeros((nbf, nbf, nmo, nmo), 'd')

    mos = range(nmo)  # preform so we don't form inside loops
    bfs = range(nbf)

    # Start with (mu,nu|sigma,eta)
    # Unpack aoints and transform eta -> l
    for mu in bfs:
        for nu in bfs:
            for sigma in bfs:
                for l in mos:
                    for eta in bfs:
                        tempvec[eta] = Ints[ijkl2intindex(mu, nu, sigma, eta)]
                    temp[mu, nu, sigma, l] = dot(orbs[:, l], tempvec)

    # Transform sigma -> k
    for mu in bfs:
        for nu in bfs:
            for l in mos:
                for k in mos:
                    temp2[mu, nu, k, l] = dot(orbs[:, k], temp[mu, nu, :, l])

    # Transform nu -> j
    for mu in bfs:
        for k in mos:
            for l in mos:
                for j in mos:
                    temp[mu, j, k, l] = dot(orbs[:, j], temp2[mu, :, k, l])

    # Transform mu -> i and repack integrals:
    MOInts = zeros(totlen, 'd')
    for i in mos:
        for j in xrange(i + 1):
            ij = i * (i + 1) / 2 + j
            for k in mos:
                for l in xrange(k + 1):
                    kl = k * (k + 1) / 2 + l
                    if ij >= kl:
                        ijkl = ijkl2intindex(i, j, k, l)
                        MOInts[ijkl] = dot(orbs[:, i], temp[:, j, k, l])

    del temp, temp2, tempvec  #force garbage collection now
    return MOInts
Beispiel #7
0
def TransformIntsMP2(Ints, orbs, nclosed):
    """\
    O(N^5) 4-index transformation of the two-electron integrals.
    Only transform the ones needed for MP2, which reduces the
    scaling to O(nN^4), where n are the occs (<<N).
    """

    from time import time

    t0 = time()

    nbf, nmo = orbs.shape
    totlen = nmo * (nmo + 1) * (nmo * nmo + nmo + 2) / 8

    occs = range(nclosed)
    mos = range(nmo)
    bfs = range(nbf)

    # Start with (mu,nu|sigma,eta)
    # Unpack aoints and transform sigma -> b
    temp = zeros((nbf, nbf, nclosed, nbf), 'd')
    tempvec = zeros(nbf, 'd')
    for mu in bfs:
        for nu in bfs:
            for eta in bfs:
                for b in occs:
                    for sigma in bfs:
                        tempvec[sigma] = Ints[ijkl2intindex(
                            mu, nu, sigma, eta)]
                    temp[mu, nu, b, eta] = dot(orbs[:, b], tempvec)

    temp2 = zeros((nclosed, nbf, nclosed, nbf), 'd')
    for nu in bfs:
        for eta in bfs:
            for b in occs:
                for a in occs:
                    temp2[a, nu, b, eta] = dot(orbs[:, a], temp[:, nu, b, eta])

    temp = zeros((nclosed, nbf, nclosed, nmo), 'd')
    for a in occs:
        for nu in bfs:
            for b in occs:
                for j in mos:
                    temp[a, nu, b, j] = dot(orbs[:, j], temp2[a, nu, b, :])

    # Transform mu -> i and repack integrals:
    MOInts = zeros(totlen, 'd')
    for a in occs:
        for j in mos:
            for b in occs:
                for i in mos:
                    aibj = ijkl2intindex(a, i, b, j)
                    MOInts[aibj] = dot(orbs[:, i], temp[a, :, b, j])

    #print "Integral transform time = ",time()-t0
    del temp, temp2, tempvec  #force garbage collection now
    return MOInts
Beispiel #8
0
def TransformIntsMP2(Ints,orbs,nclosed):
    """\
    O(N^5) 4-index transformation of the two-electron integrals.
    Only transform the ones needed for MP2, which reduces the
    scaling to O(nN^4), where n are the occs (<<N).
    """

    from time import time

    t0 = time()

    nbf,nmo = orbs.shape
    totlen = nmo*(nmo+1)*(nmo*nmo+nmo+2)/8

    occs = range(nclosed)
    mos = range(nmo)
    bfs = range(nbf)

    # Start with (mu,nu|sigma,eta)
    # Unpack aoints and transform sigma -> b
    temp = zeros((nbf,nbf,nclosed,nbf),'d')
    tempvec = zeros(nbf,'d')
    for mu in bfs:
        for nu in bfs:
            for eta in bfs:
                for b in occs:
                    for sigma in bfs:
                        tempvec[sigma] = Ints[ijkl2intindex(mu,nu,sigma,eta)]
                    temp[mu,nu,b,eta] = dot(orbs[:,b],tempvec)

    temp2 = zeros((nclosed,nbf,nclosed,nbf),'d')
    for nu in bfs:
        for eta in bfs:
            for b in occs:
                for a in occs:
                    temp2[a,nu,b,eta] = dot(orbs[:,a],temp[:,nu,b,eta])

    temp = zeros((nclosed,nbf,nclosed,nmo),'d')
    for a in occs:
        for nu in bfs:
            for b in occs:
                for j in mos:
                    temp[a,nu,b,j] = dot(orbs[:,j],temp2[a,nu,b,:])

    # Transform mu -> i and repack integrals:
    MOInts = zeros(totlen,'d')
    for a in occs:
        for j in mos:
            for b in occs:
                for i in mos:
                    aibj = ijkl2intindex(a,i,b,j)
                    MOInts[aibj] = dot(orbs[:,i],temp[a,:,b,j])

    #print "Integral transform time = ",time()-t0
    del temp,temp2,tempvec #force garbage collection now
    return MOInts
Beispiel #9
0
def TransformInts(Ints, orbs1, orbs2, nocc):

    nbf, nmo = orbs1.shape
    totlen = nmo * nmo * nmo * nmo

    occs = range(nocc)
    mos = range(nmo)
    bfs = range(nbf)

    # Start with (mu,nu|sigma,eta)
    # Unpack aoints and transform sigma -> b
    # Here sigma, b, nu, j are of first same spin group,
    #  others of second same spin group
    temp = zeros((nbf, nbf, nbf, nbf), 'd')
    tempvec = zeros(nbf, 'd')
    for mu in bfs:
        for nu in bfs:
            for eta in bfs:
                for b in bfs:
                    for sigma in bfs:
                        tempvec[sigma] = Ints[ijkl2intindex(
                            mu, nu, sigma, eta)]
                    temp[mu, nu, b, eta] = dot(orbs1[b, :], tempvec)

    temp2 = zeros((nbf, nbf, nbf, nbf), 'd')
    for nu in bfs:
        for eta in bfs:
            for b in bfs:
                for a in bfs:
                    temp2[a, nu, b, eta] = dot(orbs2[a, :], temp[:, nu, b,
                                                                 eta])

    temp = zeros((nbf, nbf, nbf, nbf), 'd')
    for a in bfs:
        for nu in bfs:
            for b in bfs:
                for j in bfs:
                    temp[a, nu, b, j] = dot(orbs1[j, :], temp2[a, nu, b, :])

    # Transform mu -> i and repack integrals:
    MOInts = zeros(totlen, 'd')
    for a in bfs:
        for j in bfs:
            for b in bfs:
                for i in bfs:
                    aibj = ijkl2intindex(a, i, b, j)
                    MOInts[aibj] = dot(orbs2[i, :], temp[a, :, b, j])

    del temp, temp2, tempvec  #force garbage collection now
    return MOInts, nbf
Beispiel #10
0
def TransformInts(Ints,orbs1,orbs2, nocc):

    nbf,nmo = orbs1.shape
    totlen = nmo*nmo*nmo*nmo

    occs = range(nocc)
    mos = range(nmo)
    bfs = range(nbf)

    # Start with (mu,nu|sigma,eta)
    # Unpack aoints and transform sigma -> b
    # Here sigma, b, nu, j are of first same spin group,
    #  others of second same spin group
    temp = zeros((nbf,nbf,nbf,nbf),'d')
    tempvec = zeros(nbf,'d')
    for mu in bfs:
        for nu in bfs:
            for eta in bfs:
                for b in bfs:
                    for sigma in bfs:
                        tempvec[sigma] = Ints[ijkl2intindex(mu,nu,sigma,eta)]
                    temp[mu,nu,b,eta] = dot(orbs1[b,:],tempvec)

    temp2 = zeros((nbf,nbf,nbf,nbf),'d')
    for nu in bfs:
        for eta in bfs:
            for b in bfs:
                for a in bfs:
                    temp2[a,nu,b,eta] = dot(orbs2[a,:],temp[:,nu,b,eta])

    temp = zeros((nbf,nbf,nbf,nbf),'d')
    for a in bfs:
        for nu in bfs:
            for b in bfs:
                for j in bfs:
                    temp[a,nu,b,j] = dot(orbs1[j,:],temp2[a,nu,b,:])

    # Transform mu -> i and repack integrals:
    MOInts = zeros(totlen,'d')
    for a in bfs:
        for j in bfs:
            for b in bfs:
                for i in bfs:
                    aibj = ijkl2intindex(a,i,b,j)
                    MOInts[aibj] = dot(orbs2[i,:],temp[a,:,b,j])

    del temp,temp2,tempvec #force garbage collection now
    return MOInts, nbf
Beispiel #11
0
def derJ(D, d2Ints_dXa, d2Ints_dYa, d2Ints_dZa):
    #modified from Ints.py -> getJ
    "Form the Coulomb operator corresponding to a density matrix D"
    nbf = D.shape[0]
    D1d = reshape(D, (nbf * nbf, ))  #1D version of Dens
    dJx = zeros((nbf, nbf), 'd')
    dJy = zeros((nbf, nbf), 'd')
    dJz = zeros((nbf, nbf), 'd')

    for i in xrange(nbf):
        for j in xrange(i + 1):
            xtemp = zeros(nbf * nbf, 'd')
            ytemp = zeros(nbf * nbf, 'd')
            ztemp = zeros(nbf * nbf, 'd')
            kl = 0
            for k in xrange(nbf):
                for l in xrange(nbf):
                    index = ijkl2intindex(i, j, k, l)
                    xtemp[kl] = d2Ints_dXa[index]
                    ytemp[kl] = d2Ints_dYa[index]
                    ztemp[kl] = d2Ints_dZa[index]
                    kl += 1
            dJx[i, j] = dot(xtemp, D1d)
            dJx[j, i] = dJx[i, j]

            dJy[i, j] = dot(ytemp, D1d)
            dJy[j, i] = dJy[i, j]

            dJz[i, j] = dot(ztemp, D1d)
            dJz[j, i] = dJz[i, j]
    return dJx, dJy, dJz
Beispiel #12
0
def derJ(D,d2Ints_dXa,d2Ints_dYa,d2Ints_dZa):
    #modified from Ints.py -> getJ
    "Form the Coulomb operator corresponding to a density matrix D"
    nbf = D.shape[0]
    D1d = reshape(D,(nbf*nbf,)) #1D version of Dens
    dJx = zeros((nbf,nbf),'d')
    dJy = zeros((nbf,nbf),'d')
    dJz = zeros((nbf,nbf),'d')

    for i in xrange(nbf):
        for j in xrange(i+1):
            xtemp = zeros(nbf*nbf,'d')
            ytemp = zeros(nbf*nbf,'d')
            ztemp = zeros(nbf*nbf,'d')
            kl = 0
            for k in xrange(nbf):
                for l in xrange(nbf):
                    index = ijkl2intindex(i,j,k,l)
                    xtemp[kl] = d2Ints_dXa[index]
                    ytemp[kl] = d2Ints_dYa[index]
                    ztemp[kl] = d2Ints_dZa[index]
                    kl += 1
            dJx[i,j] = dot(xtemp,D1d)
            dJx[j,i] = dJx[i,j]
            
            dJy[i,j] = dot(ytemp,D1d)
            dJy[j,i] = dJy[i,j]
            
            dJz[i,j] = dot(ztemp,D1d)
            dJz[j,i] = dJz[i,j]
    return dJx,dJy,dJz
Beispiel #13
0
 def eval0(self, i, E):
     # just do the simple approximation, S/A eqs 7.44-7.46
     term = 0.
     occs = range(self.nocc)
     virts = range(self.nocc, self.norb)
     for a in occs:
         for r in virts:
             for s in virts:
                 iras = self.moints[ijkl2intindex(i, r, a, s)]
                 isar = self.moints[ijkl2intindex(i, s, a, r)]
                 term += iras * (2 * iras - isar) / (
                     E + self.e0[a] - self.e0[r] - self.e0[s])
     for a in occs:
         for b in occs:
             for r in virts:
                 iabr = self.moints[ijkl2intindex(i, a, b, r)]
                 ibar = self.moints[ijkl2intindex(i, b, a, r)]
                 term += iabr * (2 * iabr - ibar) / (
                     E + self.e0[r] - self.e0[a] - self.e0[b])
     return term
Beispiel #14
0
 def eval0(self,i,E):
     # just do the simple approximation, S/A eqs 7.44-7.46
     term = 0.
     occs = range(self.nocc)
     virts = range(self.nocc,self.norb)
     for a in occs:
         for r in virts:
             for s in virts:
                 iras = self.moints[ijkl2intindex(i,r,a,s)]
                 isar = self.moints[ijkl2intindex(i,s,a,r)]
                 term += iras*(2*iras-isar)/(
                     E+self.e0[a]-self.e0[r]-self.e0[s])
     for a in occs:
         for b in occs:
             for r in virts:
                 iabr = self.moints[ijkl2intindex(i,a,b,r)]
                 ibar = self.moints[ijkl2intindex(i,b,a,r)]
                 term += iabr*(2*iabr-ibar)/(
                     E+self.e0[r]-self.e0[a]-self.e0[b])
     return term
Beispiel #15
0
def der2JmK(D,d2Ints_dXa,d2Ints_dYa,d2Ints_dZa):
    #modified from Ints.py -> get2Jmk
    "Form the 2J-K integrals corresponding to a density matrix D"
    nbf = D.shape[0]
    D1d = reshape(D,(nbf*nbf,)) #1D version of Dens
    Gx = zeros((nbf,nbf),'d')
    Gy = zeros((nbf,nbf),'d')
    Gz = zeros((nbf,nbf),'d')
    
    for i in xrange(nbf):
        for j in xrange(i+1):
            xtemp = zeros(nbf*nbf,'d')
            ytemp = zeros(nbf*nbf,'d')
            ztemp = zeros(nbf*nbf,'d')
            kl = 0
            for k in xrange(nbf):
                for l in xrange(nbf):
                    index_j = ijkl2intindex(i,j,k,l)
                    index_k1 = ijkl2intindex(i,k,j,l)
                    index_k2 = ijkl2intindex(i,l,k,j)
                    xtemp[kl] = 2.*d2Ints_dXa[index_j]-0.5*d2Ints_dXa[index_k1]\
                               -0.5*d2Ints_dXa[index_k2]
                               
                    ytemp[kl] = 2.*d2Ints_dYa[index_j]-0.5*d2Ints_dYa[index_k1]\
                               -0.5*d2Ints_dYa[index_k2]
                               
                    ztemp[kl] = 2.*d2Ints_dZa[index_j]-0.5*d2Ints_dZa[index_k1]\
                               -0.5*d2Ints_dZa[index_k2]                    
                    kl += 1

            Gx[i,j] = dot(xtemp,D1d)
            Gx[j,i] = Gx[i,j]
            
            Gy[i,j] = dot(ytemp,D1d)
            Gy[j,i] = Gy[i,j]            
            
            Gz[i,j] = dot(ztemp,D1d)
            Gz[j,i] = Gz[i,j]

    return Gx,Gy,Gz
Beispiel #16
0
 def fulleval(self,E):
     # This routine doesn't work very well.
     g = zeros((self.norb,self.norb),'d')
     orbs = range(self.norb)
     occs = range(self.nocc)
     virts = range(self.nocc,self.norb)
     term = 0.
     for i in orbs:
         for j in orbs:
             for a in occs:
                 for r in virts:
                     for s in virts:
                         iras = self.moints[ijkl2intindex(i,r,a,s)]
                         jras = self.moints[ijkl2intindex(j,r,a,s)]
                         jsar = self.moints[ijkl2intindex(j,s,a,r)]
                         term += iras*(2*jras-jsar)/(
                             E+self.e0[a]-self.e0[r]-self.e0[s])
             for a in occs:
                 for b in occs:
                     for r in virts:
                         iabr = self.moints[ijkl2intindex(i,a,b,r)]
                         jabr = self.moints[ijkl2intindex(j,a,b,r)]
                         jbar = self.moints[ijkl2intindex(j,b,a,r)]
                         term += iabr*(2*jabr-jbar)/(
                             E+self.e0[r]-self.e0[a]-self.e0[b])
             g[i,j] = -term
     for i in orbs:
         g[i,i] += E - self.e0[i]
     return det(g)
Beispiel #17
0
 def fulleval(self, E):
     # This routine doesn't work very well.
     g = zeros((self.norb, self.norb), 'd')
     orbs = range(self.norb)
     occs = range(self.nocc)
     virts = range(self.nocc, self.norb)
     term = 0.
     for i in orbs:
         for j in orbs:
             for a in occs:
                 for r in virts:
                     for s in virts:
                         iras = self.moints[ijkl2intindex(i, r, a, s)]
                         jras = self.moints[ijkl2intindex(j, r, a, s)]
                         jsar = self.moints[ijkl2intindex(j, s, a, r)]
                         term += iras * (2 * jras - jsar) / (
                             E + self.e0[a] - self.e0[r] - self.e0[s])
             for a in occs:
                 for b in occs:
                     for r in virts:
                         iabr = self.moints[ijkl2intindex(i, a, b, r)]
                         jabr = self.moints[ijkl2intindex(j, a, b, r)]
                         jbar = self.moints[ijkl2intindex(j, b, a, r)]
                         term += iabr * (2 * jabr - jbar) / (
                             E + self.e0[r] - self.e0[a] - self.e0[b])
             g[i, j] = -term
     for i in orbs:
         g[i, i] += E - self.e0[i]
     return det(g)
Beispiel #18
0
def der2JmK(D, d2Ints_dXa, d2Ints_dYa, d2Ints_dZa):
    #modified from Ints.py -> get2Jmk
    "Form the 2J-K integrals corresponding to a density matrix D"
    nbf = D.shape[0]
    D1d = reshape(D, (nbf * nbf, ))  #1D version of Dens
    Gx = zeros((nbf, nbf), 'd')
    Gy = zeros((nbf, nbf), 'd')
    Gz = zeros((nbf, nbf), 'd')

    for i in xrange(nbf):
        for j in xrange(i + 1):
            xtemp = zeros(nbf * nbf, 'd')
            ytemp = zeros(nbf * nbf, 'd')
            ztemp = zeros(nbf * nbf, 'd')
            kl = 0
            for k in xrange(nbf):
                for l in xrange(nbf):
                    index_j = ijkl2intindex(i, j, k, l)
                    index_k1 = ijkl2intindex(i, k, j, l)
                    index_k2 = ijkl2intindex(i, l, k, j)
                    xtemp[kl] = 2.*d2Ints_dXa[index_j]-0.5*d2Ints_dXa[index_k1]\
                               -0.5*d2Ints_dXa[index_k2]

                    ytemp[kl] = 2.*d2Ints_dYa[index_j]-0.5*d2Ints_dYa[index_k1]\
                               -0.5*d2Ints_dYa[index_k2]

                    ztemp[kl] = 2.*d2Ints_dZa[index_j]-0.5*d2Ints_dZa[index_k1]\
                               -0.5*d2Ints_dZa[index_k2]
                    kl += 1

            Gx[i, j] = dot(xtemp, D1d)
            Gx[j, i] = Gx[i, j]

            Gy[i, j] = dot(ytemp, D1d)
            Gy[j, i] = Gy[i, j]

            Gz[i, j] = dot(ztemp, D1d)
            Gz[j, i] = Gz[i, j]

    return Gx, Gy, Gz
Beispiel #19
0
def CISDMatrix(Ints,orbs,Ehf,orbe,occs):
    nocc, nvirt = get_occ_unocc(occs)
    singles = SingleExcitations(range(nocc),range(nocc,nocc+nvirt))
    #doubles = DoubleExcitations(range(nocc),range(nocc,nocc+nvirt))
    doubles = []
    nsin = len(singles)
    ndoub = len(doubles)
    nex = nsin+ndoub
    
    MOInts = TransformInts(Ints,orbs)

    # see Szabo/Ostlund Table 4.1
    CIMatrix = zeros((nex,nex),'d')
    for ar in xrange(nsin):
        a,r = singles[ar]
        for bs in xrange(nsin):
            b,s = singles[bs]
            rabs = ijkl2intindex(r,a,b,s)
            rsba = ijkl2intindex(r,s,b,a)
            CIMatrix[ar,bs] = 2*MOInts[rabs] - MOInts[rsba]
            if r==s and a==b: CIMatrix[ar,bs] += Ehf+orbe[r]-orbe[a]
            CIMatrix[bs,ar] = CIMatrix[ar,bs]
    return CIMatrix
Beispiel #20
0
def CISDMatrix(Ints, orbs, Ehf, orbe, occs):
    nocc, nvirt = get_occ_unocc(occs)
    singles = SingleExcitations(range(nocc), range(nocc, nocc + nvirt))
    #doubles = DoubleExcitations(range(nocc),range(nocc,nocc+nvirt))
    doubles = []
    nsin = len(singles)
    ndoub = len(doubles)
    nex = nsin + ndoub

    MOInts = TransformInts(Ints, orbs)

    # see Szabo/Ostlund Table 4.1
    CIMatrix = zeros((nex, nex), 'd')
    for ar in xrange(nsin):
        a, r = singles[ar]
        for bs in xrange(nsin):
            b, s = singles[bs]
            rabs = ijkl2intindex(r, a, b, s)
            rsba = ijkl2intindex(r, s, b, a)
            CIMatrix[ar, bs] = 2 * MOInts[rabs] - MOInts[rsba]
            if r == s and a == b: CIMatrix[ar, bs] += Ehf + orbe[r] - orbe[a]
            CIMatrix[bs, ar] = CIMatrix[ar, bs]
    return CIMatrix
Beispiel #21
0
def CISMatrix(Ints, orbs, Ehf, orbe, nocc, nvirt):
    "Naive implementation: Int xfrm + slow formation"
    # The best reference for this stuff is Chap 4 of Szabo/Ostlund

    # Generate the list, and the number of excitations:
    singles = SingleExcitations(range(nocc), range(nocc, nocc + nvirt))
    nex = len(singles)

    # Do the four-index transformation of the 2e ints. This is expensive!
    MOInts = TransformInts(Ints, orbs)

    # Build the CI matrix using the Slater Condon rules
    # see Szabo/Ostlund Table 4.1
    CIMatrix = zeros((nex, nex), 'd')
    for ar in xrange(nex):
        a, r = singles[ar]
        for bs in xrange(nex):
            b, s = singles[bs]
            rabs = ijkl2intindex(r, a, b, s)
            rsba = ijkl2intindex(r, s, b, a)
            CIMatrix[ar, bs] = 2 * MOInts[rabs] - MOInts[rsba]
            if r == s and a == b: CIMatrix[ar, bs] += Ehf + orbe[r] - orbe[a]
            CIMatrix[bs, ar] = CIMatrix[ar, bs]
    return CIMatrix
Beispiel #22
0
def CISMatrix(Ints,orbs,Ehf,orbe,nocc,nvirt):
    "Naive implementation: Int xfrm + slow formation"
    # The best reference for this stuff is Chap 4 of Szabo/Ostlund

    # Generate the list, and the number of excitations:
    singles = SingleExcitations(range(nocc),range(nocc,nocc+nvirt))
    nex = len(singles)

    # Do the four-index transformation of the 2e ints. This is expensive!
    MOInts = TransformInts(Ints,orbs)

    # Build the CI matrix using the Slater Condon rules
    # see Szabo/Ostlund Table 4.1
    CIMatrix = zeros((nex,nex),'d')
    for ar in xrange(nex):
        a,r = singles[ar]
        for bs in xrange(nex):
            b,s = singles[bs]
            rabs = ijkl2intindex(r,a,b,s)
            rsba = ijkl2intindex(r,s,b,a)
            CIMatrix[ar,bs] = 2*MOInts[rabs] - MOInts[rsba]
            if r==s and a==b: CIMatrix[ar,bs] += Ehf+orbe[r]-orbe[a]
            CIMatrix[bs,ar] = CIMatrix[ar,bs]
    return CIMatrix
Beispiel #23
0
    def get_k_mat(self):
        """ build k_pq from (11.8.8) """
        try: self.h_mat
        except: self.h_mat = transform_one_ints(self.h,self.orbs)
        try: self.MOInts
        except: self.MOInts = TransformInts(self.ERI,self.orbs)
        # except: self.MOInts = TransformInts_test(self.ERI,self.orbs)

        self.k_mat = np.zeros((self.n_orbs,self.n_orbs))
        for p,q in self.singles:
            for r in xrange(self.n_orbs):
                self.k_mat[p,q] -= 0.5*self.MOInts[ijkl2intindex(p,r,r,q)]
                # self.k_mat[p,q] -= 0.5*self.MOInts[p,r,r,q]
            self.k_mat[p,q] += self.h_mat[p,q]

        print "build of k_mat successful"    
Beispiel #24
0
    def get_k_mat(self):
        """ build k_pq from (11.8.8) """
        try: self.h_mat
        except: self.h_mat = transform_one_ints(self.h,self.orbs)
        try: self.MOInts
        except: self.MOInts = TransformInts(self.ERI,self.orbs)
        # except: self.MOInts = TransformInts_test(self.ERI,self.orbs)

        self.k_mat = np.zeros((self.n_orbs,self.n_orbs))
        for p,q in self.singles:
            for r in xrange(self.n_orbs):
                self.k_mat[p,q] -= 0.5*self.MOInts[ijkl2intindex(p,r,r,q)]
                # self.k_mat[p,q] -= 0.5*self.MOInts[p,r,r,q]
            self.k_mat[p,q] += self.h_mat[p,q]

        print "build of k_mat successful"    
Beispiel #25
0
def get2ints(bfs,coul_func):
    """Store integrals in a long array in the form (ij|kl) (chemists
    notation. We only need i>=j, k>=l, and ij <= kl"""
    from array import array
    nbf = len(bfs)
    totlen = nbf*(nbf+1)*(nbf*nbf+nbf+2)/8
    Ints = array('d',[0]*totlen)
    for i in range(nbf):
        for j in range(i+1):
            ij = i*(i+1)/2+j
            for k in range(nbf):
                for l in range(k+1):
                    kl = k*(k+1)/2+l
                    if ij >= kl:
                        ijkl = ijkl2intindex(i,j,k,l)
                        Ints[ijkl] = coulomb(bfs[i],bfs[j],bfs[k],bfs[l],
                                             coul_func)
    return Ints
Beispiel #26
0
def get2ints(bfs, coul_func):
    """Store integrals in a long array in the form (ij|kl) (chemists
    notation. We only need i>=j, k>=l, and ij <= kl"""
    from array import array
    nbf = len(bfs)
    totlen = nbf * (nbf + 1) * (nbf * nbf + nbf + 2) / 8
    Ints = array('d', [0] * totlen)
    for i in range(nbf):
        for j in range(i + 1):
            ij = i * (i + 1) / 2 + j
            for k in range(nbf):
                for l in range(k + 1):
                    kl = k * (k + 1) / 2 + l
                    if ij >= kl:
                        ijkl = ijkl2intindex(i, j, k, l)
                        Ints[ijkl] = coulomb(bfs[i], bfs[j], bfs[k], bfs[l],
                                             coul_func)
    return Ints
Beispiel #27
0
    def get_G_beta_ib_jb_pq(self, p, q):
        """ (11.8.42) """

        row_index = []
        column_index = []
        data = []

        for ib_string in self.BetaStrings.occupations:
            """
            """
            for jb_string in self.BetaStrings.occupations:

                row = self.BetaStrings.address(ib_string)
                column = self.BetaStrings.address(jb_string)
                elem = 0

                for r, s in self.singles:
                    """ loop over excitations """

                    # apply excitation operator on string:
                    phase, e_rs_jb = e_pq_on_string(r, s, jb_string)
                    if e_rs_jb == 0:
                        """ tried to annihilate vaccum or to create
                        doubly """
                        continue

                    if row != self.BetaStrings.address(e_rs_jb):
                        """ strings differed by more than the pair p q """
                        continue
                    else:
                        elem += phase * self.MOInts[ijkl2intindex(p, q, r, s)]
                        # elem += phase*self.MOInts[p,q,r,s]

                if abs(elem) > 1e-14:
                    row_index.append(row)
                    column_index.append(column)
                    data.append(elem)

        return spspa.csr_matrix(
            (np.array(data), (np.array(row_index), np.array(column_index))),
            shape=(len(self.BetaStrings.occupations),
                   len(self.BetaStrings.occupations)))
Beispiel #28
0
def der2Ints(a,bset):
    #modified from Ints.py -> get2ints
    """Store integrals in a long array in the form (ij|kl) (chemists
    notation. We only need i>=j, k>=l, and ij <= kl"""
    from array import array
    nbf = len(bset)
    totlen = nbf*(nbf+1)*(nbf*nbf+nbf+2)/8
    d2Ints_dXa = array('d',[0]*totlen)
    d2Ints_dYa = array('d',[0]*totlen)
    d2Ints_dZa = array('d',[0]*totlen)
    for i in xrange(nbf):
        for j in xrange(i+1):
            ij = i*(i+1)/2+j
            for k in xrange(nbf):
                for l in xrange(k+1):
                    kl = k*(k+1)/2+l
                    if ij >= kl:
                        ijkl = ijkl2intindex(i,j,k,l)
                        d2Ints_dXa[ijkl],d2Ints_dYa[ijkl],d2Ints_dZa[ijkl] =\
                                 der_Jints(a,bset[i],bset[j],bset[k],bset[l])
    return d2Ints_dXa,d2Ints_dYa,d2Ints_dZa
Beispiel #29
0
def der2Ints(a, bset):
    #modified from Ints.py -> get2ints
    """Store integrals in a long array in the form (ij|kl) (chemists
    notation. We only need i>=j, k>=l, and ij <= kl"""
    from array import array
    nbf = len(bset)
    totlen = nbf * (nbf + 1) * (nbf * nbf + nbf + 2) / 8
    d2Ints_dXa = array('d', [0] * totlen)
    d2Ints_dYa = array('d', [0] * totlen)
    d2Ints_dZa = array('d', [0] * totlen)
    for i in xrange(nbf):
        for j in xrange(i + 1):
            ij = i * (i + 1) / 2 + j
            for k in xrange(nbf):
                for l in xrange(k + 1):
                    kl = k * (k + 1) / 2 + l
                    if ij >= kl:
                        ijkl = ijkl2intindex(i, j, k, l)
                        d2Ints_dXa[ijkl],d2Ints_dYa[ijkl],d2Ints_dZa[ijkl] =\
                                 der_Jints(a,bset[i],bset[j],bset[k],bset[l])
    return d2Ints_dXa, d2Ints_dYa, d2Ints_dZa
Beispiel #30
0
    def get_G_beta_ib_jb_pq(self,p,q):
        """ (11.8.42) """

        row_index=[]
        column_index=[]
        data=[]

        
        for ib_string in self.BetaStrings.occupations:
            """
            """
            for jb_string in self.BetaStrings.occupations:
                
                row = self.BetaStrings.address(ib_string)
                column = self.BetaStrings.address(jb_string)
                elem = 0

                for r,s in self.singles:
                    """ loop over excitations """
    
                    # apply excitation operator on string:
                    phase, e_rs_jb = e_pq_on_string(r,s,jb_string)
                    if e_rs_jb == 0:
                        """ tried to annihilate vaccum or to create
                        doubly """
                        continue
                
                    if row != self.BetaStrings.address(e_rs_jb):
                        """ strings differed by more than the pair p q """
                        continue
                    else:
                        elem += phase*self.MOInts[ijkl2intindex(p,q,r,s)]
                        # elem += phase*self.MOInts[p,q,r,s]

                if abs(elem) > 1e-14:
                    row_index.append(row)
                    column_index.append(column)
                    data.append(elem)
                
        return spspa.csr_matrix( (np.array(data),(np.array(row_index),np.array(column_index))), shape=(len(self.BetaStrings.occupations),len(self.BetaStrings.occupations)) )
Beispiel #31
0
    def get_G_gamma(self, alpha_beta):
        """ get G_sigma matrices (11.8.33/34) 
        gamma is alpha or beta.

        It is sparse! Hence is it constructed solely from the non-zero
        elements. 
        """

        try: self.MOInts
        except: self.MOInts = TransformInts(self.ERI,self.orbs)
        # except: self.MOInts = TransformInts_test(self.ERI,self.orbs)

            
        if alpha_beta == "alpha":
            Strings = self.AlphaStrings
        elif alpha_beta == "beta":
            Strings = self.BetaStrings
        else:
            raise ValueError, 'argument alpha_beta must be alpha or beta'

        row_index = []
        column_index = []
        data = []
        
        for i_string in Strings.occupations:
            for j_string in Strings.occupations:
                
                row = Strings.address(i_string)
                column = Strings.address(j_string)
                
                elem = 0

                for p,q,r,s in self.doubles:
                    """ loop over excitations """
                    
                    # apply excitation E_rs operator on string:
                    phase_rs, e_rs_j = e_pq_on_string(r,s,j_string)
                    if e_rs_j == 0:
                        """ tried to annihilate vaccum or to create
                        doubly """
                        continue

                    # apply excitation E_pq operator on string:
                    phase_pq, e_pqrs_j = e_pq_on_string(p,q,e_rs_j)
                    if e_pqrs_j == 0:
                        """ tried to annihilate vaccum or to create
                        doubly """
                        continue
                    
                    if row != Strings.address(e_pqrs_j):
                        """ strings differed by more than two pairs p q r s """
                        continue
                    else:
                        elem += 0.5 *phase_pq *phase_rs *self.MOInts[ijkl2intindex(p,q,r,s)]
                        # elem += 0.5 *phase_pq *phase_rs *self.MOInts[p,q,r,s]

                        ### Need to think when can exit the loop. For sure if p!=q!=r!=s
                        # if p!=q and q!=r and r!=s:
                        #     """ there will not be another pqrs that
                        #     satisfies, exit pqrs loop """
                        #     row_index.append(row)
                        #     column_index.append(column)
                        #     data.append(elem)
                        #     break

                if abs(elem) > 1e-14:
                    row_index.append(row)
                    column_index.append(column)
                    data.append(elem)

        return spspa.csr_matrix( (np.array(data),(np.array(row_index),np.array(column_index))), shape=(len(Strings.occupations),len(Strings.occupations)) )
Beispiel #32
0
def EN2(molecule,**opts):#
    "General wrapper for the simple CI method"
    nalpha,nbeta = molecule.get_alphabeta()
    bfs = getbasis(molecule)
    S,h,Ints = getints(bfs,molecule)
    energy,(orbea,orbeb),(orbsa,orbsb) = uhf(molecule,integrals=(S,h,Ints),
                                             bfs=bfs,**opts)
    EHF = energy
    print "The Hatree-Fock energy is ",EHF
    #compute the transformed molecular orbital integrals

    aamoints, nbf = TransformInts(Ints,orbsa,orbsa, nalpha)
    bbmoints, nbf = TransformInts(Ints,orbsb,orbsb, nbeta)
    abmoints, nbf = TransformInts(Ints,orbsa,orbsb, nalpha)
    
    #Initialize the fractional occupations:
    Yalpha = zeros((nbf),'d')
    Ybeta = zeros((nbf),'d')

    #set up the occupied and virtual orbitals
    aoccs = range(nalpha)
    boccs = range(nbeta)
    avirt = range(nalpha,nbf) #numbers of alpha virtual orbitals
    bvirt = range(nbeta,nbf) #numbers of beta virtual orbitals

    ########  Computation of the primary energy correction  ######### 
    #Set initial correction terms to zero
    Ec1 = 0.
    sum = 0.
    z = 1.
   
    #compute correction term for two alpha electrons

    for a in aoccs:
        for b in xrange(a):
            for r in avirt:
                for s in xrange(nalpha,r):
                    arbs = aamoints[ijkl2intindex(a,r,b,s)]
                    asbr = aamoints[ijkl2intindex(a,s,b,r)]
                    rraa = aamoints[ijkl2intindex(r,r,a,a)] - \
                           aamoints[ijkl2intindex(r,a,a,r)]
                    rrbb = aamoints[ijkl2intindex(r,r,b,b)] - \
                           aamoints[ijkl2intindex(r,b,b,r)]
                    ssaa = aamoints[ijkl2intindex(s,s,a,a)] - \
                           aamoints[ijkl2intindex(s,a,a,s)]
                    ssbb = aamoints[ijkl2intindex(s,s,b,b)] - \
                           aamoints[ijkl2intindex(s,b,b,s)]
                    rrss = aamoints[ijkl2intindex(r,r,s,s)] - \
                           aamoints[ijkl2intindex(r,s,s,r)]
                    aabb = aamoints[ijkl2intindex(a,a,b,b)] - \
                           aamoints[ijkl2intindex(a,b,b,a)]

                    eigendif = (orbea[r] + orbea[s] - orbea[a] - orbea[b])
                    delcorr = (-rraa - rrbb - ssaa - ssbb + rrss + aabb) 
                    delta = eigendif + delcorr*z

                    Eio = (arbs - asbr)

                    x = -Eio/delta
                    if abs(x) > 1:
                        print "Warning a large x value has been ",\
                              "discovered with x = ",x
                    x = choose(x < 1, (1,x))
                    x = choose(x > -1, (-1,x))                   
                    sum += x*x
                    Yalpha[a] -= x*x
                    Yalpha[b] -= x*x
                    Yalpha[r] += x*x
                    Yalpha[s] += x*x
                    Ec1 += x*Eio             


    #compute correction term for two beta electrons

    for a in boccs:
        for b in xrange(a):
            for r in bvirt:
                for s in xrange(nbeta,r):
                    arbs = bbmoints[ijkl2intindex(a,r,b,s)]
                    asbr = bbmoints[ijkl2intindex(a,s,b,r)]
                    rraa = bbmoints[ijkl2intindex(r,r,a,a)] - \
                           bbmoints[ijkl2intindex(r,a,a,r)]
                    rrbb = bbmoints[ijkl2intindex(r,r,b,b)] - \
                           bbmoints[ijkl2intindex(r,b,b,r)]
                    ssaa = bbmoints[ijkl2intindex(s,s,a,a)] - \
                           bbmoints[ijkl2intindex(s,a,a,s)]
                    ssbb = bbmoints[ijkl2intindex(s,s,b,b)] - \
                           bbmoints[ijkl2intindex(s,b,b,s)]
                    rrss = bbmoints[ijkl2intindex(r,r,s,s)] - \
                           bbmoints[ijkl2intindex(r,s,s,r)]
                    aabb = bbmoints[ijkl2intindex(a,a,b,b)] - \
                           bbmoints[ijkl2intindex(a,b,b,a)]


                    eigendif = (orbeb[r] + orbeb[s] - orbeb[a] - orbeb[b])
                    delcorr = (-rraa - rrbb - ssaa - ssbb + rrss + aabb) 
                    delta = eigendif + delcorr*z

                    Eio = (arbs - asbr)

                    x = -Eio/delta
                    if abs(x) > 1: print "Warning a large x value has ",\
                       "been discovered with x = ",x
                    x = choose(x < 1, (1,x))
                    x = choose(x > -1, (-1,x))                   
                    sum += x*x
                    Ybeta[a] -= x*x
                    Ybeta[b] -= x*x
                    Ybeta[r] += x*x
                    Ybeta[s] += x*x
                    Ec1 += x*Eio

    #compute correction term for one alpha and one beta electron

    for a in aoccs:
        for b in boccs:
            for r in avirt:
                for s in bvirt:
                    arbs = abmoints[ijkl2intindex(a,r,b,s)]
                    rraa = aamoints[ijkl2intindex(r,r,a,a)] - \
                           aamoints[ijkl2intindex(r,a,a,r)]
                    rrbb = abmoints[ijkl2intindex(r,r,b,b)]
                    aass = abmoints[ijkl2intindex(a,a,s,s)]
                    ssbb = bbmoints[ijkl2intindex(s,s,b,b)] - \
                           bbmoints[ijkl2intindex(s,b,b,s)]
                    rrss = abmoints[ijkl2intindex(r,r,s,s)]
                    aabb = abmoints[ijkl2intindex(a,a,b,b)]

                    eigendif = (orbea[r] + orbeb[s] - orbea[a] - orbeb[b])
                    delcorr = (-rraa - rrbb - aass - ssbb + rrss + aabb)
                    delta = eigendif + delcorr*z

                    Eio = arbs

                    x = -Eio/delta
                    if abs(x) > 1: print "Warning a large x value has ",\
                       "been discovered with x = ",x
                    x = choose(x < 1, (1,x))
                    x = choose(x > -1, (-1,x))                   
                    sum += x*x
                    Yalpha[a] -= x*x
                    Ybeta[b] -= x*x
                    Yalpha[r] += x*x
                    Ybeta[s] += x*x
                    Ec1 += x*Eio

    #compute the fractional occupations of the occupied orbitals
    for a in aoccs:
        Yalpha[a] = 1 + Yalpha[a]
    for b in boccs:
        Ybeta[b] = 1 + Ybeta[b]
    #for a in xrange(nbf):
        #print "For alpha = ",a,"the fractional occupation is ",Yalpha[a]
        #print "For beta  = ",a,"the fractional occupation is ",Ybeta[a]

    #print the energy and its corrections
    E = energy + Ec1
    print "The total sum of excitations is ",sum
    print "The primary correlation correction is ",Ec1
    print "The total energy is ", E
    return E
Beispiel #33
0
def H2O_Molecule(tst, info, auX, auZ):
    H2O = Molecule('H2O', [('O', (0.0, 0.0, 0.0)), ('H', (auX, 0.0, auZ)),
                           ('H', (-auX, 0.0, auZ))],
                   units='Bohr')

    # Get a better energy estimate
    if dft:
        print "# info=%s A.U.=(%g,%g) " % (info, auX, auZ)
        edft, orbe2, orbs2 = dft(H2O, functional='SVWN')

    bfs = getbasis(H2O, basis_data=basis_data)
    #S is overlap of 2 basis funcs
    #h is (kinetic+nucl) 1 body term
    #ints is 2 body terms
    S, h, ints = getints(bfs, H2O)

    #enhf is the Hartee-Fock energy
    #orbe is the orbital energies
    #orbs is the orbital overlaps
    enhf, orbe, orbs = rhf(H2O, integrals=(S, h, ints))
    enuke = Molecule.get_enuke(H2O)

    # print "orbe=%d" % len(orbe)

    temp = matrixmultiply(h, orbs)
    hmol = matrixmultiply(transpose(orbs), temp)

    MOInts = TransformInts(ints, orbs)

    if single:
        print "h = \n", h
        print "S = \n", S
        print "ints = \n", ints
        print "orbe = \n", orbe
        print "orbs = \n", orbs
        print ""
        print "Index 0: 1 or 2 in the paper, Index 1: 3 or 4 in the paper (for pqrs)"
        print ""
        print "hmol = \n", hmol
        print "MOInts:"
        print "I,J,K,L = PQRS order: Cre1,Cre2,Ann1,Ann2"

    if 1:
        print "tst=%d info=%s nuc=%.9f Ehf=%.9f" % (tst, info, enuke, enhf),

    cntOrbs = 0
    maxOrb = 0
    npts = len(hmol[:])
    for i in xrange(npts):
        for j in range(i, npts):
            if abs(hmol[i, j]) > 1.0e-7:
                print "%d,%d=%.9f" % (i, j, hmol[i, j]),
        cntOrbs += 1
        if i > maxOrb: maxOrb = i
        if j > maxOrb: maxOrb = j

    nbf, nmo = orbs.shape
    mos = range(nmo)
    for i in mos:
        for j in xrange(i + 1):
            ij = i * (i + 1) / 2 + j
            for k in mos:
                for l in xrange(k + 1):
                    kl = k * (k + 1) / 2 + l
                    if ij >= kl:
                        ijkl = ijkl2intindex(i, j, k, l)
                        if abs(MOInts[ijkl]) > 1.0e-7:
                            print "%d,%d,%d,%d=%.9f" % (l, i, j, k,
                                                        MOInts[ijkl]),
            cntOrbs += 1
            if i > maxOrb: maxOrb = i
            if j > maxOrb: maxOrb = j
    print ""

    return (maxOrb, cntOrbs)
Beispiel #34
0
def EN2(molecule, **kwargs):  #
    "General wrapper for the simple CI method"
    nalpha, nbeta = molecule.get_alphabeta()
    bfs = getbasis(molecule)
    S, h, Ints = getints(bfs, molecule)
    energy, (orbea, orbeb), (orbsa, orbsb) = uhf(molecule,
                                                 integrals=(S, h, Ints),
                                                 bfs=bfs,
                                                 **kwargs)
    EHF = energy
    print "The Hatree-Fock energy is ", EHF
    #compute the transformed molecular orbital integrals

    aamoints, nbf = TransformInts(Ints, orbsa, orbsa, nalpha)
    bbmoints, nbf = TransformInts(Ints, orbsb, orbsb, nbeta)
    abmoints, nbf = TransformInts(Ints, orbsa, orbsb, nalpha)

    #Initialize the fractional occupations:
    Yalpha = zeros((nbf), 'd')
    Ybeta = zeros((nbf), 'd')

    #set up the occupied and virtual orbitals
    aoccs = range(nalpha)
    boccs = range(nbeta)
    avirt = range(nalpha, nbf)  #numbers of alpha virtual orbitals
    bvirt = range(nbeta, nbf)  #numbers of beta virtual orbitals

    ########  Computation of the primary energy correction  #########
    #Set initial correction terms to zero
    Ec1 = 0.
    sum = 0.
    z = 1.

    #compute correction term for two alpha electrons

    for a in aoccs:
        for b in xrange(a):
            for r in avirt:
                for s in xrange(nalpha, r):
                    arbs = aamoints[ijkl2intindex(a, r, b, s)]
                    asbr = aamoints[ijkl2intindex(a, s, b, r)]
                    rraa = aamoints[ijkl2intindex(r,r,a,a)] - \
                           aamoints[ijkl2intindex(r,a,a,r)]
                    rrbb = aamoints[ijkl2intindex(r,r,b,b)] - \
                           aamoints[ijkl2intindex(r,b,b,r)]
                    ssaa = aamoints[ijkl2intindex(s,s,a,a)] - \
                           aamoints[ijkl2intindex(s,a,a,s)]
                    ssbb = aamoints[ijkl2intindex(s,s,b,b)] - \
                           aamoints[ijkl2intindex(s,b,b,s)]
                    rrss = aamoints[ijkl2intindex(r,r,s,s)] - \
                           aamoints[ijkl2intindex(r,s,s,r)]
                    aabb = aamoints[ijkl2intindex(a,a,b,b)] - \
                           aamoints[ijkl2intindex(a,b,b,a)]

                    eigendif = (orbea[r] + orbea[s] - orbea[a] - orbea[b])
                    delcorr = (-rraa - rrbb - ssaa - ssbb + rrss + aabb)
                    delta = eigendif + delcorr * z

                    Eio = (arbs - asbr)

                    x = -Eio / delta
                    if abs(x) > 1:
                        print "Warning a large x value has been ",\
                              "discovered with x = ",x
                    x = choose(x < 1, (1, x))
                    x = choose(x > -1, (-1, x))
                    sum += x * x
                    Yalpha[a] -= x * x
                    Yalpha[b] -= x * x
                    Yalpha[r] += x * x
                    Yalpha[s] += x * x
                    Ec1 += x * Eio

    #compute correction term for two beta electrons

    for a in boccs:
        for b in xrange(a):
            for r in bvirt:
                for s in xrange(nbeta, r):
                    arbs = bbmoints[ijkl2intindex(a, r, b, s)]
                    asbr = bbmoints[ijkl2intindex(a, s, b, r)]
                    rraa = bbmoints[ijkl2intindex(r,r,a,a)] - \
                           bbmoints[ijkl2intindex(r,a,a,r)]
                    rrbb = bbmoints[ijkl2intindex(r,r,b,b)] - \
                           bbmoints[ijkl2intindex(r,b,b,r)]
                    ssaa = bbmoints[ijkl2intindex(s,s,a,a)] - \
                           bbmoints[ijkl2intindex(s,a,a,s)]
                    ssbb = bbmoints[ijkl2intindex(s,s,b,b)] - \
                           bbmoints[ijkl2intindex(s,b,b,s)]
                    rrss = bbmoints[ijkl2intindex(r,r,s,s)] - \
                           bbmoints[ijkl2intindex(r,s,s,r)]
                    aabb = bbmoints[ijkl2intindex(a,a,b,b)] - \
                           bbmoints[ijkl2intindex(a,b,b,a)]

                    eigendif = (orbeb[r] + orbeb[s] - orbeb[a] - orbeb[b])
                    delcorr = (-rraa - rrbb - ssaa - ssbb + rrss + aabb)
                    delta = eigendif + delcorr * z

                    Eio = (arbs - asbr)

                    x = -Eio / delta
                    if abs(x) > 1:                        print "Warning a large x value has ",\
            "been discovered with x = ",x
                    x = choose(x < 1, (1, x))
                    x = choose(x > -1, (-1, x))
                    sum += x * x
                    Ybeta[a] -= x * x
                    Ybeta[b] -= x * x
                    Ybeta[r] += x * x
                    Ybeta[s] += x * x
                    Ec1 += x * Eio

    #compute correction term for one alpha and one beta electron

    for a in aoccs:
        for b in boccs:
            for r in avirt:
                for s in bvirt:
                    arbs = abmoints[ijkl2intindex(a, r, b, s)]
                    rraa = aamoints[ijkl2intindex(r,r,a,a)] - \
                           aamoints[ijkl2intindex(r,a,a,r)]
                    rrbb = abmoints[ijkl2intindex(r, r, b, b)]
                    aass = abmoints[ijkl2intindex(a, a, s, s)]
                    ssbb = bbmoints[ijkl2intindex(s,s,b,b)] - \
                           bbmoints[ijkl2intindex(s,b,b,s)]
                    rrss = abmoints[ijkl2intindex(r, r, s, s)]
                    aabb = abmoints[ijkl2intindex(a, a, b, b)]

                    eigendif = (orbea[r] + orbeb[s] - orbea[a] - orbeb[b])
                    delcorr = (-rraa - rrbb - aass - ssbb + rrss + aabb)
                    delta = eigendif + delcorr * z

                    Eio = arbs

                    x = -Eio / delta
                    if abs(x) > 1:                        print "Warning a large x value has ",\
            "been discovered with x = ",x
                    x = choose(x < 1, (1, x))
                    x = choose(x > -1, (-1, x))
                    sum += x * x
                    Yalpha[a] -= x * x
                    Ybeta[b] -= x * x
                    Yalpha[r] += x * x
                    Ybeta[s] += x * x
                    Ec1 += x * Eio

    #compute the fractional occupations of the occupied orbitals
    for a in aoccs:
        Yalpha[a] = 1 + Yalpha[a]
    for b in boccs:
        Ybeta[b] = 1 + Ybeta[b]
    #for a in xrange(nbf):
    #print "For alpha = ",a,"the fractional occupation is ",Yalpha[a]
    #print "For beta  = ",a,"the fractional occupation is ",Ybeta[a]

    #print the energy and its corrections
    E = energy + Ec1
    print "The total sum of excitations is ", sum
    print "The primary correlation correction is ", Ec1
    print "The total energy is ", E
    return E
Beispiel #35
0
def TransformInts_mpi(Ints, orbs, rank, comm, _debug_=True):
    """
    O(N^5) 4-index transformation of the two-electron integrals. Not as
    efficient as it could be, since it inflates to the full rectangular
    matrices rather than keeping them compressed. But at least it gets the
    correct result.
    """
    '''
    THIS ROUTINE DOES NOT WORK THE PARALLELISATION
    IS HERE COMPLIATED AS THE THE FINAL RESULTS
    NEEDS ALL THE VALUES OF THE OUTER LOOP ALL THE time
    WE SHOULD FINE A WAY OF MAKING IT PARALLEL THOUGH ... 
    PLUS THE MOINTS LOOP IS UNBALANCED WITH THE IF IJ<=kl
    IT NEEDS A SPECIAL TREATMENT TO DIVIDE THE LOAD
    '''

    nbf_tot, nmo_tot = orbs.shape
    totlen = nmo_tot * (nmo_tot + 1) * (nmo_tot * nmo_tot + nmo_tot + 2) / 8

    # number of terms per process
    nmo_pp = int(nmo_tot / comm.size)
    nbf_pp = int(nbf_tot / comm.size)

    # precompute the index each process takes care of
    mos_term = range(rank * nmo_pp, (rank + 1) * nmo_pp)
    bfs_term = range(rank * nbf_pp, (rank + 1) * nbf_pp)

    # for the inner loops we still have the full range
    mos = range(nmo_tot)
    bfs = range(nbf_tot)

    # special case for the last one
    if rank == comm.size - 1:
        mos_term = range(rank * nmo_pp, nmo_tot)
        bfs_term = range(rank * nbf_pp, nbf_tot)

    # actual number of terms calculated
    nbf = len(bfs_term)
    nmo = len(mos_term)

    # initialize the temp vectors
    temp = np.zeros((nbf_tot, nbf_tot, nbf_tot, nmo_tot), 'd')
    tempvec = np.zeros(nbf_tot, 'd')
    temp2 = np.zeros((nbf_tot, nbf_tot, nmo_tot, nmo_tot), 'd')

    if rank == 0:
        print '\n\t Rearrange the 2electron integrals on %d procs' % (
            comm.size)
        print '\t There is %d BFS in the system' % (nbf_tot)
        print '\t',
        print '-' * 50
    print '\t\t Proc [%03d] computes %d terms' % (rank, len(bfs_term))

    t0 = time.time()

    ##########################################
    # Each proc compute a part of the temp
    # vector that will be assembled afterwards
    ##########################################

    # Start with (mu,nu|sigma,eta)
    # Unpack aoints and transform eta -> l
    print bfs_term
    for mu in bfs:
        for nu in bfs:
            for sigma in bfs:
                for l in mos:
                    for eta in bfs:
                        tempvec[eta] = Ints[ijkl2intindex(mu, nu, sigma, eta)]
                    temp[mu, nu, sigma, l] = np.dot(orbs[:, l], tempvec)

    print temp
    # Transform sigma -> k
    for mu in bfs_term:
        for nu in bfs:
            for l in mos:
                for k in mos:
                    temp2[mu, nu, k, l] = np.dot(orbs[:, k], temp[mu, nu, :,
                                                                  l])

    # Transform nu -> j
    for mu in bfs_term:
        for k in mos:
            for l in mos:
                for j in mos:
                    temp[mu, j, k, l] = np.dot(orbs[:, j], temp2[mu, :, k, l])

    if _debug_:
        print '\t\t Calculation [%03d] of %d terms done in %f sec ' % (
            rank, len(bfs_term), time.time() - t0)

##########################################
# Start communication between nodes
# to aggregate the values of the temp
##########################################

    comm.Barrier()

    # PROC 0 receive the data
    if rank == 0:

        if _debug_:
            print '\t\t Gather all the data on 0'

        rec_data = np.zeros((nbf_tot, nbf_tot, nbf_tot, nmo_tot), 'd')
        for iC in range(1, comm.size):

            # receive the data
            comm.Recv(rec_data, source=iC)

            rec_data[temp != 0] = 0
            temp += rec_data

            if _debug_:
                print '\t\t\t Proc [%03d] : data received from [%03d]' % (0,
                                                                          iC)

    # PROC n send data
    else:
        comm.Send(temp, dest=0)

# force garbage collection now
    if rank == 0:
        del rec_data

##########################################
# Broadcast the values of temp to all
# to finalize the transofrmation
##########################################

    if rank == 0 and _debug_:
        print '\n\t\t Broadcast the data from 0 to all procs'
    comm.Bcast(temp, root=0)

    ##########################################
    # Each procs process a part of MOInts
    # that are then aggregated
    ##########################################

    if rank == 0:
        print '\n\t Compute MO 2electron integrals on %d procs' % (comm.size)
        print '\t There is %d MO in the system' % (nmo_tot)
        print '\t',
        print '-' * 50
    print '\t\t Proc [%03d] computes %d terms' % (rank, len(mos_term))

    # Transform mu -> i and repack integrals:
    MOInts = np.zeros(totlen, 'd')
    for i in mos:
        for j in xrange(i + 1):
            ij = i * (i + 1) / 2 + j
            for k in mos:
                for l in xrange(k + 1):
                    kl = k * (k + 1) / 2 + l
                    if ij >= kl:
                        ijkl = ijkl2intindex(i, j, k, l)
                        MOInts[ijkl] = np.dot(orbs[:, i], temp[:, j, k, l])

    #force garbage collection now
    del temp, temp2, tempvec

    ##########################################
    # Start communication between nodes
    # to aggregate the values of the MOint
    ##########################################

    comm.Barrier()
    #print MOInts
    # PROC 0 receive the data
    if rank == 0:

        if _debug_:
            print '\t\t Gather all the data on 0'

        rec_data = np.zeros(totlen, 'd')
        for iC in range(1, comm.size):

            # receive the data
            comm.Recv(rec_data, source=iC)

            rec_data[MOInts != 0] = 0
            MOInts += rec_data

            if _debug_:
                print '\t\t\t Proc [%03d] : data received from [%03d]' % (0,
                                                                          iC)

    # PROC n send data
    else:
        comm.Send(MOInts, dest=0)

    # remove the unwanted
    if rank == 0:
        del rec_data

# done
    return MOInts
Beispiel #36
0
def H2O_Molecule(tst,info,auX,auZ):
    H2O = Molecule('H2O',
           [('O',  ( 0.0,  0.0, 0.0)),
            ('H',  ( auX,  0.0, auZ)),
            ('H',  (-auX,  0.0, auZ))],
           units='Bohr')

    # Get a better energy estimate
    if dft:
        print "# info=%s A.U.=(%g,%g) " % (info,auX,auZ)
        edft,orbe2,orbs2 = dft(H2O,functional='SVWN')

    bfs= getbasis(H2O,basis_data=basis_data) 
    #S is overlap of 2 basis funcs 
    #h is (kinetic+nucl) 1 body term 
    #ints is 2 body terms 
    S,h,ints=getints(bfs,H2O) 


    #enhf is the Hartee-Fock energy 
    #orbe is the orbital energies 
    #orbs is the orbital overlaps 
    enhf,orbe,orbs=rhf(H2O,integrals=(S,h,ints))
    enuke   = Molecule.get_enuke(H2O)

    # print "orbe=%d" % len(orbe)

    temp = matrixmultiply(h,orbs) 
    hmol = matrixmultiply(transpose(orbs),temp) 

    MOInts = TransformInts(ints,orbs) 

    if single:
         print "h = \n",h
         print "S = \n",S
         print "ints = \n",ints
         print "orbe = \n",orbe
         print "orbs = \n",orbs
         print ""
         print "Index 0: 1 or 2 in the paper, Index 1: 3 or 4 in the paper (for pqrs)"
         print ""
         print "hmol = \n",hmol
         print "MOInts:"
         print "I,J,K,L = PQRS order: Cre1,Cre2,Ann1,Ann2"

    if 1:
        print "tst=%d info=%s nuc=%.9f Ehf=%.9f" % (tst,info,enuke,enhf),

    cntOrbs    = 0
    maxOrb    = 0
    npts    = len(hmol[:])
    for i in xrange(npts):
        for j in range(i,npts):
            if abs(hmol[i,j]) > 1.0e-7:
                print "%d,%d=%.9f" % (i,j,hmol[i,j]),
        cntOrbs += 1
        if i > maxOrb: maxOrb = i
        if j > maxOrb: maxOrb = j

    nbf,nmo    = orbs.shape
    mos        = range(nmo)
    for i in mos:
        for j in xrange(i+1):
            ij      = i*(i+1)/2+j
            for k in mos:
                for l in xrange(k+1):
                    kl = k*(k+1)/2+l
                    if ij >= kl:
                        ijkl = ijkl2intindex(i,j,k,l)
                        if abs(MOInts[ijkl]) > 1.0e-7:
                            print "%d,%d,%d,%d=%.9f" % (l,i,j,k,MOInts[ijkl]),
            cntOrbs += 1
            if i > maxOrb: maxOrb = i
            if j > maxOrb: maxOrb = j
    print ""

    return (maxOrb,cntOrbs)
Beispiel #37
0
    def get_G_gamma(self, alpha_beta):
        """ get G_sigma matrices (11.8.33/34) 
        gamma is alpha or beta.

        It is sparse! Hence is it constructed solely from the non-zero
        elements. 
        """

        try:
            self.MOInts
        except:
            self.MOInts = TransformInts(self.ERI, self.orbs)
        # except: self.MOInts = TransformInts_test(self.ERI,self.orbs)

        if alpha_beta == "alpha":
            Strings = self.AlphaStrings
        elif alpha_beta == "beta":
            Strings = self.BetaStrings
        else:
            raise ValueError, 'argument alpha_beta must be alpha or beta'

        row_index = []
        column_index = []
        data = []

        for i_string in Strings.occupations:
            for j_string in Strings.occupations:

                row = Strings.address(i_string)
                column = Strings.address(j_string)

                elem = 0

                for p, q, r, s in self.doubles:
                    """ loop over excitations """

                    # apply excitation E_rs operator on string:
                    phase_rs, e_rs_j = e_pq_on_string(r, s, j_string)
                    if e_rs_j == 0:
                        """ tried to annihilate vaccum or to create
                        doubly """
                        continue

                    # apply excitation E_pq operator on string:
                    phase_pq, e_pqrs_j = e_pq_on_string(p, q, e_rs_j)
                    if e_pqrs_j == 0:
                        """ tried to annihilate vaccum or to create
                        doubly """
                        continue

                    if row != Strings.address(e_pqrs_j):
                        """ strings differed by more than two pairs p q r s """
                        continue
                    else:
                        elem += 0.5 * phase_pq * phase_rs * self.MOInts[
                            ijkl2intindex(p, q, r, s)]
                        # elem += 0.5 *phase_pq *phase_rs *self.MOInts[p,q,r,s]

                        ### Need to think when can exit the loop. For sure if p!=q!=r!=s
                        # if p!=q and q!=r and r!=s:
                        #     """ there will not be another pqrs that
                        #     satisfies, exit pqrs loop """
                        #     row_index.append(row)
                        #     column_index.append(column)
                        #     data.append(elem)
                        #     break

                if abs(elem) > 1e-14:
                    row_index.append(row)
                    column_index.append(column)
                    data.append(elem)

        return spspa.csr_matrix(
            (np.array(data), (np.array(row_index), np.array(column_index))),
            shape=(len(Strings.occupations), len(Strings.occupations)))