Example #1
0
File: x2c.py Project: raybrad/pyscf
def _uncontract_mol(mol, xuncontract=False):
    pmol = mol.copy()
    _bas = []
    _env = []
    ptr = len(pmol._env)
    contr_coeff = []
    for ib in range(mol.nbas):
        if isinstance(xuncontract, bool):
            uncontract_me = xuncontract
        elif isinstance(xuncontract, str):
            ia = mol.bas_atom(ib)
            uncontract_me = ((xuncontract == mol.atom_pure_symbol(ia)) or
                             (xuncontract == mol.atom_symbol(ia)))
        elif isinstance(xuncontract, (tuple, list)):
            ia = mol.bas_atom(ib)
            uncontract_me = ((mol.atom_pure_symbol(ia) in xuncontract) or
                             (mol.atom_symbol(ia) in xuncontract) or
                             (ia in xuncontract))
        else:
            raise RuntimeError('xuncontract needs to be bool, str, tuple or list type')

        if uncontract_me:
            np = mol._bas[ib,mole.NPRIM_OF]
            nc = mol._bas[ib,mole.NCTR_OF]
            pexp = mol._bas[ib,mole.PTR_EXP]
# Bypass diffuse functions to avoid linear dependence
            large = (pmol._env[pexp:pexp+np-nc] > EXP_DROP).sum()
            if large > 0:
                l = mol._bas[ib,mole.ANG_OF]
                bs = numpy.empty((large,mol._bas.shape[1]), dtype=numpy.int32)
                bs[:] = mol._bas[ib]
                bs[:,mole.NCTR_OF] = bs[:,mole.NPRIM_OF] = 1
                bs[:,mole.PTR_EXP] = numpy.arange(pexp, pexp+large)
                for i in range(large):
                    nn = mole._gaussian_int(l*2+2, mol._env[pexp+i]*2)
                    _env.append(1/numpy.sqrt(nn))
                    bs[i,mole.PTR_COEFF] = ptr
                    ptr += 1
                _bas.append(bs)
            _bas.append(mol._bas[ib])

            l = mol.bas_angular(ib)
            d = l * 2 + 1
            c1 = numpy.zeros((d*large,d*mol.bas_nctr(ib)))
            c2 = numpy.eye(d*mol.bas_nctr(ib))
            contr_coeff.append(numpy.vstack((c1,c2)))
        else:
            _bas.append(mol._bas[ib])
            l = mol.bas_angular(ib)
            d = l * 2 + 1
            contr_coeff.append(numpy.eye(d*mol.bas_nctr(ib)))
    pmol._bas = numpy.vstack(_bas)
    pmol._env = numpy.hstack((mol._env, _env))
    return pmol, scipy.linalg.block_diag(*contr_coeff)
Example #2
0
def get_pnucp(mydf, kpts=None):
    cell = mydf.cell
    if kpts is None:
        kpts_lst = numpy.zeros((1, 3))
    else:
        kpts_lst = numpy.reshape(kpts, (-1, 3))

    log = logger.Logger(mydf.stdout, mydf.verbose)
    t1 = t0 = (time.clock(), time.time())

    nkpts = len(kpts_lst)
    nao = cell.nao_nr()
    nao_pair = nao * (nao + 1) // 2

    Gv, Gvbase, kws = cell.get_Gv_weights(mydf.gs)
    kpt_allow = numpy.zeros(3)
    if mydf.eta == 0:
        charge = -cell.atom_charges()
        #coulG=4*numpy.pi/G^2 is cancelled with (sigma dot p i, sigma dot p j)
        SI = cell.get_SI(Gv)
        vGR = numpy.einsum('i,ix->x', 4 * numpy.pi * charge, SI.real) * kws
        vGI = numpy.einsum('i,ix->x', 4 * numpy.pi * charge, SI.imag) * kws
        wjR = numpy.zeros((nkpts, nao_pair))
        wjI = numpy.zeros((nkpts, nao_pair))
    else:
        nuccell = copy.copy(cell)
        half_sph_norm = .5 / numpy.sqrt(numpy.pi)
        norm = half_sph_norm / mole._gaussian_int(2, mydf.eta)
        chg_env = [mydf.eta, norm]
        ptr_eta = cell._env.size
        ptr_norm = ptr_eta + 1
        chg_bas = [[ia, 0, 1, 1, 0, ptr_eta, ptr_norm, 0]
                   for ia in range(cell.natm)]
        nuccell._atm = cell._atm
        nuccell._bas = numpy.asarray(chg_bas, dtype=numpy.int32)
        nuccell._env = numpy.hstack((cell._env, chg_env))

        wj = lib.asarray(
            mydf._int_nuc_vloc(nuccell, kpts_lst, 'int3c2e_pvp1_sph'))
        wjR = wj.real
        wjI = wj.imag
        t1 = log.timer_debug1('pnucp pass1: analytic int', *t1)

        charge = -cell.atom_charges()
        #coulG=4*numpy.pi/G^2 is cancelled with (sigma dot p i, sigma dot p j)
        aoaux = ft_ao.ft_ao(nuccell, Gv)
        vGR = numpy.einsum('i,xi->x', 4 * numpy.pi * charge, aoaux.real) * kws
        vGI = numpy.einsum('i,xi->x', 4 * numpy.pi * charge, aoaux.imag) * kws

    max_memory = max(2000, mydf.max_memory - lib.current_memory()[0])
    for k, pqkR, pqkI, p0, p1 \
            in mydf.ft_loop(mydf.gs, kpt_allow, kpts_lst,
                            max_memory=max_memory, aosym='s2'):
        # rho_ij(G) nuc(-G) / G^2
        # = [Re(rho_ij(G)) + Im(rho_ij(G))*1j] [Re(nuc(G)) - Im(nuc(G))*1j] / G^2
        if not aft_jk.gamma_point(kpts_lst[k]):
            wjI[k] += numpy.einsum('k,xk->x', vGR[p0:p1], pqkI)
            wjI[k] -= numpy.einsum('k,xk->x', vGI[p0:p1], pqkR)
        wjR[k] += numpy.einsum('k,xk->x', vGR[p0:p1], pqkR)
        wjR[k] += numpy.einsum('k,xk->x', vGI[p0:p1], pqkI)
    t1 = log.timer_debug1('contracting Vnuc', *t1)

    if mydf.eta != 0 and cell.dimension == 3:
        nucbar = sum([z / nuccell.bas_exp(i)[0] for i, z in enumerate(charge)])
        nucbar *= numpy.pi / cell.vol * 2
        ovlp = cell.pbc_intor('int1e_kin_sph', 1, lib.HERMITIAN, kpts_lst)
        for k in range(nkpts):
            s = lib.pack_tril(ovlp[k])
            wjR[k] -= nucbar * s.real
            wjI[k] -= nucbar * s.imag

    wj = []
    for k, kpt in enumerate(kpts_lst):
        if aft_jk.gamma_point(kpt):
            wj.append(lib.unpack_tril(wjR[k]))
        else:
            wj.append(lib.unpack_tril(wjR[k] + wjI[k] * 1j))

    if kpts is None or numpy.shape(kpts) == (3, ):
        wj = wj[0]
    return wj
Example #3
0
File: x2c.py Project: pengdl/pyscf
def _uncontract_mol(mol, xuncontract=False):
    '''mol._basis + uncontracted steep functions'''
    pmol = mol.copy()
    _bas = []
    _env = []
    ptr = len(pmol._env)
    contr_coeff = []
    for ib in range(mol.nbas):
        if isinstance(xuncontract, bool):
            uncontract_me = xuncontract
        elif isinstance(xuncontract, str):
            ia = mol.bas_atom(ib)
            uncontract_me = ((xuncontract == mol.atom_pure_symbol(ia))
                             or (xuncontract == mol.atom_symbol(ia)))
        elif isinstance(xuncontract, (tuple, list)):
            ia = mol.bas_atom(ib)
            uncontract_me = ((mol.atom_pure_symbol(ia) in xuncontract)
                             or (mol.atom_symbol(ia) in xuncontract)
                             or (ia in xuncontract))
        else:
            raise RuntimeError(
                'xuncontract needs to be bool, str, tuple or list type')

        if uncontract_me:
            np = mol._bas[ib, mole.NPRIM_OF]
            nc = mol._bas[ib, mole.NCTR_OF]
            l = mol.bas_angular(ib)
            pexp = mol._bas[ib, mole.PTR_EXP]
            # Modfied partially uncontraction to avoid potentially lindep in the
            # segment-contracted basis
            nkept = (pmol._env[pexp:pexp + np] > EXP_DROP).sum()
            if nkept > nc:
                b_coeff = mol.bas_ctr_coeff(ib)
                norms = mole.gto_norm(l, mol._env[pexp:pexp + np])
                importance = numpy.einsum('i,ij->i', 1 / norms, abs(b_coeff))
                idx = numpy.argsort(importance[:nkept])
                contracted = numpy.sort(idx[nkept - nc:])
                primitive = numpy.sort(idx[:nkept - nc])

                # part1: pGTOs that are associated with small coefficients
                bs = numpy.empty((nkept - nc, mol._bas.shape[1]),
                                 dtype=numpy.int32)
                bs[:] = mol._bas[ib]
                bs[:, mole.NCTR_OF] = bs[:, mole.NPRIM_OF] = 1
                norms = numpy.empty(nkept - nc)
                for k, i in enumerate(primitive):
                    norms[k] = mole.gto_norm(l, mol._env[pexp + i])
                    _env.append(mol._env[pexp + i])
                    _env.append(norms[k])
                    bs[k, mole.PTR_EXP] = ptr
                    bs[k, mole.PTR_COEFF] = ptr + 1
                    ptr += 2
                _bas.append(bs)
                d = l * 2 + 1
                part1 = numpy.zeros((d * (nkept - nc), d * nc))
                c = numpy.einsum('i,ij->ij', 1 / norms, b_coeff[primitive])
                for i in range(d):
                    part1[i::d, i::d] = c


# part2: binding the pGTOs of small exps to the pGTOs of large coefficients
                bs = mol._bas[ib].copy()
                bs[mole.NPRIM_OF] = np - nkept + nc
                idx = numpy.hstack((contracted, numpy.arange(nkept, np)))
                exps = mol._env[pexp:pexp + np][idx]
                cs = b_coeff[idx]
                ee = mole._gaussian_int(l * 2 + 2, exps[:, None] + exps)
                s1 = numpy.einsum('pi,pq,qi->i', cs, ee, cs)
                s1 = numpy.sqrt(s1)
                cs = numpy.einsum('pi,i->pi', cs, 1 / s1)
                _env.extend(exps)
                _env.extend(cs.T.reshape(-1))
                bs[mole.PTR_EXP] = ptr
                bs[mole.PTR_COEFF] = ptr + exps.size
                ptr += exps.size + cs.size
                _bas.append(bs)

                part2 = numpy.eye(d * nc)
                for i in range(nc):
                    part2[i * d:(i + 1) * d, i * d:(i + 1) * d] *= s1[i]
                contr_coeff.append(numpy.vstack((part1, part2)))
            else:
                _bas.append(mol._bas[ib])
                contr_coeff.append(numpy.eye((l * 2 + 1) * nc))
        else:
            _bas.append(mol._bas[ib])
            l = mol.bas_angular(ib)
            d = l * 2 + 1
            contr_coeff.append(numpy.eye(d * mol.bas_nctr(ib)))
    pmol._bas = numpy.vstack(_bas)
    pmol._env = numpy.hstack((mol._env, _env))
    return pmol, scipy.linalg.block_diag(*contr_coeff)
Example #4
0
def get_pnucp(mydf, kpts=None):
    cell = mydf.cell
    if kpts is None:
        kpts_lst = numpy.zeros((1, 3))
    else:
        kpts_lst = numpy.reshape(kpts, (-1, 3))

    log = logger.Logger(mydf.stdout, mydf.verbose)
    t1 = t0 = (time.clock(), time.time())

    nkpts = len(kpts_lst)
    nao = cell.nao_nr()
    nao_pair = nao * (nao + 1) // 2

    Gv, Gvbase, kws = cell.get_Gv_weights(mydf.gs)
    charge = -cell.atom_charges()
    kpt_allow = numpy.zeros(3)
    coulG = tools.get_coulG(cell, kpt_allow, gs=mydf.gs, Gv=Gv)
    coulG *= kws
    if mydf.eta == 0:
        wj = numpy.zeros((nkpts, nao_pair), dtype=numpy.complex128)
        wjI = numpy.zeros((nkpts, nao_pair))
        SI = cell.get_SI(Gv)
        vG = numpy.einsum('i,ix->x', charge, SI) * coulG
    else:
        nuccell = copy.copy(cell)
        half_sph_norm = .5 / numpy.sqrt(numpy.pi)
        norm = half_sph_norm / mole._gaussian_int(2, mydf.eta)
        chg_env = [mydf.eta, norm]
        ptr_eta = cell._env.size
        ptr_norm = ptr_eta + 1
        chg_bas = [[ia, 0, 1, 1, 0, ptr_eta, ptr_norm, 0]
                   for ia in range(cell.natm)]
        nuccell._atm = cell._atm
        nuccell._bas = numpy.asarray(chg_bas, dtype=numpy.int32)
        nuccell._env = numpy.hstack((cell._env, chg_env))

        wj = lib.asarray(
            mydf._int_nuc_vloc(nuccell, kpts_lst, 'int3c2e_pvp1_sph'))
        t1 = log.timer_debug1('pnucp pass1: analytic int', *t1)

        aoaux = ft_ao.ft_ao(nuccell, Gv)
        vG = numpy.einsum('i,xi->x', charge, aoaux) * coulG

    max_memory = max(2000, mydf.max_memory - lib.current_memory()[0])
    for aoaoks, p0, p1 in mydf.ft_loop(mydf.gs,
                                       kpt_allow,
                                       kpts_lst,
                                       max_memory=max_memory,
                                       aosym='s2',
                                       intor='GTO_ft_pdotp_sph'):
        for k, aoao in enumerate(aoaoks):
            if aft_jk.gamma_point(kpts_lst[k]):
                wj[k] += numpy.einsum('k,kx->x', vG[p0:p1].real, aoao.real)
                wj[k] += numpy.einsum('k,kx->x', vG[p0:p1].imag, aoao.imag)
            else:
                wj[k] += numpy.einsum('k,kx->x', vG[p0:p1].conj(), aoao)
    t1 = log.timer_debug1('contracting pnucp', *t1)

    if mydf.eta != 0 and cell.dimension == 3:
        nucbar = sum(
            [-z / nuccell.bas_exp(i)[0] for i, z in enumerate(charge)])
        nucbar *= numpy.pi / cell.vol * 2  # 2 due to the factor 1/2 in T
        ovlp = cell.pbc_intor('int1e_kin_sph', 1, lib.HERMITIAN, kpts_lst)
        for k in range(nkpts):
            s = lib.pack_tril(ovlp[k])
            wj[k] += nucbar * s

    wj_kpts = []
    for k, kpt in enumerate(kpts_lst):
        if aft_jk.gamma_point(kpt):
            wj_kpts.append(lib.unpack_tril(wj[k].real.copy()))
        else:
            wj_kpts.append(lib.unpack_tril(wj[k]))

    if kpts is None or numpy.shape(kpts) == (3, ):
        wj_kpts = wj_kpts[0]
    return numpy.asarray(wj_kpts)
Example #5
0
File: x2c.py Project: eronca/pyscf
def get_pnucp(mydf, kpts=None):
    cell = mydf.cell
    if kpts is None:
        kpts_lst = numpy.zeros((1,3))
    else:
        kpts_lst = numpy.reshape(kpts, (-1,3))

    log = logger.Logger(mydf.stdout, mydf.verbose)
    t1 = t0 = (time.clock(), time.time())

    nkpts = len(kpts_lst)
    nao = cell.nao_nr()
    nao_pair = nao * (nao+1) // 2

    Gv, Gvbase, kws = cell.get_Gv_weights(mydf.gs)
    kpt_allow = numpy.zeros(3)
    if mydf.eta == 0:
        charge = -cell.atom_charges()
        #coulG=4*numpy.pi/G^2 is cancelled with (sigma dot p i, sigma dot p j)
        SI = cell.get_SI(Gv)
        vGR = numpy.einsum('i,ix->x', 4*numpy.pi*charge, SI.real) * kws
        vGI = numpy.einsum('i,ix->x', 4*numpy.pi*charge, SI.imag) * kws
        wjR = numpy.zeros((nkpts,nao_pair))
        wjI = numpy.zeros((nkpts,nao_pair))
    else:
        nuccell = copy.copy(cell)
        half_sph_norm = .5/numpy.sqrt(numpy.pi)
        norm = half_sph_norm/mole._gaussian_int(2, mydf.eta)
        chg_env = [mydf.eta, norm]
        ptr_eta = cell._env.size
        ptr_norm = ptr_eta + 1
        chg_bas = [[ia, 0, 1, 1, 0, ptr_eta, ptr_norm, 0] for ia in range(cell.natm)]
        nuccell._atm = cell._atm
        nuccell._bas = numpy.asarray(chg_bas, dtype=numpy.int32)
        nuccell._env = numpy.hstack((cell._env, chg_env))

        wj = lib.asarray(mydf._int_nuc_vloc(nuccell, kpts_lst, 'cint3c2e_pvp1_sph'))
        wjR = wj.real
        wjI = wj.imag
        t1 = log.timer_debug1('pnucp pass1: analytic int', *t1)

        charge = -cell.atom_charges()
        #coulG=4*numpy.pi/G^2 is cancelled with (sigma dot p i, sigma dot p j)
        aoaux = ft_ao.ft_ao(nuccell, Gv)
        vGR = numpy.einsum('i,xi->x', 4*numpy.pi*charge, aoaux.real) * kws
        vGI = numpy.einsum('i,xi->x', 4*numpy.pi*charge, aoaux.imag) * kws

    max_memory = max(2000, mydf.max_memory-lib.current_memory()[0])
    for k, pqkR, pqkI, p0, p1 \
            in mydf.ft_loop(mydf.gs, kpt_allow, kpts_lst,
                            max_memory=max_memory, aosym='s2'):
# rho_ij(G) nuc(-G) / G^2
# = [Re(rho_ij(G)) + Im(rho_ij(G))*1j] [Re(nuc(G)) - Im(nuc(G))*1j] / G^2
        if not pwdf_jk.gamma_point(kpts_lst[k]):
            wjI[k] += numpy.einsum('k,xk->x', vGR[p0:p1], pqkI)
            wjI[k] -= numpy.einsum('k,xk->x', vGI[p0:p1], pqkR)
        wjR[k] += numpy.einsum('k,xk->x', vGR[p0:p1], pqkR)
        wjR[k] += numpy.einsum('k,xk->x', vGI[p0:p1], pqkI)
    t1 = log.timer_debug1('contracting Vnuc', *t1)

    if mydf.eta != 0 and cell.dimension == 3:
        nucbar = sum([z/nuccell.bas_exp(i)[0] for i,z in enumerate(charge)])
        nucbar *= numpy.pi/cell.vol * 2
        ovlp = cell.pbc_intor('cint1e_kin_sph', 1, lib.HERMITIAN, kpts_lst)
        for k in range(nkpts):
            s = lib.pack_tril(ovlp[k])
            wjR[k] -= nucbar * s.real
            wjI[k] -= nucbar * s.imag

    wj = []
    for k, kpt in enumerate(kpts_lst):
        if pwdf_jk.gamma_point(kpt):
            wj.append(lib.unpack_tril(wjR[k]))
        else:
            wj.append(lib.unpack_tril(wjR[k]+wjI[k]*1j))

    if kpts is None or numpy.shape(kpts) == (3,):
        wj = wj[0]
    return wj
Example #6
0
def _uncontract_mol(mol, xuncontract=False, exp_drop=0.2):
    '''mol._basis + uncontracted steep functions'''
    pmol = copy.copy(mol)
    _bas = []
    _env = []
    ptr = len(pmol._env)
    contr_coeff = []
    for ib in range(mol.nbas):
        if isinstance(xuncontract, bool):
            uncontract_me = xuncontract
        elif isinstance(xuncontract, str):
            ia = mol.bas_atom(ib)
            uncontract_me = ((xuncontract == mol.atom_pure_symbol(ia)) or
                             (xuncontract == mol.atom_symbol(ia)))
        elif isinstance(xuncontract, (tuple, list)):
            ia = mol.bas_atom(ib)
            uncontract_me = ((mol.atom_pure_symbol(ia) in xuncontract) or
                             (mol.atom_symbol(ia) in xuncontract) or
                             (ia in xuncontract))
        else:
            raise RuntimeError('xuncontract needs to be bool, str, tuple or list type')

        if uncontract_me:
            np = mol._bas[ib,mole.NPRIM_OF]
            nc = mol._bas[ib,mole.NCTR_OF]
            l = mol._bas[ib,mole.ANG_OF]
            pexp = mol._bas[ib,mole.PTR_EXP]
# Modfied partially uncontraction to avoid potentially lindep in the
# segment-contracted basis
            nkept = (pmol._env[pexp:pexp+np] > exp_drop).sum()
            if nkept > nc:
                b_coeff = mol.bas_ctr_coeff(ib)
                importance = numpy.einsum('ij->i', abs(b_coeff))
                idx = numpy.argsort(importance[:nkept])
                contracted = numpy.sort(idx[nkept-nc:])
                primitive  = numpy.sort(idx[:nkept-nc])

# part1: pGTOs that are associated with small coefficients
                bs = numpy.empty((nkept-nc,mol._bas.shape[1]), dtype=numpy.int32)
                bs[:] = mol._bas[ib]
                bs[:,mole.NCTR_OF] = bs[:,mole.NPRIM_OF] = 1
                for k, i in enumerate(primitive):
                    norm = mole.gto_norm(l, mol._env[pexp+i])
                    _env.append(mol._env[pexp+i])
                    _env.append(norm)
                    bs[k,mole.PTR_EXP] = ptr
                    bs[k,mole.PTR_COEFF] = ptr + 1
                    ptr += 2
                _bas.append(bs)
                d = l * 2 + 1
                part1 = numpy.zeros((d*(nkept-nc),d*nc))
                c = b_coeff[primitive]
                for i in range(d):
                    part1[i::d,i::d] = c

# part2: binding the pGTOs of small exps to the pGTOs of large coefficients
                bs = mol._bas[ib].copy()
                bs[mole.NPRIM_OF] = np - nkept + nc
                idx = numpy.hstack((contracted, numpy.arange(nkept,np)))
                exps = mol._env[pexp:pexp+np][idx]
                cs = mol._libcint_ctr_coeff(ib)[idx]
                ee = mole._gaussian_int(l*2+2, exps[:,None] + exps)
                s1 = numpy.einsum('pi,pq,qi->i', cs, ee, cs)
                s1 = numpy.sqrt(s1)
                cs = numpy.einsum('pi,i->pi', cs, 1/s1)
                _env.extend(exps)
                _env.extend(cs.T.reshape(-1))
                bs[mole.PTR_EXP] = ptr
                bs[mole.PTR_COEFF] = ptr + exps.size
                ptr += exps.size + cs.size
                _bas.append(bs)

                part2 = numpy.eye(d*nc)
                for i in range(nc):
                    part2[i*d:(i+1)*d,i*d:(i+1)*d] *= s1[i]
                contr_coeff.append(numpy.vstack((part1, part2)))
            else:
                _bas.append(mol._bas[ib])
                contr_coeff.append(numpy.eye((l*2+1)*nc))
        else:
            _bas.append(mol._bas[ib])
            l = mol.bas_angular(ib)
            d = l * 2 + 1
            contr_coeff.append(numpy.eye(d*mol.bas_nctr(ib)))
    pmol._bas = numpy.asarray(numpy.vstack(_bas), dtype=numpy.int32)
    pmol._env = numpy.hstack((mol._env, _env))
    return pmol, scipy.linalg.block_diag(*contr_coeff)