예제 #1
0
    def test_gga_deriv3(self):
        ng = 7
        xctype = 'GGA'
        np.random.seed(8)
        rho = np.random.rand(2, 4, ng)
        rho1 = np.random.rand(2, 4, ng)
        weight = 1

        exc, vxc, fxc, kxc = eval_xc(f'R-{xctype}', ng)
        ref = numint._rks_gga_wv2(rho[0], rho1[0], fxc, kxc, weight)
        ref[0] *= 2
        v1 = xc_deriv.transform_kxc(rho[0], fxc, kxc, xctype, spin=0)
        v1 = np.einsum('xg,yg,xyzg->zg', rho1[0], rho1[0], v1)
        self.assertAlmostEqual(abs(v1 - ref).max(), 0, 12)

        exc, vxc, fxc, kxc = eval_xc(f'U-{xctype}', ng)
        ref = np.array(numint._uks_gga_wv2(rho, rho1, fxc, kxc, weight))
        ref[:, 0] *= 2
        v1 = xc_deriv.transform_kxc(rho, fxc, kxc, xctype, spin=1)
        v1 = np.einsum('axg,byg,axbyczg->czg', rho1, rho1, v1)
        self.assertAlmostEqual(abs(v1 - ref).max(), 0, 12)
예제 #2
0
파일: tduks.py 프로젝트: chrinide/pyscf
def _contract_xc_kernel(td_grad, xc_code, dmvo, dmoo=None, with_vxc=True,
                        with_kxc=True, max_memory=2000):
    mol = td_grad.mol
    mf = td_grad.base._scf
    grids = mf.grids

    ni = mf._numint
    xctype = ni._xc_type(xc_code)

    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    nao = mo_coeff[0].shape[0]
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    # dmvo ~ reduce(numpy.dot, (orbv, Xai, orbo.T))
    dmvo = [(dmvo[0] + dmvo[0].T) * .5, # because K_{ia,jb} == K_{ia,jb}
            (dmvo[1] + dmvo[1].T) * .5]

    f1vo = numpy.zeros((2,4,nao,nao))
    deriv = 2
    if dmoo is not None:
        f1oo = numpy.zeros((2,4,nao,nao))
    else:
        f1oo = None
    if with_vxc:
        v1ao = numpy.zeros((2,4,nao,nao))
    else:
        v1ao = None
    if with_kxc:
        k1ao = numpy.zeros((2,4,nao,nao))
        deriv = 3
    else:
        k1ao = None

    if xctype == 'LDA':
        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = (ni.eval_rho2(mol, ao[0], mo_coeff[0], mo_occ[0], mask, 'LDA'),
                   ni.eval_rho2(mol, ao[0], mo_coeff[1], mo_occ[1], mask, 'LDA'))
            vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 1, deriv=deriv)[1:]

            u_u, u_d, d_d = fxc[0].T * weight
            rho1a = ni.eval_rho(mol, ao[0], dmvo[0], mask, 'LDA')
            rho1b = ni.eval_rho(mol, ao[0], dmvo[1], mask, 'LDA')
            aow = (numpy.einsum('pi,p,p->pi', ao[0], u_u, rho1a) +
                   numpy.einsum('pi,p,p->pi', ao[0], u_d, rho1b),
                   numpy.einsum('pi,p,p->pi', ao[0], u_d, rho1a) +
                   numpy.einsum('pi,p,p->pi', ao[0], d_d, rho1b))
            for k in range(4):
                f1vo[0,k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask, shls_slice, ao_loc)
                f1vo[1,k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask, shls_slice, ao_loc)
            if dmoo is not None:
                rho2a = ni.eval_rho(mol, ao[0], dmoo[0], mask, 'LDA')
                rho2b = ni.eval_rho(mol, ao[0], dmoo[1], mask, 'LDA')
                aow = (numpy.einsum('pi,p,p->pi', ao[0], u_u, rho2a) +
                       numpy.einsum('pi,p,p->pi', ao[0], u_d, rho2b),
                       numpy.einsum('pi,p,p->pi', ao[0], u_d, rho2a) +
                       numpy.einsum('pi,p,p->pi', ao[0], d_d, rho2b))
                for k in range(4):
                    f1oo[0,k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask, shls_slice, ao_loc)
                    f1oo[1,k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask, shls_slice, ao_loc)
            if with_vxc:
                vrho = vxc[0].T * weight
                aow = (numpy.einsum('pi,p->pi', ao[0], vrho[0]),
                       numpy.einsum('pi,p->pi', ao[0], vrho[1]))
                for k in range(4):
                    v1ao[0,k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask, shls_slice, ao_loc)
                    v1ao[1,k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask, shls_slice, ao_loc)
            if with_kxc:
                u_u_u, u_u_d, u_d_d, d_d_d = kxc[0].T * weight
                aow = (numpy.einsum('pi,p,p,p->pi', ao[0], u_u_u, rho1a, rho1a) +
                       numpy.einsum('pi,p,p,p->pi', ao[0], u_u_d, rho1a, rho1b)*2 +
                       numpy.einsum('pi,p,p,p->pi', ao[0], u_d_d, rho1b, rho1b),
                       numpy.einsum('pi,p,p,p->pi', ao[0], u_u_d, rho1a, rho1a) +
                       numpy.einsum('pi,p,p,p->pi', ao[0], u_d_d, rho1a, rho1b)*2 +
                       numpy.einsum('pi,p,p,p->pi', ao[0], d_d_d, rho1b, rho1b))
                for k in range(4):
                    k1ao[0,k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask, shls_slice, ao_loc)
                    k1ao[1,k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask, shls_slice, ao_loc)
            vxc = fxc = kxc = aow = rho = rho1 = rho2 = None

    elif xctype == 'GGA':
        def gga_sum_(vmat, ao, wv, mask):
            aow  = numpy.einsum('pi,p->pi', ao[0], wv[0])
            aow += numpy.einsum('npi,np->pi', ao[1:4], wv[1:])
            tmp = numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
            vmat[0] += tmp + tmp.T
            rks_grad._gga_grad_sum_(vmat[1:], mol, ao, wv, mask, ao_loc)
        ao_deriv = 2
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = (ni.eval_rho2(mol, ao, mo_coeff[0], mo_occ[0], mask, 'GGA'),
                   ni.eval_rho2(mol, ao, mo_coeff[1], mo_occ[1], mask, 'GGA'))
            vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 1, deriv=deriv)[1:]

            rho1 = (ni.eval_rho(mol, ao, dmvo[0], mask, 'GGA'),
                    ni.eval_rho(mol, ao, dmvo[1], mask, 'GGA'))
            wv = numint._uks_gga_wv1(rho, rho1, vxc, fxc, weight)
            gga_sum_(f1vo[0], ao, wv[0], mask)
            gga_sum_(f1vo[1], ao, wv[1], mask)

            if dmoo is not None:
                rho2 = (ni.eval_rho(mol, ao, dmoo[0], mask, 'GGA'),
                        ni.eval_rho(mol, ao, dmoo[1], mask, 'GGA'))
                wv = numint._uks_gga_wv1(rho, rho2, vxc, fxc, weight)
                gga_sum_(f1oo[0], ao, wv[0], mask)
                gga_sum_(f1oo[1], ao, wv[1], mask)
            if with_vxc:
                wv = numint._uks_gga_wv0(rho, vxc, weight)
                gga_sum_(v1ao[0], ao, wv[0], mask)
                gga_sum_(v1ao[1], ao, wv[1], mask)
            if with_kxc:
                wv = numint._uks_gga_wv2(rho, rho1, fxc, kxc, weight)
                gga_sum_(k1ao[0], ao, wv[0], mask)
                gga_sum_(k1ao[1], ao, wv[1], mask)
            vxc = fxc = kxc = rho = rho1 = None

    else:
        raise NotImplementedError('meta-GGA')

    f1vo[:,1:] *= -1
    if f1oo is not None: f1oo[:,1:] *= -1
    if v1ao is not None: v1ao[:,1:] *= -1
    if k1ao is not None: k1ao[:,1:] *= -1
    return f1vo, f1oo, v1ao, k1ao
예제 #3
0
파일: tduks.py 프로젝트: tmash/pyscf
def _contract_xc_kernel(td_grad,
                        xc_code,
                        dmvo,
                        dmoo=None,
                        with_vxc=True,
                        with_kxc=True,
                        max_memory=2000):
    mol = td_grad.mol
    mf = td_grad.base._scf
    grids = mf.grids

    ni = mf._numint
    xctype = ni._xc_type(xc_code)

    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    nao = mo_coeff[0].shape[0]
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    # dmvo ~ reduce(numpy.dot, (orbv, Xai, orbo.T))
    dmvo = [
        (dmvo[0] + dmvo[0].T) * .5,  # because K_{ia,jb} == K_{ia,jb}
        (dmvo[1] + dmvo[1].T) * .5
    ]

    f1vo = numpy.zeros((2, 4, nao, nao))
    deriv = 2
    if dmoo is not None:
        f1oo = numpy.zeros((2, 4, nao, nao))
    else:
        f1oo = None
    if with_vxc:
        v1ao = numpy.zeros((2, 4, nao, nao))
    else:
        v1ao = None
    if with_kxc:
        k1ao = numpy.zeros((2, 4, nao, nao))
        deriv = 3
    else:
        k1ao = None

    if xctype == 'LDA':
        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = (ni.eval_rho2(mol, ao[0], mo_coeff[0], mo_occ[0], mask,
                                'LDA'),
                   ni.eval_rho2(mol, ao[0], mo_coeff[1], mo_occ[1], mask,
                                'LDA'))
            vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 1, deriv=deriv)[1:]

            u_u, u_d, d_d = fxc[0].T * weight
            rho1a = ni.eval_rho(mol, ao[0], dmvo[0], mask, 'LDA')
            rho1b = ni.eval_rho(mol, ao[0], dmvo[1], mask, 'LDA')
            aow = (numpy.einsum('pi,p,p->pi', ao[0], u_u, rho1a) +
                   numpy.einsum('pi,p,p->pi', ao[0], u_d, rho1b),
                   numpy.einsum('pi,p,p->pi', ao[0], u_d, rho1a) +
                   numpy.einsum('pi,p,p->pi', ao[0], d_d, rho1b))
            for k in range(4):
                f1vo[0, k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask,
                                                shls_slice, ao_loc)
                f1vo[1, k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask,
                                                shls_slice, ao_loc)
            if dmoo is not None:
                rho2a = ni.eval_rho(mol, ao[0], dmoo[0], mask, 'LDA')
                rho2b = ni.eval_rho(mol, ao[0], dmoo[1], mask, 'LDA')
                aow = (numpy.einsum('pi,p,p->pi', ao[0], u_u, rho2a) +
                       numpy.einsum('pi,p,p->pi', ao[0], u_d, rho2b),
                       numpy.einsum('pi,p,p->pi', ao[0], u_d, rho2a) +
                       numpy.einsum('pi,p,p->pi', ao[0], d_d, rho2b))
                for k in range(4):
                    f1oo[0, k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask,
                                                    shls_slice, ao_loc)
                    f1oo[1, k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask,
                                                    shls_slice, ao_loc)
            if with_vxc:
                vrho = vxc[0].T * weight
                aow = (numpy.einsum('pi,p->pi', ao[0], vrho[0]),
                       numpy.einsum('pi,p->pi', ao[0], vrho[1]))
                for k in range(4):
                    v1ao[0, k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask,
                                                    shls_slice, ao_loc)
                    v1ao[1, k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask,
                                                    shls_slice, ao_loc)
            if with_kxc:
                u_u_u, u_u_d, u_d_d, d_d_d = kxc[0].T * weight
                aow = (
                    numpy.einsum('pi,p,p,p->pi', ao[0], u_u_u, rho1a, rho1a) +
                    numpy.einsum('pi,p,p,p->pi', ao[0], u_u_d, rho1a, rho1b) *
                    2 +
                    numpy.einsum('pi,p,p,p->pi', ao[0], u_d_d, rho1b, rho1b),
                    numpy.einsum('pi,p,p,p->pi', ao[0], u_u_d, rho1a, rho1a) +
                    numpy.einsum('pi,p,p,p->pi', ao[0], u_d_d, rho1a, rho1b) *
                    2 +
                    numpy.einsum('pi,p,p,p->pi', ao[0], d_d_d, rho1b, rho1b))
                for k in range(4):
                    k1ao[0, k] += numint._dot_ao_ao(mol, ao[k], aow[0], mask,
                                                    shls_slice, ao_loc)
                    k1ao[1, k] += numint._dot_ao_ao(mol, ao[k], aow[1], mask,
                                                    shls_slice, ao_loc)
            vxc = fxc = kxc = aow = rho = rho1 = rho2 = None

    elif xctype == 'GGA':

        def gga_sum_(vmat, ao, wv, mask):
            aow = numpy.einsum('pi,p->pi', ao[0], wv[0])
            aow += numpy.einsum('npi,np->pi', ao[1:4], wv[1:])
            tmp = numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
            vmat[0] += tmp + tmp.T
            rks_grad._gga_grad_sum_(vmat[1:], mol, ao, wv, mask, ao_loc)

        ao_deriv = 2
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = (ni.eval_rho2(mol, ao, mo_coeff[0], mo_occ[0], mask, 'GGA'),
                   ni.eval_rho2(mol, ao, mo_coeff[1], mo_occ[1], mask, 'GGA'))
            vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 1, deriv=deriv)[1:]

            rho1 = (ni.eval_rho(mol, ao, dmvo[0], mask, 'GGA'),
                    ni.eval_rho(mol, ao, dmvo[1], mask, 'GGA'))
            wv = numint._uks_gga_wv1(rho, rho1, vxc, fxc, weight)
            gga_sum_(f1vo[0], ao, wv[0], mask)
            gga_sum_(f1vo[1], ao, wv[1], mask)

            if dmoo is not None:
                rho2 = (ni.eval_rho(mol, ao, dmoo[0], mask, 'GGA'),
                        ni.eval_rho(mol, ao, dmoo[1], mask, 'GGA'))
                wv = numint._uks_gga_wv1(rho, rho2, vxc, fxc, weight)
                gga_sum_(f1oo[0], ao, wv[0], mask)
                gga_sum_(f1oo[1], ao, wv[1], mask)
            if with_vxc:
                wv = numint._uks_gga_wv0(rho, vxc, weight)
                gga_sum_(v1ao[0], ao, wv[0], mask)
                gga_sum_(v1ao[1], ao, wv[1], mask)
            if with_kxc:
                wv = numint._uks_gga_wv2(rho, rho1, fxc, kxc, weight)
                gga_sum_(k1ao[0], ao, wv[0], mask)
                gga_sum_(k1ao[1], ao, wv[1], mask)
            vxc = fxc = kxc = rho = rho1 = None

    else:
        raise NotImplementedError('meta-GGA')

    f1vo[:, 1:] *= -1
    if f1oo is not None: f1oo[:, 1:] *= -1
    if v1ao is not None: v1ao[:, 1:] *= -1
    if k1ao is not None: k1ao[:, 1:] *= -1
    return f1vo, f1oo, v1ao, k1ao
예제 #4
0
def _contract_xc_kernel(td_grad,
                        xc_code,
                        dmvo,
                        dmoo=None,
                        with_vxc=True,
                        with_kxc=True,
                        max_memory=2000):
    mol = td_grad.mol
    mf = td_grad.base._scf
    grids = mf.grids

    ni = mf._numint
    xctype = ni._xc_type(xc_code)

    mo_coeff = mf.mo_coeff
    mo_occ = mf.mo_occ
    nao = mo_coeff[0].shape[0]
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()

    # dmvo ~ reduce(numpy.dot, (orbv, Xai, orbo.T))
    dmvo = [
        (dmvo[0] + dmvo[0].T) * .5,  # because K_{ia,jb} == K_{ia,jb}
        (dmvo[1] + dmvo[1].T) * .5
    ]

    f1vo = numpy.zeros((2, 4, nao, nao))
    deriv = 2
    if dmoo is not None:
        f1oo = numpy.zeros((2, 4, nao, nao))
    else:
        f1oo = None
    if with_vxc:
        v1ao = numpy.zeros((2, 4, nao, nao))
    else:
        v1ao = None
    if with_kxc:
        k1ao = numpy.zeros((2, 4, nao, nao))
        deriv = 3
    else:
        k1ao = None

    if xctype == 'LDA':

        def lda_sum_(vmat, ao, wv, mask):
            aow = numint._scale_ao(ao[0], wv)
            for k in range(4):
                vmat[k] += numint._dot_ao_ao(mol, ao[k], aow, mask, shls_slice,
                                             ao_loc)

        ao_deriv = 1
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = (ni.eval_rho2(mol, ao[0], mo_coeff[0], mo_occ[0], mask,
                                xctype),
                   ni.eval_rho2(mol, ao[0], mo_coeff[1], mo_occ[1], mask,
                                xctype))
            vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 1, deriv=deriv)[1:]

            u_u, u_d, d_d = fxc[0].T * weight
            rho1a = ni.eval_rho(mol, ao[0], dmvo[0], mask, xctype)
            rho1b = ni.eval_rho(mol, ao[0], dmvo[1], mask, xctype)
            lda_sum_(f1vo[0], ao, u_u * rho1a + u_d * rho1b, mask)
            lda_sum_(f1vo[1], ao, u_d * rho1a + d_d * rho1b, mask)
            if dmoo is not None:
                rho2a = ni.eval_rho(mol, ao[0], dmoo[0], mask, xctype)
                rho2b = ni.eval_rho(mol, ao[0], dmoo[1], mask, xctype)
                lda_sum_(f1oo[0], ao, u_u * rho2a + u_d * rho2b, mask)
                lda_sum_(f1oo[1], ao, u_d * rho2a + d_d * rho2b, mask)
            if with_vxc:
                vrho = vxc[0].T * weight
                lda_sum_(v1ao[0], ao, vrho[0], mask)
                lda_sum_(v1ao[1], ao, vrho[1], mask)
            if with_kxc:
                u_u_u, u_u_d, u_d_d, d_d_d = kxc[0].T * weight
                lda_sum_(
                    k1ao[0], ao, u_u_u * rho1a * rho1a +
                    u_u_d * rho1a * rho1b * 2 + u_d_d * rho1b * rho1b, mask)
                lda_sum_(
                    k1ao[1], ao, u_u_d * rho1a * rho1a +
                    u_d_d * rho1a * rho1b * 2 + d_d_d * rho1b * rho1b, mask)

    elif xctype == 'GGA':

        def gga_sum_(vmat, ao, wv, mask):
            aow = numint._scale_ao(ao[:4], wv[:4])
            tmp = numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
            vmat[0] += tmp + tmp.T
            rks_grad._gga_grad_sum_(vmat[1:], mol, ao, wv, mask, ao_loc)

        ao_deriv = 2
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = (ni.eval_rho2(mol, ao, mo_coeff[0], mo_occ[0], mask, xctype),
                   ni.eval_rho2(mol, ao, mo_coeff[1], mo_occ[1], mask, xctype))
            vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 1, deriv=deriv)[1:]

            rho1 = (ni.eval_rho(mol, ao, dmvo[0], mask, xctype),
                    ni.eval_rho(mol, ao, dmvo[1], mask, xctype))
            wv = numint._uks_gga_wv1(rho, rho1, vxc, fxc, weight)
            gga_sum_(f1vo[0], ao, wv[0], mask)
            gga_sum_(f1vo[1], ao, wv[1], mask)

            if dmoo is not None:
                rho2 = (ni.eval_rho(mol, ao, dmoo[0], mask, xctype),
                        ni.eval_rho(mol, ao, dmoo[1], mask, xctype))
                wv = numint._uks_gga_wv1(rho, rho2, vxc, fxc, weight)
                gga_sum_(f1oo[0], ao, wv[0], mask)
                gga_sum_(f1oo[1], ao, wv[1], mask)
            if with_vxc:
                wv = numint._uks_gga_wv0(rho, vxc, weight)
                gga_sum_(v1ao[0], ao, wv[0], mask)
                gga_sum_(v1ao[1], ao, wv[1], mask)
            if with_kxc:
                wv = numint._uks_gga_wv2(rho, rho1, fxc, kxc, weight)
                gga_sum_(k1ao[0], ao, wv[0], mask)
                gga_sum_(k1ao[1], ao, wv[1], mask)
            vxc = fxc = kxc = rho = rho1 = None

    elif xctype == 'MGGA':
        logger.warn(mol, 'More tests are needed for TD-MGGA')

        def mgga_sum_(vmat, ao, wv, mask):
            aow = numint._scale_ao(ao[:4], wv[:4])
            tmp = numint._dot_ao_ao(mol, ao[0], aow, mask, shls_slice, ao_loc)
            aow = numint._scale_ao(ao[1], wv[5], aow)
            tmp += numint._dot_ao_ao(mol, ao[1], aow, mask, shls_slice, ao_loc)
            aow = numint._scale_ao(ao[2], wv[5], aow)
            tmp += numint._dot_ao_ao(mol, ao[2], aow, mask, shls_slice, ao_loc)
            aow = numint._scale_ao(ao[3], wv[5], aow)
            tmp += numint._dot_ao_ao(mol, ao[3], aow, mask, shls_slice, ao_loc)
            vmat[0] += tmp + tmp.T

            rks_grad._gga_grad_sum_(vmat[1:], mol, ao, wv[:4], mask, ao_loc)
            rks_grad._tau_grad_dot_(vmat[1:], mol, ao, wv[5] * 2, mask, ao_loc,
                                    True)

        ao_deriv = 2
        for ao, mask, weight, coords \
                in ni.block_loop(mol, grids, nao, ao_deriv, max_memory):
            rho = (ni.eval_rho2(mol, ao, mo_coeff[0], mo_occ[0], mask, xctype),
                   ni.eval_rho2(mol, ao, mo_coeff[1], mo_occ[1], mask, xctype))
            vxc, fxc, kxc = ni.eval_xc(xc_code, rho, 1, deriv=deriv)[1:]

            rho1 = (ni.eval_rho(mol, ao, dmvo[0], mask, xctype),
                    ni.eval_rho(mol, ao, dmvo[1], mask, xctype))
            wv = numint._uks_mgga_wv1(rho, rho1, vxc, fxc, weight)
            mgga_sum_(f1vo[0], ao, wv[0], mask)
            mgga_sum_(f1vo[1], ao, wv[1], mask)

            if dmoo is not None:
                rho2 = (ni.eval_rho(mol, ao, dmoo[0], mask, xctype),
                        ni.eval_rho(mol, ao, dmoo[1], mask, xctype))
                wv = numint._uks_mgga_wv1(rho, rho2, vxc, fxc, weight)
                mgga_sum_(f1oo[0], ao, wv[0], mask)
                mgga_sum_(f1oo[1], ao, wv[1], mask)
            if with_vxc:
                wv = numint._uks_mgga_wv0(rho, vxc, weight)
                mgga_sum_(v1ao[0], ao, wv[0], mask)
                mgga_sum_(v1ao[1], ao, wv[1], mask)
            if with_kxc:
                wv = numint._uks_mgga_wv2(rho, rho1, fxc, kxc, weight)
                mgga_sum_(k1ao[0], ao, wv[0], mask)
                mgga_sum_(k1ao[1], ao, wv[1], mask)
            vxc = fxc = kxc = rho = rho1 = None

    elif xctype == 'HF':
        pass
    else:
        raise NotImplementedError(f'td-uks for functional {xc_code}')

    f1vo[:, 1:] *= -1
    if f1oo is not None: f1oo[:, 1:] *= -1
    if v1ao is not None: v1ao[:, 1:] *= -1
    if k1ao is not None: k1ao[:, 1:] *= -1
    return f1vo, f1oo, v1ao, k1ao