Exemplo n.º 1
0
 def testOrthog(self):
     from PyQuante.LA2 import CanOrth, SymOrth, CholOrth, simx
     from PyQuante.NumWrap import eigh
     solver = SCF(h2, method="HF")
     h, S = solver.h, solver.S
     X1 = CanOrth(S)
     X2 = SymOrth(S)
     X3 = CholOrth(S)
     h1 = simx(h, X1)
     ha = simx(h, X2)
     h3 = simx(h, X3)
     e1, v1 = eigh(h1)
     e2, v2 = eigh(ha)
     e3, v3 = eigh(h3)
     self.assertAlmostEqual(e1[0], e2[0], 6)
     self.assertAlmostEqual(e1[0], e3[0], 6)
Exemplo n.º 2
0
 def inertial(self):
     "Transform to inertial coordinates"
     from PyQuante.NumWrap import zeros, eigh
     rcom = self.com()
     print "Translating to COM: ", rcom
     self.translate(-rcom)
     I = zeros((3, 3), 'd')
     for atom in self:
         m = atom.mass()
         x, y, z = atom.pos()
         x2, y2, z2 = x * x, y * y, z * z
         I[0, 0] += m * (y2 + z2)
         I[1, 1] += m * (x2 + z2)
         I[2, 2] += m * (x2 + y2)
         I[0, 1] -= m * x * y
         I[1, 0] = I[0, 1]
         I[0, 2] -= m * x * z
         I[2, 0] = I[0, 2]
         I[1, 2] -= m * y * z
         I[2, 1] = I[1, 2]
     E, U = eigh(I)
     print "Moments of inertial ", E
     self.urotate(U)
     print "New coordinates: "
     print self
     return
Exemplo n.º 3
0
def lanczos_minmax(F, S=None, **kwargs):
    "Estimate the min/max evals of F using a few iters of Lanczos"
    doS = S is not None
    niter = kwargs.get('niter', settings.DMPLanczosMinmaxIters)
    N = F.shape[0]
    niter = min(N, niter)
    x = zeros(N, 'd')
    x[0] = 1
    q = x
    avals = []
    bvals = []
    if doS:
        r = matrixmultiply(S, q)
    else:
        r = q
    beta = sqrt(matrixmultiply(q, r))
    wold = zeros(N, 'd')
    for i in xrange(niter):
        w = r / beta
        v = q / beta
        r = matrixmultiply(F, v)
        r = r - wold * beta
        alpha = matrixmultiply(v, r)
        avals.append(alpha)
        r = r - w * alpha
        if doS:
            q = solve(S, r)
        else:
            q = r
        beta = sqrt(matrixmultiply(q, r))
        bvals.append(beta)
        wold = w
    E, V = eigh(tridiagmat(avals, bvals))
    return min(E), max(E)
Exemplo n.º 4
0
 def testOrthog(self):
     from PyQuante.LA2 import CanOrth, SymOrth, CholOrth, simx
     from PyQuante.NumWrap import eigh
     solver = SCF(h2,method="HF")
     h,S = solver.h, solver.S
     X1 = CanOrth(S)
     X2 = SymOrth(S)
     X3 = CholOrth(S)
     h1 = simx(h,X1)
     ha = simx(h,X2)
     h3 = simx(h,X3)
     e1,v1 = eigh(h1)
     e2,v2 = eigh(ha)
     e3,v3 = eigh(h3)
     self.assertAlmostEqual(e1[0],e2[0],6)
     self.assertAlmostEqual(e1[0],e3[0],6)
Exemplo n.º 5
0
 def inertial(self):
     "Transform to inertial coordinates"
     from PyQuante.NumWrap import zeros,eigh
     rcom = self.com()
     print "Translating to COM: ",rcom
     self.translate(-rcom)
     I = zeros((3,3),'d')
     for atom in self:
         m = atom.mass()
         x,y,z = atom.pos()
         x2,y2,z2 = x*x,y*y,z*z
         I[0,0] += m*(y2+z2)
         I[1,1] += m*(x2+z2)
         I[2,2] += m*(x2+y2)
         I[0,1] -= m*x*y
         I[1,0] = I[0,1]
         I[0,2] -= m*x*z
         I[2,0] = I[0,2]
         I[1,2] -= m*y*z
         I[2,1] = I[1,2]
     E,U = eigh(I)
     print "Moments of inertial ",E
     self.urotate(U)
     print "New coordinates: "
     print self
     return
Exemplo n.º 6
0
def lanczos_minmax(F,S=None,**kwargs):
    "Estimate the min/max evals of F using a few iters of Lanczos"
    doS = S is not None
    niter = kwargs.get('niter',8)
    N = F.shape[0]
    niter = min(N,niter)
    x = zeros(N,'d')
    x[0] = 1
    q = x
    avals = []
    bvals = []
    if doS:
        r = matrixmultiply(S,q)
    else:
        r = q
    beta = sqrt(matrixmultiply(q,r))
    wold = zeros(N,'d')
    for i in xrange(niter):
        w = r/beta
        v = q/beta
        r = matrixmultiply(F,v)
        r = r - wold*beta
        alpha = matrixmultiply(v,r)
        avals.append(alpha)
        r = r-w*alpha
        if doS:
            q = solve(S,r)
        else:
            q = r
        beta = sqrt(matrixmultiply(q,r))
        bvals.append(beta)
        wold = w
    E,V = eigh(tridiagmat(avals,bvals))
    return min(E),max(E)
Exemplo n.º 7
0
def geigh(H,A,**opts):
    """\
    Generalized eigenproblem using a symmetric matrix H.
    """
    X = SymOrthCutoff(A)
    val,vec = eigh(simx(H,X))
    vec = matrixmultiply(X,vec)
    return val,vec
Exemplo n.º 8
0
def geigh(H, A, **opts):
    """\
    Generalized eigenproblem using a symmetric matrix H.
    """
    X = SymOrthCutoff(A)
    val, vec = eigh(simx(H, X))
    vec = matrixmultiply(X, vec)
    return val, vec
Exemplo n.º 9
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
Exemplo n.º 10
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
Exemplo n.º 11
0
def SymOrthCutoff(S, scut=1e-5):
    """Symmetric orthogonalization of the real symmetric matrix S.
    This is given by Ut(1/sqrt(lambda))U, where lambda,U are the
    eigenvalues/vectors.

    Only eigenvectors with eigenvalues greater that a cutoff are kept.
    This approximation is useful in cases where the basis set has
    linear dependencies.
    """
    val, vec = eigh(S)
    n = vec.shape[0]
    shalf = identity(n, 'd')
    for i in range(n):
        if val[i] > scut:
            shalf[i, i] /= sqrt(val[i])
        else:
            shalf[i, i] = 0.
    X = simx(shalf, vec, 'T')
    return X
Exemplo n.º 12
0
def SymOrthCutoff(S,scut=1e-5):
    """Symmetric orthogonalization of the real symmetric matrix S.
    This is given by Ut(1/sqrt(lambda))U, where lambda,U are the
    eigenvalues/vectors.

    Only eigenvectors with eigenvalues greater that a cutoff are kept.
    This approximation is useful in cases where the basis set has
    linear dependencies.
    """
    val,vec = eigh(S)
    n = vec.shape[0]
    shalf = identity(n,'d')
    for i in range(n):
        if val[i] > scut:
            shalf[i,i] /= sqrt(val[i])
        else:
            shalf[i,i] = 0.
    X = simx(shalf,vec,'T')
    return X
Exemplo n.º 13
0
def ocbse(orbs,h,Hs,f,a,b,noccsh):
    # Need to write this so that we don't need the orbs 3 times!
    nsh = len(noccsh)
    nbf = norb = h.shape[0]
    orbe = zeros(norb,'d')
    for ish in xrange(nsh):
        orbs_in_shell = get_orbs_in_shell(ish,noccsh,norb)
        F = get_os_fock(ish,nsh,f,a,b,h,Hs)
        # form the orbital space of all of the orbs in ish plus the virts
        T = orbs.take(orbs_in_shell,1)
        #print "take worked? ",(T==get_orbs(orbs,orbs_in_shell)).all()
        # Transform to MO space
        Fmo = ao2mo(F,T)
        mo_orbe,mo_orbs = eigh(Fmo)
        T = matrixmultiply(T,mo_orbs)
        # Insert orbital energies into the right place
        update_orbe(orbs_in_shell,orbe,mo_orbe)
        update_orbs(orbs_in_shell,orbs,T)
    return orbe,orbs
Exemplo n.º 14
0
def davidson(A, nroots, **kwargs):
    etol = kwargs.get('etol', settings.DavidsonEvecTolerance
                      )  # tolerance on the eigenval convergence
    ntol = kwargs.get('ntol', settings.DavidsonNormTolerance
                      )  # tolerance on the vector norms for addn
    n, m = A.shape
    ninit = max(nroots, 2)
    B = zeros((n, ninit), 'd')
    for i in xrange(ninit):
        B[i, i] = 1.

    nc = 0  # number of converged roots
    eigold = 1e10
    for iter in xrange(n):
        if nc >= nroots: break
        D = matrixmultiply(A, B)
        S = matrixmultiply(transpose(B), D)
        m = len(S)
        eval, evec = eigh(S)

        bnew = zeros(n, 'd')
        for i in xrange(m):
            bnew += evec[i, nc] * (D[:, i] - eval[nc] * B[:, i])

        for i in xrange(n):
            denom = max(eval[nc] - A[i, i],
                        1e-8)  # Maximum amplification factor
            bnew[i] /= denom

        norm = orthog(bnew, B)
        bnew = bnew / norm

        if abs(eval[nc] - eigold) < etol:
            nc += 1
        eigold = eval[nc]
        if norm > ntol: B = appendColumn(B, bnew)

    E = eval[:nroots]
    nv = len(evec)
    V = matrixmultiply(B[:, :nv], evec)
    return E, V
Exemplo n.º 15
0
def davidson(A,nroots,**kwargs):
    etol = kwargs.get('etol',settings.DavidsonEvecTolerance) # tolerance on the eigenval convergence
    ntol = kwargs.get('ntol',settings.DavidsonNormTolerance) # tolerance on the vector norms for addn
    n,m = A.shape
    ninit = max(nroots,2)
    B = zeros((n,ninit),'d')
    for i in xrange(ninit): B[i,i] = 1.

    nc = 0 # number of converged roots
    eigold = 1e10
    for iter in xrange(n):
        if nc >= nroots: break
        D = matrixmultiply(A,B)
        S = matrixmultiply(transpose(B),D)
        m = len(S)
        eval,evec = eigh(S)

        bnew = zeros(n,'d')
        for i in xrange(m):
            bnew += evec[i,nc]*(D[:,i] - eval[nc]*B[:,i])

        for i in xrange(n):
            denom = max(eval[nc]-A[i,i],1e-8) # Maximum amplification factor
            bnew[i] /= denom

        norm = orthog(bnew,B)
        bnew = bnew / norm

        if abs(eval[nc]-eigold) < etol:
            nc += 1
        eigold = eval[nc]
        if norm > ntol: B = appendColumn(B,bnew)

    E = eval[:nroots]
    nv = len(evec)
    V = matrixmultiply(B[:,:nv],evec)
    return E,V
Exemplo n.º 16
0
#Form Hcore
Hcore = KE + Vext

#calculate two electron integrals
elecRepulsion = Ints.get2ints(basisSet)

#Section 3############################
#Calculate Transformation Matrix X from Overlap matrix
X = linalg.SymOrth(S)

#Section 4############################
#guess density matrix from Core Hamiltonian

#diagnolize Hamiltonian and transform hamiltonian to get guess orbitals
eVal, eVec = eigh(linalg.simx(Hcore, X))

#transform orbitals from AO to MO basis
orbitals = matrixmultiply(Hcore, X)

#guess Density from guess orbitals and number of closed electron shells
D = HF.mkdens(orbitals, 0, molecule.get_closedopen()[0])

#Start of SCF Procedures############################
#init variables for SCF
cycle = 0
energy = [float("-inf")]

while (cycle < maxCycle):
    #while max. number of cycles not reached
    #continues with SCF iterations
Exemplo n.º 17
0
 def solve_fock(self):
     from PyQuante.NumWrap import eigh
     from PyQuante.LA2 import mkdens
     self.orbea,self.orbsa = eigh(self.Fa)
     self.orbeb,self.orbsb = eigh(self.Fb)
Exemplo n.º 18
0
 def solve_fock(self):
     from PyQuante.NumWrap import eigh
     self.orbe,self.orbs = eigh(self.F)
Exemplo n.º 19
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
Exemplo n.º 20
0
 def solve_fock(self):
     from PyQuante.NumWrap import eigh
     self.orbe, self.orbs = eigh(self.F)
Exemplo n.º 21
0
 def solve_fock(self):
     from PyQuante.NumWrap import eigh
     from PyQuante.LA2 import mkdens
     self.orbea, self.orbsa = eigh(self.Fa)
     self.orbeb, self.orbsb = eigh(self.Fb)