Beispiel #1
0
    def test_aux_e2(self):
        cell = pgto.Cell()
        cell.unit = 'B'
        cell.a = numpy.eye(3) * 3.
        cell.gs = numpy.array([20,20,20])
        cell.atom = 'He 0 1 1; He 1 1 0'
        cell.basis = { 'He': [[0, (0.8, 1.0)],
                              [0, (1.2, 1.0)]] }
        cell.verbose = 0
        cell.build(0, 0)
        auxcell = incore.format_aux_basis(cell)
        cell.nimgs = auxcell.nimgs = [3,3,3]
        a1 = incore.aux_e2(cell, auxcell, 'cint3c1e_sph')
        self.assertAlmostEqual(finger(a1), 0.1208944790152819, 9)
        a2 = incore.aux_e2(cell, auxcell, 'cint3c1e_sph', aosym='s2ij')
        self.assertTrue(numpy.allclose(a1, lib.unpack_tril(a2, axis=0).reshape(a1.shape)))

        numpy.random.seed(3)
        kpti_kptj = [numpy.random.random(3)]*2
        a1 = incore.aux_e2(cell, auxcell, 'cint3c1e_sph', kpti_kptj=kpti_kptj)
        self.assertAlmostEqual(finger(a1), -0.073719031689332651-0.054002639392614758j, 9)
        a2 = incore.aux_e2(cell, auxcell, 'cint3c1e_sph', aosym='s2ij', kpti_kptj=kpti_kptj)
        self.assertTrue(numpy.allclose(a1, lib.unpack_tril(a2, 1, axis=0).reshape(a1.shape)))

        numpy.random.seed(1)
        kpti_kptj = numpy.random.random((2,3))
        a1 = incore.aux_e2(cell, auxcell, 'cint3c1e_sph', kpti_kptj=kpti_kptj)
        self.assertAlmostEqual(finger(a1), 0.039329191948685879-0.039836453846241987j, 9)
Beispiel #2
0
 def test_aux_e2(self):
     tmpfile = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR)
     numpy.random.seed(1)
     kptij_lst = numpy.random.random((3,2,3))
     kptij_lst[0] = 0
     kptij_lst[1,0] = kptij_lst[1,1]
     outcore.aux_e2(cell, cell, tmpfile.name, aosym='s2ij', comp=1,
                    kptij_lst=kptij_lst, verbose=0)
     refk0 = incore.aux_e2(cell, cell, aosym='s2ij', kpti_kptj=kptij_lst[0])
     refk1 = incore.aux_e2(cell, cell, aosym='s2ij', kpti_kptj=kptij_lst[1])
     refk2 = incore.aux_e2(cell, cell, aosym='s2ij', kpti_kptj=kptij_lst[2])
     with h5py.File(tmpfile.name, 'r') as f:
         self.assertTrue(numpy.allclose(refk0, f['eri_mo/0'].value.T))
         self.assertTrue(numpy.allclose(refk1, f['eri_mo/1'].value.T))
         self.assertTrue(numpy.allclose(refk2, f['eri_mo/2'].value.T))
Beispiel #3
0
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e_sph'):
    '''Vnuc - Vloc'''
    cell = mydf.cell
    nkpts = len(kpts)

    # Use the 3c2e code with steep s gaussians to mimic nuclear density
    fakenuc = _fake_nuc(cell)
    fakenuc._atm, fakenuc._bas, fakenuc._env = \
            gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env,
                         fakenuc._atm, fakenuc._bas, fakenuc._env)

    kptij_lst = numpy.hstack((kpts, kpts)).reshape(-1, 2, 3)
    buf = incore.aux_e2(cell, fakenuc, intor, aosym='s2', kptij_lst=kptij_lst)

    charge = cell.atom_charges()
    charge = numpy.append(charge,
                          -charge)  # (charge-of-nuccell, charge-of-fakenuc)
    nao = cell.nao_nr()
    nchg = len(charge)
    nao_pair = nao * (nao + 1) // 2
    buf = buf.reshape(nkpts, nao_pair, nchg)
    mat = numpy.einsum('kxz,z->kx', buf, charge)

    if cell.dimension == 3:
        nucbar = sum([
            z / nuccell.bas_exp(i)[0]
            for i, z in enumerate(cell.atom_charges())
        ])
        nucbar *= numpy.pi / cell.vol
        ovlp = cell.pbc_intor('int1e_ovlp_sph', 1, lib.HERMITIAN, kpts)
        for k in range(nkpts):
            s = lib.pack_tril(ovlp[k])
            mat[k] += nucbar * s
    return mat
Beispiel #4
0
 def test_aux_e2(self):
     tmpfile = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR)
     numpy.random.seed(1)
     kptij_lst = numpy.random.random((3, 2, 3))
     kptij_lst[0] = 0
     kptij_lst[1, 0] = kptij_lst[1, 1]
     outcore.aux_e2(cell,
                    cell,
                    tmpfile.name,
                    aosym='s2ij',
                    comp=1,
                    kptij_lst=kptij_lst,
                    verbose=0)
     refk0 = incore.aux_e2(cell, cell, aosym='s2ij', kpti_kptj=kptij_lst[0])
     refk1 = incore.aux_e2(cell, cell, aosym='s2ij', kpti_kptj=kptij_lst[1])
     refk2 = incore.aux_e2(cell, cell, aosym='s2ij', kpti_kptj=kptij_lst[2])
     with h5py.File(tmpfile.name, 'r') as f:
         self.assertTrue(numpy.allclose(refk0, f['eri_mo/0'].value.T))
         self.assertTrue(numpy.allclose(refk1, f['eri_mo/1'].value.T))
         self.assertTrue(numpy.allclose(refk2, f['eri_mo/2'].value.T))
Beispiel #5
0
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e', aosym='s2', comp=1):
    '''Vnuc - Vloc'''
    cell = mydf.cell
    nkpts = len(kpts)

    # Use the 3c2e code with steep s gaussians to mimic nuclear density
    fakenuc = _fake_nuc(cell)
    fakenuc._atm, fakenuc._bas, fakenuc._env = \
            gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env,
                         fakenuc._atm, fakenuc._bas, fakenuc._env)

    kptij_lst = numpy.hstack((kpts, kpts)).reshape(-1, 2, 3)
    buf = incore.aux_e2(cell,
                        fakenuc,
                        intor,
                        aosym=aosym,
                        comp=comp,
                        kptij_lst=kptij_lst)

    charge = cell.atom_charges()
    charge = numpy.append(charge,
                          -charge)  # (charge-of-nuccell, charge-of-fakenuc)
    nao = cell.nao_nr()
    nchg = len(charge)
    if aosym == 's1':
        nao_pair = nao**2
    else:
        nao_pair = nao * (nao + 1) // 2
    if comp == 1:
        buf = buf.reshape(nkpts, nao_pair, nchg)
        mat = numpy.einsum('kxz,z->kx', buf, charge)
    else:
        buf = buf.reshape(nkpts, comp, nao_pair, nchg)
        mat = numpy.einsum('kcxz,z->kcx', buf, charge)

    # vbar is the interaction between the background charge
    # and the compensating function.  0D, 1D, 2D do not have vbar.
    if cell.dimension == 3 and intor in ('int3c2e', 'int3c2e_sph',
                                         'int3c2e_cart'):
        assert (comp == 1)
        charge = -cell.atom_charges()

        nucbar = sum([z / nuccell.bas_exp(i)[0] for i, z in enumerate(charge)])
        nucbar *= numpy.pi / cell.vol

        ovlp = cell.pbc_intor('int1e_ovlp', 1, lib.HERMITIAN, kpts)
        for k in range(nkpts):
            if aosym == 's1':
                mat[k] -= nucbar * ovlp[k].reshape(nao_pair)
            else:
                mat[k] -= nucbar * lib.pack_tril(ovlp[k])
    return mat
Beispiel #6
0
    def test_aux_e2(self):
        cell = pgto.Cell()
        cell.unit = 'B'
        cell.a = numpy.eye(3) * 3.
        cell.mesh = numpy.array([41] * 3)
        cell.atom = 'He 0 1 1; He 1 1 0'
        cell.basis = {'He': [[0, (0.8, 1.0)], [0, (1.2, 1.0)]]}
        cell.verbose = 0
        cell.build(0, 0)
        auxcell = incore.format_aux_basis(cell)
        a1 = incore.aux_e2(cell, auxcell, 'int3c1e_sph')
        self.assertAlmostEqual(lib.fp(a1), 0.1208944790152819, 9)
        a2 = incore.aux_e2(cell, auxcell, 'int3c1e_sph', aosym='s2ij')
        self.assertTrue(
            numpy.allclose(a1,
                           lib.unpack_tril(a2, axis=0).reshape(a1.shape)))

        numpy.random.seed(3)
        kpt = numpy.random.random(3)
        kptij_lst = numpy.array([[kpt, kpt]])
        a1 = incore.aux_e2(cell, auxcell, 'int3c1e_sph', kptij_lst=kptij_lst)
        self.assertAlmostEqual(lib.fp(a1),
                               -0.073719031689332651 - 0.054002639392614758j,
                               9)
        a2 = incore.aux_e2(cell,
                           auxcell,
                           'int3c1e_sph',
                           aosym='s2',
                           kptij_lst=kptij_lst)
        self.assertTrue(
            numpy.allclose(a1,
                           lib.unpack_tril(a2, 1, axis=0).reshape(a1.shape)))

        numpy.random.seed(1)
        kptij_lst = numpy.random.random((1, 2, 3))
        a1 = incore.aux_e2(cell, auxcell, 'int3c1e_sph', kptij_lst=kptij_lst)
        self.assertAlmostEqual(lib.fp(a1),
                               0.039329191948685879 - 0.039836453846241987j, 9)
Beispiel #7
0
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e_sph'):
    '''Vnuc - Vloc'''
    cell = mydf.cell
    nkpts = len(kpts)

    # Use the 3c2e code with steep s gaussians to mimic nuclear density
    fakenuc = aft._fake_nuc(cell)
    fakenuc._atm, fakenuc._bas, fakenuc._env = \
            gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env,
                         fakenuc._atm, fakenuc._bas, fakenuc._env)

    kptij_lst = numpy.hstack((kpts, kpts)).reshape(-1, 2, 3)
    ishs = mpi.work_balanced_partition(numpy.arange(cell.nbas),
                                       costs=numpy.arange(1, cell.nbas + 1))
    if len(ishs) > 0:
        ish0, ish1 = ishs[0], ishs[-1] + 1
        buf = incore.aux_e2(cell,
                            fakenuc,
                            intor,
                            aosym='s2',
                            kptij_lst=kptij_lst,
                            shls_slice=(ish0, ish1, 0, cell.nbas, 0,
                                        fakenuc.nbas))
    else:
        buf = numpy.zeros(0)

    charge = cell.atom_charges()
    charge = numpy.append(charge,
                          -charge)  # (charge-of-nuccell, charge-of-fakenuc)
    nao = cell.nao_nr()
    nchg = len(charge)
    nao_pair = nao * (nao + 1) // 2
    buf = buf.reshape(nkpts, -1, nchg)
    # scaled by 1./mpi.pool.size because nuc is mpi.reduced in get_nuc function
    buf = numpy.einsum('kxz,z->kx', buf, 1. / mpi.pool.size * charge)
    mat = numpy.empty((nkpts, nao_pair), dtype=numpy.complex128)
    for k in range(nkpts):
        mat[k] = mpi.allgather(buf[k])

    if rank == 0 and cell.dimension == 3:
        nucbar = sum([
            z / nuccell.bas_exp(i)[0]
            for i, z in enumerate(cell.atom_charges())
        ])
        nucbar *= numpy.pi / cell.vol
        ovlp = cell.pbc_intor('int1e_ovlp_sph', 1, lib.HERMITIAN, kpts)
        for k in range(nkpts):
            s = lib.pack_tril(ovlp[k])
            mat[k] += nucbar * s
    return mat
Beispiel #8
0
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e_sph', aosym='s2', comp=1):
    '''Vnuc - Vloc'''
    cell = mydf.cell
    nkpts = len(kpts)

# Use the 3c2e code with steep s gaussians to mimic nuclear density
    fakenuc = aft._fake_nuc(cell)
    fakenuc._atm, fakenuc._bas, fakenuc._env = \
            gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env,
                         fakenuc._atm, fakenuc._bas, fakenuc._env)

    kptij_lst = numpy.hstack((kpts,kpts)).reshape(-1,2,3)
    ishs = mpi.work_balanced_partition(numpy.arange(cell.nbas),
                                       costs=numpy.arange(1, cell.nbas+1))
    if len(ishs) > 0:
        ish0, ish1 = ishs[0], ishs[-1]+1
        buf = incore.aux_e2(cell, fakenuc, intor, aosym='s2', kptij_lst=kptij_lst,
                            shls_slice=(ish0,ish1,0,cell.nbas,0,fakenuc.nbas))
    else:
        buf = numpy.zeros(0)

    charge = cell.atom_charges()
    charge = numpy.append(charge, -charge)  # (charge-of-nuccell, charge-of-fakenuc)
    nao = cell.nao_nr()
    nchg = len(charge)
    nao_pair = nao*(nao+1)//2
    buf = buf.reshape(nkpts,-1,nchg)
# scaled by 1./mpi.pool.size because nuc is mpi.reduced in get_nuc function
    buf = numpy.einsum('kxz,z->kx', buf, 1./mpi.pool.size*charge)
    mat = numpy.empty((nkpts,nao_pair), dtype=numpy.complex128)
    for k in range(nkpts):
        mat[k] = mpi.allgather(buf[k])

    if (rank == 0 and
        cell.dimension == 3 and intor in ('int3c2e', 'int3c2e_sph',
                                          'int3c2e_cart')):
        assert(comp == 1)
        charges = cell.atom_charges()

        nucbar = sum([z/nuccell.bas_exp(i)[0] for i,z in enumerate(charges)])
        nucbar *= numpy.pi/cell.vol

        ovlp = cell.pbc_intor('int1e_ovlp_sph', 1, lib.HERMITIAN, kpts)
        for k in range(nkpts):
            if aosym == 's1':
                mat[k] += nucbar * ovlp[k].reshape(nao_pair)
            else:
                mat[k] += nucbar * lib.pack_tril(ovlp[k])

    return mat
Beispiel #9
0
 def test_aux_e2(self):
     tmpfile = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR)
     numpy.random.seed(1)
     kptij_lst = numpy.random.random((3,2,3))
     kptij_lst[0] = 0
     outcore.aux_e2(cell, cell, tmpfile.name, aosym='s2', comp=1,
                    kptij_lst=kptij_lst, verbose=0)
     refk = incore.aux_e2(cell, cell, aosym='s2', kptij_lst=kptij_lst)
     with h5py.File(tmpfile.name, 'r') as f:
         nao = cell.nao_nr()
         idx = numpy.tril_indices(nao)
         idx = idx[0] * nao + idx[1]
         self.assertTrue(numpy.allclose(refk[0,idx], f['eri_mo/0'].value.T))
         self.assertTrue(numpy.allclose(refk[1], f['eri_mo/1'].value.T))
         self.assertTrue(numpy.allclose(refk[2], f['eri_mo/2'].value.T))
Beispiel #10
0
 def test_aux_e1(self):
     tmpfile = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR)
     numpy.random.seed(1)
     kptij_lst = numpy.random.random((3,2,3))
     kptij_lst[0] = 0
     outcore.aux_e1(cell, cell, tmpfile.name, aosym='s2', comp=1,
                    kptij_lst=kptij_lst, verbose=0)
     refk = incore.aux_e2(cell, cell, aosym='s2', kptij_lst=kptij_lst)
     with h5py.File(tmpfile.name, 'r') as f:
         nao = cell.nao_nr()
         idx = numpy.tril_indices(nao)
         idx = idx[0] * nao + idx[1]
         self.assertTrue(numpy.allclose(refk[0,idx], f['eri_mo/0'].value.T))
         self.assertTrue(numpy.allclose(refk[1], f['eri_mo/1'].value.T))
         self.assertTrue(numpy.allclose(refk[2], f['eri_mo/2'].value.T))
Beispiel #11
0
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e', aosym='s2', comp=1):
    '''Vnuc - Vloc'''
    cell = mydf.cell
    nkpts = len(kpts)

# Use the 3c2e code with steep s gaussians to mimic nuclear density
    fakenuc = _fake_nuc(cell)
    fakenuc._atm, fakenuc._bas, fakenuc._env = \
            gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env,
                         fakenuc._atm, fakenuc._bas, fakenuc._env)

    kptij_lst = numpy.hstack((kpts,kpts)).reshape(-1,2,3)
    buf = incore.aux_e2(cell, fakenuc, intor, aosym=aosym, comp=comp,
                        kptij_lst=kptij_lst)

    charge = cell.atom_charges()
    charge = numpy.append(charge, -charge)  # (charge-of-nuccell, charge-of-fakenuc)
    nao = cell.nao_nr()
    nchg = len(charge)
    if aosym == 's1':
        nao_pair = nao**2
    else:
        nao_pair = nao*(nao+1)//2
    if comp == 1:
        buf = buf.reshape(nkpts,nao_pair,nchg)
        mat = numpy.einsum('kxz,z->kx', buf, charge)
    else:
        buf = buf.reshape(nkpts,comp,nao_pair,nchg)
        mat = numpy.einsum('kcxz,z->kcx', buf, charge)

    # vbar is the interaction between the background charge
    # and the compensating function.  0D, 1D, 2D do not have vbar.
    if cell.dimension == 3 and intor in ('int3c2e', 'int3c2e_sph',
                                         'int3c2e_cart'):
        assert(comp == 1)
        charge = -cell.atom_charges()

        nucbar = sum([z/nuccell.bas_exp(i)[0] for i,z in enumerate(charge)])
        nucbar *= numpy.pi/cell.vol

        ovlp = cell.pbc_intor('int1e_ovlp', 1, lib.HERMITIAN, kpts)
        for k in range(nkpts):
            if aosym == 's1':
                mat[k] -= nucbar * ovlp[k].reshape(nao_pair)
            else:
                mat[k] -= nucbar * lib.pack_tril(ovlp[k])
    return mat
Beispiel #12
0
def get_pp_loc_part2(cell, kpts=None):
    '''PRB, 58, 3641 Eq (1), integrals associated to C1, C2, C3, C4
    '''
    from pyscf.pbc.df import incore
    if kpts is None:
        kpts_lst = numpy.zeros((1, 3))
    else:
        kpts_lst = numpy.reshape(kpts, (-1, 3))
    nkpts = len(kpts_lst)

    intors = ('int3c2e', 'int3c1e', 'int3c1e_r2_origk', 'int3c1e_r4_origk',
              'int3c1e_r6_origk')
    kptij_lst = numpy.hstack((kpts_lst, kpts_lst)).reshape(-1, 2, 3)
    buf = 0
    for cn in range(1, 5):
        fakecell = fake_cell_vloc(cell, cn)
        if fakecell.nbas > 0:
            v = incore.aux_e2(cell,
                              fakecell,
                              intors[cn],
                              aosym='s2',
                              comp=1,
                              kptij_lst=kptij_lst)
            buf += numpy.einsum('...i->...', v)

    if isinstance(buf, int):
        if any(
                cell.atom_symbol(ia) in cell._pseudo
                for ia in range(cell.natm)):
            pass
        else:
            lib.logger.warn(
                cell, 'cell.pseudo was specified but its elements %s '
                'were not found in the system.', cell._pseudo.keys())
        vpploc = [0] * nkpts
    else:
        buf = buf.reshape(nkpts, -1)
        vpploc = []
        for k, kpt in enumerate(kpts_lst):
            v = lib.unpack_tril(buf[k])
            if abs(kpt).sum() < 1e-9:  # gamma_point:
                v = v.real
            vpploc.append(v)
    if kpts is None or numpy.shape(kpts) == (3, ):
        vpploc = vpploc[0]
    return vpploc
Beispiel #13
0
def ecp_int(cell, kpts=None):
    from pyscf.pbc.df import incore
    if kpts is None:
        kpts_lst = numpy.zeros((1, 3))
    else:
        kpts_lst = numpy.reshape(kpts, (-1, 3))

    cell, contr_coeff = gto.cell._split_basis(cell)
    lib.logger.debug1(cell, 'nao %d -> nao %d', *(contr_coeff.shape))

    ecpcell = gto.Cell()
    ecpcell._atm = cell._atm
    # append a fictitious s function to mimic the auxiliary index in pbc.incore.
    # ptr2last_env_idx to force PBCnr3c_fill_* function to copy the entire "env"
    ptr2last_env_idx = len(cell._env) - 1
    ecpbas = numpy.vstack([[0, 0, 1, 1, 0, ptr2last_env_idx, 0, 0],
                           cell._ecpbas]).astype(numpy.int32)
    ecpcell._bas = ecpbas
    ecpcell._env = cell._env
    # In pbc.incore _ecpbas is appended to two sets of cell._bas and the
    # fictitious s function.
    cell._env[AS_ECPBAS_OFFSET] = cell.nbas * 2 + 1
    cell._env[AS_NECPBAS] = len(cell._ecpbas)
    # shls_slice of auxiliary index (0,1) corresponds to the fictitious s function
    shls_slice = (0, cell.nbas, 0, cell.nbas, 0, 1)

    kptij_lst = numpy.hstack((kpts_lst, kpts_lst)).reshape(-1, 2, 3)
    buf = incore.aux_e2(cell,
                        ecpcell,
                        'ECPscalar',
                        aosym='s2',
                        kptij_lst=kptij_lst,
                        shls_slice=shls_slice)
    buf = buf.reshape(len(kpts_lst), -1)
    mat = []
    for k, kpt in enumerate(kpts_lst):
        v = lib.unpack_tril(buf[k], lib.HERMITIAN)
        if abs(kpt).sum() < 1e-9:  # gamma_point:
            v = v.real
        mat.append(reduce(numpy.dot, (contr_coeff.T, v, contr_coeff)))
    if kpts is None or numpy.shape(kpts) == (3, ):
        mat = mat[0]
    return mat
Beispiel #14
0
def get_pp_loc_part2(cell, kpts=None):
    '''PRB, 58, 3641 Eq (1), integrals associated to C1, C2, C3, C4
    '''
    from pyscf.pbc.df import incore
    if kpts is None:
        kpts_lst = numpy.zeros((1,3))
    else:
        kpts_lst = numpy.reshape(kpts, (-1,3))
    nkpts = len(kpts_lst)

    intors = ('int3c2e', 'int3c1e', 'int3c1e_r2_origk',
              'int3c1e_r4_origk', 'int3c1e_r6_origk')
    kptij_lst = numpy.hstack((kpts_lst,kpts_lst)).reshape(-1,2,3)
    buf = 0
    for cn in range(1, 5):
        fakecell = fake_cell_vloc(cell, cn)
        if fakecell.nbas > 0:
            v = incore.aux_e2(cell, fakecell, intors[cn], aosym='s2', comp=1,
                              kptij_lst=kptij_lst)
            buf += numpy.einsum('...i->...', v)

    if isinstance(buf, int):
        if any(cell.atom_symbol(ia) in cell._pseudo for ia in range(cell.natm)):
            pass
        else:
            lib.logger.warn(cell, 'cell.pseudo was specified but its elements %s '
                             'were not found in the system.', cell._pseudo.keys())
        vpploc = [0] * nkpts
    else:
        buf = buf.reshape(nkpts,-1)
        vpploc = []
        for k, kpt in enumerate(kpts_lst):
            v = lib.unpack_tril(buf[k])
            if abs(kpt).sum() < 1e-9:  # gamma_point:
                v = v.real
            vpploc.append(v)
    if kpts is None or numpy.shape(kpts) == (3,):
        vpploc = vpploc[0]
    return vpploc
Beispiel #15
0
def ecp_int(cell, kpts=None):
    from pyscf.pbc.df import incore
    if kpts is None:
        kpts_lst = numpy.zeros((1,3))
    else:
        kpts_lst = numpy.reshape(kpts, (-1,3))

    cell, contr_coeff = gto.cell._split_basis(cell)
    lib.logger.debug1(cell, 'nao %d -> nao %d', *(contr_coeff.shape))

    ecpcell = gto.Cell()
    ecpcell._atm = cell._atm
    # append a fictitious s function to mimic the auxiliary index in pbc.incore.
    # ptr2last_env_idx to force PBCnr3c_fill_* function to copy the entire "env"
    ptr2last_env_idx = len(cell._env) - 1
    ecpbas = numpy.vstack([[0, 0, 1, 1, 0, ptr2last_env_idx, 0, 0],
                           cell._ecpbas]).astype(numpy.int32)
    ecpcell._bas = ecpbas
    ecpcell._env = cell._env
    # In pbc.incore _ecpbas is appended to two sets of cell._bas and the
    # fictitious s function.
    cell._env[AS_ECPBAS_OFFSET] = cell.nbas * 2 + 1
    cell._env[AS_NECPBAS] = len(cell._ecpbas)
    # shls_slice of auxiliary index (0,1) corresponds to the fictitious s function
    shls_slice = (0, cell.nbas, 0, cell.nbas, 0, 1)

    kptij_lst = numpy.hstack((kpts_lst,kpts_lst)).reshape(-1,2,3)
    buf = incore.aux_e2(cell, ecpcell, 'ECPscalar', aosym='s2',
                        kptij_lst=kptij_lst, shls_slice=shls_slice)
    buf = buf.reshape(len(kpts_lst),-1)
    mat = []
    for k, kpt in enumerate(kpts_lst):
        v = lib.unpack_tril(buf[k], lib.HERMITIAN)
        if abs(kpt).sum() < 1e-9:  # gamma_point:
            v = v.real
        mat.append(reduce(numpy.dot, (contr_coeff.T, v, contr_coeff)))
    if kpts is None or numpy.shape(kpts) == (3,):
        mat = mat[0]
    return mat
Beispiel #16
0
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e', aosym='s2', comp=1):
    '''Vnuc - Vloc'''
    cell = mydf.cell
    nkpts = len(kpts)

    # Use the 3c2e code with steep s gaussians to mimic nuclear density
    fakenuc = _fake_nuc(cell)
    fakenuc._atm, fakenuc._bas, fakenuc._env = \
            gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env,
                         fakenuc._atm, fakenuc._bas, fakenuc._env)

    kptij_lst = numpy.hstack((kpts, kpts)).reshape(-1, 2, 3)
    buf = incore.aux_e2(cell,
                        fakenuc,
                        intor,
                        aosym=aosym,
                        comp=comp,
                        kptij_lst=kptij_lst)

    charge = cell.atom_charges()
    charge = numpy.append(charge,
                          -charge)  # (charge-of-nuccell, charge-of-fakenuc)
    nao = cell.nao_nr()
    nchg = len(charge)
    if aosym == 's1':
        nao_pair = nao**2
    else:
        nao_pair = nao * (nao + 1) // 2
    if comp == 1:
        buf = buf.reshape(nkpts, nao_pair, nchg)
        mat = numpy.einsum('kxz,z->kx', buf, charge)
    else:
        buf = buf.reshape(nkpts, comp, nao_pair, nchg)
        mat = numpy.einsum('kcxz,z->kcx', buf, charge)

    if cell.dimension != 0 and intor in ('int3c2e', 'int3c2e_sph',
                                         'int3c2e_cart'):
        assert (comp == 1)
        charge = -cell.atom_charges()

        if cell.dimension == 1 or cell.dimension == 2:
            Gv, Gvbase, kws = cell.get_Gv_weights(mydf.mesh)
            G0idx, SI_on_z = pbcgto.cell._SI_for_uniform_model_charge(cell, Gv)
            ZSI = numpy.einsum("i,ix->x", charge, cell.get_SI(Gv[G0idx]))
            ZSI -= numpy.einsum('i,xi->x', charge,
                                ft_ao.ft_ao(nuccell, Gv[G0idx]))
            coulG = 4 * numpy.pi / numpy.linalg.norm(Gv[G0idx], axis=1)**2
            nucbar = numpy.einsum('i,i,i,i', ZSI.conj(), coulG, kws[G0idx],
                                  SI_on_z)
            if abs(kpts).sum() < 1e-9:
                nucbar = nucbar.real
        else:  # cell.dimension == 3
            nucbar = sum(
                [z / nuccell.bas_exp(i)[0] for i, z in enumerate(charge)])
            nucbar *= numpy.pi / cell.vol

        ovlp = cell.pbc_intor('int1e_ovlp', 1, lib.HERMITIAN, kpts)
        for k in range(nkpts):
            if aosym == 's1':
                mat[k] -= nucbar * ovlp[k].reshape(nao_pair)
            else:
                mat[k] -= nucbar * lib.pack_tril(ovlp[k])

    return mat