Beispiel #1
0
    def test_L1(self):
        pcmobj = ddcosmo.DDCOSMO(mol0)
        r_vdw = pcmobj.get_atomic_radii()
        coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere(pcmobj.lebedev_order)
        ylm_1sph = numpy.vstack(sph.real_sph_vec(coords_1sph, pcmobj.lmax, True))

        fi = ddcosmo.make_fi(pcmobj, r_vdw)
        L1 = ddcosmo_grad.make_L1(pcmobj, r_vdw, ylm_1sph, fi)

        pcmobj = ddcosmo.DDCOSMO(mol1)
        fi = ddcosmo.make_fi(pcmobj, r_vdw)
        L_1 = ddcosmo.make_L(pcmobj, r_vdw, ylm_1sph, fi)

        pcmobj = ddcosmo.DDCOSMO(mol2)
        fi = ddcosmo.make_fi(pcmobj, r_vdw)
        L_2 = ddcosmo.make_L(pcmobj, r_vdw, ylm_1sph, fi)
        self.assertAlmostEqual(abs((L_2-L_1)/dx - L1[0,2]).max(), 0, 7)
Beispiel #2
0
    def test_L1(self):
        pcmobj = ddcosmo.DDCOSMO(mol0)
        r_vdw = pcmobj.get_atomic_radii()
        coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere(pcmobj.lebedev_order)
        ylm_1sph = numpy.vstack(sph.real_sph_vec(coords_1sph, pcmobj.lmax, True))

        fi = ddcosmo.make_fi(pcmobj, r_vdw)
        L1 = ddcosmo_grad.make_L1(pcmobj, r_vdw, ylm_1sph, fi)

        pcmobj = ddcosmo.DDCOSMO(mol1)
        fi = ddcosmo.make_fi(pcmobj, r_vdw)
        L_1 = ddcosmo.make_L(pcmobj, r_vdw, ylm_1sph, fi)

        pcmobj = ddcosmo.DDCOSMO(mol2)
        fi = ddcosmo.make_fi(pcmobj, r_vdw)
        L_2 = ddcosmo.make_L(pcmobj, r_vdw, ylm_1sph, fi)
        self.assertAlmostEqual(abs((L_2-L_1)/dx - L1[0,2]).max(), 0, 7)
Beispiel #3
0
def B1_dot_x(pcmobj, dm, r_vdw, ui, ylm_1sph, cached_pol, L):
    mol = pcmobj.mol
    mol = pcmobj.mol
    natm = mol.natm
    nao = mol.nao
    lmax = pcmobj.lmax
    nlm = (lmax + 1)**2

    dms = numpy.asarray(dm)
    is_single_dm = dms.ndim == 2
    dms = dms.reshape(-1, nao, nao)
    n_dm = dms.shape[0]

    atom_coords = mol.atom_coords()
    atom_charges = mol.atom_charges()
    aoslices = mol.aoslice_by_atom()
    grids = pcmobj.grids
    coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere(
        pcmobj.lebedev_order)
    ngrid_1sph = coords_1sph.shape[0]

    extern_point_idx = ui > 0
    fi0 = ddcosmo.make_fi(pcmobj, r_vdw)
    fi1 = ddcosmo_grad.make_fi1(pcmobj, pcmobj.get_atomic_radii())
    fi1[:, :, ui == 0] = 0
    ui1 = -fi1

    Bx = numpy.zeros((natm, 3, nao, nao))

    ao = mol.eval_gto('GTOval', grids.coords)
    aow = numpy.einsum('gi,g->gi', ao, grids.weights)
    aopair = numpy.einsum('gi,gj->gij', ao, aow)
    den = numpy.einsum('gij,ij->g', aopair, dm)
    psi0 = numpy.zeros((natm, nlm))
    i1 = 0
    for ia in range(natm):
        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        fac_pol = ddcosmo._vstack_factor_fak_pol(fak_pol, lmax)
        i0, i1 = i1, i1 + fac_pol.shape[1]
        psi0[ia] = -numpy.einsum('mn,n->m', fac_pol, den[i0:i1])
    LS0 = numpy.linalg.solve(L.reshape(natm * nlm, -1).T, psi0.ravel())
    LS0 = LS0.reshape(natm, nlm)

    phi0 = numpy.zeros((natm, nlm))
    phi1 = numpy.zeros((natm, 3, natm, nlm))
    int3c2e = mol._add_suffix('int3c2e')
    int3c2e_ip1 = mol._add_suffix('int3c2e_ip1')
    cintopt = gto.moleintor.make_cintopt(mol._atm, mol._bas, mol._env, int3c2e)
    cintopt_ip1 = gto.moleintor.make_cintopt(mol._atm, mol._bas, mol._env,
                                             int3c2e_ip1)
    for ia in range(natm):
        cav_coords = atom_coords[ia] + r_vdw[ia] * coords_1sph
        #fakemol = gto.fakemol_for_charges(cav_coords[ui[ia]>0])
        fakemol = gto.fakemol_for_charges(cav_coords)
        v_nj = df.incore.aux_e2(mol,
                                fakemol,
                                intor=int3c2e,
                                aosym='s1',
                                cintopt=cintopt)

        v_phi = numpy.einsum('pqg,pq->g', v_nj, dm)
        phi0[ia] = numpy.einsum('n,ln,n,n->l', weights_1sph, ylm_1sph, ui[ia],
                                v_phi)
        phi1[:, :, ia] += lib.einsum('n,ln,azn,n->azl', weights_1sph, ylm_1sph,
                                     ui1[:, :, ia], v_phi)
        Bx += lib.einsum('l,n,ln,azn,ijn->azij', LS0[ia], weights_1sph,
                         ylm_1sph, ui1[:, :, ia], v_nj)

        wtmp = lib.einsum('n,ln,n->ln', weights_1sph, ylm_1sph, ui[ia])

        v_e1_nj = df.incore.aux_e2(mol,
                                   fakemol,
                                   intor=int3c2e_ip1,
                                   comp=3,
                                   aosym='s1',
                                   cintopt=cintopt_ip1)
        vtmp = lib.einsum('l,ln,xijn->xij', LS0[ia], wtmp, v_e1_nj)
        Bx[ia] += vtmp
        Bx[ia] += vtmp.transpose(0, 2, 1)

        for ja in range(natm):
            shl0, shl1, p0, p1 = aoslices[ja]
            Bx[ja, :, p0:p1, :] -= vtmp[:, p0:p1]
            Bx[ja, :, :, p0:p1] -= vtmp[:, p0:p1].transpose(0, 2, 1)
            tmp = numpy.einsum('xijn,ij->xn', v_e1_nj[:, p0:p1], dm[p0:p1])
            tmp += numpy.einsum('xijn,ji->xn', v_e1_nj[:, p0:p1], dm[:, p0:p1])
            phitmp = numpy.einsum('ln,xn->xl', wtmp, tmp)
            phi1[ja, :, ia] -= phitmp
            phi1[ia, :, ia] += phitmp

    Xvec0 = numpy.linalg.solve(L.reshape(natm * nlm, -1), phi0.ravel())
    Xvec0 = Xvec0.reshape(natm, nlm)

    L1 = ddcosmo_grad.make_L1(pcmobj, r_vdw, ylm_1sph, fi0)

    phi1 -= lib.einsum('aziljm,jm->azil', L1, Xvec0)
    Xvec1 = numpy.linalg.solve(L.reshape(natm * nlm, -1),
                               phi1.reshape(-1, natm * nlm).T)
    Xvec1 = Xvec1.T.reshape(natm, 3, natm, nlm)

    psi1 = numpy.zeros((natm, 3, natm, nlm))
    i1 = 0
    for ia, (coords, weight,
             weight1) in enumerate(rks_grad.grids_response_cc(grids)):
        i0, i1 = i1, i1 + weight.size
        ao = mol.eval_gto('GTOval_sph_deriv1', coords)
        aow = numpy.einsum('gi,g->gi', ao[0], weight)
        aopair1 = lib.einsum('xgi,gj->xgij', ao[1:], aow)
        aow = numpy.einsum('gi,zxg->zxgi', ao[0], weight1)
        aopair0 = lib.einsum('zxgi,gj->zxgij', aow, ao[0])
        den0 = numpy.einsum('zxgij,ij->zxg', aopair0, dm)
        den1 = numpy.empty((natm, 3, weight.size))
        for ja in range(natm):
            shl0, shl1, p0, p1 = aoslices[ja]
            den1[ja] = numpy.einsum('xgij,ij->xg', aopair1[:, :, p0:p1],
                                    dm[p0:p1, :])
            den1[ja] += numpy.einsum('xgij,ji->xg', aopair1[:, :, p0:p1],
                                     dm[:, p0:p1])

        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        fac_pol = ddcosmo._vstack_factor_fak_pol(fak_pol, lmax)
        scaled_weights = lib.einsum('azm,mn->azn', Xvec1[:, :, ia], fac_pol)
        scaled_weights *= weight
        aow = numpy.einsum('gi,azg->azgi', ao[0], scaled_weights)
        Bx -= numpy.einsum('gi,azgj->azij', ao[0], aow)

        tmp = numpy.einsum('mn,zxn->zxm', fac_pol, den1)
        psi1[:, :, ia] -= numpy.einsum('mn,zxn->zxm', fac_pol, den0)
        psi1[ia, :, ia] -= tmp.sum(axis=0)
        for ja in range(natm):
            psi1[ja, :, ia] += tmp[ja]

        eta_nj = lib.einsum('mn,m->n', fac_pol, Xvec0[ia])
        Bx -= lib.einsum('n,zxnpq->zxpq', eta_nj, aopair0)
        vtmp = lib.einsum('n,xnpq->xpq', eta_nj, aopair1)
        Bx[ia] -= vtmp
        Bx[ia] -= vtmp.transpose(0, 2, 1)
        for ja in range(natm):
            shl0, shl1, q0, q1 = aoslices[ja]
            Bx[ja, :, q0:q1, :] += vtmp[:, q0:q1]
            Bx[ja, :, :, q0:q1] += vtmp[:, q0:q1].transpose(0, 2, 1)

    psi1 -= numpy.einsum('il,aziljm->azjm', LS0, L1)
    LS1 = numpy.linalg.solve(
        L.reshape(natm * nlm, -1).T,
        psi1.reshape(-1, natm * nlm).T)
    LS1 = LS1.T.reshape(natm, 3, natm, nlm)

    cav_coords = (atom_coords.reshape(natm, 1, 3) +
                  numpy.einsum('r,gx->rgx', r_vdw, coords_1sph))
    cav_coords = cav_coords[extern_point_idx]
    fakemol = gto.fakemol_for_charges(cav_coords)
    v_nj = df.incore.aux_e2(mol,
                            fakemol,
                            intor=int3c2e,
                            aosym='s1',
                            cintopt=cintopt)
    v_phi = numpy.zeros((natm, ngrid_1sph, nao, nao))
    v_phi[extern_point_idx] += v_nj.transpose(2, 0, 1)
    Bx += lib.einsum('azjx,n,xn,jn,jnpq->azpq', LS1, weights_1sph, ylm_1sph,
                     ui, v_phi)

    return Bx
Beispiel #4
0
def make_B1(pcmobj, r_vdw, ui, ylm_1sph, cached_pol, L):
    '''1st order'''
    mol = pcmobj.mol
    coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere(
        pcmobj.lebedev_order)
    ngrid_1sph = coords_1sph.shape[0]
    mol = pcmobj.mol
    natm = mol.natm
    nao = mol.nao
    lmax = pcmobj.lmax
    nlm = (lmax + 1)**2

    atom_coords = mol.atom_coords()
    atom_charges = mol.atom_charges()
    grids = pcmobj.grids

    extern_point_idx = ui > 0
    cav_coords = (atom_coords.reshape(natm, 1, 3) +
                  numpy.einsum('r,gx->rgx', r_vdw, coords_1sph))

    cav_coords = cav_coords[extern_point_idx]
    int3c2e = mol._add_suffix('int3c2e')
    cintopt = gto.moleintor.make_cintopt(mol._atm, mol._bas, mol._env, int3c2e)
    fakemol = gto.fakemol_for_charges(cav_coords)
    v_nj = df.incore.aux_e2(mol,
                            fakemol,
                            intor=int3c2e,
                            aosym='s1',
                            cintopt=cintopt)
    nao_pair = v_nj.shape[0]
    v_phi = numpy.zeros((natm, ngrid_1sph, nao, nao))
    v_phi[extern_point_idx] += v_nj.transpose(2, 0, 1)
    phi0 = numpy.einsum('n,xn,jn,jnpq->jxpq', weights_1sph, ylm_1sph, ui,
                        v_phi)

    Xvec0 = numpy.linalg.solve(L.reshape(natm * nlm, -1),
                               phi0.reshape(natm * nlm, -1))
    Xvec0 = Xvec0.reshape(natm, nlm, nao, nao)

    ao = mol.eval_gto('GTOval', grids.coords)
    aow = numpy.einsum('gi,g->gi', ao, grids.weights)
    aopair = numpy.einsum('gi,gj->gij', ao, aow)

    psi0 = numpy.zeros((natm, nlm, nao, nao))
    i1 = 0
    for ia in range(natm):
        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        i0, i1 = i1, i1 + fak_pol[0].shape[1]
        p1 = 0
        for l in range(lmax + 1):
            fac = 4 * numpy.pi / (l * 2 + 1)
            p0, p1 = p1, p1 + (l * 2 + 1)
            psi0[ia, p0:p1] = -fac * numpy.einsum('mn,nij->mij', fak_pol[l],
                                                  aopair[i0:i1])

    fi0 = ddcosmo.make_fi(pcmobj, r_vdw)
    fi1 = ddcosmo_grad.make_fi1(pcmobj, pcmobj.get_atomic_radii())
    fi1[:, :, ui == 0] = 0
    ui1 = -fi1

    phi1 = numpy.zeros(ui1.shape[:3] + (nlm, nao, nao))
    int3c2e = mol._add_suffix('int3c2e')
    int3c2e_ip1 = mol._add_suffix('int3c2e_ip1')
    aoslices = mol.aoslice_by_atom()
    for ia in range(natm):
        cav_coords = atom_coords[ia] + r_vdw[ia] * coords_1sph
        #fakemol = gto.fakemol_for_charges(cav_coords[ui[ia]>0])
        fakemol = gto.fakemol_for_charges(cav_coords)
        v_nj = df.incore.aux_e2(mol, fakemol, intor=int3c2e, aosym='s1')
        phi1[:, :, ia] += lib.einsum('n,ln,azn,ijn->azlij', weights_1sph,
                                     ylm_1sph, ui1[:, :, ia], v_nj)

        v_e1_nj = df.incore.aux_e2(mol,
                                   fakemol,
                                   intor=int3c2e_ip1,
                                   comp=3,
                                   aosym='s1')
        v_e2_nj = v_e1_nj + v_e1_nj.transpose(0, 2, 1, 3)
        phi1[ia, :, ia] += lib.einsum('n,ln,n,xijn->xlij', weights_1sph,
                                      ylm_1sph, ui[ia], v_e2_nj)

        for ja in range(natm):
            shl0, shl1, p0, p1 = aoslices[ja]
            v = numpy.einsum('n,ln,n,xijn->xlij', weights_1sph, ylm_1sph,
                             ui[ia], v_e1_nj[:, p0:p1])
            phi1[ja, :, ia, :, p0:p1, :] -= v
            phi1[ja, :, ia, :, :, p0:p1] -= v.transpose(0, 1, 3, 2)

    psi1 = numpy.zeros((natm, 3, natm, nlm, nao, nao))
    i1 = 0
    for ia, (coords, weight,
             weight1) in enumerate(rks_grad.grids_response_cc(grids)):
        i0, i1 = i1, i1 + weight.size
        ao = mol.eval_gto('GTOval_sph_deriv1', coords)
        aow = numpy.einsum('gi,g->gi', ao[0], weight)
        aopair1 = lib.einsum('xgi,gj->xgij', ao[1:], aow)
        aow = numpy.einsum('gi,zxg->zxgi', ao[0], weight1)
        aopair0 = lib.einsum('zxgi,gj->zxgij', aow, ao[0])

        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        p1 = 0
        for l in range(lmax + 1):
            fac = 4 * numpy.pi / (l * 2 + 1)
            p0, p1 = p1, p1 + (l * 2 + 1)
            psi1[:, :, ia, p0:p1] -= fac * numpy.einsum(
                'mn,zxnij->zxmij', fak_pol[l], aopair0)
            vtmp = fac * numpy.einsum('mn,xnij->xmij', fak_pol[l], aopair1)
            psi1[ia, :, ia, p0:p1] -= vtmp
            psi1[ia, :, ia, p0:p1] -= vtmp.transpose(0, 1, 3, 2)

            for ja in range(natm):
                shl0, shl1, q0, q1 = aoslices[ja]
                psi1[ja, :, ia, p0:p1, q0:q1, :] += vtmp[:, :, q0:q1]
                psi1[ja, :, ia, p0:p1, :,
                     q0:q1] += vtmp[:, :, q0:q1].transpose(0, 1, 3, 2)

    L1 = ddcosmo_grad.make_L1(pcmobj, r_vdw, ylm_1sph, fi0)

    Xvec1 = numpy.linalg.solve(
        L.reshape(natm * nlm, -1),
        phi1.transpose(2, 3, 0, 1, 4, 5).reshape(natm * nlm, -1))
    Xvec1 = Xvec1.reshape(natm, nlm, natm, 3, nao,
                          nao).transpose(2, 3, 0, 1, 4, 5)
    LS0 = numpy.linalg.solve(
        L.reshape(natm * nlm, -1).T, psi0.reshape(natm * nlm, -1))
    LS0 = LS0.reshape(natm, nlm, nao, nao)

    B = lib.einsum('ixnlpq,nlrs->ixpqrs', psi1, Xvec0)
    B += lib.einsum('nlpq,ixnlrs->ixpqrs', psi0, Xvec1)
    B -= lib.einsum('ilpq,aziljm,jmrs->azpqrs', LS0, L1, Xvec0)
    B = B + B.transpose(0, 1, 4, 5, 2, 3)
    return B
Beispiel #5
0
def nuc_part1(pcmobj, r_vdw, ui, ylm_1sph, cached_pol, L):
    '''1st order'''
    mol = pcmobj.mol
    natm = mol.natm
    coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere(
        pcmobj.lebedev_order)
    ngrid_1sph = coords_1sph.shape[0]
    lmax = pcmobj.lmax
    nlm = (lmax + 1)**2
    nao = mol.nao
    atom_coords = mol.atom_coords()
    atom_charges = mol.atom_charges()
    grids = pcmobj.grids
    aoslices = mol.aoslice_by_atom()

    extern_point_idx = ui > 0
    fi0 = ddcosmo.make_fi(pcmobj, r_vdw)
    fi1 = ddcosmo_grad.make_fi1(pcmobj, pcmobj.get_atomic_radii())
    fi1[:, :, ui == 0] = 0
    ui1 = -fi1

    vmat1 = numpy.zeros((natm, 3, nao, nao))

    cav_coords = (atom_coords.reshape(natm, 1, 3) +
                  numpy.einsum('r,gx->rgx', r_vdw, coords_1sph))

    v_phi = numpy.zeros((natm, ngrid_1sph))
    for ia in range(natm):
        # Note (-) sign is not applied to atom_charges, because (-) is explicitly
        # included in rhs and L matrix
        d_rs = atom_coords.reshape(-1, 1, 3) - cav_coords[ia]
        v_phi[ia] = numpy.einsum('z,zp->p', atom_charges,
                                 1. / lib.norm(d_rs, axis=2))
    phi0 = -numpy.einsum('n,xn,jn,jn->jx', weights_1sph, ylm_1sph, ui, v_phi)

    Xvec0 = numpy.linalg.solve(L.reshape(natm * nlm, -1), phi0.ravel())
    Xvec0 = Xvec0.reshape(natm, nlm)

    ngrid_1sph = weights_1sph.size
    v_phi0 = numpy.empty((natm, ngrid_1sph))
    for ia in range(natm):
        cav_coords = atom_coords[ia] + r_vdw[ia] * coords_1sph
        d_rs = atom_coords.reshape(-1, 1, 3) - cav_coords
        v_phi0[ia] = numpy.einsum('z,zp->p', atom_charges,
                                  1. / lib.norm(d_rs, axis=2))
    phi1 = -numpy.einsum('n,ln,azjn,jn->azjl', weights_1sph, ylm_1sph, ui1,
                         v_phi0)

    for ia in range(natm):
        cav_coords = atom_coords[ia] + r_vdw[ia] * coords_1sph
        for ja in range(natm):
            rs = atom_coords[ja] - cav_coords
            d_rs = lib.norm(rs, axis=1)
            v_phi = atom_charges[ja] * numpy.einsum('px,p->px', rs,
                                                    1. / d_rs**3)
            tmp = numpy.einsum('n,ln,n,nx->xl', weights_1sph, ylm_1sph, ui[ia],
                               v_phi)
            phi1[ja, :, ia] += tmp  # response of the other atoms
            phi1[ia, :, ia] -= tmp  # response of cavity grids

    L1 = ddcosmo_grad.make_L1(pcmobj, r_vdw, ylm_1sph, fi0)

    phi1 -= lib.einsum('aziljm,jm->azil', L1, Xvec0)
    Xvec1 = numpy.linalg.solve(L.reshape(natm * nlm, -1),
                               phi1.reshape(-1, natm * nlm).T)
    Xvec1 = Xvec1.T.reshape(natm, 3, natm, nlm)

    i1 = 0
    for ia, (coords, weight,
             weight1) in enumerate(rks_grad.grids_response_cc(grids)):
        i0, i1 = i1, i1 + weight.size
        ao = mol.eval_gto('GTOval_sph_deriv1', coords)
        aow = numpy.einsum('gi,g->gi', ao[0], weight)
        aopair1 = lib.einsum('xgi,gj->xgij', ao[1:], aow)
        aow = numpy.einsum('gi,zxg->zxgi', ao[0], weight1)
        aopair0 = lib.einsum('zxgi,gj->zxgij', aow, ao[0])

        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        fac_pol = ddcosmo._vstack_factor_fak_pol(fak_pol, lmax)
        vmat1 -= numpy.einsum('m,mn,zxnij->zxij', Xvec0[ia], fac_pol, aopair0)
        vtmp = numpy.einsum('m,mn,xnij->xij', Xvec0[ia], fac_pol, aopair1)
        vmat1[ia, :] -= vtmp
        vmat1[ia, :] -= vtmp.transpose(0, 2, 1)

        for ja in range(natm):
            shl0, shl1, p0, p1 = aoslices[ja]
            vmat1[ja, :, p0:p1, :] += vtmp[:, p0:p1]
            vmat1[ja, :, :, p0:p1] += vtmp[:, p0:p1].transpose(0, 2, 1)

        scaled_weights = lib.einsum('azm,mn->azn', Xvec1[:, :, ia], fac_pol)
        scaled_weights *= weight
        aow = numpy.einsum('gi,azg->azgi', ao[0], scaled_weights)
        vmat1 -= numpy.einsum('gi,azgj->azij', ao[0], aow)

    psi0 = numpy.zeros((natm, nlm))
    for ia in range(natm):
        psi0[ia,
             0] += numpy.sqrt(4 * numpy.pi) / r_vdw[ia] * mol.atom_charge(ia)

    LS0 = numpy.linalg.solve(L.reshape(natm * nlm, -1).T, psi0.ravel())
    LS0 = LS0.reshape(natm, nlm)

    LS1 = numpy.einsum('il,aziljm->azjm', LS0, L1)
    LS1 = numpy.linalg.solve(
        L.reshape(natm * nlm, -1).T,
        LS1.reshape(-1, natm * nlm).T)
    LS1 = LS1.T.reshape(natm, 3, natm, nlm)

    int3c2e = mol._add_suffix('int3c2e')
    int3c2e_ip1 = mol._add_suffix('int3c2e_ip1')
    cintopt = gto.moleintor.make_cintopt(mol._atm, mol._bas, mol._env, int3c2e)
    for ia in range(natm):
        cav_coords = atom_coords[ia] + r_vdw[ia] * coords_1sph
        #fakemol = gto.fakemol_for_charges(cav_coords[ui[ia]>0])
        fakemol = gto.fakemol_for_charges(cav_coords)
        wtmp = lib.einsum('l,n,ln->ln', LS0[ia], weights_1sph, ylm_1sph)
        v_nj = df.incore.aux_e2(mol,
                                fakemol,
                                intor=int3c2e,
                                aosym='s1',
                                cintopt=cintopt)
        vmat1 -= numpy.einsum('azl,n,ln,n,pqn->azpq', LS1[:, :, ia],
                              weights_1sph, ylm_1sph, ui[ia], v_nj)
        vmat1 += lib.einsum('ln,azn,ijn->azij', wtmp, ui1[:, :, ia], v_nj)

        v_e1_nj = df.incore.aux_e2(mol,
                                   fakemol,
                                   intor=int3c2e_ip1,
                                   comp=3,
                                   aosym='s1')
        vtmp = lib.einsum('ln,n,xijn->xij', wtmp, ui[ia], v_e1_nj)
        vmat1[ia] += vtmp
        vmat1[ia] += vtmp.transpose(0, 2, 1)

        for ja in range(natm):
            shl0, shl1, p0, p1 = aoslices[ja]
            vmat1[ja, :, p0:p1, :] -= vtmp[:, p0:p1]
            vmat1[ja, :, :, p0:p1] -= vtmp[:, p0:p1].transpose(0, 2, 1)

    return vmat1