コード例 #1
0
ファイル: test_mole.py プロジェクト: chrinide/pyscf
 def test_intor_cross(self):
     mol1 = gto.M(atom='He', basis={'He': [(2,(1.,1))]}, cart=True)
     s0 = gto.intor_cross('int1e_ovlp', mol1, mol0)
     self.assertEqual(s0.shape, (6, 34))
     s0 = gto.intor_cross('int1e_ovlp', mol0, mol1)
     self.assertEqual(s0.shape, (34, 6))
     s0 = gto.intor_cross('int1e_ovlp_cart', mol0, mol1)
     self.assertEqual(s0.shape, (36, 6))
コード例 #2
0
 def test_intor_cross(self):
     mol1 = gto.M(atom='He', basis={'He': [(2, (1., 1))]}, cart=True)
     s0 = gto.intor_cross('int1e_ovlp', mol1, mol0)
     self.assertEqual(s0.shape, (6, 34))
     s0 = gto.intor_cross('int1e_ovlp', mol0, mol1)
     self.assertEqual(s0.shape, (34, 6))
     s0 = gto.intor_cross('int1e_ovlp_cart', mol0, mol1)
     self.assertEqual(s0.shape, (36, 6))
コード例 #3
0
ファイル: cores.py プロジェクト: luglio/pyscf-mp2-f12
def core2(xmol, opt, libint = False, clean = True):
    if libint: # use libint integrals
        # dir
        binpath, tmppath = get_dir()
        binpath += 'hf2'
        # label
        labelpath = tmppath + '2' + str(opt)
        with open(labelpath, 'wb') as f:
            f.write(str(opt))
        # atom
        atmpath = labelpath + 'a'
        with open(atmpath, 'wb') as f:
            f.write(atom2xyz(xmol.mol))
        # basis
        bs1 = basis2g94(xmol.mol.basis, xmol.dic)
        bs2 = basis2g94(xmol.Vmol.basis, xmol.dic)
        # run
        cmd00 = make_command((binpath, str(opt), atmpath, bs1, bs1, labelpath + 'o00'))
        cprint(cmd00)
        os.system(cmd00)
        cmd01 = make_command((binpath, str(opt), atmpath, bs1, bs2, labelpath + 'o01'))
        cprint(cmd01)
        os.system(cmd01)
        '''cmd10 = make_command((binpath, str(opt), atmpath, bs2, bs1, labelpath + 'o10'))
        os.system(cmd10)'''
        cmd11 = make_command((binpath, str(opt), atmpath, bs2, bs2, labelpath + 'o11'))
        cprint(cmd11)
        os.system(cmd11)
        # load
        nh = xmol.nHAO
        nc = xmol.nCAO
        n = nh + nc
        AO00 = loadmatrix2((nh, nh), labelpath + 'o00')
        AO01 = loadmatrix2((nh, nc), labelpath + 'o01')
        AO11 = loadmatrix2((nc, nc), labelpath + 'o11')
        # clean
        if clean:
            shutil.rmtree(tmppath)
        # return
        out = np.zeros((n, n))
        out[:nh, :nh] = AO00
        out[:nh, nh:] = AO01
        out[nh:, :nh] = HerConj(AO01)
        out[nh:, nh:] = AO11
        return out
    else: # use pyscf
        f00 = gto.intor_cross(coredic2[opt], xmol.mol, xmol.mol)
        f01 = gto.intor_cross(coredic2[opt], xmol.mol, xmol.Vmol)
        f11 = gto.intor_cross(coredic2[opt], xmol.Vmol, xmol.Vmol)
        if opt == 1: # nuc integral from pyscf counts twice
            return np.hstack((np.vstack((f00, HerConj(f01))), np.vstack((f01, f11)))) * 0.5
        else:
            return np.hstack((np.vstack((f00, HerConj(f01))), np.vstack((f01, f11))))
コード例 #4
0
ファイル: test_mo_mapping.py プロジェクト: berquist/pyscf
 def test_mo_1to1map(self):
     mol1 = gto.M(atom = '''O 0 0 0; O 0 0 1''', basis='6-31g')
     mol2 = gto.M(atom = '''O 0 0 0; O 0 0 1''', basis='ccpvdz')
     s = gto.intor_cross('cint1e_ovlp_sph', mol1, mol2)
     idx = mo_mapping.mo_1to1map(s)
     self.assertTrue(numpy.allclose(idx,
         [0, 1, 2, 3, 4, 5, 6, 7, 8, 14, 15, 16, 17, 18, 19, 20, 21, 22]))
コード例 #5
0
 def test_mo_1to1map(self):
     mol1 = gto.M(atom = '''O 0 0 0; O 0 0 1''', basis='6-31g')
     mol2 = gto.M(atom = '''O 0 0 0; O 0 0 1''', basis='ccpvdz')
     s = gto.intor_cross('cint1e_ovlp_sph', mol1, mol2)
     idx = mo_mapping.mo_1to1map(s)
     self.assertTrue(numpy.allclose(idx,
         [0, 1, 2, 3, 4, 5, 6, 7, 8, 14, 15, 16, 17, 18, 19, 20, 21, 22]))
コード例 #6
0
ファイル: orth.py プロジェクト: yfyh2013/pyscf
    def ecp_ano_det_ovlp(atm_ecp, atm_ano, ecpcore):
        ecp_ao_loc = atm_ecp.ao_loc_nr()
        ano_ao_loc = atm_ano.ao_loc_nr()
        ecp_ao_dim = ecp_ao_loc[1:] - ecp_ao_loc[:-1]
        ano_ao_dim = ano_ao_loc[1:] - ano_ao_loc[:-1]
        ecp_bas_l = [[atm_ecp.bas_angular(i)] * d
                     for i, d in enumerate(ecp_ao_dim)]
        ano_bas_l = [[atm_ano.bas_angular(i)] * d
                     for i, d in enumerate(ano_ao_dim)]
        ecp_bas_l = numpy.hstack(ecp_bas_l)
        ano_bas_l = numpy.hstack(ano_bas_l)

        ecp_idx = []
        ano_idx = []
        for l in range(4):
            nocc, nfrac = atom_hf.frac_occ(stdsymb, l)
            if nfrac > 1e-15:
                nocc += 1
            if nocc == 0:
                break
            i0 = ecpcore[l] * (2 * l + 1)
            i1 = nocc * (2 * l + 1)
            ecp_idx.append(numpy.where(ecp_bas_l == l)[0][:i1 - i0])
            ano_idx.append(numpy.where(ano_bas_l == l)[0][i0:i1])
        ecp_idx = numpy.hstack(ecp_idx)
        ano_idx = numpy.hstack(ano_idx)
        s12 = gto.intor_cross('int1e_ovlp', atm_ecp, atm_ano)[ecp_idx][:,
                                                                       ano_idx]
        return numpy.linalg.det(s12)
コード例 #7
0
ファイル: cores.py プロジェクト: luglio/pyscf-mp2-f12
def core2hf_(mf, opt, dic = None, libint = False, clean = True):
    if libint:
        # dir
        binpath, tmppath = get_dir()
        binpath += 'hf2'
        # label
        labelpath = tmppath + '2' + str(opt)
        with open(labelpath, 'wb') as f:
            f.write(str(opt))
        # atom
        atmpath = labelpath + 'a'
        with open(atmpath, 'wb') as f:
            f.write(atom2xyz(mf.mol))
        # basis
        bs1 = basis2g94(mf.mol.basis, dic)
        # run
        cmd00 = make_command((binpath, str(opt), atmpath, bs1, bs1, labelpath + 'o00'))
        cprint(cmd00)
        os.system(cmd00)
        # load
        n = mf.mo_coeff.shape[0]
        AO00 = loadmatrix2((n, n), labelpath + 'o00')
        # clean
        if clean:
            shutil.rmtree(tmppath)
        # return
        return AO00
    else:
        f00 = gto.intor_cross(coredic2[opt], mf.mol, mf.mol)
        if opt == 1:
            return 0.5 * f00
        else:
            return f00
コード例 #8
0
ファイル: mo_mapping.py プロジェクト: diradical/pyscf
def mo_map(mol1, mo1, mol2, mo2, base=1, tol=.5):
    s = gto.intor_cross('cint1e_ovlp_sph', mol1, mol2)
    s = reduce(numpy.dot, (mo1.T, s, mo2))
    idx = numpy.argwhere(abs(s) > tol)
    for i,j in idx:
        logger.info(mol1, '<mo-1|mo-2>  %d  %d  %12.8f',
                    i+base, j+base, s[i,j])
    return idx, s
コード例 #9
0
ファイル: xMole.py プロジェクト: luglio/pyscf-mp2-f12
 def __init__(self, mf, CABSbasis = None, CABSp = False, name = 'xMole'):
     self.dic = dictg94()
     self.f12 = (-0.27070, -0.19532, -0.30552, -0.81920, -0.18297, -2.85917, -0.10986, -9.50073, -0.06810, -35.69989, -0.04224, -197.79328)
     self._vhf = mf
     self.mol = mf.mol
     molname = name.replace(' ','').replace('/','').replace('\\','')
     if molname == '':
         self.molname = 'xMole'
     self.molname = molname
     # TODO: use multi bases
     if CABSbasis is None:
         CABSbasis = mf.mol.basis + '_optri'
     self.Vmol = gto.M(atom = mf.mol.atom, basis = CABSbasis)
     self.CABSp = CABSp
     # use CABS+ or CABS
     if CABSp:
         ovlp1 = gto.intor_cross('cint1e_ovlp_sph', self.mol, self.mol)
         ovlp2 = gto.intor_cross('cint1e_ovlp_sph', self.Vmol, self.mol)
         #S12t = np.dot(np.vstack((ovlp1, ovlp2)), mf.mo_coeff)
         # There are not differences whether to use <AO|AO> matrix or <MO|AO>
         S12t = np.vstack((ovlp1, ovlp2))
         Vt, S, Ut = np.linalg.svd(S12t)
         rnk = rankcount(S)
         (self.nHAO, self.nHMO) = np.shape(mf.mo_coeff)
         (self.nCAO, self.nCMO) = np.shape(Vt)
         self.nCAO -= self.nHAO
         self.nCMO -= rnk
         self.Xmo_coeff = np.hstack((np.vstack((mf.mo_coeff, np.zeros((self.nCAO, self.nHMO)))), Vt[:, rnk:]))
     else:
         ovlpx = gto.intor_cross('cint1e_ovlp_sph', self.Vmol, self.mol)
         Vt, S, Ut = np.linalg.svd(ovlpx)
         rnk = rankcount(S)
         C = Vt[:, rnk:]
         (self.nHAO, self.nHMO) = np.shape(mf.mo_coeff)
         (self.nCAO, self.nCMO) = np.shape(C)
         self.Xmo_coeff = np.zeros((self.nHAO + self.nCAO, self.nHMO + self.nCMO))
         self.Xmo_coeff[:self.nHAO, :self.nHMO] = mf.mo_coeff
         self.Xmo_coeff[self.nHAO:, self.nHMO:] = C
     # mo numbers
     self.no = mf.mol.nelectron // 2
     self.nv = self.nHMO - self.no
     self.nc = self.nCMO
     cprint(self.Xmo_coeff.shape)
コード例 #10
0
def get_locorb(mf, localize='pm', pair=True):
    mol = mf.mol
    mo = mf.mo_coeff
    nbf = mf.mo_coeff.shape[0]
    nif = mf.mo_coeff.shape[1]
    mol2 = mf.mol.copy()
    mol2.basis = 'sto-6g'
    mol2.build()
    mf2 = scf.RHF(mol2)
    mf2.max_cycle = 150
    #dm = mf2.from_chk('loc_rhf_proj.chk')
    mf2.kernel()
    mo2 = mf2.mo_coeff
    #nbf2 = mf2.mo_coeff.shape[0]
    #nif2 = mf2.mo_coeff.shape[1]
    idx = np.count_nonzero(mf.mo_occ)
    cross_S = gto.intor_cross('int1e_ovlp', mol, mol2)
    print(idx, mo.shape, mo2.shape, cross_S.shape)
    vir_cross = einsum('ji,jk,kl->il', mo[:, idx:], cross_S, mo2[:, idx:])

    u, s, v = scipy.linalg.svd(vir_cross)
    print('SVD', s)
    projmo = np.dot(mo[:, idx:], u)
    mf.mo_coeff[:, idx:] = projmo

    npair = np.sum(mf2.mo_occ == 0)
    print('npair', npair)
    idx2 = np.count_nonzero(mf.mo_occ)
    ncore = chemcore(mol)
    idx1 = min(idx2 - npair, ncore)
    idx3 = idx2 + npair
    print('MOs after projection')
    dump_mat.dump_mo(mf.mol, mf.mo_coeff[:, idx1:idx3], ncol=10)
    occ_idx = slice(idx1, idx2)
    vir_idx = slice(idx2, idx3)
    if localize:
        mf = loc(mf, occ_idx, vir_idx, localize)
    if pair:
        mo_dipole = dipole_integral(mol, mf.mo_coeff)
        #ncore = idx1
        nopen = np.sum(mf.mo_occ == 1)
        nalpha = idx2
        #nvir_lmo = npair
        alpha_coeff = pair_by_tdm(ncore, npair, nopen, nalpha, npair, nbf, nif,
                                  mf.mo_coeff, mo_dipole)
        mf.mo_coeff = alpha_coeff.copy()
        print('MOs after pairing')
        ncore = idx2 - npair
        dump_mat.dump_mo(mf.mol, mf.mo_coeff[:, idx1:idx3], ncol=10)
    return mf, mf.mo_coeff, npair, ncore
コード例 #11
0
    def ecp_ano_det_ovlp(atm_ecp, atm_ano, ecpcore):
        ecp_ao_loc = atm_ecp.ao_loc_nr()
        ano_ao_loc = atm_ano.ao_loc_nr()
        ecp_ao_dim = ecp_ao_loc[1:] - ecp_ao_loc[:-1]
        ano_ao_dim = ano_ao_loc[1:] - ano_ao_loc[:-1]
        ecp_bas_l = [[atm_ecp.bas_angular(i)] * d
                     for i, d in enumerate(ecp_ao_dim)]
        ano_bas_l = [[atm_ano.bas_angular(i)] * d
                     for i, d in enumerate(ano_ao_dim)]
        ecp_bas_l = numpy.hstack(ecp_bas_l)
        ano_bas_l = numpy.hstack(ano_bas_l)

        nelec_core = 0
        ecp_occ_tmp = []
        ecp_idx = []
        ano_idx = []
        for l in range(4):
            nocc, frac = atom_hf.frac_occ(stdsymb, l)
            l_occ = [2] * ((nocc - ecpcore[l]) * (2 * l + 1))
            if frac > 1e-15:
                l_occ.extend([frac] * (2 * l + 1))
                nocc += 1
            if nocc == 0:
                break
            nelec_core += 2 * ecpcore[l] * (2 * l + 1)
            i0 = ecpcore[l] * (2 * l + 1)
            i1 = nocc * (2 * l + 1)
            ecp_idx.append(numpy.where(ecp_bas_l == l)[0][:i1 - i0])
            ano_idx.append(numpy.where(ano_bas_l == l)[0][i0:i1])
            ecp_occ_tmp.append(l_occ[:i1 - i0])
        ecp_idx = numpy.hstack(ecp_idx)
        ano_idx = numpy.hstack(ano_idx)
        ecp_occ = numpy.zeros(atm_ecp.nao_nr())
        ecp_occ[ecp_idx] = numpy.hstack(ecp_occ_tmp)
        nelec_valence_left = int(
            gto.charge(stdsymb) - nelec_core - sum(ecp_occ[ecp_idx]))
        if nelec_valence_left > 0:
            logger.warn(
                mol, 'Characters of %d valence electrons are not identified.\n'
                'It can affect the "meta-lowdin" localization method '
                'and the population analysis of SCF method.\n'
                'Adjustment to the core/valence partition may be needed '
                '(see function lo.nao.set_atom_conf)\nto get reasonable '
                'local orbitals or Mulliken population.\n', nelec_valence_left)
            # Return 0 to force the projection to ANO basis
            return 0
        else:
            s12 = gto.intor_cross('int1e_ovlp', atm_ecp,
                                  atm_ano)[ecp_idx][:, ano_idx]
            return numpy.linalg.det(s12)
コード例 #12
0
ファイル: mo_mapping.py プロジェクト: zzy2014/pyscf
def mo_map(mol1, mo1, mol2, mo2, base=BASE, tol=.5):
    '''Given two orbitals, based on their overlap <i|j>, search all
    orbital-pairs which have significant overlap.

    Returns:
        Two lists.  First list is the orbital-pair indices, second is the
        overlap value.
    '''
    s = gto.intor_cross('int1e_ovlp', mol1, mol2)
    s = reduce(numpy.dot, (mo1.T, s, mo2))
    idx = numpy.argwhere(abs(s) > tol) + base
    for i, j in idx:
        logger.info(mol1, '<mo-1|mo-2>  %d  %d  %12.8f', i, j, s[i, j])
    return idx, s
コード例 #13
0
ファイル: mo_mapping.py プロジェクト: chrinide/pyscf
def mo_map(mol1, mo1, mol2, mo2, base=BASE, tol=.5):
    '''Given two orbitals, based on their overlap <i|j>, search all
    orbital-pairs which have significant overlap.

    Returns:
        Two lists.  First list is the orbital-pair indices, second is the
        overlap value.
    '''
    s = gto.intor_cross('int1e_ovlp', mol1, mol2)
    s = reduce(numpy.dot, (mo1.T, s, mo2))
    idx = numpy.argwhere(abs(s) > tol) + base
    for i,j in idx:
        logger.info(mol1, '<mo-1|mo-2>  %d  %d  %12.8f',
                    i, j, s[i,j])
    return idx, s
コード例 #14
0
ファイル: orth.py プロジェクト: chrinide/pyscf
    def ecp_ano_det_ovlp(atm_ecp, atm_ano, ecpcore):
        ecp_ao_loc = atm_ecp.ao_loc_nr()
        ano_ao_loc = atm_ano.ao_loc_nr()
        ecp_ao_dim = ecp_ao_loc[1:] - ecp_ao_loc[:-1]
        ano_ao_dim = ano_ao_loc[1:] - ano_ao_loc[:-1]
        ecp_bas_l = [[atm_ecp.bas_angular(i)]*d for i,d in enumerate(ecp_ao_dim)]
        ano_bas_l = [[atm_ano.bas_angular(i)]*d for i,d in enumerate(ano_ao_dim)]
        ecp_bas_l = numpy.hstack(ecp_bas_l)
        ano_bas_l = numpy.hstack(ano_bas_l)

        nelec_core = 0
        ecp_occ_tmp = []
        ecp_idx = []
        ano_idx = []
        for l in range(4):
            nocc, frac = atom_hf.frac_occ(stdsymb, l)
            l_occ = [2] * ((nocc-ecpcore[l])*(2*l+1))
            if frac > 1e-15:
                l_occ.extend([frac] * (2*l+1))
                nocc += 1
            if nocc == 0:
                break
            nelec_core += 2 * ecpcore[l] * (2*l+1)
            i0 = ecpcore[l] * (2*l+1)
            i1 = nocc * (2*l+1)
            ecp_idx.append(numpy.where(ecp_bas_l==l)[0][:i1-i0])
            ano_idx.append(numpy.where(ano_bas_l==l)[0][i0:i1])
            ecp_occ_tmp.append(l_occ[:i1-i0])
        ecp_idx = numpy.hstack(ecp_idx)
        ano_idx = numpy.hstack(ano_idx)
        ecp_occ = numpy.zeros(atm_ecp.nao_nr())
        ecp_occ[ecp_idx] = numpy.hstack(ecp_occ_tmp)
        nelec_valence_left = int(gto.mole.charge(stdsymb) - nelec_core
                                 - sum(ecp_occ[ecp_idx]))
        if nelec_valence_left > 0:
            logger.warn(mol, 'Characters of %d valence electrons are not identified.\n'
                        'It can affect the "meta-lowdin" localization method '
                        'and the population analysis of SCF method.\n'
                        'Adjustment to the core/valence partition may be needed '
                        '(see function lo.nao.set_atom_conf)\nto get reasonable '
                        'local orbitals or Mulliken population.\n',
                        nelec_valence_left)
            # Return 0 to force the projection to ANO basis
            return 0
        else:
            s12 = gto.intor_cross('int1e_ovlp', atm_ecp, atm_ano)[ecp_idx][:,ano_idx]
            return numpy.linalg.det(s12)
コード例 #15
0
    def get_hcore(self, mol=None):
        '''1-component X2c Foldy-Wouthuysen (FW Hamiltonian  (spin-free part only)
        '''
        if mol is None: mol = self.mol
        if mol.has_ecp():
            raise NotImplementedError

        xmol, contr_coeff = self.get_xmol(mol)
        c = lib.param.LIGHT_SPEED
        assert ('1E' in self.approx.upper())
        t = xmol.intor_symmetric('int1e_kin')
        v = xmol.intor_symmetric('int1e_nuc')
        s = xmol.intor_symmetric('int1e_ovlp')
        w = xmol.intor_symmetric('int1e_pnucp')
        if 'get_xmat' in self.__dict__:
            # If the get_xmat method is overwritten by user, build the X
            # matrix with the external get_xmat method
            x = self.get_xmat(xmol)
            h1 = x2c._get_hcore_fw(t, v, w, s, x, c)

        elif 'ATOM' in self.approx.upper():
            atom_slices = xmol.offset_nr_by_atom()
            nao = xmol.nao_nr()
            x = numpy.zeros((nao, nao))
            for ia in range(xmol.natm):
                ish0, ish1, p0, p1 = atom_slices[ia]
                shls_slice = (ish0, ish1, ish0, ish1)
                t1 = xmol.intor('int1e_kin', shls_slice=shls_slice)
                s1 = xmol.intor('int1e_ovlp', shls_slice=shls_slice)
                with xmol.with_rinv_at_nucleus(ia):
                    z = -xmol.atom_charge(ia)
                    v1 = z * xmol.intor('int1e_rinv', shls_slice=shls_slice)
                    w1 = z * xmol.intor('int1e_prinvp', shls_slice=shls_slice)
                x[p0:p1, p0:p1] = x2c._x2c1e_xmatrix(t1, v1, w1, s1, c)
            h1 = x2c._get_hcore_fw(t, v, w, s, x, c)

        else:
            h1 = x2c._x2c1e_get_hcore(t, v, w, s, c)

        if self.basis is not None:
            s22 = xmol.intor_symmetric('int1e_ovlp')
            s21 = gto.intor_cross('int1e_ovlp', xmol, mol)
            c = lib.cho_solve(s22, s21)
            h1 = reduce(numpy.dot, (c.T, h1, c))
        if self.xuncontract and contr_coeff is not None:
            h1 = reduce(numpy.dot, (contr_coeff.T, h1, contr_coeff))
        return h1
コード例 #16
0
def hcore_hess_generator(x2cobj, mol=None):
    '''nuclear gradients of 1-component X2c hcore Hamiltonian  (spin-free part only)
    '''
    if mol is None: mol = x2cobj.mol
    xmol, contr_coeff = x2cobj.get_xmol(mol)

    if x2cobj.basis is not None:
        s22 = xmol.intor_symmetric('int1e_ovlp')
        s21 = gto.intor_cross('int1e_ovlp', xmol, mol)
        contr_coeff = lib.cho_solve(s22, s21)

    get_h1_xmol = gen_sf_hfw(xmol, x2cobj.approx)
    def hcore_deriv(ia, ja):
        h1 = get_h1_xmol(ia, ja)
        if contr_coeff is not None:
            h1 = lib.einsum('pi,xypq,qj->xyij', contr_coeff, h1, contr_coeff)
        return numpy.asarray(h1)
    return hcore_deriv
コード例 #17
0
def gen_proj(mol, intor = 'ovlp', verbose = False) :
    natm = mol.natm
    mole_coords = mol.atom_coords(unit="Ang")
    test_mol = gto.Mole()
    if verbose :
        test_mol.verbose = 4
    else :
        test_mol.verbose = 0
    test_mol.atom = [["Ne", coord] for coord in mole_coords]
    test_mol.basis = BASIS
    test_mol.spin = 0
    test_mol.build(0,0,unit="Ang")
    proj = gto.intor_cross(f'int1e_{intor}_sph', mol, test_mol) 
    
    def proj_func(mo):
        proj_coeff = np.matmul(mo, proj).reshape(*mo.shape[:2], natm, -1)
        if verbose:
            print('shape of coeff data          ', proj_coeff.shape)
        # res : nframe x nocc/nvir x natm x nproj
        return proj_coeff, proj_coeff.shape[-1]
    
    return proj_func
コード例 #18
0
 def proj_intor(self, intor):
     """1-electron integrals between origin and projected basis"""
     proj = gto.intor_cross(intor, self.mol, self._pmol)
     return proj
コード例 #19
0
print 'Total number of HF MOs  is equal to    ', N_total

N_occ = 0
for i in range(N_total):
    if HF_occ[i] > 0:
        N_occ += 1

print 'Number of occupied HF MOs is equal to  ', N_occ

labels = mol.spheric_labels(0)
N_AO = len(labels)
labels = mol2.spheric_labels(0)
print 'Number of occupied AOs is equal to  ', N_AO
S_11 = mol.intor_symmetric("cint1e_ovlp_sph")
S_22 = mol2.intor_symmetric("cint1e_ovlp_sph")
S_21 = gto.intor_cross('cint1e_ovlp_sph', mol2, mol)
#====================================================================
#    CHOOSE AOs for Projector
#====================================================================
AO = AOset(mol2, 0, 2, 3)  # choose 3d orbs for  Fe, atom with id0

for i in range(1, 6):
    AO.append(mol2.search_ao_nr(i, 1, 1,
                                2))  #add pz orbs of C from the 1st ring
for j in range(11, 16):
    AO.append(mol2.search_ao_nr(j, 1, 1,
                                2))  #add pz orbs of C from the 2nd ring

Np_AO = len(AO)

for i in range(Np_AO):
コード例 #20
0
ファイル: 33-rotate_wfn.py プロジェクト: tigerchu/pyscf-doc
#!/usr/bin/env python
#
# Author: Qiming Sun <*****@*****.**>
#
'''
Transform FCI wave functions according to the underlying one-particle
basis transformations.
'''

from functools import reduce
import numpy
from pyscf import gto, scf, fci

myhf1 = gto.M(atom='H 0 0 0; F 0 0 1.1', basis='6-31g',
              verbose=0).apply(scf.RHF).run()
e1, ci1 = fci.FCI(myhf1.mol, myhf1.mo_coeff).kernel()
print('FCI energy of mol1', e1)

myhf2 = gto.M(atom='H 0 0 0; F 0 0 1.2', basis='6-31g',
              verbose=0).apply(scf.RHF).run()

s12 = gto.intor_cross('cint1e_ovlp_sph', myhf1.mol, myhf2.mol)
s12 = reduce(numpy.dot, (myhf1.mo_coeff.T, s12, myhf2.mo_coeff))
norb = myhf2.mo_energy.size
nelec = myhf2.mol.nelectron
ci2 = fci.addons.transform_ci_for_orbital_rotation(ci1, norb, nelec, s12)

print('alpha-string, beta-string,  CI coefficients')
for c, stra, strb in fci.addons.large_ci(ci2, norb, nelec):
    print(stra, strb, c)
コード例 #21
0
ファイル: 20-ao_integrals.py プロジェクト: eronca/pyscf
s1 = mol.intor('cint1e_ipovlp_sph', comp=3)
t1 = mol.intor('cint1e_ipkin_sph' , comp=3)
v1 = mol.intor('cint1e_ipnuc_sph' , comp=3)

print('Dipole %s' % numpy.einsum('xij,ij->x',
                                 mol.intor('cint1e_r_sph', comp=3), dm))

#
# AO overlap between two molecules
#
mol1 = gto.M(
    verbose = 0,
    atom = 'H 0 1 0; H 1 0 0',
    basis = 'ccpvdz'
)
s = gto.intor_cross('cint1e_ovlp_sph', mol, mol1)
print('overlap shape (%d, %d)' % s.shape)

#
# 2e integrals (New in PySCF-1.1).  keyword aosym is required to specify the
# permutation symmetry in the AO integral matrix.  s8 means 8-fold symmetry,
# s2kl means 2-fold symmetry for the symmetry between kl only
#
eri = mol.intor('cint2e_sph', aosym='s8')
#
# 2e gradient integrals on first atom only
#
eri = mol.intor('cint2e_ip1_sph', aosym='s2kl')

#
# 2e integral gradients on certain atom
コード例 #22
0
ファイル: 20-ao_integrals.py プロジェクト: chrinide/pyscf
s1 = mol.intor('int1e_ipovlp')  # (3,N,N) array, 3 for x,y,z components
t1 = mol.intor('int1e_ipkin' )  # (3,N,N) array, 3 for x,y,z components
v1 = mol.intor('int1e_ipnuc' )  # (3,N,N) array, 3 for x,y,z components

mol.set_common_origin([0,0,0])  # Set gauge origin before computing dipole integrals
print('Dipole %s' % numpy.einsum('xij,ji->x', mol.intor('int1e_r'), dm))

#
# AO overlap between two molecules
#
mol1 = gto.M(
    verbose = 0,
    atom = 'H 0 1 0; H 1 0 0',
    basis = 'ccpvdz'
)
s = gto.intor_cross('int1e_ovlp', mol, mol1)
print('overlap shape (%d, %d)' % s.shape)

#
# 2e integrals.  Keyword aosym is to specify the permutation symmetry in the
# AO integral matrix.  s8 means 8-fold symmetry, s2kl means 2-fold symmetry
# for the symmetry between kl in (ij|kl)
#
eri = mol.intor('int2e', aosym='s8')

#
# 2e gradient integrals (against electronic coordinates) on bra of first atom.
# aosym=s2kl indicates that the permutation symmetry is used on k,l indices of
# (ij|kl). The resultant eri is a 3-dimension array (3, N*N, N*(N+1)/2) where
# N is the number of AO orbitals.
#
コード例 #23
0
ファイル: pbasis.py プロジェクト: chrinide/pyscf-scripts
rdm2_mp2 = 2.0*einsum('iajb,iajb->iajb', eri_mo, e_denom)
rdm2_mp2 -= einsum('ibja,iajb->iajb', eri_mo, e_denom)
e_mp2 = numpy.einsum('iajb,iajb->', eri_mo, rdm2_mp2, optimize=True)
lib.logger.info(mf,"E(MP2): %12.8f" % e_mp2)
lib.logger.info(mf,"E(HF+MP2): %12.8f" % (e_mp2+ehf))

pmol = mol.copy()
pmol.atom = mol._atom
pmol.unit = 'B'
pmol.symmetry = False
pmol.basis = 'sto-6g'
pmol.build(False, False)

sb = mol.intor('int1e_ovlp')
sbinv = numpy.linalg.inv(sb)
sbs = gto.intor_cross('int1e_ovlp', mol, pmol)
ss = reduce(numpy.dot, (sbs.T,sbinv,sbs))
ssinv = numpy.linalg.inv(ss)
sslow = scipy.linalg.sqrtm(ss)
h = numpy.dot(mf.mo_coeff*mf.mo_energy, mf.mo_coeff.T)
hb = reduce(numpy.dot, (sb,h,sb))
hs = reduce(numpy.dot, (sbs.T,h,sbs))
mo_energy, mo_coeff = mf.eig(hs, ss)

# Composite basis big_prim x small_states
cp = reduce(numpy.dot, (sbinv, sbs, mo_coeff))
nocc = mol.nelectron//2
for i in range(nocc):
    cp[:,i] = mf.mo_coeff[:,i]
sp = reduce(numpy.dot, (cp.T, sb, cp))
hp = reduce(numpy.dot, (cp.T, hb, cp)) 
コード例 #24
0
v = mol.intor('int1e_nuc')
# Overlap, kinetic, nuclear attraction gradients (against electron coordinates
# on bra)
s1 = mol.intor('int1e_ipovlp')  # (3,N,N) array, 3 for x,y,z components
t1 = mol.intor('int1e_ipkin')  # (3,N,N) array, 3 for x,y,z components
v1 = mol.intor('int1e_ipnuc')  # (3,N,N) array, 3 for x,y,z components

mol.set_common_origin([0, 0, 0
                       ])  # Set gauge origin before computing dipole integrals
print('Dipole %s' % numpy.einsum('xij,ji->x', mol.intor('int1e_r'), dm))

#
# AO overlap between two molecules
#
mol1 = gto.M(verbose=0, atom='H 0 1 0; H 1 0 0', basis='ccpvdz')
s = gto.intor_cross('int1e_ovlp', mol, mol1)
print('overlap shape (%d, %d)' % s.shape)

#
# 2e integrals.  Keyword aosym is to specify the permutation symmetry in the
# AO integral matrix.  s8 means 8-fold symmetry, s2kl means 2-fold symmetry
# for the symmetry between kl in (ij|kl)
#
eri = mol.intor('int2e', aosym='s8')

#
# 2e gradient integrals (against electronic coordinates) on bra of first atom.
# aosym=s2kl indicates that the permutation symmetry is used on k,l indices of
# (ij|kl). The resultant eri is a 3-dimension array (3, N*N, N*(N+1)/2) where
# N is the number of AO orbitals.
#
コード例 #25
0
ファイル: avas_test.py プロジェクト: chrinide/pyscf-scripts
def kernel(mf,
           locc,
           lvir,
           threshold_occ=THRESHOLD_OCC,
           threshold_vir=THRESHOLD_VIR,
           minao=MINAO,
           with_iao=WITH_IAO,
           openshell_option=OPENSHELL_OPTION,
           canonicalize=CANONICALIZE,
           ncore=NCORE,
           localize=None,
           verbose=None):

    from pyscf.tools import mo_mapping

    if isinstance(verbose, logger.Logger):
        log = verbose
    elif verbose is not None:
        log = logger.Logger(mf.stdout, verbose)
    else:
        log = logger.Logger(mf.stdout, mf.verbose)
    mol = mf.mol

    log.info('\n** AVAS **')
    if isinstance(mf, scf.uhf.UHF):
        raise NotImplementedError
    else:
        nao, nmo = mf.mo_coeff.shape
        nocc = mol.nelectron // 2 - ncore
        nvir = nmo - nocc - ncore
        mo_coeff = mf.mo_coeff
        mo_occ = mf.mo_occ
        mo_energy = mf.mo_energy
        mo_coeff_core = mf.mo_coeff[:, :ncore]
        mo_coeff_occ = mf.mo_coeff[:, ncore:ncore + nocc]
        mo_coeff_vir = mf.mo_coeff[:, ncore + nocc:]
        mo_occ_core = mf.mo_occ[:ncore]
        if ncore > 0: mofreeze = mo_coeff_core
        mo_occ_occ = mf.mo_occ[ncore:ncore + nocc]
        mo_occ_vir = mf.mo_occ[ncore + nocc:]
        mo_energy_core = mf.mo_occ[:ncore]
        mo_enery_occ = mf.mo_occ[ncore:ncore + nocc]
        mo_energy_vir = mf.mo_occ[ncore + nocc:]
    ovlp = mol.intor_symmetric('int1e_ovlp')
    log.info('Total number of HF MOs is equal to %d', mf.mo_coeff.shape[1])
    log.info('Number of occupied HF MOs is equal to %d', nocc)
    log.info('Number of core HF MOs is equal to  %d', ncore)

    mol = mf.mol
    pmol = mol.copy()
    pmol.atom = mol._atom
    pmol.unit = 'B'
    pmol.symmetry = False
    pmol.basis = minao
    pmol.build(False, False)

    baslstocc = pmol.search_ao_label(locc)
    log.info('reference occ AO indices for %s %s: %s', minao, locc, baslstocc)
    baslstvir = pmol.search_ao_label(lvir)
    print lvir, pmol.search_ao_label(lvir)
    log.info('reference vir AO indices for %s %s: %s', minao, lvir, baslstvir)

    s2occ = pmol.intor_symmetric('int1e_ovlp')[baslstocc][:, baslstocc]
    s21occ = gto.intor_cross('int1e_ovlp', pmol, mol)[baslstocc]
    s21occ = numpy.dot(s21occ, mo_coeff_occ)

    s2vir = pmol.intor_symmetric('int1e_ovlp')[baslstvir][:, baslstvir]
    s21vir = gto.intor_cross('int1e_ovlp', pmol, mol)[baslstvir]
    s21vir = numpy.dot(s21vir, mo_coeff_vir)

    saocc = s21occ.T.dot(scipy.linalg.solve(s2occ, s21occ, sym_pos=True))
    savir = s21vir.T.dot(scipy.linalg.solve(s2vir, s21vir, sym_pos=True))

    log.info('Threshold_occ %s', threshold_occ)
    wocc, u = numpy.linalg.eigh(saocc)
    log.info('projected occ eig %s', wocc[::-1])
    ncas_occ = (wocc > threshold_occ).sum()
    log.info('Active from occupied = %d , eig %s', ncas_occ,
             wocc[wocc > threshold_occ][::-1])
    nelecas = (mol.nelectron - ncore * 2) - (wocc < threshold_occ).sum() * 2
    mocore = mo_coeff_occ.dot(u[:, wocc < threshold_occ])
    log.info('Inactive from occupied = %d', mocore.shape[1])
    mocas = mo_coeff_occ.dot(u[:, wocc > threshold_occ])

    log.info('Threshold_vir %s', threshold_vir)
    wvir, u = numpy.linalg.eigh(savir)
    log.debug('projected vir eig %s', wvir[::-1])
    ncas_vir = (wvir > threshold_vir).sum()
    log.info('Active from unoccupied = %d , eig %s', ncas_vir,
             wvir[wvir > threshold_vir][::-1])
    mocas = numpy.hstack((mocas, mo_coeff_vir.dot(u[:, wvir > threshold_vir])))
    movir = mo_coeff_vir.dot(u[:, wvir < threshold_vir])
    log.info('Inactive from unoccupied = %d', movir.shape[1])
    ncas = mocas.shape[1]
    log.info('Dimensions of active %d', ncas)

    nalpha = (nelecas + mol.spin) // 2
    log.info('# of alpha electrons %d', nalpha)
    nbeta = nelecas - nalpha
    log.info('# of beta electrons %d', nbeta)

    if canonicalize:
        from pyscf.mcscf import dmet_cas

        def trans(c):
            if c.shape[1] == 0:
                return c
            else:
                csc = reduce(numpy.dot, (c.T, ovlp, mo_coeff))
                fock = numpy.dot(csc * mo_energy, csc.T)
                e, u = scipy.linalg.eigh(fock)
                return dmet_cas.symmetrize(mol, e, numpy.dot(c, u), ovlp, log)

        if ncore > 0:
            mo = numpy.hstack(
                [trans(mofreeze),
                 trans(mocore),
                 trans(mocas),
                 trans(movir)])
        else:
            mo = numpy.hstack([trans(mocore), trans(mocas), trans(movir)])
    else:
        if ncore > 0:
            mo = numpy.hstack((mofreeze, mocore, mocas, movir))
        else:
            mo = numpy.hstack((mocore, mocas, movir))

    return ncas, nelecas, mo
コード例 #26
0
def kernel(mf,
           aolabels,
           threshold=THRESHOLD,
           minao=MINAO,
           with_iao=WITH_IAO,
           openshell_option=OPENSHELL_OPTION,
           canonicalize=CANONICALIZE,
           ncore=0,
           verbose=None):
    '''AVAS method to construct mcscf active space.
    Ref. arXiv:1701.07862 [physics.chem-ph]

    Args:
        mf : an :class:`SCF` object

        aolabels : string or a list of strings
            AO labels for AO active space

    Kwargs:
        threshold : float
            Tructing threshold of the AO-projector above which AOs are kept in
            the active space.
        minao : str
            A reference AOs for AVAS.
        with_iao : bool
            Whether to use IAO localization to construct the reference active AOs.
        openshell_option : int
            How to handle singly-occupied orbitals in the active space. The
            singly-occupied orbitals are projected as part of alpha orbitals
            if openshell_option=2, or completely kept in active space if
            openshell_option=3.  See Section III.E option 2 or 3 of the
            reference paper for more details.
        canonicalize : bool
            Orbitals defined in AVAS method are local orbitals.  Symmetrizing
            the core, active and virtual space.
        ncore : integer
            Number of core orbitals to exclude from the AVAS method.

    Returns:
        active-space-size, #-active-electrons, orbital-initial-guess-for-CASCI/CASSCF

    Examples:

    >>> from pyscf import gto, scf, mcscf
    >>> from pyscf.mcscf import avas
    >>> mol = gto.M(atom='Cr 0 0 0; Cr 0 0 1.6', basis='ccpvtz')
    >>> mf = scf.RHF(mol).run()
    >>> ncas, nelecas, mo = avas.avas(mf, ['Cr 3d', 'Cr 4s'])
    >>> mc = mcscf.CASSCF(mf, ncas, nelecas).run(mo)
    '''
    from pyscf.tools import mo_mapping

    if isinstance(verbose, logger.Logger):
        log = verbose
    elif verbose is not None:
        log = logger.Logger(mf.stdout, verbose)
    else:
        log = logger.Logger(mf.stdout, mf.verbose)
    mol = mf.mol

    log.info('\n** AVAS **')
    if isinstance(mf, scf.uhf.UHF):
        log.note('UHF/UKS object is found.  AVAS takes alpha orbitals only')
        mo_coeff = mf.mo_coeff[0]
        mo_occ = mf.mo_occ[0]
        mo_energy = mf.mo_energy[0]
        assert (openshell_option != 1)
    else:
        mo_coeff = mf.mo_coeff
        mo_occ = mf.mo_occ
        mo_energy = mf.mo_energy
    nocc = numpy.count_nonzero(mo_occ != 0)
    ovlp = mol.intor_symmetric('int1e_ovlp')
    log.info('  Total number of HF MOs  is equal to    %d', mo_coeff.shape[1])
    log.info('  Number of occupied HF MOs is equal to  %d', nocc)

    mol = mf.mol
    pmol = mol.copy()
    pmol.atom = mol._atom
    pmol.unit = 'B'
    pmol.symmetry = False
    pmol.basis = minao
    pmol.build(False, False)

    baslst = pmol.search_ao_label(aolabels)
    log.info('reference AO indices for %s %s: %s', minao, aolabels, baslst)

    if with_iao:
        from pyscf.lo import iao
        c = iao.iao(mol, mo_coeff[:, ncore:nocc], minao)[:, baslst]
        s2 = reduce(numpy.dot, (c.T, ovlp, c))
        s21 = reduce(numpy.dot, (c.T, ovlp, mo_coeff[:, ncore:]))
    else:
        s2 = pmol.intor_symmetric('int1e_ovlp')[baslst][:, baslst]
        s21 = gto.intor_cross('int1e_ovlp', pmol, mol)[baslst]
        s21 = numpy.dot(s21, mo_coeff[:, ncore:])
    sa = s21.T.dot(scipy.linalg.solve(s2, s21, sym_pos=True))

    from pyscf.symm import label_orb_symm
    symm = label_orb_symm(mol,
                          mol.irrep_name,
                          mol.symm_orb,
                          mo_coeff,
                          tol=1e-5)

    if openshell_option == 2:
        wocc, u = numpy.linalg.eigh(sa[:(nocc - ncore), :(nocc - ncore)])
        log.info('Option 2: threshold %s', threshold)
        ncas_occ = (wocc > threshold).sum()
        nelecas = (mol.nelectron - ncore * 2) - (wocc < threshold).sum() * 2
        if ncore > 0: mofreeze = mo_coeff[:, :ncore]
        mocore = mo_coeff[:, ncore:nocc].dot(u[:, wocc < threshold])
        mocas = mo_coeff[:, ncore:nocc].dot(u[:, wocc > threshold])
        mask = (wocc > threshold).tolist()
        #print nocc-ncore,mocore.shape,wocc<threshold
        #print nocc-ncore,mocas.shape,wocc>threshold
        #print 'BM',mask,len(mask)

        wvir, u = numpy.linalg.eigh(sa[(nocc - ncore):, (nocc - ncore):])
        ncas_vir = (wvir > threshold).sum()
        mocas = numpy.hstack(
            (mocas, mo_coeff[:, nocc:].dot(u[:, wvir > threshold])))
        movir = mo_coeff[:, nocc:].dot(u[:, wvir < threshold])
        ncas = mocas.shape[1]
        mask += (wvir > threshold).tolist()
        #print mo_coeff.shape[0]-nocc,mocas.shape,wvir>threshold
        #print mo_coeff.shape[0]-nocc,movir.shape,wvir<threshold
        #print 'BM',mask,len(mask)

    elif openshell_option == 3:
        docc = nocc - mol.spin
        wocc, u = numpy.linalg.eigh(sa[:(docc - ncore), :(docc - ncore)])
        log.info('Option 3: threshold %s, num open shell %d', threshold,
                 mol.spin)
        ncas_occ = (wocc > threshold).sum()
        nelecas = (mol.nelectron - ncore * 2) - (wocc < threshold).sum() * 2
        if ncore > 0: mofreeze = mo_coeff[:, :ncore]
        mocore = mo_coeff[:, ncore:docc].dot(u[:, wocc < threshold])
        mocas = mo_coeff[:, ncore:docc].dot(u[:, wocc > threshold])

        wvir, u = numpy.linalg.eigh(sa[(nocc - ncore):, (nocc - ncore):])
        ncas_vir = (wvir > threshold).sum()
        mocas = numpy.hstack((mocas, mo_coeff[:, docc:nocc],
                              mo_coeff[:, nocc:].dot(u[:, wvir > threshold])))
        movir = mo_coeff[:, nocc:].dot(u[:, wvir < threshold])
        ncas = mocas.shape[1]

    log.debug('projected occ eig %s', wocc[::-1])
    log.debug('projected vir eig %s', wvir[::-1])
    log.info('Active from occupied = %d , eig %s', ncas_occ,
             wocc[wocc > threshold][::-1])
    log.info('Inactive from occupied = %d', mocore.shape[1])
    log.info('Active from unoccupied = %d , eig %s', ncas_vir,
             wvir[wvir > threshold][::-1])
    log.info('Inactive from unoccupied = %d', movir.shape[1])
    log.info('Dimensions of active %d', ncas)
    nalpha = (nelecas + mol.spin) // 2
    nbeta = nelecas - nalpha
    log.info('# of alpha electrons %d', nalpha)
    log.info('# of beta electrons %d', nbeta)
    selected = [i for i in range(len(mask)) if mask[i]]
    list_of_sym = [symm[i] for i in selected]
    print selected
    print list_of_sym
    for elt in set(symm):
        n = 0
        for i in list_of_sym:
            if i == elt: n += 1
        print elt, n

    if canonicalize:
        from pyscf.mcscf import dmet_cas

        def trans(c):
            if c.shape[1] == 0:
                return c
            else:
                csc = reduce(numpy.dot, (c.T, ovlp, mo_coeff))
                fock = numpy.dot(csc * mo_energy, csc.T)
                e, u = scipy.linalg.eigh(fock)
                return dmet_cas.symmetrize(mol, e, numpy.dot(c, u), ovlp, log)

        if ncore > 0:
            mo = numpy.hstack(
                [trans(mofreeze),
                 trans(mocore),
                 trans(mocas),
                 trans(movir)])
        else:
            mo = numpy.hstack([trans(mocore), trans(mocas), trans(movir)])
    else:
        mo = numpy.hstack((mocore, mocas, movir))
    return ncas, nelecas, mo
コード例 #27
0
ファイル: 43-avas.py プロジェクト: eronca/pyscf
print 'Total number of HF MOs  is equal to    ' ,N_total

N_occ=0
for i in range (N_total):
   if HF_occ[i] > 0:
     N_occ+=1

print 'Number of occupied HF MOs is equal to  ', N_occ

labels = mol.spheric_labels(0)
N_AO = len (labels)
labels = mol2.spheric_labels(0)
print 'Number of occupied AOs is equal to  ', N_AO
S_11=mol.intor_symmetric("cint1e_ovlp_sph")
S_22=mol2.intor_symmetric("cint1e_ovlp_sph")
S_21 = gto.intor_cross('cint1e_ovlp_sph', mol2, mol)
#====================================================================
#    CHOOSE AOs for Projector 
#====================================================================
AO =  AOset(mol2, 0, 2, 3) # choose 3d orbs for  Fe, atom with id0

for i in range (1,6):
 AO.append(mol2.search_ao_nr(i,1,1,2)) #add pz orbs of C from the 1st ring
for j in range (11,16):
 AO.append(mol2.search_ao_nr(j,1,1,2)) #add pz orbs of C from the 2nd ring

Np_AO=len(AO)

for i in range (Np_AO):
 idx= AO[i]
 print idx, '  ', labels[idx]
コード例 #28
0
ファイル: avas.py プロジェクト: chrinide/pyscf
def kernel(mf, aolabels, threshold=THRESHOLD, minao=MINAO, with_iao=WITH_IAO,
           openshell_option=OPENSHELL_OPTION, canonicalize=CANONICALIZE,
           ncore=0, verbose=None):
    '''AVAS method to construct mcscf active space.
    Ref. arXiv:1701.07862 [physics.chem-ph]

    Args:
        mf : an :class:`SCF` object

        aolabels : string or a list of strings
            AO labels for AO active space

    Kwargs:
        threshold : float
            Tructing threshold of the AO-projector above which AOs are kept in
            the active space.
        minao : str
            A reference AOs for AVAS.
        with_iao : bool
            Whether to use IAO localization to construct the reference active AOs.
        openshell_option : int
            How to handle singly-occupied orbitals in the active space. The
            singly-occupied orbitals are projected as part of alpha orbitals
            if openshell_option=2, or completely kept in active space if
            openshell_option=3.  See Section III.E option 2 or 3 of the
            reference paper for more details.
        canonicalize : bool
            Orbitals defined in AVAS method are local orbitals.  Symmetrizing
            the core, active and virtual space.
        ncore : integer
            Number of core orbitals to exclude from the AVAS method.

    Returns:
        active-space-size, #-active-electrons, orbital-initial-guess-for-CASCI/CASSCF

    Examples:

    >>> from pyscf import gto, scf, mcscf
    >>> from pyscf.mcscf import avas
    >>> mol = gto.M(atom='Cr 0 0 0; Cr 0 0 1.6', basis='ccpvtz')
    >>> mf = scf.RHF(mol).run()
    >>> ncas, nelecas, mo = avas.avas(mf, ['Cr 3d', 'Cr 4s'])
    >>> mc = mcscf.CASSCF(mf, ncas, nelecas).run(mo)
    '''
    from pyscf.tools import mo_mapping

    if isinstance(verbose, logger.Logger):
        log = verbose
    elif verbose is not None:
        log = logger.Logger(mf.stdout, verbose)
    else:
        log = logger.Logger(mf.stdout, mf.verbose)
    mol = mf.mol

    log.info('\n** AVAS **')
    if isinstance(mf, scf.uhf.UHF):
        log.note('UHF/UKS object is found.  AVAS takes alpha orbitals only')
        mo_coeff = mf.mo_coeff[0]
        mo_occ = mf.mo_occ[0]
        mo_energy = mf.mo_energy[0]
        assert(openshell_option != 1)
    else:
        mo_coeff = mf.mo_coeff
        mo_occ = mf.mo_occ
        mo_energy = mf.mo_energy
    nocc = numpy.count_nonzero(mo_occ != 0)
    ovlp = mol.intor_symmetric('int1e_ovlp')
    log.info('  Total number of HF MOs  is equal to    %d' ,mo_coeff.shape[1])
    log.info('  Number of occupied HF MOs is equal to  %d', nocc)

    mol = mf.mol
    pmol = mol.copy()
    pmol.atom = mol._atom
    pmol.unit = 'B'
    pmol.symmetry = False
    pmol.basis = minao
    pmol.build(False, False)

    baslst = pmol.search_ao_label(aolabels)
    log.info('reference AO indices for %s %s: %s', minao, aolabels, baslst)

    if with_iao:
        from pyscf.lo import iao
        c = iao.iao(mol, mo_coeff[:,ncore:nocc], minao)[:,baslst]
        s2 = reduce(numpy.dot, (c.T, ovlp, c))
        s21 = reduce(numpy.dot, (c.T, ovlp, mo_coeff[:, ncore:]))
    else:
        s2 = pmol.intor_symmetric('int1e_ovlp')[baslst][:,baslst]
        s21 = gto.intor_cross('int1e_ovlp', pmol, mol)[baslst]
        s21 = numpy.dot(s21, mo_coeff[:, ncore:])
    sa = s21.T.dot(scipy.linalg.solve(s2, s21, sym_pos=True))

    if openshell_option == 2:
        wocc, u = numpy.linalg.eigh(sa[:(nocc-ncore), :(nocc-ncore)])
        log.info('Option 2: threshold %s', threshold)
        ncas_occ = (wocc > threshold).sum()
        nelecas = (mol.nelectron - ncore * 2) - (wocc < threshold).sum() * 2
        if ncore > 0: mofreeze = mo_coeff[:,:ncore]
        mocore = mo_coeff[:,ncore:nocc].dot(u[:,wocc<threshold])
        mocas = mo_coeff[:,ncore:nocc].dot(u[:,wocc>threshold])

        wvir, u = numpy.linalg.eigh(sa[(nocc-ncore):,(nocc-ncore):])
        ncas_vir = (wvir > threshold).sum()
        mocas = numpy.hstack((mocas, mo_coeff[:,nocc:].dot(u[:,wvir>threshold])))
        movir = mo_coeff[:,nocc:].dot(u[:,wvir<threshold])
        ncas = mocas.shape[1]

    elif openshell_option == 3:
        docc = nocc - mol.spin
        wocc, u = numpy.linalg.eigh(sa[:(docc-ncore),:(docc-ncore)])
        log.info('Option 3: threshold %s, num open shell %d', threshold, mol.spin)
        ncas_occ = (wocc > threshold).sum()
        nelecas = (mol.nelectron - ncore * 2) - (wocc < threshold).sum() * 2
        if ncore > 0: mofreeze = mo_coeff[:,:ncore]
        mocore = mo_coeff[:,ncore:docc].dot(u[:,wocc<threshold])
        mocas = mo_coeff[:,ncore:docc].dot(u[:,wocc>threshold])

        wvir, u = numpy.linalg.eigh(sa[(nocc-ncore):,(nocc-ncore):])
        ncas_vir = (wvir > threshold).sum()
        mocas = numpy.hstack((mocas, mo_coeff[:,docc:nocc],
                              mo_coeff[:,nocc:].dot(u[:,wvir>threshold])))
        movir = mo_coeff[:,nocc:].dot(u[:,wvir<threshold])
        ncas = mocas.shape[1]

    log.debug('projected occ eig %s', wocc[::-1])
    log.debug('projected vir eig %s', wvir[::-1])
    log.info('Active from occupied = %d , eig %s', ncas_occ, wocc[wocc>threshold][::-1])
    log.info('Inactive from occupied = %d', mocore.shape[1])
    log.info('Active from unoccupied = %d , eig %s', ncas_vir, wvir[wvir>threshold][::-1])
    log.info('Inactive from unoccupied = %d', movir.shape[1])
    log.info('Dimensions of active %d', ncas)
    nalpha = (nelecas + mol.spin) // 2
    nbeta = nelecas - nalpha
    log.info('# of alpha electrons %d', nalpha)
    log.info('# of beta electrons %d', nbeta)

    if canonicalize:
        from pyscf.mcscf import dmet_cas
        def trans(c):
            if c.shape[1] == 0:
                return c
            else:
                csc = reduce(numpy.dot, (c.T, ovlp, mo_coeff))
                fock = numpy.dot(csc*mo_energy, csc.T)
                e, u = scipy.linalg.eigh(fock)
                return dmet_cas.symmetrize(mol, e, numpy.dot(c, u), ovlp, log)
        if ncore > 0:
           mo = numpy.hstack([trans(mofreeze), trans(mocore), trans(mocas), trans(movir)])
        else:
           mo = numpy.hstack([trans(mocore), trans(mocas), trans(movir)])
    else:
        mo = numpy.hstack((mocore, mocas, movir))
    return ncas, nelecas, mo
コード例 #29
0
def MakePiOS(mol, mf, PiAtomsList, nPiOcc=None, nPiVirt=None):
    np.set_printoptions(precision=4,
                        linewidth=10000,
                        edgeitems=3,
                        suppress=False)

    print(
        "================================CONSTRUCTING PI-ORBITALS==========================================="
    )
    # PiAtoms list contains the set of main-group atoms involved in the pi-system of the chromophores(?)
    # indices are 1-based.

    mol2 = mol.copy()
    mol2.basis = 'MINAO'
    mol2.build()

    # make a minimal AO basis for our atoms. We load the basis from a library
    # just to have access to its shell-composition. Need that to find the indices
    # of all atoms, and the AO indices of the px/py/pz functions.

    Elements, Coords = Atoms_w_Coords(mol2)
    Shells = MakeShells(mol2, Elements)

    def AssignTag(iAt, Element, Tag):
        assert (Elements[iAt - 1] == Element)
        Elements[iAt - 1] = Element + Tag

    # fix type of atom for the donor-acceptor which are exchanging the hydrogens.
    # During the process, the hydrogens are moving and the Huckel-Theory
    # formal number of contributed pi-electrons may change.
    # These settings override the auto-detection of number of pi electrons
    # based on atomic connectivity in GetNumPiElec() below.


#    AssignTag(50, "N", "1e")

    OrbBasis = mol.basis
    C = mf.mo_coeff
    S1 = mol.intor_symmetric("cint1e_ovlp_sph")
    S2 = mol2.intor_symmetric("cint1e_ovlp_sph")
    S12 = gto.intor_cross('cint1e_ovlp_sph', mol, mol2)
    SMo = mdot(C.T, S1, C)
    print("    MO deviation from orthogonality  {:8.2e} \n".format(
        rmsd(SMo - np.eye(SMo.shape[0]))))

    # make arrays of occupation numbers and orbital eigenvalues.
    Occ = mf.mo_occ
    Eps = mf.mo_energy

    nOrb = C.shape[1]
    if (mol.spin == 0):
        nOcc = np.sum(Occ == 2)
    else:
        nOcc = np.sum(Occ == 2) + np.sum(Occ == 1)
        n1 = np.sum(Occ == 1)
        print("    Number of singly occupied orbitals      {} ".format(n1))

    nVir = np.sum(Occ == 0)
    assert (nOcc + nVir == nOrb)
    print("    Number of occupied orbitals      {} ".format(nOcc))
    print("    Number of unoccupied orbitals    {} ".format(nVir))

    # Compute Fock matrix from orbital eigenvalues (SCF has to be fully converged)
    Fock = mdot(S1, C, np.diag(Eps), C.T, S1.T)
    Rdm = mdot(C, np.diag(Occ), C.T)

    COcc = C[:, :nOcc]
    CVir = C[:, nOcc:]

    Smh1 = MakeSmh(S1)
    Sh1 = np.dot(S1, Smh1)

    # Compute IAO basis (non-orthogonal). Will be used to identify the
    # pi-MO-space of the target atom groups.
    CIb = MakeIaosRaw(COcc, S1, S2, S12)
    CIbOcc = np.linalg.lstsq(CIb, COcc)[0]
    Err = np.dot(Sh1, np.dot(CIb, CIbOcc) - COcc)

    # check orthogonality of IAO basis occupied orbitals
    SIb = mdot(CIb.T, S1, CIb)
    SIbOcc = mdot(CIbOcc.T, SIb, CIbOcc)
    nIb = SIb.shape[0]

    if 0:
        # make the a representation of the virtual valence space.
        SmhIb = MakeSmh(SIb)

        nIbVir = nIb - nOcc  # number of virtual valence orbitals

        CTargetIb = CIb
        STargetIb = mdot(CTargetIb.T, S1, CTargetIb)
        SmhTargetIb = MakeSmh(STargetIb)
        STargetIbVir = mdot(SmhTargetIb, CTargetIb.T, S1, CVir)
        U, sig, Vt = np.linalg.svd(STargetIbVir, full_matrices=False)
        print("    Number of target MINAO basis fn     {}\n".format(
            CTargetIb.shape[1]))

        print("SIbVir Singular Values (n={})".format(len(sig)))
        print("    [{}]".format(', '.join('{:.4f}'.format(k) for k in sig)))

        assert (np.abs(sig[nIbVir - 1] - 1.0) < 1e-4)
        assert (np.abs(sig[nIbVir] - 0.0) < 1e-4)

        # for pi systems: do it like here -^ for the virtuals, but
        # for COcc and CVir both. What we should do is:
        #   - instead of CIb, we use CTargetIb = CIb * (AO-linear-comb-matrix)
        #   - instead of SmhIb, we use its corresponding target-AO overlap matrix:
        #     SmhTargetIb = MakeSmh(mdot(CTargetIb.T, S1, CTargetIb))
        #   - instead of using nOcc/nVir/nIb to determine the target number
        #     of orbitals, we obtain the target number of pi electrons by counting
        #     their subset from the selected main group atoms (see CHEM 408 u11).
        #     From this determine the number of occupied pi-orbitals this system
        #     is supposed to have, and virtual orbitals as nTargetIb - nPiOcc
        # The AoMix matrix is made from the pi-system's inertial tensor to get the
        # local z-direction, and then linearly-combining this onto the highest-N p-AOs.

    CActOcc = []
    CActVir = []

    # add pi-HOMOs and pi-LUMOs
    CFragOcc, CFragVir, nOccOrbExpected, nVirtOrbExpected = MakePiSystemOrbitals(
        "Pi-System", PiAtomsList, None, Elements, Coords, CIb, Shells, S1, S12,
        S2, Fock, COcc, CVir)
    if (nPiOcc is None):
        for i in range(1, nOccOrbExpected + 1):
            CActOcc.append(CFragOcc[:, -i])
    else:
        for i in range(1, nPiOcc + 1):
            CActOcc.append(CFragOcc[:, -i])

    if (nPiVirt is None):
        for j in range(nVirtOrbExpected):
            CActVir.append(CFragVir[:, j])
    else:
        for j in range(nPiVirt):
            CActVir.append(CFragVir[:, j])

    nActOcc = len(CActOcc)
    nActVir = len(CActVir)

    print("\n -- Joining active spaces")
    if (mol.spin == 0):
        nElec = 2 * len(CActOcc)
    else:
        nElec = 2 * len(CActOcc) - n1
    CAct = np.array(CActOcc + CActVir).T
    if 0:
        # orthogonalize and semi-canonicalize
        SAct = mdot(CAct.T, S1, CAct)
        ew, ev = np.linalg.eigh(SAct)
        print(
            "    CAct initial overlap (if all ~approx 1, then the initial active orbitals are near-orthogonal. That is good.)"
        )
        print("    [{}]".format(', '.join('{:.4f}'.format(k) for k in ew)))

        CAct = np.dot(CAct, MakeSmh(SAct))
        CAct = SemiCanonicalize(CAct, Fock, S1, "active")

    print("    Number of Active Electrons     {} ".format(nElec))
    print("    Number of Active Orbitals      {} ".format(CAct.shape[1]))

    # make new non-active occupied and non-active virtual orbitals,
    # in order to rebuild a full MO matrix.
    def MakeInactiveSpace(Name, CActList, COrb1):
        CAct = np.array(CActList).T
        SAct = mdot(CAct.T, S1, CAct)
        CAct = np.dot(CAct, MakeSmh(SAct))

        SActMo = mdot(COrb1.T, S1.T, CAct, CAct.T, S1, COrb1)
        ew, ev = np.linalg.eigh(
            SActMo)  # small ews first (orbs not overlapping with active orbs).

        nRest = COrb1.shape[1] - CAct.shape[1]
        if 0:
            for i in range(len(ew)):
                print("{:4} {:15.6f}  {}".format(i, ew[i], i == nRest))
        assert (np.abs(ew[nRest - 1] - 0.0) < 1e-8)
        assert (np.abs(ew[nRest] - 1.0) < 1e-8)
        CNewOrb1 = np.dot(COrb1, ev[:, :nRest])
        return SemiCanonicalize(CNewOrb1, Fock, S1, Name, Print=False)

    CNewClo = MakeInactiveSpace("NewClo", CActOcc, COcc)
    CNewExt = MakeInactiveSpace("NewVir", CActVir, CVir)
    nNewClo = CNewClo.shape[1]
    nNewExt = CNewExt.shape[1]

    # re-orthogonalize (should be orthogonal already, but just to be sure).
    COrbNew = np.hstack([CAct])
    if 1:
        COrbNew = np.hstack([CNewClo, CAct, CNewExt])
        SMo = mdot(COrbNew.T, S1, COrbNew)
        COrbNew = np.dot(COrbNew, MakeSmh(SMo))

    print("    Number of Core Orbitals        {} ".format(CNewClo.shape[1]))
    print("    Number of Virtual Orbitals     {} ".format(CNewExt.shape[1]))
    print("    Total Number of Orbitals       {} ".format(COrbNew.shape[1]))

    return CNewClo.shape[1], CAct.shape[1], CNewExt.shape[1], nElec, COrbNew
コード例 #30
0
ファイル: 32-wfn_overlap.py プロジェクト: chrinide/pyscf
from functools import reduce
import numpy
from pyscf import gto, scf, ci

#
# RCISD wavefunction overlap
#
myhf1 = gto.M(atom='H 0 0 0; F 0 0 1.1', basis='6-31g', verbose=0).apply(scf.RHF).run()
ci1 = ci.CISD(myhf1).run()
print('CISD energy of mol1', ci1.e_tot)

myhf2 = gto.M(atom='H 0 0 0; F 0 0 1.2', basis='6-31g', verbose=0).apply(scf.RHF).run()
ci2 = ci.CISD(myhf2).run()
print('CISD energy of mol2', ci2.e_tot)

s12 = gto.intor_cross('cint1e_ovlp_sph', myhf1.mol, myhf2.mol)
s12 = reduce(numpy.dot, (myhf1.mo_coeff.T, s12, myhf2.mo_coeff))
nmo = myhf2.mo_energy.size
nocc = myhf2.mol.nelectron // 2
print('<CISD-mol1|CISD-mol2> = ', ci.cisd.overlap(ci1.ci, ci2.ci, nmo, nocc, s12))

#
# UCISD wavefunction overlap
#
myhf1 = gto.M(atom='H 0 0 0; F 0 0 1.1', basis='6-31g', spin=2, verbose=0).apply(scf.UHF).run()
ci1 = ci.UCISD(myhf1).run()
print('CISD energy of mol1', ci1.e_tot)

myhf2 = gto.M(atom='H 0 0 0; F 0 0 1.2', basis='6-31g', spin=2, verbose=0).apply(scf.UHF).run()
ci2 = ci.UCISD(myhf2).run()
print('CISD energy of mol2', ci2.e_tot)
コード例 #31
0
def kernel(mf,
           aolabels,
           threshold=.2,
           minao='minao',
           with_iao=False,
           openshelloption=2,
           canonicalize=True,
           verbose=None):
    '''AVAS method to construct mcscf active space.
    Ref. arXiv:1701.07862 [physics.chem-ph]

    Args:
        mf : an :class:`SCF` object

        aolabels : string or a list of strings
            AO labels for AO active space

    Kwargs:
        threshold : float
            Tructing threshold of the AO-projector above which AOs are kept in
            the active space.
        minao : str
            A reference AOs for AVAS.
        with_iao : bool
            Whether to use IAO localization to construct the reference active AOs.
        openshelloption : int
            How to handle singly-occupied orbitals in the active space. The
            singly-occupied orbitals are projected as part of alpha orbitals
            if openshelloption=2, or completely kept in active space if
            openshelloption=3.  See Section III.E option 2 or 3 of the
            reference paper for more details.
        canonicalize : bool
            Orbitals defined in AVAS method are local orbitals.  Symmetrizing
            the core, active and virtual space.

    Returns:
        active-space-size, #-active-electrons, orbital-initial-guess-for-CASCI/CASSCF

    Examples:

    >>> from pyscf import gto, scf, mcscf
    >>> from pyscf.mcscf import avas
    >>> mol = gto.M(atom='Cr 0 0 0; Cr 0 0 1.6', basis='ccpvtz')
    >>> mf = scf.RHF(mol).run()
    >>> ncas, nelecas, mo = avas.avas(mf, ['Cr 3d', 'Cr 4s'])
    >>> mc = mcscf.CASSCF(mf, ncas, nelecas).run(mo)
    '''
    if isinstance(verbose, logger.Logger):
        log = verbose
    elif verbose is not None:
        log = logger.Logger(mf.stdout, verbose)
    else:
        log = logger.Logger(mf.stdout, mf.verbose)
    mol = mf.mol

    log.info('\n** AVAS **')
    if isinstance(mf, scf.uhf.UHF):
        log.note('UHF/UKS object is found.  AVAS takes alpha orbitals only')
        mo_coeff = mf.mo_coeff[0]
        mo_occ = mf.mo_occ[0]
        mo_energy = mf.mo_energy[0]
        assert (openshelloption != 1)
    else:
        mo_coeff = mf.mo_coeff
        mo_occ = mf.mo_occ
        mo_energy = mf.mo_energy
    nocc = numpy.count_nonzero(mo_occ != 0)
    ovlp = mol.intor_symmetric('cint1e_ovlp_sph')
    log.info('  Total number of HF MOs  is equal to    %d', mo_coeff.shape[1])
    log.info('  Number of occupied HF MOs is equal to  %d', nocc)

    mol = mf.mol
    pmol = mol.copy()
    pmol.atm = mol._atm
    pmol.basis = minao
    pmol.build(False, False)

    if isinstance(aolabels, str):
        aolabels = re.sub(' +', ' ', aolabels.strip(), count=1)
        baslst = [
            i for i, s in enumerate(pmol.spherical_labels(1)) if aolabels in s
        ]
    elif isinstance(aolabels[0], str):
        aolabels = [re.sub(' +', ' ', x.strip(), count=1) for x in aolabels]
        baslst = [
            i for i, s in enumerate(pmol.spherical_labels(1))
            if any(x in s for x in aolabels)
        ]
    else:
        raise RuntimeError
    baslst = numpy.asarray(baslst)
    log.info('reference AO indices for %s %s: %s', minao, aolabels, baslst)

    if with_iao:
        from pyscf.lo import iao
        c = iao.iao(mol, mo_coeff[:, :nocc], minao)[:, baslst]
        s2 = reduce(numpy.dot, (c.T, ovlp, c))
        s21 = reduce(numpy.dot, (c.T, ovlp, mo_coeff))
    else:
        s2 = pmol.intor_symmetric('cint1e_ovlp_sph')[baslst][:, baslst]
        s21 = gto.intor_cross('cint1e_ovlp_sph', pmol, mol)[baslst]
        s21 = numpy.dot(s21, mo_coeff)
    sa = s21.T.dot(scipy.linalg.solve(s2, s21, sym_pos=True))

    if openshelloption == 2:
        wocc, u = numpy.linalg.eigh(sa[:nocc, :nocc])
        log.info('Option 2: threshold %s', threshold)
        ncas_occ = (wocc > threshold).sum()
        nelecas = mol.nelectron - (wocc < threshold).sum() * 2
        mocore = mo_coeff[:, :nocc].dot(u[:, wocc < threshold])
        mocas = mo_coeff[:, :nocc].dot(u[:, wocc > threshold])

        wvir, u = numpy.linalg.eigh(sa[nocc:, nocc:])
        ncas_vir = (wvir > threshold).sum()
        mocas = numpy.hstack(
            (mocas, mo_coeff[:, nocc:].dot(u[:, wvir > threshold])))
        movir = mo_coeff[:, nocc:].dot(u[:, wvir < threshold])
        ncas = mocas.shape[1]

    elif openshelloption == 3:
        docc = nocc - mol.spin
        wocc, u = numpy.linalg.eigh(sa[:docc, :docc])
        log.info('Option 3: threshold %s, num open shell %d', threshold,
                 mol.spin)
        ncas_occ = (wocc > threshold).sum()
        nelecas = mol.nelectron - (wocc < threshold).sum() * 2
        mocore = mo_coeff[:, :docc].dot(u[:, wocc < threshold])
        mocas = mo_coeff[:, :docc].dot(u[:, wocc > threshold])

        wvir, u = numpy.linalg.eigh(sa[nocc:, nocc:])
        ncas_vir = (wvir > threshold).sum()
        mocas = numpy.hstack((mocas, mo_coeff[:, docc:nocc],
                              mo_coeff[:, nocc:].dot(u[:, wvir > threshold])))
        movir = mo_coeff[:, nocc:].dot(u[:, wvir < threshold])
        ncas = mocas.shape[1]

    log.debug('projected occ eig %s', wocc[::-1])
    log.debug('projected vir eig %s', wvir[::-1])
    log.info('Active from occupied = %d , eig %s', ncas_occ,
             wocc[wocc > threshold][::-1])
    log.info('Inactive from occupied = %d', mocore.shape[1])
    log.info('Active from unoccupied = %d , eig %s', ncas_vir,
             wvir[wvir > threshold][::-1])
    log.info('Inactive from unoccupied = %d', movir.shape[1])
    log.info('Dimensions of active %d', ncas)
    nalpha = (nelecas + mol.spin) // 2
    nbeta = nelecas - nalpha
    log.info('# of alpha electrons %d', nalpha)
    log.info('# of beta electrons %d', nbeta)

    if canonicalize:
        from pyscf.mcscf import dmet_cas

        def trans(c):
            if c.shape[1] == 0:
                return c
            else:
                csc = reduce(numpy.dot, (c.T, ovlp, mo_coeff))
                fock = numpy.dot(csc * mo_energy, csc.T)
                e, u = scipy.linalg.eigh(fock)
                return dmet_cas.symmetrize(mol, e, numpy.dot(c, u), ovlp, log)

        mo = numpy.hstack([trans(mocore), trans(mocas), trans(movir)])
    else:
        mo = numpy.hstack((mocore, mocas, movir))
    return ncas, nelecas, mo
コード例 #32
0
s = mol.intor('cint1e_ovlp_sph')
t = mol.intor('cint1e_kin_sph')
v = mol.intor('cint1e_nuc_sph')
# Overlap, kinetic, nuclear attraction gradients (against electron coordinates)
s1 = mol.intor('cint1e_ipovlp_sph', comp=3)
t1 = mol.intor('cint1e_ipkin_sph', comp=3)
v1 = mol.intor('cint1e_ipnuc_sph', comp=3)

print('Dipole %s' %
      numpy.einsum('xij,ij->x', mol.intor('cint1e_r_sph', comp=3), dm))

#
# AO overlap between two molecules
#
mol1 = gto.M(verbose=0, atom='H 0 1 0; H 1 0 0', basis='ccpvdz')
s = gto.intor_cross('cint1e_ovlp_sph', mol, mol1)
print('overlap shape (%d, %d)' % s.shape)

#
# 2e integrals.  Keyword aosym is to specify the permutation symmetry in the
# AO integral matrix.  s8 means 8-fold symmetry, s2kl means 2-fold symmetry
# for the symmetry between kl in (ij|kl)
#
eri = mol.intor('cint2e_sph', aosym='s8')
#
# 2e gradient integrals on first atom only
#
eri = mol.intor('cint2e_ip1_sph', aosym='s2kl')

#
# 2e integral gradients on certain atom
コード例 #33
0
def _kernel(avas_obj):
    mf = avas_obj._scf
    mol = mf.mol
    log = logger.new_logger(avas_obj)
    log.info('\n** AVAS **')

    assert avas_obj.openshell_option != 1

    if isinstance(mf, scf.uhf.UHF):
        log.note('UHF/UKS object is found.  AVAS takes alpha orbitals only')
        mo_coeff = mf.mo_coeff[0]
        mo_occ = mf.mo_occ[0]
        mo_energy = mf.mo_energy[0]
    else:
        mo_coeff = mf.mo_coeff
        mo_occ = mf.mo_occ
        mo_energy = mf.mo_energy

    ncore = avas_obj.ncore
    nocc = numpy.count_nonzero(mo_occ != 0)
    ovlp = mol.intor_symmetric('int1e_ovlp')
    log.info('  Total number of HF MOs  is equal to    %d' ,mo_coeff.shape[1])
    log.info('  Number of occupied HF MOs is equal to  %d', nocc)

    mol = mf.mol
    pmol = mol.copy()
    pmol.atom = mol._atom
    pmol.unit = 'B'
    pmol.symmetry = False
    pmol.basis = avas_obj.minao
    pmol.build(False, False)

    baslst = pmol.search_ao_label(avas_obj.aolabels)
    log.info('reference AO indices for %s %s: %s',
             avas_obj.minao, avas_obj.aolabels, baslst)

    if avas_obj.with_iao:
        from pyscf.lo import iao
        c = iao.iao(mol, mo_coeff[:,ncore:nocc], avas_obj.minao)[:,baslst]
        s2 = reduce(numpy.dot, (c.T, ovlp, c))
        s21 = reduce(numpy.dot, (c.T, ovlp, mo_coeff[:, ncore:]))
    else:
        s2 = pmol.intor_symmetric('int1e_ovlp')[baslst][:,baslst]
        s21 = gto.intor_cross('int1e_ovlp', pmol, mol)[baslst]
        s21 = numpy.dot(s21, mo_coeff[:, ncore:])
    sa = s21.T.dot(scipy.linalg.solve(s2, s21, sym_pos=True))

    threshold = avas_obj.threshold
    if avas_obj.openshell_option == 2:
        wocc, u = numpy.linalg.eigh(sa[:(nocc-ncore), :(nocc-ncore)])
        log.info('Option 2: threshold %s', threshold)
        ncas_occ = (wocc > threshold).sum()
        nelecas = (mol.nelectron - ncore * 2) - (wocc < threshold).sum() * 2
        mocore = mo_coeff[:,ncore:nocc].dot(u[:,wocc<threshold])
        mocas = mo_coeff[:,ncore:nocc].dot(u[:,wocc>=threshold])

        wvir, u = numpy.linalg.eigh(sa[(nocc-ncore):,(nocc-ncore):])
        ncas_vir = (wvir > threshold).sum()
        mocas = numpy.hstack((mocas,
                              mo_coeff[:,nocc:].dot(u[:,wvir>=threshold])))
        movir = mo_coeff[:,nocc:].dot(u[:,wvir<threshold])
        ncas = mocas.shape[1]

        occ_weights = numpy.hstack([wocc[wocc<threshold], wocc[wocc>=threshold]])
        vir_weights = numpy.hstack([wvir[wvir>=threshold], wvir[wvir<threshold]])

    elif avas_obj.openshell_option == 3:
        docc = nocc - mol.spin
        wocc, u = numpy.linalg.eigh(sa[:(docc-ncore),:(docc-ncore)])
        log.info('Option 3: threshold %s, num open shell %d', threshold, mol.spin)
        ncas_occ = (wocc > threshold).sum()
        nelecas = (mol.nelectron - ncore * 2) - (wocc < threshold).sum() * 2
        mocore = mo_coeff[:,ncore:docc].dot(u[:,wocc<threshold])
        mocas = mo_coeff[:,ncore:docc].dot(u[:,wocc>=threshold])

        wvir, u = numpy.linalg.eigh(sa[(nocc-ncore):,(nocc-ncore):])
        ncas_vir = (wvir > threshold).sum()
        mocas = numpy.hstack((mocas,
                              mo_coeff[:,docc:nocc],
                              mo_coeff[:,nocc:].dot(u[:,wvir>=threshold])))
        movir = mo_coeff[:,nocc:].dot(u[:,wvir<threshold])
        ncas = mocas.shape[1]

        occ_weights = numpy.hstack([wocc[wocc<threshold], numpy.ones(nocc-docc),
                                    wocc[wocc>=threshold]])
        vir_weights = numpy.hstack([wvir[wvir>=threshold], wvir[wvir<threshold]])
    else:
        raise RuntimeError(f'Unknown option openshell_option {avas_obj.openshell_option}')

    log.debug('projected occ eig %s', occ_weights)
    log.debug('projected vir eig %s', vir_weights)
    log.info('Active from occupied = %d , eig %s', ncas_occ, occ_weights[occ_weights>=threshold])
    log.info('Inactive from occupied = %d', mocore.shape[1])
    log.info('Active from unoccupied = %d , eig %s', ncas_vir, vir_weights[vir_weights>=threshold])
    log.info('Inactive from unoccupied = %d', movir.shape[1])
    log.info('Dimensions of active %d', ncas)
    nalpha = (nelecas + mol.spin) // 2
    nbeta = nelecas - nalpha
    log.info('# of alpha electrons %d', nalpha)
    log.info('# of beta electrons %d', nbeta)

    mofreeze = mo_coeff[:,:ncore]
    if avas_obj.canonicalize:
        from pyscf.mcscf import dmet_cas

        def trans(c):
            if c.shape[1] == 0:
                return c
            else:
                csc = reduce(numpy.dot, (c.T, ovlp, mo_coeff))
                fock = numpy.dot(csc*mo_energy, csc.T)
                e, u = scipy.linalg.eigh(fock)
                return dmet_cas.symmetrize(mol, e, numpy.dot(c, u), ovlp, log)
        if ncore > 0:
            mofreeze = trans(mofreeze)
        mocore = trans(mocore)
        mocas = trans(mocas)
        movir = trans(movir)
    mo = numpy.hstack((mofreeze, mocore, mocas, movir))
    return ncas, nelecas, mo, occ_weights, vir_weights