示例#1
0
def multipoles1(r, lmax, reorder_dipole=True):
    ngrid = r.shape[0]
    xs = numpy.ones((lmax+1,ngrid))
    ys = numpy.ones((lmax+1,ngrid))
    zs = numpy.ones((lmax+1,ngrid))
    for i in range(1,lmax+1):
        xs[i] = xs[i-1] * r[:,0]
        ys[i] = ys[i-1] * r[:,1]
        zs[i] = zs[i-1] * r[:,2]
    ylms = []
    for l in range(lmax+1):
        nd = (l+1)*(l+2)//2
        c = numpy.empty((nd,3,ngrid))
        k = 0
        for lx in reversed(range(0, l+1)):
            for ly in reversed(range(0, l-lx+1)):
                lz = l - lx - ly
                c[k,0] = lx * xs[lx-1] * ys[ly] * zs[lz]
                c[k,1] = ly * xs[lx] * ys[ly-1] * zs[lz]
                c[k,2] = lz * xs[lx] * ys[ly] * zs[lz-1]
                k += 1
        ylm = gto.cart2sph(l, c.reshape(nd,3*ngrid).T)
        ylm = ylm.reshape(3,ngrid,l*2+1).transpose(0,2,1)
        ylms.append(ylm)

# when call libcint, p functions are ordered as px,py,pz
# reorder px,py,pz to p(-1),p(0),p(1)
    if (not reorder_dipole) and lmax >= 1:
        ylms[1] = ylms[1][:,[1,2,0]]
    return ylms
示例#2
0
def write_mo(fout, mol, mo_coeff, mo_energy=None, mo_occ=None):
    nmo = mo_coeff.shape[1]
    mo_cart = []
    centers = []
    types = []
    exps = []
    p0 = 0
    for ib in range(mol.nbas):
        ia = mol.bas_atom(ib)
        l = mol.bas_angular(ib)
        es = mol.bas_exp(ib)
        c = mol.bas_ctr_coeff(ib)
        np, nc = c.shape
        nd = nc * (2 * l + 1)
        mosub = mo_coeff[p0:p0 + nd].reshape(-1, nc, nmo)
        c2s = gto.cart2sph(l)
        mosub = numpy.einsum('yki,cy,pk->pci', mosub, c2s, c)
        mo_cart.append(mosub.reshape(-1, nmo))

        for t in TYPE_MAP[l]:
            types.append([t] * np)
        ncart = gto.len_cart(l)
        exps.extend([es] * ncart)
        centers.extend([ia + 1] * (np * ncart))
        p0 += nd
    mo_cart = numpy.vstack(mo_cart)
    centers = numpy.hstack(centers)
    types = numpy.hstack(types)
    exps = numpy.hstack(exps)
    nprim, nmo = mo_cart.shape

    fout.write('title line\n')
    fout.write(
        'GAUSSIAN            %3d MOL ORBITALS    %3d PRIMITIVES      %3d NUCLEI\n'
        % (mo_cart.shape[1], mo_cart.shape[0], mol.natm))
    for ia in range(mol.natm):
        x, y, z = mol.atom_coord(ia)
        fout.write(
            '%-4s %-4d (CENTRE%3d) %12.8f %12.8f %12.8f  CHARGE = %.1f\n' %
            (mol.atom_pure_symbol(ia), ia, ia, x, y, z, mol.atom_charge(ia)))
    for i0, i1 in lib.prange(0, nprim, 20):
        fout.write('CENTRE ASSIGNMENTS  %s\n' %
                   ''.join('%3d' % x for x in centers[i0:i1]))
    for i0, i1 in lib.prange(0, nprim, 20):
        fout.write('TYPE ASSIGNMENTS    %s\n' % ''.join('%3d' % x
                                                        for x in types[i0:i1]))
    for i0, i1 in lib.prange(0, nprim, 5):
        fout.write('EXPONENTS %s\n' % ' '.join('%14.7E' % x
                                               for x in exps[i0:i1]))

    for k in range(nmo):
        mo = mo_cart[:, k]
        if mo_energy is None or mo_occ is None:
            fout.write('CANMO %d\n' (k, mo_occ[k], mo_energy[k]))
        else:
            fout.write(
                'MO  %-4d                  OCC NO = %12.8f ORB. ENERGY = %12.8f\n'
                % (k, mo_occ[k], mo_energy[k]))
        for i0, i1 in lib.prange(0, nprim, 5):
            fout.write('%s\n' % ' '.join('%15.8E' % x for x in mo[i0:i1]))
示例#3
0
def multipoles1(r, lmax, reorder_dipole=True):
    ngrid = r.shape[0]
    xs = numpy.ones((lmax+1,ngrid))
    ys = numpy.ones((lmax+1,ngrid))
    zs = numpy.ones((lmax+1,ngrid))
    for i in range(1,lmax+1):
        xs[i] = xs[i-1] * r[:,0]
        ys[i] = ys[i-1] * r[:,1]
        zs[i] = zs[i-1] * r[:,2]
    ylms = []
    for l in range(lmax+1):
        nd = (l+1)*(l+2)//2
        c = numpy.empty((nd,3,ngrid))
        k = 0
        for lx in reversed(range(0, l+1)):
            for ly in reversed(range(0, l-lx+1)):
                lz = l - lx - ly
                c[k,0] = lx * xs[lx-1] * ys[ly] * zs[lz]
                c[k,1] = ly * xs[lx] * ys[ly-1] * zs[lz]
                c[k,2] = lz * xs[lx] * ys[ly] * zs[lz-1]
                k += 1
        ylm = gto.cart2sph(l, c.reshape(nd,3*ngrid).T)
        ylm = ylm.reshape(3,ngrid,l*2+1).transpose(0,2,1)
        ylms.append(ylm)

# when call libcint, p functions are ordered as px,py,pz
# reorder px,py,pz to p(-1),p(0),p(1)
    if (not reorder_dipole) and lmax >= 1:
        ylms[1] = ylms[1][:,[1,2,0]]
    return ylms
示例#4
0
def write_mo(fout, mol, mo_coeff, mo_energy=None, mo_occ=None):
    nmo = mo_coeff.shape[1]
    mo_cart = []
    centers = []
    types = []
    exps = []
    p0 = 0
    for ib in range(mol.nbas):
        ia = mol.bas_atom(ib)
        l = mol.bas_angular(ib)
        es = mol.bas_exp(ib)
        c = mol.bas_ctr_coeff(ib)
        np, nc = c.shape
        nd = nc*(2*l+1)
        mosub = mo_coeff[p0:p0+nd].reshape(-1,nc,nmo)
        c2s = gto.cart2sph(l)
        mosub = numpy.einsum('yki,cy,pk->pci', mosub, c2s, c)
        mo_cart.append(mosub.reshape(-1,nmo))

        for t in TYPE_MAP[l]:
            types.append([t]*np)
        ncart = gto.len_cart(l)
        exps.extend([es]*ncart)
        centers.extend([ia+1]*(np*ncart))
        p0 += nd
    mo_cart = numpy.vstack(mo_cart)
    centers = numpy.hstack(centers)
    types = numpy.hstack(types)
    exps = numpy.hstack(exps)
    nprim, nmo = mo_cart.shape

    fout.write('title line\n')
    fout.write('GAUSSIAN            %3d MOL ORBITALS    %3d PRIMITIVES      %3d NUCLEI\n'
               % (mo_cart.shape[1], mo_cart.shape[0], mol.natm))
    for ia in range(mol.natm):
        x, y, z = mol.atom_coord(ia)
        fout.write('%-4s %-4d (CENTRE%3d) %12.8f %12.8f %12.8f  CHARGE = %.1f\n'
                   % (mol.atom_pure_symbol(ia), ia, ia, x, y, z,
                      mol.atom_charge(ia)))
    for i0, i1 in lib.prange(0, nprim, 20):
        fout.write('CENTRE ASSIGNMENTS  %s\n' % ''.join('%3d'%x for x in centers[i0:i1]))
    for i0, i1 in lib.prange(0, nprim, 20):
        fout.write('TYPE ASSIGNMENTS    %s\n' % ''.join('%3d'%x for x in types[i0:i1]))
    for i0, i1 in lib.prange(0, nprim, 5):
        fout.write('EXPONENTS %s\n' % ' '.join('%14.7E'%x for x in exps[i0:i1]))

    for k in range(nmo):
        mo = mo_cart[:,k]
        if mo_energy is None or mo_occ is None:
            fout.write('CANMO %d\n'
                       (k, mo_occ[k], mo_energy[k]))
        else:
            fout.write('MO  %-4d                  OCC NO = %12.8f ORB. ENERGY = %12.8f\n' %
                       (k, mo_occ[k], mo_energy[k]))
        for i0, i1 in lib.prange(0, nprim, 5):
            fout.write('%s\n' % ' '.join('%15.8E'%x for x in mo[i0:i1]))
示例#5
0
文件: sph.py 项目: rvexiau/pyscf
def multipoles(r, lmax, reorder_dipole=True):
    '''
    Compute all multipoles upto lmax

    rad = numpy.linalg.norm(r, axis=1)
    ylms = real_ylm(r/rad.reshape(-1,1), lmax)
    pol = [rad**l*y for l, y in enumerate(ylms)]

    Kwargs:
        reorder_p : bool
            sort dipole to the order (x,y,z)
    '''
    from pyscf import gto

    # libcint cart2sph transformation provide the capability to compute
    # multipole directly.  cart2sph function is fast for low angular moment.
    ngrid = r.shape[0]
    xs = numpy.ones((lmax + 1, ngrid))
    ys = numpy.ones((lmax + 1, ngrid))
    zs = numpy.ones((lmax + 1, ngrid))
    for i in range(1, lmax + 1):
        xs[i] = xs[i - 1] * r[:, 0]
        ys[i] = ys[i - 1] * r[:, 1]
        zs[i] = zs[i - 1] * r[:, 2]
    ylms = []
    for l in range(lmax + 1):
        nd = (l + 1) * (l + 2) // 2
        c = numpy.empty((nd, ngrid))
        k = 0
        for lx in reversed(range(0, l + 1)):
            for ly in reversed(range(0, l - lx + 1)):
                lz = l - lx - ly
                c[k] = xs[lx] * ys[ly] * zs[lz]
                k += 1
        ylm = gto.cart2sph(l, c.T).T
        ylms.append(ylm)


# when call libcint, p functions are ordered as px,py,pz
# reorder px,py,pz to p(-1),p(0),p(1)
    if (not reorder_dipole) and lmax >= 1:
        ylms[1] = ylms[1][[1, 2, 0]]
    return ylms
示例#6
0
def write_coeff(fout, mol, mo_coeff):
    #fout.write('ALDET\n')
    nmo = mo_coeff.shape[1]
    mo_cart = []
    centers = []
    types = []
    exps = []
    p0 = 0
    for ib in range(mol.nbas):
        ia = mol.bas_atom(ib)
        l = mol.bas_angular(ib)
        es = mol.bas_exp(ib)
        c = mol._libcint_ctr_coeff(ib)
        #c = mol.bas_ctr_coeff(ib)
        np, nc = c.shape
        nd = nc*(2*l+1)
        mosub = mo_coeff[p0:p0+nd].reshape(-1,nc,nmo)
        c2s = gto.cart2sph(l)
        mosub = numpy.einsum('yki,cy,pk->pci', mosub, c2s, c)
        mo_cart.append(mosub.transpose(1,0,2).reshape(-1,nmo))

        for t in TYPE_MAP[l]:
            types.append([t]*np)
        ncart = gto.len_cart(l)
        exps.extend([es]*ncart)
        centers.extend([ia+1]*(np*ncart))
        p0 += nd
    mo_cart = numpy.vstack(mo_cart)
    centers = numpy.hstack(centers)
    types = numpy.hstack(types)
    exps = numpy.hstack(exps)
    nprim, nmo = mo_cart.shape

    fout.write('From PySCF\n')
    for k in range(nmo):
        mo = mo_cart[:,k]
        fout.write('CANMO %d\n' % (k+1))
        for i0, i1 in lib.prange(0, nprim, 5):
            fout.write(' %s\n' % ' '.join('%15.8E'%x for x in mo[i0:i1]))
    fout.write('END DATA\n')
示例#7
0
def mo_comps(test, mol, mo_coeff, cart=False, orth_method='meta_lowdin'):
    '''Pick particular AOs based on the given test function
    compute the AO components
    '''
    if cart:
        s = mol.intor_symmetric('cint1e_ovlp_cart')
        preao = lo.orth.pre_orth_ao(mol)
        tc2s = []
        for ib in range(mol.nbas):
            l = mol.bas_angular(ib)
            tc2s.append(gto.cart2sph(l))
        tc2s = scipy.linalg.block_diag(*tc2s)
        lao = lo.orth.orth_ao(mol, orth_method)
        lao = numpy.dot(tc2s, lao)
    else:
        s = mol.intor_symmetric('cint1e_ovlp_sph')
        lao = lo.orth.orth_ao(mol, orth_method)

    idx = [i for i,x in enumerate(mol.spheric_labels(1)) if test(x)]
    idx = numpy.array(idx)
    mo1 = reduce(numpy.dot, (lao[:,idx].T, s, mo_coeff))
    s1 = numpy.einsum('ki,ki->i', mo1, mo1)
    return s1
示例#8
0
def write_mo(fout, mol, mo_coeff, mo_energy=None, mo_occ=None):
    if mol.cart:
        raise NotImplementedError('Cartesian basis not available')

    #FIXME: Duplicated primitives may lead to problems.  x2c._uncontract_mol
    # is the workaround at the moment to remove duplicated primitives.
    from pyscf.x2c import x2c
    mol, ctr = x2c._uncontract_mol(mol, True, 0.)
    mo_coeff = numpy.dot(ctr, mo_coeff)

    nmo = mo_coeff.shape[1]
    mo_cart = []
    centers = []
    types = []
    exps = []
    p0 = 0
    for ib in range(mol.nbas):
        ia = mol.bas_atom(ib)
        l = mol.bas_angular(ib)
        es = mol.bas_exp(ib)
        c = mol._libcint_ctr_coeff(ib)
        np, nc = c.shape
        nd = nc*(2*l+1)
        mosub = mo_coeff[p0:p0+nd].reshape(-1,nc,nmo)
        c2s = gto.cart2sph(l)
        mosub = numpy.einsum('yki,cy,pk->pci', mosub, c2s, c)
        mo_cart.append(mosub.transpose(1,0,2).reshape(-1,nmo))

        for t in TYPE_MAP[l]:
            types.append([t]*np)
        ncart = mol.bas_len_cart(ib)
        exps.extend([es]*ncart)
        centers.extend([ia+1]*(np*ncart))
        p0 += nd
    mo_cart = numpy.vstack(mo_cart)
    centers = numpy.hstack(centers)
    types = numpy.hstack(types)
    exps = numpy.hstack(exps)
    nprim, nmo = mo_cart.shape

    fout.write('From PySCF\n')
    fout.write('GAUSSIAN            %3d MOL ORBITALS    %3d PRIMITIVES      %3d NUCLEI\n'
               % (mo_cart.shape[1], mo_cart.shape[0], mol.natm))
    for ia in range(mol.natm):
        x, y, z = mol.atom_coord(ia)
        fout.write('  %-4s %-4d (CENTRE%3d)  %11.8f %11.8f %11.8f  CHARGE = %.1f\n'
                   % (mol.atom_pure_symbol(ia), ia+1, ia+1, x, y, z,
                      mol.atom_charge(ia)))
    for i0, i1 in lib.prange(0, nprim, 20):
        fout.write('CENTRE ASSIGNMENTS  %s\n' % ''.join('%3d'%x for x in centers[i0:i1]))
    for i0, i1 in lib.prange(0, nprim, 20):
        fout.write('TYPE ASSIGNMENTS    %s\n' % ''.join('%3d'%x for x in types[i0:i1]))
    for i0, i1 in lib.prange(0, nprim, 5):
        fout.write('EXPONENTS  %s\n' % ' '.join('%13.7E'%x for x in exps[i0:i1]))

    for k in range(nmo):
        mo = mo_cart[:,k]
        if mo_energy is None and mo_occ is None:
            fout.write('CANMO %d\n' % (k+1))
        elif mo_energy is None:
            fout.write('MO  %-4d                  OCC NO = %12.8f ORB. ENERGY = 0.0000\n' %
                       (k+1, mo_occ[k]))
        else:
            fout.write('MO  %-4d                  OCC NO = %12.8f ORB. ENERGY = %12.8f\n' %
                       (k+1, mo_occ[k], mo_energy[k]))
        for i0, i1 in lib.prange(0, nprim, 5):
            fout.write(' %s\n' % ' '.join('%15.8E'%x for x in mo[i0:i1]))
    fout.write('END DATA\n')
    if mo_energy is None or mo_occ is None:
        fout.write('ALDET    ENERGY =        0.0000000000   VIRIAL(-V/T)  =   0.00000000\n')
    elif mo_energy is None and mo_occ is None:
        pass
    else :
        fout.write('RHF      ENERGY =        0.0000000000   VIRIAL(-V/T)  =   0.00000000\n')
示例#9
0
def write_wfn(fout, mol, mo_coeff, mo_energy, mo_occ, tot_ener):
    from pyscf.x2c import x2c
    mol, ctr = x2c._uncontract_mol(mol, True, 0.)
    mo_coeff = numpy.dot(ctr, mo_coeff)

    nmo = mo_coeff.shape[1]
    mo_cart = []
    from pyscf import gto
    centers = []
    types = []
    exps = []
    p0 = 0
    for ib in range(mol.nbas):
        ia = mol.bas_atom(ib)
        l = mol.bas_angular(ib)
        es = mol.bas_exp(ib)
        c = mol._libcint_ctr_coeff(ib)
        np, nc = c.shape
        nd = nc * (2 * l + 1)
        mosub = mo_coeff[p0:p0 + nd].reshape(-1, nc, nmo)
        c2s = gto.cart2sph(l)
        mosub = numpy.einsum('yki,cy,pk->pci', mosub, c2s, c)
        mo_cart.append(mosub.transpose(1, 0, 2).reshape(-1, nmo))

        for t in TYPE_MAP[l]:
            types.append([t] * np)
        ncart = mol.bas_len_cart(ib)
        exps.extend([es] * ncart)
        centers.extend([ia + 1] * (np * ncart))
        p0 += nd
    mo_cart = numpy.vstack(mo_cart)
    centers = numpy.hstack(centers)
    types = numpy.hstack(types)
    exps = numpy.hstack(exps)
    nprim, nmo = mo_cart.shape

    fout.write('From PySCF\\n')
    fout.write('GAUSSIAN %14d MOL ORBITALS %6d PRIMITIVES %8d NUCLEI\\n' %
               (mo_cart.shape[1], mo_cart.shape[0], mol.natm))
    for ia in range(mol.natm):
        x, y, z = mol.atom_coord(ia)
        fout.write('%3s%8d (CENTRE%3d) %12.8f%12.8f%12.8f  CHARGE = %4.1f\\n' %
                   (mol.atom_pure_symbol(ia), ia + 1, ia + 1, x, y, z,
                    mol.atom_charge(ia)))
    for i0, i1 in lib.prange(0, nprim, 20):
        fout.write('CENTRE ASSIGNMENTS  %s\\n' %
                   ''.join('%3d' % x for x in centers[i0:i1]))
    for i0, i1 in lib.prange(0, nprim, 20):
        fout.write('TYPE ASSIGNMENTS    %s\\n' %
                   ''.join('%3d' % x for x in types[i0:i1]))
    for i0, i1 in lib.prange(0, nprim, 5):
        fout.write('EXPONENTS  %s\\n' % ' '.join('%13.7E' % x
                                                 for x in exps[i0:i1]))

    for k in range(nmo):
        mo = mo_cart[:, k]
        fout.write(
            'MO  %-12d          OCC NO = %12.8f ORB. ENERGY = %12.8f\\n' %
            (k + 1, mo_occ[k], mo_energy[k]))
        for i0, i1 in lib.prange(0, nprim, 5):
            fout.write(' %s\\n' % ' '.join('%15.8E' % x for x in mo[i0:i1]))
    fout.write('END DATA\\n')
    fout.write(' THE SCF ENERGY =%20.12f THE VIRIAL(-V/T)=   0.00000000\\n' %
               tot_ener)
示例#10
0
def mo_comps(test_or_idx,
             mol,
             mo_coeff,
             cart=False,
             orth_method='meta_lowdin'):
    '''Pick particular AOs based on the given test function to compute the AO
    contributions for each MO

    Args:
        test_or_idx : filter function or list
            If test_or_idx is a list, it is considered as the AO indices.
            If it's a function,  the AO indices are the items for which the
            function value is true.

    Kwargs:
        cart : bool
            whether the orbital coefficients are based on cartesian basis.
        orth_method : str
            The localization method to generated orthogonal AO upon which the AO
            contribution are computed.  It can be one of 'meta_lowdin',
            'lowdin' or 'nao'.

    Returns:
        A list of float to indicate the total contributions (normalized to 1) of
        localized AOs

    Examples:

    >>> from pyscf import gto, scf
    >>> from pyscf.tools import mo_mapping
    >>> mol = gto.M(atom='H 0 0 0; F 0 0 1', basis='6-31g')
    >>> mf = scf.RHF(mol).run()
    >>> comp = mo_mapping.mo_comps(lambda x: 'F 2s' in x, mol, mf.mo_coeff)
    >>> print('MO-id    components')
    >>> for i in enumerate(comp):
    ...     print('%-3d      %.10f' % (i, comp[i]))
    MO-id    components
    0        0.0000066344
    1        0.8796915532
    2        0.0590259826
    3        0.0000000000
    4        0.0000000000
    5        0.0435028851
    6        0.0155889103
    7        0.0000000000
    8        0.0000000000
    9        0.0000822361
    10       0.0021017982
    '''
    if cart:
        s = mol.intor_symmetric('cint1e_ovlp_cart')
        preao = lo.orth.pre_orth_ao(mol)
        tc2s = []
        for ib in range(mol.nbas):
            l = mol.bas_angular(ib)
            t = gto.cart2sph(l)
            for i in range(mol.bas_nctr(ib)):
                tc2s.append(t)
        tc2s = scipy.linalg.block_diag(*tc2s)
        lao = lo.orth.orth_ao(mol, orth_method)
        lao = numpy.dot(tc2s, lao)
    else:
        s = mol.intor_symmetric('cint1e_ovlp_sph')
        lao = lo.orth.orth_ao(mol, orth_method)

    if callable(test_or_idx):
        idx = [
            i for i, x in enumerate(mol.spheric_labels(1)) if test_or_idx(x)
        ]
    else:
        idx = numpy.asarray(test_or_idx, dtype=int)
    if len(idx) == 0:
        logger.warn(mol, 'Required orbitals are not found')
    mo1 = reduce(numpy.dot, (lao[:, idx].T, s, mo_coeff))
    s1 = numpy.einsum('ki,ki->i', mo1, mo1)
    return s1
示例#11
0
文件: mo_mapping.py 项目: v1j4y/pyscf
def mo_comps(test_or_idx, mol, mo_coeff, cart=False, orth_method='meta_lowdin'):
    '''Pick particular AOs based on the given test function to compute the AO
    contributions for each MO

    Args:
        test_or_idx : filter function or 1D array
            If test_or_idx is a list, it is considered as the AO indices.
            If it's a function,  the AO indices are the items for which the
            function value is true.

    Kwargs:
        cart : bool
            whether the orbital coefficients are based on cartesian basis.
        orth_method : str
            The localization method to generated orthogonal AO upon which the AO
            contribution are computed.  It can be one of 'meta_lowdin',
            'lowdin' or 'nao'.

    Returns:
        A list of float to indicate the total contributions (normalized to 1) of
        localized AOs

    Examples:

    >>> from pyscf import gto, scf
    >>> from pyscf.tools import mo_mapping
    >>> mol = gto.M(atom='H 0 0 0; F 0 0 1', basis='6-31g')
    >>> mf = scf.RHF(mol).run()
    >>> comp = mo_mapping.mo_comps(lambda x: 'F 2s' in x, mol, mf.mo_coeff)
    >>> print('MO-id    components')
    >>> for i in enumerate(comp):
    ...     print('%-3d      %.10f' % (i, comp[i]))
    MO-id    components
    0        0.0000066344
    1        0.8796915532
    2        0.0590259826
    3        0.0000000000
    4        0.0000000000
    5        0.0435028851
    6        0.0155889103
    7        0.0000000000
    8        0.0000000000
    9        0.0000822361
    10       0.0021017982
    '''
    if cart:
        s = mol.intor_symmetric('cint1e_ovlp_cart')
        preao = lo.orth.pre_orth_ao(mol)
        tc2s = []
        for ib in range(mol.nbas):
            l = mol.bas_angular(ib)
            tc2s.append(gto.cart2sph(l))
        tc2s = scipy.linalg.block_diag(*tc2s)
        lao = lo.orth.orth_ao(mol, orth_method)
        lao = numpy.dot(tc2s, lao)
    else:
        s = mol.intor_symmetric('cint1e_ovlp_sph')
        lao = lo.orth.orth_ao(mol, orth_method)

    if callable(test):
        idx = [i for i,x in enumerate(mol.spheric_labels(1)) if test(x)]
    else:
        idx = test
    idx = numpy.asarray(idx)
    mo1 = reduce(numpy.dot, (lao[:,idx].T, s, mo_coeff))
    s1 = numpy.einsum('ki,ki->i', mo1, mo1)
    return s1