Example #1
0
    def h_op(x):
        x1 = numpy.zeros_like(focka)
        x1[mask] = x
        x1 = x1 - x1.T
        x2 = numpy.zeros_like(focka)

        #: x2[nb:,:na] = numpy.einsum('sp,qs->pq', focka[:na,nb:], x1[:na,:na])
        #: x2[nb:,:na] += numpy.einsum('rq,rp->pq', focka[:na,:na], x1[:na,nb:])
        #: x2[na:,:na] -= numpy.einsum('sp,rp->rs', focka[:na,:na], x1[na:,:na])
        #: x2[na:,:na] -= numpy.einsum('ps,qs->pq', focka[na:], x1[:na]) * 2
        #: x2[nb:na,:nb] += numpy.einsum('qr,pr->pq', focka[:nb], x1[nb:na])
        #: x2[nb:na,:nb] -= numpy.einsum('rq,sq->rs', focka[nb:na], x1[:nb])
        #: x2[nb:,:na] += numpy.einsum('sp,qs->pq', fockb[:nb,nb:], x1[:na,:nb])
        #: x2[nb:,:na] += numpy.einsum('rq,rp->pq', fockb[:nb,:na], x1[:nb,nb:])
        #: x2[nb:,:nb] -= numpy.einsum('sp,rp->rs', fockb[:nb], x1[nb:])
        #: x2[nb:,:nb] -= numpy.einsum('rq,sq->rs', fockb[nb:], x1[:nb]) * 2
        x2[viridxb[:,None],occidxa] = \
                (numpy.einsum('sp,qs->pq', focka[occidxa[:,None],viridxb], x1[occidxa[:,None],occidxa])
                +numpy.einsum('rq,rp->pq', focka[occidxa[:,None],occidxa], x1[occidxa[:,None],viridxb]))
        x2[viridxa[:,None],occidxa] -= \
                (numpy.einsum('sp,rp->rs', focka[occidxa[:,None],occidxa], x1[viridxa[:,None],occidxa])
                +numpy.einsum('ps,qs->pq', focka[viridxa], x1[occidxa]) * 2)
        x2[occidxa[:,None],occidxb] += \
                (numpy.einsum('qr,pr->pq', focka[occidxb], x1[occidxa])
                -numpy.einsum('rq,sq->rs', focka[occidxa], x1[occidxb]))

        x2[viridxb[:,None],occidxa] += \
                (numpy.einsum('sp,qs->pq', fockb[occidxb[:,None],viridxb], x1[occidxa[:,None],occidxb])
                +numpy.einsum('rq,rp->pq', fockb[occidxb[:,None],occidxa], x1[occidxb[:,None],viridxb]))
        x2[viridxb[:,None],occidxb] -= \
                (numpy.einsum('sp,rp->rs', fockb[occidxb], x1[viridxb])
                +numpy.einsum('rq,sq->rs', fockb[viridxb], x1[occidxb]) * 2)
        x2 *= .5

        d1a = reduce(numpy.dot, (mo_coeff[:,viridxa], x1[viridxa[:,None],occidxa], mo_coeff[:,occidxa].T))
        d1b = reduce(numpy.dot, (mo_coeff[:,viridxb], x1[viridxb[:,None],occidxb], mo_coeff[:,occidxb].T))
        if hasattr(mf, 'xc'):
            if APPROX_XC_HESSIAN:
                vj, vk = mf.get_jk(mol, numpy.array((d1a+d1a.T,d1b+d1b.T)))
                if abs(hyb) < 1e-10:
                    dvhf = vj[0] + vj[1]
                else:
                    dvhf = (vj[0] + vj[1]) - vk * hyb
            else:
                from pyscf.dft import uks
                if save_for_dft[0] is None:
                    save_for_dft[0] = mf.make_rdm1(mo_coeff, mo_occ)
                    save_for_dft[1] = mf.get_veff(mol, save_for_dft[0])
                dm1 = numpy.array((save_for_dft[0][0]+d1a+d1a.T,
                                   save_for_dft[0][1]+d1b+d1b.T))
                vhf1 = uks.get_veff_(mf, mol, dm1, dm_last=save_for_dft[0],
                                     vhf_last=save_for_dft[1])
                dvhf = (vhf1[0]-save_for_dft[1][0], vhf1[1]-save_for_dft[1][1])
                save_for_dft[0] = dm1
                save_for_dft[1] = vhf1
        else:
            dvhf = mf.get_veff(mol, numpy.array((d1a+d1a.T,d1b+d1b.T)))
        x2[viridxa[:,None],occidxa] += reduce(numpy.dot, (mo_coeff[:,viridxa].T, dvhf[0], mo_coeff[:,occidxa]))
        x2[viridxb[:,None],occidxb] += reduce(numpy.dot, (mo_coeff[:,viridxb].T, dvhf[1], mo_coeff[:,occidxb]))
        return x2[mask]
Example #2
0
 def get_veff(self, mol=None, dm=None, dm_last=0, vhf_last=0, hermi=1):
     """Coulomb + XC functional"""
     if mol is None:
         mol = self.mol
     if dm is None:
         dm = self.make_rdm1()
     return uks.get_veff_(self, mol, dm, dm_last, vhf_last, hermi)
Example #3
0
File: rks.py Project: matk86/pyscf
 def get_veff(self, mol=None, dm=None, dm_last=0, vhf_last=0, hermi=1):
     '''Coulomb + XC functional'''
     from pyscf.dft import uks
     if mol is None: mol = self.mol
     if dm is None: dm = self.make_rdm1()
     return uks.get_veff_(self, mol, dm, dm_last, vhf_last, hermi)