Beispiel #1
0
    def mkQmatrix(self):
        #computes Q matrix which is basically density matrix weighted by the orbital eigenvalues
        if self.restricted:
            occ_orbe = self.orbe[0:self.nclosed]
            occ_orbs = self.orbs[:, 0:self.nclosed]
            Qmat = matrixmultiply(
                occ_orbs,
                matrixmultiply(diagonal_mat(occ_orbe), transpose(occ_orbs)))
            return Qmat

        if self.unrestricted:
            occ_orbs_A = self.orbs_a[:, 0:self.nalpha]
            occ_orbs_B = self.orbs_b[:, 0:self.nbeta]
            occ_orbe_A = self.orbe_a[0:self.nalpha]
            occ_orbe_B = self.orbe_b[0:self.nbeta]

            Qa = matrixmultiply(
                occ_orbs_A,
                matrixmultiply(diagonal_mat(occ_orbe_A),
                               transpose(occ_orbs_A)))
            Qb = matrixmultiply(
                occ_orbs_B,
                matrixmultiply(diagonal_mat(occ_orbe_B),
                               transpose(occ_orbs_B)))
            return Qa, Qb
Beispiel #2
0
def mk_auger_dens(c, occ):
    "Forms a density matrix from a coef matrix c and occupations in occ"
    #count how many states we were given
    nstates = occ.shape[0]
    D = 0.0
    for i in xrange(nstates):
        D += occ[i]*dot( c[:,i:i+1], transpose(c[:,i:i+1]))
    #pad_out(D)
    return D
Beispiel #3
0
def mk_auger_dens(c, occ):
    "Forms a density matrix from a coef matrix c and occupations in occ"
    #count how many states we were given
    nstates = occ.shape[0]
    D = 0.0
    for i in xrange(nstates):
        D += occ[i] * dot(c[:, i:i + 1], transpose(c[:, i:i + 1]))
    #pad_out(D)
    return D
Beispiel #4
0
 def mk_auger_dens(self):
     "Forms a density matrix from a coef matrix c and occupations in occ"
     if self.restricted:
         nstates = self.occs.shape[0]
         D = 0.0
         for i in range(nstates):
             D += self.occs[i]*dot( self.orbs[:,i:i+1], transpose(self.orbs[:,i:i+1]))
         #pad_out(D)
         return D
     if self.fixedocc:
         nastates = self.occs_a.shape[0]
         nbstates = self.occs_b.shape[0]
         Da,Db = 0.0,0.0
         for i in range(nastates):
             Da += self.occs_a[i]*dot( self.orbs_a[:,i:i+1], transpose(self.orbs_a[:,i:i+1]))
         for i in range(nbstates):
             Db += self.occs_b[i]*dot( self.orbs_b[:,i:i+1], transpose(self.orbs_b[:,i:i+1]))
         
         return Da,Db
Beispiel #5
0
 def mk_auger_Qmatrix(self):
     #computes Q matrix using occ arrays, which is basically density matrix weighted by the orbital eigenvalues
     if self.restricted:
         nstates = self.occs.shape[0]
         Qmat = 0.0
         for i in range(nstates):
             Qmat += self.orbe[i]*self.occs[i]*dot( self.orbs[:,i:i+1], transpose(self.orbs[:,i:i+1]))
         return Qmat
         
     if self.fixedocc:
         nastates = self.occs_a.shape[0]
         nbstates = self.occs_b.shape[0]
         Qa,Qb = 0.0,0.0
         for i in range(nastates):
             Qa += self.orbe_a[i]*self.occs_a[i]*dot( self.orbs_a[:,i:i+1], transpose(self.orbs_a[:,i:i+1]))
         for i in range(nbstates):
             Qb += self.orbe_a[i]*self.occs_b[i]*dot( self.orbs_b[:,i:i+1], transpose(self.orbs_b[:,i:i+1]))
         
         return Qa,Qb
Beispiel #6
0
 def mk_auger_Qmatrix(self):
     #computes Q matrix using occ arrays, which is basically density matrix weighted by the orbital eigenvalues
     if self.restricted:
         nstates = self.occs.shape[0]
         Qmat = 0.0
         for i in xrange(nstates):
             Qmat += self.orbe[i]*self.occs[i]*dot( self.orbs[:,i:i+1], transpose(self.orbs[:,i:i+1]))
         return Qmat
         
     if self.fixedocc:
         nastates = self.occs_a.shape[0]
         nbstates = self.occs_b.shape[0]
         Qa,Qb = 0.0,0.0
         for i in xrange(nastates):
             Qa += self.orbe_a[i]*self.occs_a[i]*dot( self.orbs_a[:,i:i+1], transpose(self.orbs_a[:,i:i+1]))
         for i in xrange(nbstates):
             Qb += self.orbe_a[i]*self.occs_b[i]*dot( self.orbs_b[:,i:i+1], transpose(self.orbs_b[:,i:i+1]))
         
         return Qa,Qb
Beispiel #7
0
 def mk_auger_dens(self):
     "Forms a density matrix from a coef matrix c and occupations in occ"
     if self.restricted:
         nstates = self.occs.shape[0]
         D = 0.0
         for i in xrange(nstates):
             D += self.occs[i]*dot( self.orbs[:,i:i+1], transpose(self.orbs[:,i:i+1]))
         #pad_out(D)
         return D
     if self.fixedocc:
         nastates = self.occs_a.shape[0]
         nbstates = self.occs_b.shape[0]
         Da,Db = 0.0,0.0
         for i in xrange(nastates):
             Da += self.occs_a[i]*dot( self.orbs_a[:,i:i+1], transpose(self.orbs_a[:,i:i+1]))
         for i in xrange(nbstates):
             Db += self.occs_b[i]*dot( self.orbs_b[:,i:i+1], transpose(self.orbs_b[:,i:i+1]))
         
         return Da,Db
Beispiel #8
0
 def mkQmatrix(self):
     #computes Q matrix which is basically density matrix weighted by the orbital eigenvalues
     if self.restricted:
         occ_orbe = self.orbe[0:self.nclosed]
         occ_orbs = self.orbs[:,0:self.nclosed]
         Qmat = matrixmultiply( occ_orbs, matrixmultiply( diagonal_mat(occ_orbe), transpose(occ_orbs) ) )
         return Qmat
         
     if self.unrestricted:
         occ_orbs_A = self.orbs_a[:,0:self.nalpha]
         occ_orbs_B = self.orbs_b[:,0:self.nbeta]
         occ_orbe_A = self.orbe_a[0:self.nalpha]
         occ_orbe_B = self.orbe_b[0:self.nbeta]
         
         Qa = matrixmultiply( occ_orbs_A, matrixmultiply( diagonal_mat(occ_orbe_A), transpose(occ_orbs_A) ) )
         Qb = matrixmultiply( occ_orbs_B, matrixmultiply( diagonal_mat(occ_orbe_B), transpose(occ_orbs_B) ) )
         return Qa,Qb
Beispiel #9
0
def mkdens_occs(c,occs,**kwargs):
    "Density matrix from a set of occupations (e.g. from FD expression)."
    tol = kwargs.get('tol',settings.FDOccTolerance)
    verbose = kwargs.get('verbose')
    # Determine how many orbs have occupations greater than 0
    norb = 0
    for fi in occs:
        if fi < tol: break
        norb += 1
    if verbose:
        print "mkdens_occs: %d occupied orbitals found" % norb
    # Determine how many doubly occupied orbitals we have
    nclosed = 0
    for i in xrange(norb):
        if abs(1.-occs[i]) > tol: break
        nclosed += 1
    if verbose:
        print "mkdens_occs: %d closed-shell orbitals found" % nclosed
    D = mkdens(c,0,nclosed)
    for i in xrange(nclosed,norb):
        D = D + occs[i]*matrixmultiply(c[:,i:i+1],transpose(c[:,i:i+1]))
    return D
Beispiel #10
0
def getXC(gr,nel,**kwargs):
    "Form the exchange-correlation matrix"

    functional = kwargs.get('functional','SVWN')
    do_grad_dens = need_gradients[functional]
    do_spin_polarized = kwargs.get('do_spin_polarized')
    
    gr.floor_density()  # Insure that the values of the density don't underflow
    gr.renormalize(nel) # Renormalize to the proper # electrons

    dens = gr.dens()
    weight = gr.weights()
    gamma = gr.get_gamma()
    npts = len(dens)

    if gr.version == 1:
        amdens = zeros((2,npts),'d')
        amgamma = zeros((3,npts),'d')
        amdens[0,:] = amdens[1,:] = 0.5*dens
        if gamma is not None:
            amgamma[0,:] = amgamma[1,:] = amgamma[2,:] = 0.25*gamma
    elif gr.version == 2:
        amdens = gr.density.T
        amgamma = gr.gamma.T

    fxc,dfxcdna,dfxcdnb,dfxcdgaa,dfxcdgab,dfxcdgbb = XC(amdens,amgamma,**kwargs)

    Exc = dot(weight,fxc)

    wva = weight*dfxcdna  # Combine w*v in a vector for multiplication by bfs

    # First do the part that doesn't depend upon gamma
    nbf = gr.get_nbf()
    Fxca = zeros((nbf,nbf),'d')
    for i in xrange(nbf):
        wva_i = wva*gr.bfgrid[:,i] 
        for j in xrange(nbf):
            Fxca[i,j] = dot(wva_i,gr.bfgrid[:,j])

    # Now do the gamma-dependent part.
    # Fxc_a += dot(2 dfxcdgaa*graddensa + dfxcdgab*graddensb,grad(chia*chib))
    # We can do the dot product as
    #  sum_grid sum_xyz A[grid,xyz]*B[grid,xyz]
    # or a 2d trace product
    # Here A contains the dfxcdgaa stuff
    #      B contains the grad(chia*chib)

    # Possible errors: gr.grad() here should be the grad of the b part?
    if do_grad_dens:
        # A,B are dimensioned (npts,3)
        A = transpose(0.5*transpose(gr.grad())*(weight*(2*dfxcdgaa+dfxcdgab)))
        for a in xrange(nbf):
            for b in xrange(a+1):
                B = gr.grad_bf_prod(a,b)
                Fxca[a,b] += sum(ravel(A*B))
                Fxca[b,a] = Fxca[a,b]
    if not do_spin_polarized: return Exc,Fxca

    wvb = weight*dfxcdnb  # Combine w*v in a vector for multiplication by bfs

    # First do the part that doesn't depend upon gamma
    Fxcb = zeros((nbf,nbf),'d')
    for i in xrange(nbf):
        wvb_i = wvb*gr.bfgrid[:,i] 
        for j in xrange(nbf):
            Fxcb[i,j] = dot(wvb_i,gr.bfgrid[:,j])

    # Now do the gamma-dependent part.
    # Fxc_b += dot(2 dfxcdgbb*graddensb + dfxcdgab*graddensa,grad(chia*chib))
    # We can do the dot product as
    #  sum_grid sum_xyz A[grid,xyz]*B[grid,xyz]
    # or a 2d trace product
    # Here A contains the dfxcdgaa stuff
    #      B contains the grad(chia*chib)

    # Possible errors: gr.grad() here should be the grad of the b part?
    if do_grad_dens:
        # A,B are dimensioned (npts,3)
        A = transpose(0.5*transpose(gr.grad())*(weight*(2*dfxcdgbb+dfxcdgab)))
        for a in xrange(nbf):
            for b in xrange(a+1):
                B = gr.grad_bf_prod(a,b)
                Fxcb[a,b] += sum(ravel(A*B))
                Fxcb[b,a] = Fxcb[a,b]
    return Exc,Fxca,Fxcb
Beispiel #11
0
 def mk_B_Dmat(self, nstart, nstop):
     "Form a density matrix C*Ct given eigenvectors C[nstart:nstop,:]"
     d = self.orbs_b[:, nstart:nstop]
     Dmat = matrixmultiply(d, transpose(d))
     return Dmat
Beispiel #12
0
 def mk_B_Dmat(self,nstart,nstop):
     "Form a density matrix C*Ct given eigenvectors C[nstart:nstop,:]"
     d = self.orbs_b[:,nstart:nstop]
     Dmat = matrixmultiply(d,transpose(d))
     return Dmat
Beispiel #13
0
def getXC(gr, nel, **kwargs):
    "Form the exchange-correlation matrix"

    functional = kwargs.get('functional', 'SVWN')
    do_grad_dens = need_gradients[functional]
    do_spin_polarized = kwargs.get('do_spin_polarized')

    gr.floor_density()  # Insure that the values of the density don't underflow
    gr.renormalize(nel)  # Renormalize to the proper # electrons

    dens = gr.dens()
    weight = gr.weights()
    gamma = gr.get_gamma()
    npts = len(dens)

    if gr.version == 1:
        amdens = zeros((2, npts), 'd')
        amgamma = zeros((3, npts), 'd')
        amdens[0, :] = amdens[1, :] = 0.5 * dens
        if gamma is not None:
            amgamma[0, :] = amgamma[1, :] = amgamma[2, :] = 0.25 * gamma
    elif gr.version == 2:
        amdens = gr.density.T
        amgamma = gr.gamma.T

    fxc, dfxcdna, dfxcdnb, dfxcdgaa, dfxcdgab, dfxcdgbb = XC(
        amdens, amgamma, **kwargs)

    Exc = dot(weight, fxc)

    wva = weight * dfxcdna  # Combine w*v in a vector for multiplication by bfs

    # First do the part that doesn't depend upon gamma
    nbf = gr.get_nbf()
    Fxca = zeros((nbf, nbf), 'd')
    for i in xrange(nbf):
        wva_i = wva * gr.bfgrid[:, i]
        for j in xrange(nbf):
            Fxca[i, j] = dot(wva_i, gr.bfgrid[:, j])

    # Now do the gamma-dependent part.
    # Fxc_a += dot(2 dfxcdgaa*graddensa + dfxcdgab*graddensb,grad(chia*chib))
    # We can do the dot product as
    #  sum_grid sum_xyz A[grid,xyz]*B[grid,xyz]
    # or a 2d trace product
    # Here A contains the dfxcdgaa stuff
    #      B contains the grad(chia*chib)

    # Possible errors: gr.grad() here should be the grad of the b part?
    if do_grad_dens:
        # A,B are dimensioned (npts,3)
        A = transpose(0.5 * transpose(gr.grad()) * (weight *
                                                    (2 * dfxcdgaa + dfxcdgab)))
        for a in xrange(nbf):
            for b in xrange(a + 1):
                B = gr.grad_bf_prod(a, b)
                Fxca[a, b] += sum(ravel(A * B))
                Fxca[b, a] = Fxca[a, b]
    if not do_spin_polarized: return Exc, Fxca

    wvb = weight * dfxcdnb  # Combine w*v in a vector for multiplication by bfs

    # First do the part that doesn't depend upon gamma
    Fxcb = zeros((nbf, nbf), 'd')
    for i in xrange(nbf):
        wvb_i = wvb * gr.bfgrid[:, i]
        for j in xrange(nbf):
            Fxcb[i, j] = dot(wvb_i, gr.bfgrid[:, j])

    # Now do the gamma-dependent part.
    # Fxc_b += dot(2 dfxcdgbb*graddensb + dfxcdgab*graddensa,grad(chia*chib))
    # We can do the dot product as
    #  sum_grid sum_xyz A[grid,xyz]*B[grid,xyz]
    # or a 2d trace product
    # Here A contains the dfxcdgaa stuff
    #      B contains the grad(chia*chib)

    # Possible errors: gr.grad() here should be the grad of the b part?
    if do_grad_dens:
        # A,B are dimensioned (npts,3)
        A = transpose(0.5 * transpose(gr.grad()) * (weight *
                                                    (2 * dfxcdgbb + dfxcdgab)))
        for a in xrange(nbf):
            for b in xrange(a + 1):
                B = gr.grad_bf_prod(a, b)
                Fxcb[a, b] += sum(ravel(A * B))
                Fxcb[b, a] = Fxcb[a, b]
    return Exc, Fxca, Fxcb