コード例 #1
0
def der_kinetic_integral(a,bfi,bfj):
    """
    The kinetic energy operator does not depend on the atomic position so we only
    have to consider differentiating the Gaussian functions.  There are 4 possible
    cases we have to evaluate
    
    Case 1: Neither of the basis functions depends on the position of atom A which gives:
        dT_ij/dXa = 0
    
    Cases 2 and 3: Only one of the basis functions depends the position of atom A which 
    gives us either of the following possible integrals to evaluate
        dT_ij/dXa = integral{dr dg_i/dXa T g_j }
        
        dT_ij/dXa = integral{dr g_i T dg_j/dXa  }
    
    Case 4: Both of the basis functions depend on the position of atom A which gives the
    following integral to evaluate
        dT_ij/dXa = integral{dr dg_i/dXa T g_j + g_i T dg_j/dXa  }
    """
    dTij_dXa,dTij_dYa,dTij_dZa = 0.0,0.0,0.0
 
    #we use atom ids on the CGBFs to evaluate which of the 4 above case we have
    #bfi is centered on atom a
    if bfi.atid==a:
        for upbf in bfj.prims:
            for vpbf in bfi.prims:
                alpha = vpbf.exp
                l,m,n = vpbf.powers
                origin = vpbf.origin
                coefs  = upbf.coef*vpbf.coef
                                
                #x component
                v = PGBF(alpha,origin,(l+1,m,n))
                v.normalize()
                
                terma = sqrt(alpha*(2.0*l+1.0))*coefs*v.kinetic(upbf)
                
                if l>0:
                    v.reset_powers(l-1,m,n)
                    v.normalize()
                    termb = -2*l*sqrt(alpha/(2.0*l-1.0))*coefs*v.kinetic(upbf)
                else: termb = 0.0
                
                dTij_dXa += terma + termb

                #y component
                v.reset_powers(l,m+1,n)
                v.normalize()
                terma = sqrt(alpha*(2.0*m+1.0))*coefs*v.kinetic(upbf)
                
                if m>0:
                    v.reset_powers(l,m-1,n)
                    v.normalize()
                    termb = -2*m*sqrt(alpha/(2.0*m-1.0))*coefs*v.kinetic(upbf)
                else: termb = 0.0
                
                dTij_dYa += terma + termb
                
                #z component
                v.reset_powers(l,m,n+1)
                v.normalize()
                terma = sqrt(alpha*(2.0*n+1.0))*coefs*v.kinetic(upbf)
                
                if n>0:
                    v.reset_powers(l,m,n-1)
                    v.normalize()
                    termb = -2*n*sqrt(alpha/(2.0*n-1.0))*coefs*v.kinetic(upbf)
                else: termb = 0.0
                
                dTij_dZa += terma + termb
                

    #bfj is centered on atom a
    if bfj.atid==a:
        for upbf in bfi.prims:
            for vpbf in bfj.prims:
                alpha = vpbf.exp
                l,m,n = vpbf.powers
                origin = vpbf.origin
                coefs  = upbf.coef*vpbf.coef
                                
                #x component
                v = PGBF(alpha,origin,(l+1,m,n))
                v.normalize()
                
                terma = sqrt(alpha*(2.0*l+1.0))*coefs*v.kinetic(upbf)
                
                if l>0:
                    v.reset_powers(l-1,m,n)
                    v.normalize()
                    termb = -2*l*sqrt(alpha/(2.0*l-1.0))*coefs*v.kinetic(upbf)
                else: termb = 0.0
                
                dTij_dXa += terma + termb
                
                #y component
                v.reset_powers(l,m+1,n)
                v.normalize()
                terma = sqrt(alpha*(2.0*m+1.0))*coefs*v.kinetic(upbf)
                
                if m>0:
                    v.reset_powers(l,m-1,n)
                    v.normalize()
                    termb = -2*m*sqrt(alpha/(2.0*m-1.0))*coefs*v.kinetic(upbf)
                else: termb = 0.0
                
                dTij_dYa += terma + termb
                
                #z component
                v.reset_powers(l,m,n+1)
                v.normalize()
                terma = sqrt(alpha*(2.0*n+1.0))*coefs*v.kinetic(upbf)
                
                if n>0:
                    v.reset_powers(l,m,n-1)
                    v.normalize()
                    termb = -2*n*sqrt(alpha/(2.0*n-1.0))*coefs*v.kinetic(upbf)
                else: termb = 0.0
                
                dTij_dZa += terma + termb

    return dTij_dXa,dTij_dYa,dTij_dZa
コード例 #2
0
def der_overlap_element(a,bfi, bfj):
    """
    finds the derivative of the overlap integral with respect to the 
    atomic coordinate of atom "a".  Note there are four possible cases
    for evaluating this integral:
     1. Neither of the basis functions depend on the position of atom a
        ie. they are centered on atoms other than atom a
     2 and 3. One of the basis functions depends on the position of atom a
        so we need to evaluate the derivative of a Gaussian with the 
        recursion (right word?) relation derived on page 442 of Szabo.
     4. Both of the basis functions are centered on atom a, which through the
        recursion relation for the derivative of a Gaussian basis function will
        require the evaluation of 4 overlap integrals...

    this function will return a 3 element list with the derivatives of the overlap
    integrals with respect to the atomic coordinates Xa,Ya,Za.
    """
    dSij_dXa,dSij_dYa,dSij_dZa = 0.0,0.0,0.0
    
    #we use atom ids on the CGBFs to evaluate which of the 4 above case we have
    if bfi.atid==a: #bfi is centered on atom a
        for upbf in bfj.prims:
            for vpbf in bfi.prims:
                alpha = vpbf.exp
                l,m,n = vpbf.powers
                origin = vpbf.origin
                coefs  = upbf.coef*vpbf.coef
                                
                #x component
                v = PGBF(alpha,origin,(l+1,m,n))
                v.normalize()
                
                terma = sqrt(alpha*(2.0*l+1.0))*coefs*v.overlap(upbf)
                
                if l>0:
                    v.reset_powers(l-1,m,n)
                    v.normalize()
                    termb = -2*l*sqrt(alpha/(2.0*l-1.0))*coefs*v.overlap(upbf)
                else: termb = 0.0
                
                dSij_dXa += terma + termb
                
                
                #y component
                v.reset_powers(l,m+1,n)
                v.normalize()
                terma = sqrt(alpha*(2.0*m+1.0))*coefs*v.overlap(upbf)
                
                if m>0:
                    v.reset_powers(l,m-1,n)
                    v.normalize()
                    termb = -2*m*sqrt(alpha/(2.0*m-1.0))*coefs*v.overlap(upbf)
                else: termb = 0.0
                
                dSij_dYa += terma + termb
                
                #z component
                v.reset_powers(l,m,n+1)
                v.normalize()
                terma = sqrt(alpha*(2.0*n+1.0))*coefs*v.overlap(upbf)
                
                if n>0:
                    v.reset_powers(l,m,n-1)
                    v.normalize()
                    termb = -2*n*sqrt(alpha/(2.0*n-1.0))*coefs*v.overlap(upbf)
                else: termb = 0.0
                
                dSij_dZa += terma + termb

                
    #bfj is centered on atom a
    if bfj.atid==a:
        for upbf in bfi.prims:
            for vpbf in bfj.prims:
                alpha = vpbf.exp
                l,m,n = vpbf.powers
                origin = vpbf.origin
                coefs = upbf.coef*vpbf.coef
                
                #x component 
                v = PGBF(alpha,origin,(l+1,m,n))
                v.normalize()
                
                terma = sqrt(alpha*(2.0*l+1.0))*coefs*v.overlap(upbf)
                
                if l>0:
                    v.reset_powers(l-1,m,n)
                    v.normalize()
                    termb = -2*l*sqrt(alpha/(2.0*l-1.0))*coefs*v.overlap(upbf)
                else: termb = 0.0
                
                dSij_dXa += terma + termb
                

                #y component
                v.reset_powers(l,m+1,n)
                v.normalize()
                terma = sqrt(alpha*(2.0*m+1.0))*coefs*v.overlap(upbf)
                
                if m>0:
                    v.reset_powers(l,m-1,n)
                    v.normalize()
                    termb = -2*m*sqrt(alpha/(2.0*m-1.0))*coefs*v.overlap(upbf)
                else: termb = 0.0
                
                dSij_dYa += terma + termb
                
                #z component
                v.reset_powers(l,m,n+1)
                v.normalize()
                terma = sqrt(alpha*(2.0*n+1.0))*coefs*v.overlap(upbf)
                
                if n>0:
                    v.reset_powers(l,m,n-1)
                    v.normalize()
                    termb = -2*n*sqrt(alpha/(2.0*n-1.0))*coefs*v.overlap(upbf)
                else: termb = 0.0
                
                dSij_dZa += terma + termb

    return dSij_dXa,dSij_dYa,dSij_dZa
コード例 #3
0
def der_Jints(a, bfi,bfj,bfk,bfl):
    """
    This function will find the atomic gradient of the Coloumb integral over
    basis functions i,j,k, and l as in
    
    grad_a <ij|kl> = <gi j|kl> + <i gj|kl> + <ij|gk l> + <ij|k gl>
    """
    dJint_dXa,dJint_dYa,dJint_dZa = 0.0,0.0,0.0
    
    if bfi.atid==a: #bfi is centered on atom a
        for tpbf in bfi.prims:
            for upbf in bfj.prims:
                for vpbf in bfk.prims:
                    for wpbf in bfl.prims:
                        alpha  = tpbf.exp
                        l,m,n  = tpbf.powers
                        origin = tpbf.origin
                        coefs  = tpbf.coef*upbf.coef*vpbf.coef*wpbf.coef
                        
                        #x component
                        tmp = PGBF(alpha, origin,(l+1,m,n)) #temp pgbf
                        tmp.normalize()
                        
                        terma = sqrt(alpha*(2.0*l+1.0))*coefs*coulomb(tmp,upbf,vpbf,wpbf)
                        
                        if l>0:
                            tmp.reset_powers(l-1,m,n)
                            tmp.normalize()
                            termb = -2*l*sqrt(alpha/(2.*l-1))*coefs*coulomb(tmp,upbf,vpbf,wpbf)
                        else: termb = 0.0
                        
                        dJint_dXa += terma+termb
                        
                        #y component
                        tmp.reset_powers(l,m+1,n)
                        tmp.normalize()
                        
                        terma = sqrt(alpha*(2.0*m+1.0))*coefs*coulomb(tmp,upbf,vpbf,wpbf)
                        
                        if m>0:
                            tmp.reset_powers(l,m-1,n)
                            tmp.normalize()
                            termb = -2*m*sqrt(alpha/(2.*m-1))*coefs*coulomb(tmp,upbf,vpbf,wpbf)
                        else: termb=0.0
                        
                        dJint_dYa += terma + termb

                        #z component
                        tmp.reset_powers(l,m,n+1)
                        tmp.normalize()
                        
                        terma = sqrt(alpha*(2.0*n+1.0))*coefs*coulomb(tmp,upbf,vpbf,wpbf)
                        
                        if n>0:
                            tmp.reset_powers(l,m,n-1)
                            tmp.normalize()
                            termb = -2*n*sqrt(alpha/(2.*n-1))*coefs*coulomb(tmp,upbf,vpbf,wpbf)
                        else: termb=0.0
                        
                        dJint_dZa += terma + termb
                        
    if bfj.atid==a: #bfj is centered on atom a
        for tpbf in bfi.prims:
            for upbf in bfj.prims:
                for vpbf in bfk.prims:
                    for wpbf in bfl.prims:
                        alpha  = upbf.exp
                        l,m,n  = upbf.powers
                        origin = upbf.origin
                        coefs  = tpbf.coef*upbf.coef*vpbf.coef*wpbf.coef
                        
                        #x component
                        tmp = PGBF(alpha, origin,(l+1,m,n)) #temp pgbf
                        tmp.normalize()
                        
                        terma = sqrt(alpha*(2.0*l+1.0))*coefs*coulomb(tpbf,tmp,vpbf,wpbf)
                        
                        if l>0:
                            tmp.reset_powers(l-1,m,n)
                            tmp.normalize()
                            termb = -2*l*sqrt(alpha/(2.*l-1))*coefs*coulomb(tpbf,tmp,vpbf,wpbf)
                        else: termb = 0.0
                        
                        dJint_dXa += terma+termb
                        
                        #y component
                        tmp.reset_powers(l,m+1,n)
                        tmp.normalize()
                        
                        terma = sqrt(alpha*(2.0*m+1.0))*coefs*coulomb(tpbf,tmp,vpbf,wpbf)
                        
                        if m>0:
                            tmp.reset_powers(l,m-1,n)
                            tmp.normalize()
                            termb = -2*m*sqrt(alpha/(2.*m-1))*coefs*coulomb(tpbf,tmp,vpbf,wpbf)
                        else: termb=0.0
                        
                        dJint_dYa += terma + termb

                        #z component
                        tmp.reset_powers(l,m,n+1)
                        tmp.normalize()
                        
                        terma = sqrt(alpha*(2.0*n+1.0))*coefs*coulomb(tpbf,tmp,vpbf,wpbf)
                        
                        if n>0:
                            tmp.reset_powers(l,m,n-1)
                            tmp.normalize()
                            termb = -2*n*sqrt(alpha/(2.*n-1))*coefs*coulomb(tpbf,tmp,vpbf,wpbf)
                        else: termb=0.0
                        
                        dJint_dZa += terma + termb
    
    if bfk.atid==a: #bfk is centered on atom a
        for tpbf in bfi.prims:
            for upbf in bfj.prims:
                for vpbf in bfk.prims:
                    for wpbf in bfl.prims:
                        alpha  = vpbf.exp
                        l,m,n  = vpbf.powers
                        origin = vpbf.origin
                        coefs  = tpbf.coef*upbf.coef*vpbf.coef*wpbf.coef
                        
                        #x component
                        tmp = PGBF(alpha, origin,(l+1,m,n)) #temp pgbf
                        tmp.normalize()
                        
                        terma = sqrt(alpha*(2.0*l+1.0))*coefs*coulomb(tpbf,upbf,tmp,wpbf)
                        
                        if l>0:
                            tmp.reset_powers(l-1,m,n)
                            tmp.normalize()
                            termb = -2*l*sqrt(alpha/(2.*l-1))*coefs*coulomb(tpbf,upbf,tmp,wpbf)
                        else: termb = 0.0
                        
                        dJint_dXa += terma+termb
                        
                        #y component
                        tmp.reset_powers(l,m+1,n)
                        tmp.normalize()
                        
                        terma = sqrt(alpha*(2.0*m+1.0))*coefs*coulomb(tpbf,upbf,tmp,wpbf)
                        
                        if m>0:
                            tmp.reset_powers(l,m-1,n)
                            tmp.normalize()
                            termb = -2*m*sqrt(alpha/(2.*m-1))*coefs*coulomb(tpbf,upbf,tmp,wpbf)
                        else: termb=0.0
                        
                        dJint_dYa += terma + termb

                        #z component
                        tmp.reset_powers(l,m,n+1)
                        tmp.normalize()
                        
                        terma = sqrt(alpha*(2.0*n+1.0))*coefs*coulomb(tpbf,upbf,tmp,wpbf)
                        
                        if n>0:
                            tmp.reset_powers(l,m,n-1)
                            tmp.normalize()
                            termb = -2*n*sqrt(alpha/(2.*n-1))*coefs*coulomb(tpbf,upbf,tmp,wpbf)
                        else: termb=0.0
                        
                        dJint_dZa += terma + termb
    
    if bfl.atid==a: #bfl is centered on atom a
        for tpbf in bfi.prims:
            for upbf in bfj.prims:
                for vpbf in bfk.prims:
                    for wpbf in bfl.prims:
                        alpha  = wpbf.exp
                        l,m,n  = wpbf.powers
                        origin = wpbf.origin
                        coefs  = tpbf.coef*upbf.coef*vpbf.coef*wpbf.coef
                        
                        #x component
                        tmp = PGBF(alpha, origin,(l+1,m,n)) #temp pgbf
                        tmp.normalize()
                        
                        terma = sqrt(alpha*(2.0*l+1.0))*coefs*coulomb(tpbf,upbf,vpbf,tmp)
                        
                        if l>0:
                            tmp.reset_powers(l-1,m,n)
                            tmp.normalize()
                            termb = -2*l*sqrt(alpha/(2.*l-1))*coefs*coulomb(tpbf,upbf,vpbf,tmp)
                        else: termb = 0.0
                        
                        dJint_dXa += terma+termb
                        
                        #y component
                        tmp.reset_powers(l,m+1,n)
                        tmp.normalize()
                        
                        terma = sqrt(alpha*(2.0*m+1.0))*coefs*coulomb(tpbf,upbf,vpbf,tmp)
                        
                        if m>0:
                            tmp.reset_powers(l,m-1,n)
                            tmp.normalize()
                            termb = -2*m*sqrt(alpha/(2.*m-1))*coefs*coulomb(tpbf,upbf,vpbf,tmp)
                        else: termb=0.0
                        
                        dJint_dYa += terma + termb

                        #z component
                        tmp.reset_powers(l,m,n+1)
                        tmp.normalize()
                        
                        terma = sqrt(alpha*(2.0*n+1.0))*coefs*coulomb(tpbf,upbf,vpbf,tmp)
                        
                        if n>0:
                            tmp.reset_powers(l,m,n-1)
                            tmp.normalize()
                            termb = -2*n*sqrt(alpha/(2.*n-1))*coefs*coulomb(tpbf,upbf,vpbf,tmp)
                        else: termb=0.0
                        
                        dJint_dZa += terma + termb
    
    return dJint_dXa,dJint_dYa,dJint_dZa
コード例 #4
0
def der_nuc_att(a,bfi,bfj,atoms):
    """
    This function finds the atomic gradient of the nuclear attraction integrals. Since the
    nuclear attraction operator explicitly depends on the atomic coordinates we find 
    
    grad <i|V|j> = <grad i|V|j> + <i|V|grad j> + <i| grad V |j>
    
    The first two terms are straightforward to evaluate using the recursion relation for the
    derivative of a Gaussian basis function.  The last term found through the nuclear_gradient
    function in the primitive Gaussian class.  
    """
    
    dVij_dXa,dVij_dYa,dVij_dZa = 0.0,0.0,0.0
    if bfi.atid==a: #bfi is centered on atom a
        for upbf in bfj.prims:
            for vpbf in bfi.prims:
                alpha = vpbf.exp
                l,m,n = vpbf.powers
                origin = vpbf.origin
                coefs  = upbf.coef*vpbf.coef
                                
                #x component
                v = PGBF(alpha,origin,(l+1,m,n))
                v.normalize()
                
                terma=0.0
                for atom in atoms:                    
                    terma += atom.atno*sqrt(alpha*(2.0*l+1.0))*coefs*v.nuclear(upbf,atom.pos())
                
                if l>0:
                    v.reset_powers(l-1,m,n)
                    v.normalize()
                    
                    termb=0.0
                    for atom in atoms:
                        termb += -2*l*atom.atno*sqrt(alpha/(2.0*l-1.0))*coefs*v.nuclear(upbf,atom.pos())
                        
                else: termb = 0.0
                
                dVij_dXa += terma + termb
                
                
                #y component
                v.reset_powers(l,m+1,n)
                v.normalize()

                terma=0.0
                for atom in atoms:
                    terma += atom.atno*sqrt(alpha*(2.0*m+1.0))*coefs*v.nuclear(upbf,atom.pos())
                
                if m>0:
                    v.reset_powers(l,m-1,n)
                    v.normalize()
                    
                    termb=0.0
                    for atom in atoms:
                        termb += -2*m*atom.atno*sqrt(alpha/(2.0*m-1.0))*coefs*v.nuclear(upbf,atom.pos())
                else: termb = 0.0
                
                dVij_dYa += terma + termb
                
                #z component
                v.reset_powers(l,m,n+1)
                v.normalize()
                
                terma=0.0
                for atom in atoms:
                    terma += atom.atno*sqrt(alpha*(2.0*n+1.0))*coefs*v.nuclear(upbf,atom.pos())
                
                if n>0:
                    v.reset_powers(l,m,n-1)
                    v.normalize()
                    
                    termb=0.0
                    for atom in atoms:
                        termb += -2*n*atom.atno*sqrt(alpha/(2.0*n-1.0))*coefs*v.nuclear(upbf,atom.pos())
                else: termb = 0.0
                
                dVij_dZa += terma + termb

                
    #bfj is centered on atom a
    if bfj.atid==a:
        for upbf in bfi.prims:
            for vpbf in bfj.prims:
                alpha = vpbf.exp
                l,m,n = vpbf.powers
                origin = vpbf.origin
                coefs = upbf.coef*vpbf.coef
                
                #x component 
                v = PGBF(alpha,origin,(l+1,m,n))
                v.normalize()
                
                terma=0.0
                for atom in atoms:
                    terma += atom.atno*sqrt(alpha*(2.0*l+1.0))*coefs*v.nuclear(upbf,atom.pos())
                
                if l>0:
                    v.reset_powers(l-1,m,n)
                    v.normalize()
                    
                    termb=0.0
                    for atom in atoms:
                        termb += -2*l*atom.atno*sqrt(alpha/(2.0*l-1.0))*coefs*v.nuclear(upbf,atom.pos())
                else: termb = 0.0
                
                dVij_dXa += terma + termb
                

                #y component
                v.reset_powers(l,m+1,n)
                v.normalize()

                terma=0.0
                for atom in atoms:
                    terma += atom.atno*sqrt(alpha*(2.0*m+1.0))*coefs*v.nuclear(upbf,atom.pos())
                
                if m>0:
                    v.reset_powers(l,m-1,n)
                    v.normalize()
                    
                    termb=0.0
                    for atom in atoms:
                        termb += -2*m*atom.atno*sqrt(alpha/(2.0*m-1.0))*coefs*v.nuclear(upbf,atom.pos())
                else: termb = 0.0
                
                dVij_dYa += terma + termb
                
                #z component
                v.reset_powers(l,m,n+1)
                v.normalize()
                
                terma=0.0
                for atom in atoms:
                    terma += atom.atno*sqrt(alpha*(2.0*n+1.0))*coefs*v.nuclear(upbf,atom.pos())
                
                if n>0:
                    v.reset_powers(l,m,n-1)
                    v.normalize()
                    
                    termb = 0.0
                    for atom in atoms:
                        termb += -2*n*atom.atno*sqrt(alpha/(2.0*n-1.0))*coefs*v.nuclear(upbf,atom.pos())
                else: termb = 0.0
                
                dVij_dZa += terma + termb
    
    #finally evaluate <i| grad V |j>
    for atom in atoms:
        if atom.atid==a:
            for upbf in bfi.prims:
                for vpbf in bfj.prims:
                    prefactor = upbf.coef*vpbf.coef*atom.atno
                    list = upbf.nuclear_gradient(vpbf,atom.pos())
                    
                    dVij_dXa+=prefactor*list[0]
                    dVij_dYa+=prefactor*list[1]
                    dVij_dZa+=prefactor*list[2]
        

    return dVij_dXa,dVij_dYa,dVij_dZa
コード例 #5
0
def der_Jints(a, bfi, bfj, bfk, bfl):
    """
    This function will find the atomic gradient of the Coloumb integral over
    basis functions i,j,k, and l as in
    
    grad_a <ij|kl> = <gi j|kl> + <i gj|kl> + <ij|gk l> + <ij|k gl>
    """
    dJint_dXa, dJint_dYa, dJint_dZa = 0.0, 0.0, 0.0

    if bfi.atid == a:  #bfi is centered on atom a
        for tpbf in bfi.prims:
            for upbf in bfj.prims:
                for vpbf in bfk.prims:
                    for wpbf in bfl.prims:
                        alpha = tpbf.exp
                        l, m, n = tpbf.powers
                        origin = tpbf.origin
                        coefs = tpbf.coef * upbf.coef * vpbf.coef * wpbf.coef

                        #x component
                        tmp = PGBF(alpha, origin, (l + 1, m, n))  #temp pgbf
                        tmp.normalize()

                        terma = sqrt(alpha *
                                     (2.0 * l + 1.0)) * coefs * coulomb(
                                         tmp, upbf, vpbf, wpbf)

                        if l > 0:
                            tmp.reset_powers(l - 1, m, n)
                            tmp.normalize()
                            termb = -2 * l * sqrt(
                                alpha / (2. * l - 1)) * coefs * coulomb(
                                    tmp, upbf, vpbf, wpbf)
                        else:
                            termb = 0.0

                        dJint_dXa += terma + termb

                        #y component
                        tmp.reset_powers(l, m + 1, n)
                        tmp.normalize()

                        terma = sqrt(alpha *
                                     (2.0 * m + 1.0)) * coefs * coulomb(
                                         tmp, upbf, vpbf, wpbf)

                        if m > 0:
                            tmp.reset_powers(l, m - 1, n)
                            tmp.normalize()
                            termb = -2 * m * sqrt(
                                alpha / (2. * m - 1)) * coefs * coulomb(
                                    tmp, upbf, vpbf, wpbf)
                        else:
                            termb = 0.0

                        dJint_dYa += terma + termb

                        #z component
                        tmp.reset_powers(l, m, n + 1)
                        tmp.normalize()

                        terma = sqrt(alpha *
                                     (2.0 * n + 1.0)) * coefs * coulomb(
                                         tmp, upbf, vpbf, wpbf)

                        if n > 0:
                            tmp.reset_powers(l, m, n - 1)
                            tmp.normalize()
                            termb = -2 * n * sqrt(
                                alpha / (2. * n - 1)) * coefs * coulomb(
                                    tmp, upbf, vpbf, wpbf)
                        else:
                            termb = 0.0

                        dJint_dZa += terma + termb

    if bfj.atid == a:  #bfj is centered on atom a
        for tpbf in bfi.prims:
            for upbf in bfj.prims:
                for vpbf in bfk.prims:
                    for wpbf in bfl.prims:
                        alpha = upbf.exp
                        l, m, n = upbf.powers
                        origin = upbf.origin
                        coefs = tpbf.coef * upbf.coef * vpbf.coef * wpbf.coef

                        #x component
                        tmp = PGBF(alpha, origin, (l + 1, m, n))  #temp pgbf
                        tmp.normalize()

                        terma = sqrt(alpha *
                                     (2.0 * l + 1.0)) * coefs * coulomb(
                                         tpbf, tmp, vpbf, wpbf)

                        if l > 0:
                            tmp.reset_powers(l - 1, m, n)
                            tmp.normalize()
                            termb = -2 * l * sqrt(
                                alpha / (2. * l - 1)) * coefs * coulomb(
                                    tpbf, tmp, vpbf, wpbf)
                        else:
                            termb = 0.0

                        dJint_dXa += terma + termb

                        #y component
                        tmp.reset_powers(l, m + 1, n)
                        tmp.normalize()

                        terma = sqrt(alpha *
                                     (2.0 * m + 1.0)) * coefs * coulomb(
                                         tpbf, tmp, vpbf, wpbf)

                        if m > 0:
                            tmp.reset_powers(l, m - 1, n)
                            tmp.normalize()
                            termb = -2 * m * sqrt(
                                alpha / (2. * m - 1)) * coefs * coulomb(
                                    tpbf, tmp, vpbf, wpbf)
                        else:
                            termb = 0.0

                        dJint_dYa += terma + termb

                        #z component
                        tmp.reset_powers(l, m, n + 1)
                        tmp.normalize()

                        terma = sqrt(alpha *
                                     (2.0 * n + 1.0)) * coefs * coulomb(
                                         tpbf, tmp, vpbf, wpbf)

                        if n > 0:
                            tmp.reset_powers(l, m, n - 1)
                            tmp.normalize()
                            termb = -2 * n * sqrt(
                                alpha / (2. * n - 1)) * coefs * coulomb(
                                    tpbf, tmp, vpbf, wpbf)
                        else:
                            termb = 0.0

                        dJint_dZa += terma + termb

    if bfk.atid == a:  #bfk is centered on atom a
        for tpbf in bfi.prims:
            for upbf in bfj.prims:
                for vpbf in bfk.prims:
                    for wpbf in bfl.prims:
                        alpha = vpbf.exp
                        l, m, n = vpbf.powers
                        origin = vpbf.origin
                        coefs = tpbf.coef * upbf.coef * vpbf.coef * wpbf.coef

                        #x component
                        tmp = PGBF(alpha, origin, (l + 1, m, n))  #temp pgbf
                        tmp.normalize()

                        terma = sqrt(alpha *
                                     (2.0 * l + 1.0)) * coefs * coulomb(
                                         tpbf, upbf, tmp, wpbf)

                        if l > 0:
                            tmp.reset_powers(l - 1, m, n)
                            tmp.normalize()
                            termb = -2 * l * sqrt(
                                alpha / (2. * l - 1)) * coefs * coulomb(
                                    tpbf, upbf, tmp, wpbf)
                        else:
                            termb = 0.0

                        dJint_dXa += terma + termb

                        #y component
                        tmp.reset_powers(l, m + 1, n)
                        tmp.normalize()

                        terma = sqrt(alpha *
                                     (2.0 * m + 1.0)) * coefs * coulomb(
                                         tpbf, upbf, tmp, wpbf)

                        if m > 0:
                            tmp.reset_powers(l, m - 1, n)
                            tmp.normalize()
                            termb = -2 * m * sqrt(
                                alpha / (2. * m - 1)) * coefs * coulomb(
                                    tpbf, upbf, tmp, wpbf)
                        else:
                            termb = 0.0

                        dJint_dYa += terma + termb

                        #z component
                        tmp.reset_powers(l, m, n + 1)
                        tmp.normalize()

                        terma = sqrt(alpha *
                                     (2.0 * n + 1.0)) * coefs * coulomb(
                                         tpbf, upbf, tmp, wpbf)

                        if n > 0:
                            tmp.reset_powers(l, m, n - 1)
                            tmp.normalize()
                            termb = -2 * n * sqrt(
                                alpha / (2. * n - 1)) * coefs * coulomb(
                                    tpbf, upbf, tmp, wpbf)
                        else:
                            termb = 0.0

                        dJint_dZa += terma + termb

    if bfl.atid == a:  #bfl is centered on atom a
        for tpbf in bfi.prims:
            for upbf in bfj.prims:
                for vpbf in bfk.prims:
                    for wpbf in bfl.prims:
                        alpha = wpbf.exp
                        l, m, n = wpbf.powers
                        origin = wpbf.origin
                        coefs = tpbf.coef * upbf.coef * vpbf.coef * wpbf.coef

                        #x component
                        tmp = PGBF(alpha, origin, (l + 1, m, n))  #temp pgbf
                        tmp.normalize()

                        terma = sqrt(alpha *
                                     (2.0 * l + 1.0)) * coefs * coulomb(
                                         tpbf, upbf, vpbf, tmp)

                        if l > 0:
                            tmp.reset_powers(l - 1, m, n)
                            tmp.normalize()
                            termb = -2 * l * sqrt(
                                alpha / (2. * l - 1)) * coefs * coulomb(
                                    tpbf, upbf, vpbf, tmp)
                        else:
                            termb = 0.0

                        dJint_dXa += terma + termb

                        #y component
                        tmp.reset_powers(l, m + 1, n)
                        tmp.normalize()

                        terma = sqrt(alpha *
                                     (2.0 * m + 1.0)) * coefs * coulomb(
                                         tpbf, upbf, vpbf, tmp)

                        if m > 0:
                            tmp.reset_powers(l, m - 1, n)
                            tmp.normalize()
                            termb = -2 * m * sqrt(
                                alpha / (2. * m - 1)) * coefs * coulomb(
                                    tpbf, upbf, vpbf, tmp)
                        else:
                            termb = 0.0

                        dJint_dYa += terma + termb

                        #z component
                        tmp.reset_powers(l, m, n + 1)
                        tmp.normalize()

                        terma = sqrt(alpha *
                                     (2.0 * n + 1.0)) * coefs * coulomb(
                                         tpbf, upbf, vpbf, tmp)

                        if n > 0:
                            tmp.reset_powers(l, m, n - 1)
                            tmp.normalize()
                            termb = -2 * n * sqrt(
                                alpha / (2. * n - 1)) * coefs * coulomb(
                                    tpbf, upbf, vpbf, tmp)
                        else:
                            termb = 0.0

                        dJint_dZa += terma + termb

    return dJint_dXa, dJint_dYa, dJint_dZa
コード例 #6
0
def der_kinetic_integral(a, bfi, bfj):
    """
    The kinetic energy operator does not depend on the atomic position so we only
    have to consider differentiating the Gaussian functions.  There are 4 possible
    cases we have to evaluate
    
    Case 1: Neither of the basis functions depends on the position of atom A which gives:
        dT_ij/dXa = 0
    
    Cases 2 and 3: Only one of the basis functions depends the position of atom A which 
    gives us either of the following possible integrals to evaluate
        dT_ij/dXa = integral{dr dg_i/dXa T g_j }
        
        dT_ij/dXa = integral{dr g_i T dg_j/dXa  }
    
    Case 4: Both of the basis functions depend on the position of atom A which gives the
    following integral to evaluate
        dT_ij/dXa = integral{dr dg_i/dXa T g_j + g_i T dg_j/dXa  }
    """
    dTij_dXa, dTij_dYa, dTij_dZa = 0.0, 0.0, 0.0

    #we use atom ids on the CGBFs to evaluate which of the 4 above case we have
    #bfi is centered on atom a
    if bfi.atid == a:
        for upbf in bfj.prims:
            for vpbf in bfi.prims:
                alpha = vpbf.exp
                l, m, n = vpbf.powers
                origin = vpbf.origin
                coefs = upbf.coef * vpbf.coef

                #x component
                v = PGBF(alpha, origin, (l + 1, m, n))
                v.normalize()

                terma = sqrt(alpha * (2.0 * l + 1.0)) * coefs * v.kinetic(upbf)

                if l > 0:
                    v.reset_powers(l - 1, m, n)
                    v.normalize()
                    termb = -2 * l * sqrt(
                        alpha / (2.0 * l - 1.0)) * coefs * v.kinetic(upbf)
                else:
                    termb = 0.0

                dTij_dXa += terma + termb

                #y component
                v.reset_powers(l, m + 1, n)
                v.normalize()
                terma = sqrt(alpha * (2.0 * m + 1.0)) * coefs * v.kinetic(upbf)

                if m > 0:
                    v.reset_powers(l, m - 1, n)
                    v.normalize()
                    termb = -2 * m * sqrt(
                        alpha / (2.0 * m - 1.0)) * coefs * v.kinetic(upbf)
                else:
                    termb = 0.0

                dTij_dYa += terma + termb

                #z component
                v.reset_powers(l, m, n + 1)
                v.normalize()
                terma = sqrt(alpha * (2.0 * n + 1.0)) * coefs * v.kinetic(upbf)

                if n > 0:
                    v.reset_powers(l, m, n - 1)
                    v.normalize()
                    termb = -2 * n * sqrt(
                        alpha / (2.0 * n - 1.0)) * coefs * v.kinetic(upbf)
                else:
                    termb = 0.0

                dTij_dZa += terma + termb

    #bfj is centered on atom a
    if bfj.atid == a:
        for upbf in bfi.prims:
            for vpbf in bfj.prims:
                alpha = vpbf.exp
                l, m, n = vpbf.powers
                origin = vpbf.origin
                coefs = upbf.coef * vpbf.coef

                #x component
                v = PGBF(alpha, origin, (l + 1, m, n))
                v.normalize()

                terma = sqrt(alpha * (2.0 * l + 1.0)) * coefs * v.kinetic(upbf)

                if l > 0:
                    v.reset_powers(l - 1, m, n)
                    v.normalize()
                    termb = -2 * l * sqrt(
                        alpha / (2.0 * l - 1.0)) * coefs * v.kinetic(upbf)
                else:
                    termb = 0.0

                dTij_dXa += terma + termb

                #y component
                v.reset_powers(l, m + 1, n)
                v.normalize()
                terma = sqrt(alpha * (2.0 * m + 1.0)) * coefs * v.kinetic(upbf)

                if m > 0:
                    v.reset_powers(l, m - 1, n)
                    v.normalize()
                    termb = -2 * m * sqrt(
                        alpha / (2.0 * m - 1.0)) * coefs * v.kinetic(upbf)
                else:
                    termb = 0.0

                dTij_dYa += terma + termb

                #z component
                v.reset_powers(l, m, n + 1)
                v.normalize()
                terma = sqrt(alpha * (2.0 * n + 1.0)) * coefs * v.kinetic(upbf)

                if n > 0:
                    v.reset_powers(l, m, n - 1)
                    v.normalize()
                    termb = -2 * n * sqrt(
                        alpha / (2.0 * n - 1.0)) * coefs * v.kinetic(upbf)
                else:
                    termb = 0.0

                dTij_dZa += terma + termb

    return dTij_dXa, dTij_dYa, dTij_dZa
コード例 #7
0
def der_overlap_element(a, bfi, bfj):
    """
    finds the derivative of the overlap integral with respect to the 
    atomic coordinate of atom "a".  Note there are four possible cases
    for evaluating this integral:
     1. Neither of the basis functions depend on the position of atom a
        ie. they are centered on atoms other than atom a
     2 and 3. One of the basis functions depends on the position of atom a
        so we need to evaluate the derivative of a Gaussian with the 
        recursion (right word?) relation derived on page 442 of Szabo.
     4. Both of the basis functions are centered on atom a, which through the
        recursion relation for the derivative of a Gaussian basis function will
        require the evaluation of 4 overlap integrals...

    this function will return a 3 element list with the derivatives of the overlap
    integrals with respect to the atomic coordinates Xa,Ya,Za.
    """
    dSij_dXa, dSij_dYa, dSij_dZa = 0.0, 0.0, 0.0

    #we use atom ids on the CGBFs to evaluate which of the 4 above case we have
    if bfi.atid == a:  #bfi is centered on atom a
        for upbf in bfj.prims:
            for vpbf in bfi.prims:
                alpha = vpbf.exp
                l, m, n = vpbf.powers
                origin = vpbf.origin
                coefs = upbf.coef * vpbf.coef

                #x component
                v = PGBF(alpha, origin, (l + 1, m, n))
                v.normalize()

                terma = sqrt(alpha * (2.0 * l + 1.0)) * coefs * v.overlap(upbf)

                if l > 0:
                    v.reset_powers(l - 1, m, n)
                    v.normalize()
                    termb = -2 * l * sqrt(
                        alpha / (2.0 * l - 1.0)) * coefs * v.overlap(upbf)
                else:
                    termb = 0.0

                dSij_dXa += terma + termb

                #y component
                v.reset_powers(l, m + 1, n)
                v.normalize()
                terma = sqrt(alpha * (2.0 * m + 1.0)) * coefs * v.overlap(upbf)

                if m > 0:
                    v.reset_powers(l, m - 1, n)
                    v.normalize()
                    termb = -2 * m * sqrt(
                        alpha / (2.0 * m - 1.0)) * coefs * v.overlap(upbf)
                else:
                    termb = 0.0

                dSij_dYa += terma + termb

                #z component
                v.reset_powers(l, m, n + 1)
                v.normalize()
                terma = sqrt(alpha * (2.0 * n + 1.0)) * coefs * v.overlap(upbf)

                if n > 0:
                    v.reset_powers(l, m, n - 1)
                    v.normalize()
                    termb = -2 * n * sqrt(
                        alpha / (2.0 * n - 1.0)) * coefs * v.overlap(upbf)
                else:
                    termb = 0.0

                dSij_dZa += terma + termb

    #bfj is centered on atom a
    if bfj.atid == a:
        for upbf in bfi.prims:
            for vpbf in bfj.prims:
                alpha = vpbf.exp
                l, m, n = vpbf.powers
                origin = vpbf.origin
                coefs = upbf.coef * vpbf.coef

                #x component
                v = PGBF(alpha, origin, (l + 1, m, n))
                v.normalize()

                terma = sqrt(alpha * (2.0 * l + 1.0)) * coefs * v.overlap(upbf)

                if l > 0:
                    v.reset_powers(l - 1, m, n)
                    v.normalize()
                    termb = -2 * l * sqrt(
                        alpha / (2.0 * l - 1.0)) * coefs * v.overlap(upbf)
                else:
                    termb = 0.0

                dSij_dXa += terma + termb

                #y component
                v.reset_powers(l, m + 1, n)
                v.normalize()
                terma = sqrt(alpha * (2.0 * m + 1.0)) * coefs * v.overlap(upbf)

                if m > 0:
                    v.reset_powers(l, m - 1, n)
                    v.normalize()
                    termb = -2 * m * sqrt(
                        alpha / (2.0 * m - 1.0)) * coefs * v.overlap(upbf)
                else:
                    termb = 0.0

                dSij_dYa += terma + termb

                #z component
                v.reset_powers(l, m, n + 1)
                v.normalize()
                terma = sqrt(alpha * (2.0 * n + 1.0)) * coefs * v.overlap(upbf)

                if n > 0:
                    v.reset_powers(l, m, n - 1)
                    v.normalize()
                    termb = -2 * n * sqrt(
                        alpha / (2.0 * n - 1.0)) * coefs * v.overlap(upbf)
                else:
                    termb = 0.0

                dSij_dZa += terma + termb

    return dSij_dXa, dSij_dYa, dSij_dZa
コード例 #8
0
def der_nuc_att(a, bfi, bfj, atoms):
    """
    This function finds the atomic gradient of the nuclear attraction integrals. Since the
    nuclear attraction operator explicitly depends on the atomic coordinates we find 
    
    grad <i|V|j> = <grad i|V|j> + <i|V|grad j> + <i| grad V |j>
    
    The first two terms are straightforward to evaluate using the recursion relation for the
    derivative of a Gaussian basis function.  The last term found through the nuclear_gradient
    function in the primitive Gaussian class.  
    """

    dVij_dXa, dVij_dYa, dVij_dZa = 0.0, 0.0, 0.0
    if bfi.atid == a:  #bfi is centered on atom a
        for upbf in bfj.prims:
            for vpbf in bfi.prims:
                alpha = vpbf.exp
                l, m, n = vpbf.powers
                origin = vpbf.origin
                coefs = upbf.coef * vpbf.coef

                #x component
                v = PGBF(alpha, origin, (l + 1, m, n))
                v.normalize()

                terma = 0.0
                for atom in atoms:
                    terma += atom.atno * sqrt(
                        alpha *
                        (2.0 * l + 1.0)) * coefs * v.nuclear(upbf, atom.pos())

                if l > 0:
                    v.reset_powers(l - 1, m, n)
                    v.normalize()

                    termb = 0.0
                    for atom in atoms:
                        termb += -2 * l * atom.atno * sqrt(
                            alpha / (2.0 * l - 1.0)) * coefs * v.nuclear(
                                upbf, atom.pos())

                else:
                    termb = 0.0

                dVij_dXa += terma + termb

                #y component
                v.reset_powers(l, m + 1, n)
                v.normalize()

                terma = 0.0
                for atom in atoms:
                    terma += atom.atno * sqrt(
                        alpha *
                        (2.0 * m + 1.0)) * coefs * v.nuclear(upbf, atom.pos())

                if m > 0:
                    v.reset_powers(l, m - 1, n)
                    v.normalize()

                    termb = 0.0
                    for atom in atoms:
                        termb += -2 * m * atom.atno * sqrt(
                            alpha / (2.0 * m - 1.0)) * coefs * v.nuclear(
                                upbf, atom.pos())
                else:
                    termb = 0.0

                dVij_dYa += terma + termb

                #z component
                v.reset_powers(l, m, n + 1)
                v.normalize()

                terma = 0.0
                for atom in atoms:
                    terma += atom.atno * sqrt(
                        alpha *
                        (2.0 * n + 1.0)) * coefs * v.nuclear(upbf, atom.pos())

                if n > 0:
                    v.reset_powers(l, m, n - 1)
                    v.normalize()

                    termb = 0.0
                    for atom in atoms:
                        termb += -2 * n * atom.atno * sqrt(
                            alpha / (2.0 * n - 1.0)) * coefs * v.nuclear(
                                upbf, atom.pos())
                else:
                    termb = 0.0

                dVij_dZa += terma + termb

    #bfj is centered on atom a
    if bfj.atid == a:
        for upbf in bfi.prims:
            for vpbf in bfj.prims:
                alpha = vpbf.exp
                l, m, n = vpbf.powers
                origin = vpbf.origin
                coefs = upbf.coef * vpbf.coef

                #x component
                v = PGBF(alpha, origin, (l + 1, m, n))
                v.normalize()

                terma = 0.0
                for atom in atoms:
                    terma += atom.atno * sqrt(
                        alpha *
                        (2.0 * l + 1.0)) * coefs * v.nuclear(upbf, atom.pos())

                if l > 0:
                    v.reset_powers(l - 1, m, n)
                    v.normalize()

                    termb = 0.0
                    for atom in atoms:
                        termb += -2 * l * atom.atno * sqrt(
                            alpha / (2.0 * l - 1.0)) * coefs * v.nuclear(
                                upbf, atom.pos())
                else:
                    termb = 0.0

                dVij_dXa += terma + termb

                #y component
                v.reset_powers(l, m + 1, n)
                v.normalize()

                terma = 0.0
                for atom in atoms:
                    terma += atom.atno * sqrt(
                        alpha *
                        (2.0 * m + 1.0)) * coefs * v.nuclear(upbf, atom.pos())

                if m > 0:
                    v.reset_powers(l, m - 1, n)
                    v.normalize()

                    termb = 0.0
                    for atom in atoms:
                        termb += -2 * m * atom.atno * sqrt(
                            alpha / (2.0 * m - 1.0)) * coefs * v.nuclear(
                                upbf, atom.pos())
                else:
                    termb = 0.0

                dVij_dYa += terma + termb

                #z component
                v.reset_powers(l, m, n + 1)
                v.normalize()

                terma = 0.0
                for atom in atoms:
                    terma += atom.atno * sqrt(
                        alpha *
                        (2.0 * n + 1.0)) * coefs * v.nuclear(upbf, atom.pos())

                if n > 0:
                    v.reset_powers(l, m, n - 1)
                    v.normalize()

                    termb = 0.0
                    for atom in atoms:
                        termb += -2 * n * atom.atno * sqrt(
                            alpha / (2.0 * n - 1.0)) * coefs * v.nuclear(
                                upbf, atom.pos())
                else:
                    termb = 0.0

                dVij_dZa += terma + termb

    #finally evaluate <i| grad V |j>
    for atom in atoms:
        if atom.atid == a:
            for upbf in bfi.prims:
                for vpbf in bfj.prims:
                    prefactor = upbf.coef * vpbf.coef * atom.atno
                    list = upbf.nuclear_gradient(vpbf, atom.pos())

                    dVij_dXa += prefactor * list[0]
                    dVij_dYa += prefactor * list[1]
                    dVij_dZa += prefactor * list[2]

    return dVij_dXa, dVij_dYa, dVij_dZa