Esempio n. 1
0
def get_irrep_nelec(mol, mo_coeff, mo_occ, s=None):
    '''Alpha/beta electron numbers for each irreducible representation.

    Args:
        mol : an instance of :class:`Mole`
            To provide irrep_id, and spin-adapted basis
        mo_occ : a list of 1D ndarray
            Regular occupancy, without grouping for irreps
        mo_coeff : a list of 2D ndarray
            Regular orbital coefficients, without grouping for irreps

    Returns:
        irrep_nelec : dict
            The number of alpha/beta electrons for each irrep {'ir_name':(int,int), ...}.

    Examples:

    >>> mol = gto.M(atom='O 0 0 0; H 0 0 1; H 0 1 0', basis='ccpvdz', symmetry=True, charge=1, spin=1, verbose=0)
    >>> mf = scf.UHF(mol)
    >>> mf.scf()
    -75.623975516256721
    >>> scf.uhf_symm.get_irrep_nelec(mol, mf.mo_coeff, mf.mo_occ)
    {'A1': (3, 3), 'A2': (0, 0), 'B1': (1, 1), 'B2': (1, 0)}
    '''
    orbsyma = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb,
                                  mo_coeff[0], s)
    orbsymb = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb,
                                  mo_coeff[1], s)
    orbsyma = numpy.array(orbsyma)
    orbsymb = numpy.array(orbsymb)
    irrep_nelec = dict([(mol.irrep_name[k], (int(sum(mo_occ[0][orbsyma==ir])),
                                             int(sum(mo_occ[1][orbsymb==ir]))))
                        for k, ir in enumerate(mol.irrep_id)])
    return irrep_nelec
Esempio n. 2
0
    def get_grad(self, mo_coeff, mo_occ, fock=None):
        mol = self.mol
        if not mol.symmetry:
            return uhf.UHF.get_grad(self, mo_coeff, mo_occ, fock)

        if fock is None:
            dm1 = self.make_rdm1(mo_coeff, mo_occ)
            fock = self.get_hcore(mol) + self.get_veff(self.mol, dm1)
        ovlp_ao = self.get_ovlp()
        orbsyma = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb,
                                      mo_coeff[0], ovlp_ao, False)
        orbsymb = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb,
                                      mo_coeff[1], ovlp_ao, False)
        orbsyma = numpy.asarray(orbsyma)
        orbsymb = numpy.asarray(orbsymb)

        occidxa = mo_occ[0] > 0
        occidxb = mo_occ[1] > 0
        viridxa = ~occidxa
        viridxb = ~occidxb
        ga = reduce(numpy.dot, (mo_coeff[0][:,viridxa].T.conj(), fock[0],
                                mo_coeff[0][:,occidxa]))
        ga[orbsyma[viridxa].reshape(-1,1)!=orbsyma[occidxa]] = 0
        gb = reduce(numpy.dot, (mo_coeff[1][:,viridxb].T.conj(), fock[1],
                                mo_coeff[1][:,occidxb]))
        gb[orbsymb[viridxb].reshape(-1,1)!=orbsymb[occidxb]] = 0
        return numpy.hstack((ga.ravel(), gb.ravel()))
Esempio n. 3
0
 def gen_g_hop(self, mo_coeff, mo_occ, fock_ao=None, h1e=None):
     mol = self._scf.mol
     if mol.symmetry:
         ovlp_ao = self._scf.get_ovlp()
         self._orbsym =(symm.label_orb_symm(mol, mol.irrep_id,
                                 mol.symm_orb, mo_coeff[0], s=ovlp_ao),
                        symm.label_orb_symm(mol, mol.irrep_id,
                                 mol.symm_orb, mo_coeff[1], s=ovlp_ao))
     return gen_g_hop_uhf(self, mo_coeff, mo_occ, fock_ao, h1e)
Esempio n. 4
0
    def kernel(self, mo_coeff=None, ci0=None, macro=None, micro=None, callback=None, _kern=None):
        if mo_coeff is None:
            mo_coeff = self.mo_coeff
        else:
            self.mo_coeff = mo_coeff
        if macro is None:
            macro = self.max_cycle_macro
        if micro is None:
            micro = self.max_cycle_micro
        if callback is None:
            callback = self.callback
        if _kern is None:
            _kern = mc1step.kernel

        if self.verbose > logger.QUIET:
            pyscf.gto.mole.check_sanity(self, self._keys, self.stdout)

        self.mol.check_sanity(self)
        self.dump_flags()

        # irrep_name = self.mol.irrep_name
        irrep_name = self.mol.irrep_id
        try:
            self.orbsym = symm.label_orb_symm(self.mol, irrep_name, self.mol.symm_orb, mo_coeff, s=self._scf.get_ovlp())
        except ValueError:
            logger.warn(self, "mc1step_symm symmetrizes input orbitals")
            s = self._scf.get_ovlp()
            mo_coeff = symm.symmetrize_orb(self.mol, mo_coeff, s=s)
            diag = numpy.einsum("ki,ki->i", mo_coeff, numpy.dot(s, mo_coeff))
            mo_coeff = numpy.einsum("ki,i->ki", mo_coeff, 1 / numpy.sqrt(diag))
            self.orbsym = symm.label_orb_symm(self.mol, irrep_name, self.mol.symm_orb, mo_coeff, s=s)

        if not hasattr(self.fcisolver, "orbsym") or not self.fcisolver.orbsym:
            ncore = self.ncore
            nocc = self.ncore + self.ncas
            self.fcisolver.orbsym = self.orbsym[ncore:nocc]
        logger.debug(self, "Active space irreps %s", str(self.fcisolver.orbsym))

        self.converged, self.e_tot, e_cas, self.ci, self.mo_coeff = _kern(
            self,
            mo_coeff,
            tol=self.conv_tol,
            conv_tol_grad=self.conv_tol_grad,
            macro=macro,
            micro=micro,
            ci0=ci0,
            callback=callback,
            verbose=self.verbose,
        )
        logger.note(self, "CASSCF energy = %.15g", self.e_tot)
        return self.e_tot, e_cas, self.ci, self.mo_coeff
Esempio n. 5
0
    def test_kernel_symm(self):
        mol = gto.Mole()
        mol.verbose = 0
        mol.output = None
        mol.atom = [
            ['O', ( 0., 0.    , 0.   )],
            ['H', ( 0., -0.757, 0.587)],
            ['H', ( 0., 0.757 , 0.587)],]
        mol.basis = 'sto-3g'
        mol.symmetry = 1
        mol.build()
        m = scf.RHF(mol).run()

        norb = m.mo_coeff.shape[1]
        nelec = mol.nelectron - 2
        h1e = reduce(numpy.dot, (m.mo_coeff.T, scf.hf.get_hcore(mol), m.mo_coeff))
        eri = ao2mo.incore.full(m._eri, m.mo_coeff)
        orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, m.mo_coeff)

        myci = selected_ci_symm.SCI().set(orbsym=orbsym, select_cutoff=.5e-3)
        e1, c1 = myci.kernel(h1e, eri, norb, nelec)
        myci = direct_spin1_symm.FCISolver().set(orbsym=orbsym)
        e2, c2 = myci.kernel(h1e, eri, norb, nelec)

        self.assertAlmostEqual(e1, e2, 6)
        c2_cut = selected_ci.from_fci(c2, c1._strs, norb, nelec)
        self.assertAlmostEqual(abs(numpy.dot(c1.ravel(), c2_cut.ravel())), 1, 6)

        myci = selected_ci_symm.SCI().set(orbsym=orbsym, select_cutoff=1e-5)
        e1, c1 = myci.kernel(h1e, eri, norb, nelec, ci0=c2_cut, wfnsym=0)
        self.assertAlmostEqual(e1, e2, 9)
        c2_cut = selected_ci.from_fci(c2, c1._strs, norb, nelec)
        self.assertAlmostEqual(abs(numpy.dot(c1.ravel(), c2_cut.ravel())), 1, 9)
Esempio n. 6
0
    def get_occ(self, mo_energy, mo_coeff=None):
        ''' We cannot assume default mo_energy value, because the orbital
        energies are sorted after doing SCF.  But in this function, we need
        the orbital energies are grouped by symmetry irreps
        '''
        mol = self.mol
        nirrep = len(mol.symm_orb)
        if mo_coeff is not None:
            orbsym = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb,
                                         mo_coeff, self.get_ovlp(), False)
            orbsym = numpy.asarray(orbsym)
        else:
            orbsym = [numpy.repeat(ir, mol.symm_orb[i].shape[1])
                      for i, ir in enumerate(mol.irrep_id)]
            orbsym = numpy.hstack(orbsym)

        mo_occ = numpy.zeros_like(mo_energy)
        mo_e_left = []
        idx_e_left = []
        nelec_fix = 0
        for i, ir in enumerate(mol.irrep_id):
            irname = mol.irrep_name[i]
            ir_idx = numpy.where(orbsym == ir)[0]
            if irname in self.irrep_nelec:
                n = self.irrep_nelec[irname]
                e_idx = numpy.argsort(mo_energy[ir_idx])
                mo_occ[ir_idx[e_idx[:n//2]]] = 2
                nelec_fix += n
            else:
                idx_e_left.append(ir_idx)
        nelec_float = mol.nelectron - nelec_fix
        assert(nelec_float >= 0)
        if nelec_float > 0:
            idx_e_left = numpy.hstack(idx_e_left)
            mo_e_left = mo_energy[idx_e_left]
            mo_e_sort = numpy.argsort(mo_e_left)
            occ_idx = idx_e_left[mo_e_sort[:(nelec_float//2)]]
            mo_occ[occ_idx] = 2

        viridx = (mo_occ==0)
        if self.verbose < logger.INFO or viridx.sum() == 0:
            return mo_occ
        ehomo = max(mo_energy[mo_occ>0 ])
        elumo = min(mo_energy[mo_occ==0])
        noccs = []
        for i, ir in enumerate(mol.irrep_id):
            irname = mol.irrep_name[i]
            ir_idx = (orbsym == ir)

            noccs.append(int(mo_occ[ir_idx].sum()))
            if ehomo in mo_energy[ir_idx]:
                irhomo = irname
            if elumo in mo_energy[ir_idx]:
                irlumo = irname
        logger.info(self, 'H**O (%s) = %.15g  LUMO (%s) = %.15g',
                    irhomo, ehomo, irlumo, elumo)
        if self.verbose >= logger.DEBUG:
            logger.debug(self, 'irrep_nelec = %s', noccs)
            _dump_mo_energy(mol, mo_energy, mo_occ, ehomo, elumo, orbsym)
        return mo_occ
Esempio n. 7
0
def get_irrep_nelec(mol, mo_coeff, mo_occ, s=None):
    '''Electron numbers for each irreducible representation.

    Args:
        mol : an instance of :class:`Mole`
            To provide irrep_id, and spin-adapted basis
        mo_coeff : 2D ndarray
            Regular orbital coefficients, without grouping for irreps
        mo_occ : 1D ndarray
            Regular occupancy, without grouping for irreps

    Returns:
        irrep_nelec : dict
            The number of electrons for each irrep {'ir_name':int,...}.

    Examples:

    >>> mol = gto.M(atom='O 0 0 0; H 0 0 1; H 0 1 0', basis='ccpvdz', symmetry=True, verbose=0)
    >>> mf = scf.RHF(mol)
    >>> mf.scf()
    -76.016789472074251
    >>> scf.hf_symm.get_irrep_nelec(mol, mf.mo_coeff, mf.mo_occ)
    {'A1': 6, 'A2': 0, 'B1': 2, 'B2': 2}
    '''
    orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, mo_coeff, s)
    orbsym = numpy.array(orbsym)
    irrep_nelec = dict([(mol.irrep_name[k], int(sum(mo_occ[orbsym==ir])))
                        for k, ir in enumerate(mol.irrep_id)])
    return irrep_nelec
Esempio n. 8
0
    def get_grad(self, mo_coeff, mo_occ, fock=None):
        mol = self.mol
        if not self.mol.symmetry:
            return rohf.ROHF.get_grad(self, mo_coeff, mo_occ, fock)

        if fock is None:
            dm1 = self.make_rdm1(mo_coeff, mo_occ)
            fock = self.get_hcore(mol) + self.get_veff(self.mol, dm1)
        orbsym = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb,
                                     mo_coeff, self.get_ovlp(), False)
        orbsym = numpy.asarray(orbsym)
        sym_allow = orbsym.reshape(-1,1) == orbsym

        occidxa = mo_occ > 0
        occidxb = mo_occ == 2
        viridxa = ~occidxa
        viridxb = ~occidxb
        focka = reduce(numpy.dot, (mo_coeff.T, fock[0], mo_coeff))
        fockb = reduce(numpy.dot, (mo_coeff.T, fock[1], mo_coeff))
        uniq_var_a = viridxa.reshape(-1,1) & occidxa
        uniq_var_b = viridxb.reshape(-1,1) & occidxb
        g = numpy.zeros_like(focka)
        g[uniq_var_a]  = focka[uniq_var_a]
        g[uniq_var_b] += fockb[uniq_var_b]
        g[~sym_allow] = 0
        return g[uniq_var_a | uniq_var_b].ravel()
Esempio n. 9
0
def from_chkfile(filename, chkfile, tol=TOL, float_format=DEFAULT_FLOAT_FORMAT):
    '''Read SCF results from PySCF chkfile and transform 1-electron,
    2-electron integrals using the SCF orbitals.  The transformed integrals is
    written to FCIDUMP'''
    from pyscf import scf, symm
    with open(filename, 'w') as fout:
        mol, scf_rec = scf.chkfile.load_scf(chkfile)
        mo_coeff = numpy.array(scf_rec['mo_coeff'])
        nmo = mo_coeff.shape[1]
        if mol.symmetry:
            orbsym = symm.label_orb_symm(mol, mol.irrep_id,
                                         mol.symm_orb, mo_coeff, check=False)
            write_head(fout, nmo, mol.nelectron, mol.spin, orbsym)
        else:
            write_head(fout, nmo, mol.nelectron, mol.spin)

        eri = ao2mo.full(mol, mo_coeff, verbose=0)
        write_eri(fout, ao2mo.restore(8, eri, nmo), nmo, tol, float_format)

        t = mol.intor_symmetric('int1e_kin')
        v = mol.intor_symmetric('int1e_nuc')
        h = reduce(numpy.dot, (mo_coeff.T, t+v, mo_coeff))
        write_hcore(fout, h, nmo, tol, float_format)
        output_format = ' ' + float_format + '  0  0  0  0\n'
        fout.write(output_format % mol.energy_nuc())
Esempio n. 10
0
def orbital_coeff(mol, fout, mo_coeff, spin='Alpha', symm=None, ene=None,
                  occ=None, ignore_h=False):
    from pyscf.symm import label_orb_symm
    if ignore_h:
        mol, mo_coeff = remove_high_l(mol, mo_coeff)
    aoidx = order_ao_index(mol)
    nmo = mo_coeff.shape[1]
    if symm is None:
        symm = ['A']*nmo
        if mol.symmetry:
            try:
                symm = label_orb_symm(mol, mol.irrep_name, mol.symm_orb,
                                      mo_coeff, tol=1e-5)
            except ValueError as e:
                logger.warn(mol, str(e))
    if ene is None:
        ene = numpy.arange(nmo)
    assert(spin == 'Alpha' or spin == 'Beta')
    if occ is None:
        occ = numpy.zeros(nmo)
        neleca, nelecb = mol.nelec
        if spin == 'Alpha':
            occ[:neleca] = 1
        else:
            occ[:nelecb] = 1
    fout.write('[MO]\n')
    for imo in range(nmo):
        fout.write(' Sym= %s\n' % symm[imo])
        fout.write(' Ene= %15.10g\n' % ene[imo])
        fout.write(' Spin= %s\n' % spin)
        fout.write(' Occup= %10.5f\n' % occ[imo])
        for i,j in enumerate(aoidx):
            fout.write(' %3d    %18.14g\n' % (i+1, mo_coeff[j,imo]))
Esempio n. 11
0
            def gen_g_hop(self, mo_coeff, mo_occ, fock_ao=None, h1e=None):
                mol = self._scf.mol
                if mol.symmetry:
# label the symmetry every time calling gen_g_hop because kernel function may
# change mo_coeff ordering after calling self.eig
                    self._orbsym = symm.label_orb_symm(mol, mol.irrep_id,
                            mol.symm_orb, mo_coeff, s=self._scf.get_ovlp())
                return gen_g_hop_rohf(self, mo_coeff, mo_occ, fock_ao, h1e)
Esempio n. 12
0
 def test_symmetrize_space(self):
     from pyscf import gto, symm, scf
     mol = gto.M(atom = 'C  0  0  0; H  1  1  1; H -1 -1  1; H  1 -1 -1; H -1  1 -1',
                 basis = 'sto3g', verbose=0)
     mf = scf.RHF(mol).run()
     mol.build(0, 0, symmetry='D2')
     mo = symm.symmetrize_space(mol, mf.mo_coeff)
     irreps = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo)
     self.assertEqual(irreps, ['A','A','A','B1','B1','B2','B2','B3','B3'])
Esempio n. 13
0
    def analyze(self, verbose=logger.DEBUG):
        from pyscf.tools import dump_mat
        mo_energy = self.mo_energy
        mo_occ = self.mo_occ
        mo_coeff = self.mo_coeff
        log = logger.Logger(self.stdout, verbose)
        mol = self.mol
        nirrep = len(mol.irrep_id)
        ovlp_ao = self.get_ovlp()
        orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, mo_coeff,
                                     s=ovlp_ao)
        orbsym = numpy.array(orbsym)
        wfnsym = 0
        ndoccs = []
        nsoccs = []
        for k,ir in enumerate(mol.irrep_id):
            ndoccs.append(sum(orbsym[mo_occ==2] == ir))
            nsoccs.append(sum(orbsym[mo_occ==1] == ir))
            if nsoccs[k] % 2:
                wfnsym ^= ir
        if mol.groupname in ('Dooh', 'Coov'):
            log.info('TODO: total symmetry for %s', mol.groupname)
        else:
            log.info('total symmetry = %s',
                     symm.irrep_id2name(mol.groupname, wfnsym))
        log.info('occupancy for each irrep:  ' + (' %4s'*nirrep),
                 *mol.irrep_name)
        log.info('double occ                 ' + (' %4d'*nirrep), *ndoccs)
        log.info('single occ                 ' + (' %4d'*nirrep), *nsoccs)
        log.info('**** MO energy ****')
        irname_full = {}
        for k,ir in enumerate(mol.irrep_id):
            irname_full[ir] = mol.irrep_name[k]
        irorbcnt = {}
        for k, j in enumerate(orbsym):
            if j in irorbcnt:
                irorbcnt[j] += 1
            else:
                irorbcnt[j] = 1
            log.info('MO #%d (%s #%d), energy= %.15g occ= %g',
                     k+1, irname_full[j], irorbcnt[j], mo_energy[k], mo_occ[k])

        if verbose >= logger.DEBUG:
            label = mol.spheric_labels(True)
            molabel = []
            irorbcnt = {}
            for k, j in enumerate(orbsym):
                if j in irorbcnt:
                    irorbcnt[j] += 1
                else:
                    irorbcnt[j] = 1
                molabel.append('#%-d(%s #%d)' % (k+1, irname_full[j], irorbcnt[j]))
            log.debug(' ** MO coefficients **')
            dump_mat.dump_rec(mol.stdout, mo_coeff, label, molabel, start=1)

        dm = self.make_rdm1(mo_coeff, mo_occ)
        return self.mulliken_meta(mol, dm, s=ovlp_ao, verbose=verbose)
Esempio n. 14
0
 def __init__(self):
     self.__dict__.update(cis.__dict__)
     self.h1e = reduce(numpy.dot, (mo.T, scf.hf.get_hcore(mol), mo))
     self.eri = ao2mo.outcore.full_iofree(mol, mo)
     self.eci = None
     self.ci = None
     if mol.symmetry:
         self.orbsym = symm.label_orb_symm(mol, mol.irrep_id,
                                           mol.symm_orb, mo)
     self._keys = set(self.__dict__.keys())
Esempio n. 15
0
def analyze(mf, verbose=logger.DEBUG, **kwargs):
    '''Analyze the given SCF object:  print orbital energies, occupancies;
    print orbital coefficients; Occupancy for each irreps; Mulliken population analysis
    '''
    from pyscf.lo import orth
    from pyscf.tools import dump_mat
    mol = mf.mol
    if not mol.symmetry:
        return hf.analyze(mf, verbose, **kwargs)

    mo_energy = mf.mo_energy
    mo_occ = mf.mo_occ
    mo_coeff = mf.mo_coeff
    log = logger.Logger(mf.stdout, verbose)
    nirrep = len(mol.irrep_id)
    ovlp_ao = mf.get_ovlp()
    orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, mo_coeff,
                                 s=ovlp_ao, check=False)
    orbsym = numpy.array(orbsym)
    wfnsym = 0
    noccs = [sum(orbsym[mo_occ>0]==ir) for ir in mol.irrep_id]
    log.note('total symmetry = %s', symm.irrep_id2name(mol.groupname, wfnsym))
    log.note('occupancy for each irrep:  ' + (' %4s'*nirrep), *mol.irrep_name)
    log.note('double occ                 ' + (' %4d'*nirrep), *noccs)
    log.note('**** MO energy ****')
    irname_full = {}
    for k,ir in enumerate(mol.irrep_id):
        irname_full[ir] = mol.irrep_name[k]
    irorbcnt = {}
    for k, j in enumerate(orbsym):
        if j in irorbcnt:
            irorbcnt[j] += 1
        else:
            irorbcnt[j] = 1
        log.note('MO #%d (%s #%d), energy= %.15g occ= %g',
                 k+1, irname_full[j], irorbcnt[j], mo_energy[k], mo_occ[k])

    if verbose >= logger.DEBUG:
        label = mol.spheric_labels(True)
        molabel = []
        irorbcnt = {}
        for k, j in enumerate(orbsym):
            if j in irorbcnt:
                irorbcnt[j] += 1
            else:
                irorbcnt[j] = 1
            molabel.append('#%-d(%s #%d)' % (k+1, irname_full[j], irorbcnt[j]))
        log.debug(' ** MO coefficients (expansion on meta-Lowdin AOs) **')
        orth_coeff = orth.orth_ao(mol, 'meta_lowdin', s=ovlp_ao)
        c = reduce(numpy.dot, (orth_coeff.T, ovlp_ao, mo_coeff))
        dump_mat.dump_rec(mf.stdout, c, label, molabel, start=1, **kwargs)

    dm = mf.make_rdm1(mo_coeff, mo_occ)
    return mf.mulliken_meta(mol, dm, s=ovlp_ao, verbose=log)
Esempio n. 16
0
def label_symmetry_(mc, mo_coeff):
    #irrep_name = mc.mol.irrep_name
    irrep_name = mc.mol.irrep_id
    s = mc._scf.get_ovlp()
    try:
        mc.orbsym = symm.label_orb_symm(mc.mol, irrep_name,
                                        mc.mol.symm_orb, mo_coeff, s=s)
    except ValueError:
        logger.warn(mc, 'mc1step_symm symmetrizes input orbitals')
        ncore = mc.ncore
        nocc = mc.ncore + mc.ncas
        mo_cor = symm.symmetrize_space(mc.mol, mo_coeff[:,    :ncore], s=s)
        mo_act = symm.symmetrize_space(mc.mol, mo_coeff[:,ncore:nocc], s=s)
        mo_vir = symm.symmetrize_space(mc.mol, mo_coeff[:,nocc:     ], s=s)
        mo_coeff = numpy.hstack((mo_cor,mo_act,mo_vir))
        mc.orbsym = symm.label_orb_symm(mc.mol, irrep_name,
                                        mc.mol.symm_orb, mo_coeff, s=s)

    if not hasattr(mc.fcisolver, 'orbsym') or not mc.fcisolver.orbsym:
        ncore = mc.ncore
        nocc = mc.ncore + mc.ncas
        mc.fcisolver.orbsym = mc.orbsym[ncore:nocc]
    logger.debug(mc, 'Active space irreps %s', str(mc.fcisolver.orbsym))
Esempio n. 17
0
    def get_grad(self, mo_coeff, mo_occ, fock=None):
        mol = self.mol
        if fock is None:
            dm1 = self.make_rdm1(mo_coeff, mo_occ)
            fock = self.get_hcore(mol) + self.get_veff(self.mol, dm1)
        orbsym = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb,
                                     mo_coeff, self.get_ovlp(), False)
        orbsym = numpy.asarray(orbsym)

        occidx = mo_occ > 0
        viridx = ~occidx
        g = reduce(numpy.dot, (mo_coeff[:,viridx].T.conj(), fock,
                               mo_coeff[:,occidx])) * 2
        sym_allow = orbsym[viridx].reshape(-1,1) == orbsym[occidx]
        g[~sym_allow] = 0
        return g.ravel()
Esempio n. 18
0
def write_integrals(xci, orb):
    mol = xci.mol
    orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, orb)
    h1e = reduce(numpy.dot, (orb.T, xci.get_hcore(), orb))
    norb = orb.shape[1]
    if xci._eri is not None:
        h2e = ao2mo.restore(1, ao2mo.full(xci._eri, orb), norb)
    else:
        h2e = ao2mo.restore(1, ao2mo.full(mol, orb), norb)

    with h5py.File(xci.integralfile, 'w') as f:
        f['h1e']    = h1e
        f['h2e']    = h2e
        f['norb'  ] = numpy.array(norb, dtype=numpy.int32)
        f['group' ] = mol.groupname
        f['orbsym'] = numpy.asarray(orbsym, dtype=numpy.int32)
        f['ecore' ] = mol.energy_nuc()
Esempio n. 19
0
def get_orbsym(mol, mo_coeff, s=None, check=False):
    if mo_coeff is None:
        orbsym = numpy.hstack([[ir] * mol.symm_orb[i].shape[1]
                               for i, ir in enumerate(mol.irrep_id)])
    elif getattr(mo_coeff, 'orbsym', None) is not None:
        orbsym = mo_coeff.orbsym
    else:
        nao = mo_coeff.shape[0] // 2
        if isinstance(s, numpy.ndarray):
            assert(s.size == nao**2 or numpy.allclose(s[:nao,:nao], s[nao:,nao:]))
            s = s[:nao,:nao]
        mo_a = mo_coeff[:nao].copy()
        mo_b = mo_coeff[nao:]
        zero_alpha_idx = numpy.linalg.norm(mo_a, axis=0) < 1e-7
        mo_a[:,zero_alpha_idx] = mo_b[:,zero_alpha_idx]
        orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb,
                                     mo_a, s, check)
    return numpy.asarray(orbsym)
Esempio n. 20
0
def generate_hamiltonian():
    ###     PYSCF INPUT
    r0 = 1.50
    molecule = '''
    Cr
    Cr   1   {}
    '''.format(r0)
    charge = 0
    spin  = 0
    basis_set = 'def2-svp'

    ###     TPSCI BASIS INPUT
    orb_basis = 'scf'
    cas = True
    cas_nstart = 12
    cas_nstop =  42
    loc_start = 1
    loc_stop = 6
    cas_nel = 24

    def ordering_diatomics_cr(mol,C):
    # {{{
        ##DZ basis diatomics reordering with frozen 1s

        orb_type = ['s','pz','dz','px','dxz','py','dyz','dx2-y2','dxy']
        ref = np.zeros(C.shape[1])

        ## Find dimension of each space
        dim_orb = []
        for orb in orb_type:
            print("Orb type",orb)
            idx = 0
            for label in mol.ao_labels():
                if orb in label:
                    #print(label)
                    idx += 1

            ##frozen 1s orbitals
            if orb == 's':
                idx -= 6
            elif orb == 'px':
                idx -=2
            elif orb == 'py':
                idx -=2
            elif orb == 'pz':
                idx -=2
            dim_orb.append(idx)
            print(idx)


        new_idx = []
        ## Find orbitals corresponding to each orb space
        for i,orb in enumerate(orb_type):
            print("Orbital type:",orb)
            from pyscf import mo_mapping
            s_pop = mo_mapping.mo_comps(orb, mol, C)
            print(s_pop)
            ref += s_pop
            cas_list = s_pop.argsort()[-dim_orb[i]:]
            print('cas_list', np.array(cas_list))
            new_idx.extend(cas_list)
            #print(orb,' population for active space orbitals', s_pop[cas_list])

        ao_labels = mol.ao_labels()
        #idx = mol.search_ao_label(['N.*s'])
        #for i in idx:
        #    print(i, ao_labels[i])
        print(ref)
        print(new_idx)
        for label in mol.ao_labels():
            print(label)

        return new_idx
    # }}}

    # basis is SVP read comments by alex thom paper DOI:10.1021/acs.jctc.9b01023
    from pyscf import gto
    basis_set={'Cr': gto.parse('''
    BASIS "ao basis" PRINT
    #BASIS SET: (14s,8p,5d) -> [5s,2p,2d]
    Cr    S
      51528.086349               0.14405823106E-02
       7737.2103487              0.11036202287E-01
       1760.3748470              0.54676651806E-01
        496.87706544             0.18965038103
        161.46520598             0.38295412850
         55.466352268            0.29090050668
    Cr    S
        107.54732999            -0.10932281100
         12.408671897            0.64472599471
          5.0423628826           0.46262712560
    Cr    S
          8.5461640165          -0.22711013286
          1.3900441221           0.73301527591
          0.56066602876          0.44225565433
    Cr    S
          0.71483705972E-01      1.0000000000
    Cr    S
          0.28250687604E-01      1.0000000000
    Cr    P
        640.48536096             0.96126715203E-02
        150.69711194             0.70889834655E-01
         47.503755296            0.27065258990
         16.934120165            0.52437343414
          6.2409680590           0.34107994714
    Cr    P
          3.0885463206           0.33973986903
          1.1791047769           0.57272062927
          0.43369774432          0.24582728206
    Cr    D
         27.559479426            0.30612488044E-01
          7.4687020327           0.15593270944
          2.4345903574           0.36984421276
          0.78244754808          0.47071118077
    Cr    D
          0.21995774311          0.33941649889
    END''')}


    ###     TPSCI CLUSTER INPUT
    init_fspace = ((1, 1),(3, 3),(3, 3),(3, 3), (1, 1), (1, 1))
    blocks = [range(0,4),range(4,10),range(10,16),range(16,22),range(22,26),range(26,30)]

    # Integrals from pyscf
    #Integrals from pyscf
    pmol = PyscfHelper()
    pmol.init(molecule,charge,spin,basis_set,orb_basis,
                    cas_nstart=cas_nstart,cas_nstop=cas_nstop,cas_nel=cas_nel,cas=True,
                    loc_nstart=loc_start,loc_nstop = loc_stop)

    h = pmol.h
    g = pmol.g
    ecore = pmol.ecore
    print("Ecore:%16.8f"%ecore)
    C = pmol.C
    K = pmol.K
    mol = pmol.mol
    mo_energy = pmol.mf.mo_energy
    dm_aa = pmol.dm_aa
    dm_bb = pmol.dm_bb

    do_fci = 0
    do_hci = 0
    do_tci = 1

    if do_fci:
        efci, fci_dim = run_fci_pyscf(h,g,nelec,ecore=ecore)
    if do_hci:
        ehci, hci_dim = run_hci_pyscf(h,g,nelec,ecore=ecore,select_cutoff=5e-4,ci_cutoff=5e-4)

    #cluster using hcore

    idx = ordering_diatomics_cr(mol,C)
    h,g = reorder_integrals(idx,h,g)
    C = C[:,idx]
    mo_energy = mo_energy[idx]
    dm_aa = dm_aa[:,idx]
    dm_aa = dm_aa[idx,:]
    dm_bb = dm_bb[:,idx]
    dm_bb = dm_bb[idx,:]

    print(dm_aa)


    from pyscf import molden
    molden.from_mo(pmol.mol, 'h8.molden', C)
    print(h)
    mol = pmol.mol
    if mol.symmetry == True:
        from pyscf import symm
        mo = symm.symmetrize_orb(mol, C)
        osym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo)
        #symm.addons.symmetrize_space(mol, mo, s=None, check=True, tol=1e-07)
        for i in range(len(osym)):
            print("%4d %8s %16.8f"%(i+1,osym[i],mo_energy[i]))




    clusters = []

    for ci,c in enumerate(blocks):
        clusters.append(Cluster(ci,c))

    print(" Clusters:")
    [print(ci) for ci in clusters]

    clustered_ham = ClusteredOperator(clusters, core_energy=ecore)
    print(" Add 1-body terms")
    clustered_ham.add_local_terms()
    clustered_ham.add_1b_terms(h)
    print(" Add 2-body terms")
    clustered_ham.add_2b_terms(g)

    # intial state
    ci_vector = ClusteredState(clusters)
    ci_vector.init(init_fspace)
    ci_vector.print()

    # do cmf
    do_cmf = 1
    if do_cmf:
        # Get CMF reference
        e_cmf, cmf_conv, rdm_a, rdm_b = cmf(clustered_ham, ci_vector, h, g, max_iter=10, dm_guess=(dm_aa, dm_bb), diis=True)

    print(" Final CMF Total Energy %12.8f" %(e_cmf + ecore))

    # build cluster basis and operator matrices using CMF optimized density matrices
    for ci_idx, ci in enumerate(clusters):
        print(ci)
        fspaces_i = init_fspace[ci_idx]
        delta_e = 2
        fspaces_i = ci.possible_fockspaces( delta_elec=(fspaces_i[0], fspaces_i[1], delta_e) )


        print()
        print(" Form basis by diagonalizing local Hamiltonian for cluster: ",ci_idx)

        ci.form_fockspace_eigbasis(h, g, fspaces_i, max_roots=100, rdm1_a=rdm_a, rdm1_b=rdm_b)


        print(" Build mats for cluster ",ci.idx)
        ci.build_op_matrices()
        ci.build_local_terms(h,g)


    hamiltonian_file = open('hamiltonian_file', 'wb')
    pickle.dump(clustered_ham, hamiltonian_file)

    print(" Done.")
Esempio n. 21
0
    def get_occ(self, mo_energy=None, mo_coeff=None, orbsym=None):
        if mo_energy is None: mo_energy = self.mo_energy
        mol = self.mol
        if not self.mol.symmetry:
            return rohf.ROHF.get_occ(self, mo_energy, mo_coeff)

        if mo_coeff is None or self._focka_ao is None:
            mo_ea = mo_eb = mo_energy
        else:
            mo_ea = numpy.einsum('ik,ik->k', mo_coeff,
                                 self._focka_ao.dot(mo_coeff))
            mo_eb = numpy.einsum('ik,ik->k', mo_coeff,
                                 self._fockb_ao.dot(mo_coeff))
        nmo = mo_ea.size
        mo_occ = numpy.zeros(nmo)
        if orbsym is None:
            if mo_coeff is not None:
                orbsym = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb,
                                             mo_coeff, self.get_ovlp(), False)
                orbsym = numpy.asarray(orbsym)
            else:
                orbsym = [
                    numpy.repeat(ir, mol.symm_orb[i].shape[1])
                    for i, ir in enumerate(mol.irrep_id)
                ]
                orbsym = numpy.hstack(orbsym)
        else:
            orbsym = numpy.asarray(orbsym)
        assert (mo_energy.size == orbsym.size)

        float_idx = []
        neleca_fix = 0
        nelecb_fix = 0
        for i, ir in enumerate(mol.irrep_id):
            irname = mol.irrep_name[i]
            ir_idx = numpy.where(orbsym == ir)[0]
            if irname in self.irrep_nelec:
                if isinstance(self.irrep_nelec[irname], (int, numpy.integer)):
                    nelecb = self.irrep_nelec[irname] // 2
                    neleca = self.irrep_nelec[irname] - nelecb
                else:
                    neleca, nelecb = self.irrep_nelec[irname]
                mo_occ[ir_idx] = rohf._fill_rohf_occ(mo_energy[ir_idx],
                                                     mo_ea[ir_idx],
                                                     mo_eb[ir_idx], nelecb,
                                                     neleca - nelecb)
                neleca_fix += neleca
                nelecb_fix += nelecb
            else:
                float_idx.append(ir_idx)

        nelec_float = mol.nelectron - neleca_fix - nelecb_fix
        assert (nelec_float >= 0)
        if len(float_idx) > 0:
            float_idx = numpy.hstack(float_idx)
            nopen = mol.spin - (neleca_fix - nelecb_fix)
            ncore = (nelec_float - nopen) // 2
            mo_occ[float_idx] = rohf._fill_rohf_occ(mo_energy[float_idx],
                                                    mo_ea[float_idx],
                                                    mo_eb[float_idx], ncore,
                                                    nopen)

        ncore = self.nelec[1]
        nocc = self.nelec[0]
        nopen = nocc - ncore
        vir_idx = (mo_occ == 0)
        if self.verbose >= logger.INFO and nocc < nmo and ncore > 0:
            ehomo = max(mo_energy[mo_occ > 0])
            elumo = min(mo_energy[mo_occ == 0])
            ndoccs = []
            nsoccs = []
            for i, ir in enumerate(mol.irrep_id):
                irname = mol.irrep_name[i]
                ir_idx = (orbsym == ir)

                ndoccs.append(numpy.count_nonzero(mo_occ[ir_idx] == 2))
                nsoccs.append(numpy.count_nonzero(mo_occ[ir_idx] == 1))
                if ehomo in mo_energy[ir_idx]:
                    irhomo = irname
                if elumo in mo_energy[ir_idx]:
                    irlumo = irname

            # to help self.eigh compute orbital energy
            self._irrep_doccs = ndoccs
            self._irrep_soccs = nsoccs

            logger.info(self, 'H**O (%s) = %.15g  LUMO (%s) = %.15g', irhomo,
                        ehomo, irlumo, elumo)

            logger.debug(self, 'double occ irrep_nelec = %s', ndoccs)
            logger.debug(self, 'single occ irrep_nelec = %s', nsoccs)
            #_dump_mo_energy(mol, mo_energy, mo_occ, ehomo, elumo, orbsym,
            #                verbose=self.verbose)
            if nopen > 0:
                core_idx = mo_occ == 2
                open_idx = mo_occ == 1
                vir_idx = mo_occ == 0
                logger.debug(
                    self,
                    '                  Roothaan           | alpha              | beta'
                )
                logger.debug(self,
                             '  Highest 2-occ = %18.15g | %18.15g | %18.15g',
                             max(mo_energy[core_idx]), max(mo_ea[core_idx]),
                             max(mo_eb[core_idx]))
                logger.debug(self,
                             '  Lowest 0-occ =  %18.15g | %18.15g | %18.15g',
                             min(mo_energy[vir_idx]), min(mo_ea[vir_idx]),
                             min(mo_eb[vir_idx]))
                for i in numpy.where(open_idx)[0]:
                    logger.debug(
                        self, '  1-occ =         %18.15g | %18.15g | %18.15g',
                        mo_energy[i], mo_ea[i], mo_eb[i])

            numpy.set_printoptions(threshold=nmo)
            logger.debug(self, '  Roothaan mo_energy =\n%s', mo_energy)
            logger.debug1(self, '  alpha mo_energy =\n%s', mo_ea)
            logger.debug1(self, '  beta  mo_energy =\n%s', mo_eb)
            numpy.set_printoptions(threshold=1000)
        return mo_occ
Esempio n. 22
0
def writeNevpt2Integrals(mc, dm1, dm2, dm1eff, aaavsplit, frozen):
    eris = _ERIS(mc, mc.mo_coeff)
    nocc = mc.ncore + mc.ncas
    ncore = mc.ncore
    nact = mc.ncas
    norbs = eris['ppaa'].shape[0]
    nvirt = norbs - ncore - nact
    eris_sp = {}
    #eris_sp['cvcv']= numpy.zeros(shape=(1,1)) #numpy.zeros(shape=(mc.ncore, norbs-mc.ncore-mc.ncas, mc.ncore, norbs-mc.ncas-mc.ncore))
    eris_sp['h1eff'] = 1. * eris['h1eff']  #numpy.zeros(shape=(norbs, norbs))
    int1 = reduce(numpy.dot, (mc.mo_coeff.T, mc.get_hcore(), mc.mo_coeff))
    #eris_sp['h1eff'] = makeheff(int1, eris['papa'], eris['ppaa'], dm1, ncore, nvirt)

    eris_sp['h1eff'][:mc.ncore, :mc.ncore] += numpy.einsum(
        'abcd,cd', eris['ppaa'][:mc.ncore, :mc.ncore, :, :], dm1eff)
    eris_sp['h1eff'][:mc.ncore, :mc.ncore] -= numpy.einsum(
        'abcd,bd', eris['papa'][:mc.ncore, :, :mc.ncore, :], dm1eff) * 0.5
    eris_sp['h1eff'][mc.ncas + mc.ncore:, mc.ncas + mc.ncore:] += numpy.einsum(
        'abcd,cd', eris['ppaa'][mc.ncas + mc.ncore:,
                                mc.ncas + mc.ncore:, :, :], dm1eff)
    eris_sp['h1eff'][mc.ncas + mc.ncore:, mc.ncas + mc.ncore:] -= numpy.einsum(
        'abcd,bd', eris['papa'][mc.ncas + mc.ncore:, :,
                                mc.ncas + mc.ncore:, :], dm1eff) * 0.5

    offdiagonal = 0.0
    #zero out off diagonal core
    for k in range(mc.ncore):
        for l in range(mc.ncore):
            if (k != l):
                offdiagonal = max(abs(offdiagonal), abs(eris_sp['h1eff'][k,
                                                                         l]))
    #zero out off diagonal virtuals
    for k in range(mc.ncore + mc.ncas, norbs):
        for l in range(mc.ncore + mc.ncas, norbs):
            if (k != l):
                offdiagonal = max(abs(offdiagonal), abs(eris_sp['h1eff'][k,
                                                                         l]))

    if (abs(offdiagonal) > 1e-6):
        print "WARNING ***** Have to use natorual orbitals from casscf ****"
        print "offdiagonal elements ", offdiagonal

    eriscvcv = eris['cvcv']
    if (not isinstance(eris['cvcv'], type(eris_sp['h1eff']))):
        #eriscvcv = h5py.File(eris['cvcv'].name,'r')["eri_mo"]
        eriscvcv = lib.chkfile.load(
            eris['cvcv'].name,
            "eri_mo")  #h5py.File(eris['cvcv'].name,'r')["eri_mo"]
    eris_sp['cvcv'] = eriscvcv.reshape(mc.ncore, norbs - mc.ncore - mc.ncas,
                                       mc.ncore, norbs - mc.ncore - mc.ncas)

    import os
    os.system("mkdir int")

    numpy.save(
        "int/W:caac",
        numpy.asfortranarray(eris['papa'][frozen:mc.ncore, :,
                                          frozen:mc.ncore, :].transpose(
                                              0, 3, 1, 2)))
    numpy.save(
        "int/W:aeca",
        numpy.asfortranarray(eris['papa'][frozen:mc.ncore, :,
                                          mc.ncore + mc.ncas:, :].transpose(
                                              1, 2, 0, 3)))
    numpy.save(
        "int/W:ccaa",
        numpy.asfortranarray(eris['papa'][frozen:mc.ncore, :,
                                          frozen:mc.ncore, :].transpose(
                                              0, 2, 1, 3)))
    numpy.save(
        "int/W:eeaa",
        numpy.asfortranarray(eris['papa'][mc.ncore + mc.ncas:, :,
                                          mc.ncore + mc.ncas:, :].transpose(
                                              0, 2, 1, 3)))
    numpy.save(
        "int/W:caca",
        numpy.asfortranarray(eris['ppaa'][frozen:mc.ncore,
                                          frozen:mc.ncore, :, :].transpose(
                                              0, 2, 1, 3)))
    numpy.save(
        "int/W:eaca",
        numpy.asfortranarray(eris['ppaa'][mc.ncore + mc.ncas:,
                                          frozen:mc.ncore, :, :].transpose(
                                              0, 2, 1, 3)))
    numpy.save(
        "int/W:eecc",
        numpy.asfortranarray(eris_sp['cvcv'][frozen:, :,
                                             frozen:, :].transpose(1, 3, 0,
                                                                   2)))
    numpy.save(
        "int/W:ccae",
        numpy.asfortranarray(eris['pacv'][frozen:mc.ncore, :,
                                          frozen:, :].transpose(0, 2, 1, 3)))

    numpy.save(
        "int/W:aaaa",
        numpy.asfortranarray(eris['ppaa'][mc.ncore:mc.ncore + mc.ncas,
                                          mc.ncore:mc.ncore +
                                          mc.ncas, :, :].transpose(0, 2, 1,
                                                                   3)))
    numpy.save(
        "int/W:eeca",
        numpy.asfortranarray(eris['pacv'][mc.ncore + mc.ncas:, :,
                                          frozen:, :].transpose(3, 0, 2, 1)))
    numpy.save("int/int1eff",
               numpy.asfortranarray(eris_sp['h1eff'][frozen:, frozen:]))
    numpy.save("int/E1.npy", numpy.asfortranarray(dm1))
    numpy.save("int/E2.npy", numpy.asfortranarray(dm2))
    #numpy.save("int/E3",dm3)
    #numpy.save("int/E3B.npy", dm3.transpose(0,3,1,4,2,5))
    #numpy.save("int/E3C.npy", dm3.transpose(5,0,2,4,1,3))

    nc = mc.ncore + mc.ncas
    energyE0 = 1.0 * numpy.einsum('ij,ij', eris_sp['h1eff'][ncore:nc,
                                                            ncore:nc], dm1)
    energyE0 += 0.5 * numpy.einsum(
        'ijkl,ijkl', eris['ppaa'][mc.ncore:mc.ncore + mc.ncas,
                                  mc.ncore:mc.ncore + mc.ncas, :, :].transpose(
                                      0, 2, 1, 3), dm2)
    mo = mc.mo_coeff
    dmcore = numpy.dot(mo[:, :ncore], mo[:, :ncore].T) * 2
    vj, vk = mc._scf.get_jk(mc.mol, dmcore)
    vhfcore = reduce(numpy.dot, (mo.T, vj - vk * 0.5, mo))
    energyE0 += numpy.einsum('ij,ji', dmcore, mc.get_hcore()) \
                  + numpy.einsum('ij,ji', dmcore, vj-0.5*vk) * .5
    energyE0 += mc.mol.energy_nuc()
    print "Energy = ", energyE0

    from pyscf import symm
    mol = mc.mol
    orbsymout = []
    orbsym = []
    if (mol.symmetry):
        orbsym = symm.label_orb_symm(mc.mol,
                                     mc.mol.irrep_id,
                                     mc.mol.symm_orb,
                                     mc.mo_coeff,
                                     s=mc._scf.get_ovlp())
    if mol.symmetry and orbsym:
        if mol.groupname.lower() == 'dooh':
            orbsymout = [dmrg_sym.IRREP_MAP['D2h'][i % 10] for i in orbsym]
        elif mol.groupname.lower() == 'coov':
            orbsymout = [dmrg_sym.IRREP_MAP['C2v'][i % 10] for i in orbsym]
        else:
            orbsymout = [dmrg_sym.IRREP_MAP[mol.groupname][i] for i in orbsym]
    else:
        orbsymout = []

    ncore = mc.ncore
    mo = mc.mo_coeff

    dmcore = numpy.dot(mo[:, :ncore], mo[:, :ncore].T) * 2
    vj, vk = mc._scf.get_jk(mc.mol, dmcore)
    vhfcore = reduce(numpy.dot, (mo.T, vj - vk * 0.5, mo))
    energy_core = numpy.einsum('ij,ji', dmcore, mc.get_hcore()) \
                  + numpy.einsum('ij,ji', dmcore, vj-0.5*vk) * .5
    print energy_core
    virtOrbs = range(ncore + mc.ncas, eris_sp['h1eff'].shape[0])
    chunks = len(virtOrbs) / aaavsplit
    virtRange = [
        virtOrbs[i:i + chunks] for i in xrange(0, len(virtOrbs), chunks)
    ]
    for K in range(aaavsplit):
        currentOrbs = range(ncore, mc.ncas + ncore) + virtRange[K]
        fout = open('FCIDUMP_aaav%d' % (K), 'w')
        #tools.fcidump.write_head(fout, eris_sp['h1eff'].shape[0]-ncore, mol.nelectron-2*ncore, orbsym= orbsymout[ncore:])

        tools.fcidump.write_head(
            fout,
            mc.ncas + len(virtRange[K]),
            mol.nelectron - 2 * ncore,
            orbsym=(orbsymout[ncore:ncore + mc.ncas] +
                    orbsymout[virtRange[K][0]:virtRange[K][-1] + 1]))
        ij = ncore * (ncore + 1) / 2
        for i in range(len(currentOrbs)):
            for j in range(ncore, mc.ncas + ncore):
                for k in range(mc.ncas):
                    for l in range(k + 1):
                        I = currentOrbs[i]
                        if abs(eris['ppaa'][I, j, k, l]) > 1.e-8:
                            fout.write(' %17.9e %4d %4d %4d %4d\n' \
                                           % (eris['ppaa'][I,j,k,l], i+1, j+1-ncore, k+1, l+1))

        h1eff = numpy.zeros(shape=(mc.ncas + len(virtRange[K]),
                                   mc.ncas + len(virtRange[K])))
        h1eff[:mc.ncas, :mc.ncas] = eris_sp['h1eff'][ncore:ncore + mc.ncas,
                                                     ncore:ncore + mc.ncas]
        h1eff[mc.ncas:,
              mc.ncas:] = eris_sp['h1eff'][virtRange[K][0]:virtRange[K][-1] +
                                           1,
                                           virtRange[K][0]:virtRange[K][-1] +
                                           1]
        h1eff[:mc.ncas,
              mc.ncas:] = eris_sp['h1eff'][ncore:ncore + mc.ncas,
                                           virtRange[K][0]:virtRange[K][-1] +
                                           1]
        h1eff[mc.ncas:, :mc.ncas] = eris_sp['h1eff'][
            virtRange[K][0]:virtRange[K][-1] + 1, ncore:ncore + mc.ncas]

        tools.fcidump.write_hcore(fout,
                                  h1eff,
                                  mc.ncas + len(virtRange[K]),
                                  tol=1e-8)
        #tools.fcidump.write_hcore(fout, eris_sp['h1eff'][virtRange[K][0]:virtRange[K][-1]+1, virtRange[K][0]:virtRange[K][-1]+1], len(virtRange[K]), tol=1e-8)
        fout.write(' %17.9e  0  0  0  0\n' %
                   (mol.energy_nuc() + energy_core - energyE0))
        fout.close()

    nc = ncore + mc.ncas
    fout = open('FCIDUMP_aaac', 'w')
    tools.fcidump.write_head(fout,
                             nc - frozen,
                             mol.nelectron - 2 * frozen,
                             orbsym=orbsymout[frozen:nc])
    for i in range(frozen, nc):
        for j in range(ncore, nc):
            for k in range(ncore, nc):
                for l in range(ncore, k + 1):
                    if abs(eris['ppaa'][i, j, k - ncore, l - ncore]) > 1.e-8:
                        fout.write(' %17.9e %4d %4d %4d %4d\n' \
                                   % (eris['ppaa'][i,j,k-ncore,l-ncore], i+1-frozen, j+1-frozen, k+1-frozen, l+1-frozen))

    dmrge = energyE0 - mol.energy_nuc() - energy_core

    ecore_aaac = 0.0
    for i in range(frozen, ncore):
        ecore_aaac += 2.0 * eris_sp['h1eff'][i, i]
    tools.fcidump.write_hcore(fout,
                              eris_sp['h1eff'][frozen:nc, frozen:nc],
                              nc - frozen,
                              tol=1e-8)
    fout.write(' %17.9e  0  0  0  0\n' % (-dmrge - ecore_aaac))
    fout.close()

    return norbs, energyE0
Esempio n. 23
0
    def hchain(n_sites, r=1.8, pg_reorder=True, **kwargs):
        """
        1D Hydrogen chain model. r in bohr.
        """
        if 'scratch' in kwargs:
            import os
            if not os.path.isdir(kwargs['scratch']):
                os.mkdir(kwargs['scratch'])
            os.environ['TMPDIR'] = kwargs['scratch']

        from pyscf import gto, scf, symm, ao2mo

        BOHR = 0.52917721092  # Angstroms
        r = r * BOHR
        mol = gto.M(atom=[['H', (i * r, 0, 0)] for i in range(n_sites)],
                    basis='sto6g',
                    verbose=0,
                    symmetry='d2h')
        pg = mol.symmetry.lower()

        # Reorder
        if pg == 'd2h':
            fcidump_sym = [
                "Ag", "B3u", "B2u", "B1g", "B1u", "B2g", "B3g", "Au"
            ]
            optimal_reorder = [
                "Ag", "B1u", "B3u", "B2g", "B2u", "B3g", "B1g", "Au"
            ]
        elif pg == 'c1':
            fcidump_sym = ["A"]
            optimal_reorder = ["A"]
        else:
            assert False

        # SCF
        m = scf.RHF(mol)
        m.kernel()
        mo_coeff = m.mo_coeff
        n_ao = mo_coeff.shape[0]
        n_mo = mo_coeff.shape[1]

        orb_sym_str = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb,
                                          mo_coeff)
        orb_sym = np.array([fcidump_sym.index(i) + 1 for i in orb_sym_str])

        # Sort the orbitals by symmetry for more efficient DMRG
        if pg_reorder:
            idx = np.argsort([optimal_reorder.index(i) for i in orb_sym_str])
            orb_sym = orb_sym[idx]
            mo_coeff = mo_coeff[:, idx]
            ridx = np.argsort(idx)
        else:
            ridx = np.array(list(range(n_mo)), dtype=int)

        h1e = mo_coeff.T @ m.get_hcore() @ mo_coeff
        g2e = ao2mo.restore(8, ao2mo.kernel(mol, mo_coeff), n_mo)
        ecore = mol.energy_nuc()
        del m, mol

        with HamilTools._init(**kwargs) as ():
            fcidump = FCIDUMP()
            n_elec = n_sites
            tol = 1E-13
            mh1e = np.zeros((n_sites * (n_sites + 1) // 2))
            k = 0
            for i in range(0, n_sites):
                for j in range(0, i + 1):
                    assert abs(h1e[i, j] - h1e[j, i]) < tol
                    mh1e[k] = h1e[i, j]
                    k += 1
            mg2e = g2e.flatten().copy()
            mh1e[np.abs(mh1e) < tol] = 0.0
            mg2e[np.abs(mg2e) < tol] = 0.0
            fcidump.initialize_su2(n_sites, n_elec, 0, 1, ecore, mh1e, mg2e)
            fcidump.orb_sym = VectorUInt8(orb_sym)
            with HamilTools._from_fcidump(fcidump, pg=pg) as hamil:
                yield hamil
mol = gto.M(atom='C 0 0 0; C 0 0 1.24253', basis='cc-pvdz', symmetry=1,
            symmetry_subgroup='D2h')

# run HF and store HF results in mf
mf = scf.RHF(mol).run()

# run MP2 and store MP2 results in mp2
mp2 = mp.MP2(mf).run()

rdm1 = numpy.diag(mf.mo_occ)  # The HF 1-particle density matrix in MO representation
rdm1 += mp2.make_rdm1()  # Add the correlation part

natocc, natorb = numpy.linalg.eigh(rdm1)
# Note natorb is in MO basis representation
natorb = numpy.dot(mf.mo_coeff, natorb)
try:
    natorb_sym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, natorb)
    print(natorb_sym)
except ValueError:
    print('The diagonalization for rdm1 breaks the symmetry of the degenerated natural orbitals.')

print('\nIn eigenvalue sovler symm.eigh, we diagonalize the density matrix with the MO symmetry '
      'information.  The eigenvectors are all symmetry adapted.')
orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, mf.mo_coeff)
natocc, natorb = symm.eigh(rdm1, orbsym)
natorb = numpy.dot(mf.mo_coeff, natorb)
natorb_sym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, natorb)
print(natorb_sym)

Esempio n. 25
0
def canonicalize(mc, mo_coeff=None, ci=None, eris=None, sort=False,
                 cas_natorb=False, casdm1=None, verbose=logger.NOTE):
    '''Canonicalized CASCI/CASSCF orbitals of effecitve Fock matrix.
    Effective Fock matrix is built with one-particle density matrix (see
    also :func:`mcscf.casci.get_fock`)

    Args:
        mc : a CASSCF/CASCI object or RHF object

    Returns:
        A tuple, (natural orbitals, CI coefficients, orbital energies)
        The orbital energies are the diagonal terms of general Fock matrix.
    '''
    from pyscf.lo import orth
    from pyscf.tools import dump_mat
    log = logger.new_logger(mc, verbose)

    if mo_coeff is None: mo_coeff = mc.mo_coeff
    if ci is None: ci = mc.ci
    if casdm1 is None:
        casdm1 = mc.fcisolver.make_rdm1(ci, mc.ncas, mc.nelecas)
    ncore = mc.ncore
    nocc = ncore + mc.ncas
    nmo = mo_coeff.shape[1]
    fock_ao = mc.get_fock(mo_coeff, ci, eris, casdm1, verbose)
    fock = reduce(numpy.dot, (mo_coeff.T, fock_ao, mo_coeff))
    mo_energy = fock.diagonal().copy()
    if cas_natorb:
        mo_coeff1, ci, occ = mc.cas_natorb(mo_coeff, ci, eris, sort, casdm1,
                                           verbose)
        ma = mo_coeff1[:,ncore:nocc]
        mo_energy[ncore:nocc] = numpy.einsum('ji,ji->i', ma, fock_ao.dot(ma))
    else:
# Keep the active space unchanged by default.  The rotation in active space
# may cause problem for external CI solver eg DMRG.
        mo_coeff1 = numpy.empty_like(mo_coeff)
        mo_coeff1[:,ncore:nocc] = mo_coeff[:,ncore:nocc]
    if ncore > 0:
        # note the last two args of ._eig for mc1step_symm
        # mc._eig function is called to handle symmetry adapated fock
        w, c1 = mc._eig(fock[:ncore,:ncore], 0, ncore)
        if sort:
            idx = numpy.argsort(w.round(9), kind='mergesort')
            w = w[idx]
            c1 = c1[:,idx]
        mo_coeff1[:,:ncore] = numpy.dot(mo_coeff[:,:ncore], c1)
        mo_energy[:ncore] = w
    if nmo-nocc > 0:
        w, c1 = mc._eig(fock[nocc:,nocc:], nocc, nmo)
        if sort:
            idx = numpy.argsort(w.round(9), kind='mergesort')
            w = w[idx]
            c1 = c1[:,idx]
        mo_coeff1[:,nocc:] = numpy.dot(mo_coeff[:,nocc:], c1)
        mo_energy[nocc:] = w

    if hasattr(mo_coeff, 'orbsym'):
        if sort:
            orbsym = symm.label_orb_symm(mc.mol, mc.mol.irrep_id,
                                         mc.mol.symm_orb, mo_coeff1)
        else:
            orbsym = mo_coeff.orbsym
        mo_coeff1 = lib.tag_array(mo_coeff1, orbsym=orbsym)

    if log.verbose >= logger.DEBUG:
        for i in range(nmo):
            log.debug('i = %d  <i|F|i> = %12.8f', i+1, mo_energy[i])
# still return ci coefficients, in case the canonicalization funciton changed
# cas orbitals, the ci coefficients should also be updated.
    return mo_coeff1, ci, mo_energy
Esempio n. 26
0
def get_mo_from_h5(mol, h5fname, symmetry=None):
    ''' Get MO vectors for a pyscf molecule from an h5 file written by OpenMolcas

        Args:
            mol : instance gto.mole
                Must be in the same point group as the OpenMolcas calculation,
                or set the symmetry argument
            h5fname : str
                Path to an h5 file generated by OpenMolcas containing (at
                least) groups 'BASIS_FUNCTION_IDS', 'MO_OCCUPATIONS',
                'MO_VECTORS', and 'MO_ENERGIES' and additionally 'DESYM_MATRIX'
                and 'DESYM_BASIS_FUNCTION_IDS' if symmetry is used.

        Kwargs:
            symmetry : str
                Point group of the calculation in OpenMolcas. If not provided,
                mol.groupname is used instead

        Returns:
            mo_coeff : ndarray of shape (nao_nr, nao_nr)
    '''

    if symmetry is not None:
        mol = mol.copy()
        mol.build(symmetry=symmetry)
    nao = mol.nao_nr()

    with h5py.File(h5fname, 'r') as f:
        try:
            molcas_basids = f['DESYM_BASIS_FUNCTION_IDS'][()]
            molcas_usymm = f['DESYM_MATRIX'][()].reshape(nao, nao)
        except KeyError:
            assert (not mol.symmetry
                    ), "Can't find desym_ data; mol.symmetry = {}".format(
                        mol.symmetry)
            molcas_basids = f['BASIS_FUNCTION_IDS'][()]
        molcas_coeff = f['MO_VECTORS'][()]
        mo_energy = f['MO_ENERGIES'][()]
        mo_occ = f['MO_OCCUPATIONS'][()]

    idx_ao = []
    for (c, n, l, m) in molcas_basids:
        # 0-index atom list in PySCF, 1-index atom list in Molcas
        c -= 1
        # Actual principal quantum number in PySCF, 1-indexed list in Molcas
        n += l
        # l=1, ml=(-1,0,1) is (x,y,z) in PySCF, (y,z,x) in Molcas
        if l == 1:
            m = m - 2 if m > 0 else m + 1
        idx_ao.append(mol.search_ao_nr(c, l, m, n))
    idx_ao = np.argsort(np.asarray(idx_ao))

    if mol.symmetry:
        # I have to figure out what order the Molcas irreps are in on the fly
        # because it seems to change depending on the xyz
        molcas_usymm = molcas_usymm[:, idx_ao]
        proj = np.stack([(np.dot(molcas_usymm, ir_coeff)**2).sum(1)
                         for ir_coeff in mol.symm_orb],
                        axis=0)
        errstr = ("Can't interpret h5 symmetry information; wrong mol? "
                  " <mol.symm_orb|desym_matrix> =\n{}").format(proj)
        assert (np.allclose(np.amax(proj), 1)), errstr
        ix_irrep = np.argmax(proj, axis=0)
        uniq_idx = np.sort(np.unique(ix_irrep, return_index=True)[1])
        uniq_idx = np.append(uniq_idx, len(ix_irrep))
        nmo_irrep = []
        for ix, i in enumerate(uniq_idx[:-1]):
            j = uniq_idx[ix + 1]
            assert (len(np.unique(ix_irrep[i:j])) == 1), errstr
            nmo_irrep.append(j - i)
        nmo_irrep = np.asarray(nmo_irrep)
        usymm_irrep_offset = np.cumsum(nmo_irrep) - nmo_irrep
        coeff_irrep_offset = np.cumsum(nmo_irrep**2) - nmo_irrep**2
        mo_coeff = np.zeros((nao, nao), dtype=np.float_)
        for m_ir, usymm_off, coeff_off in zip(nmo_irrep, usymm_irrep_offset,
                                              coeff_irrep_offset):
            i, j = usymm_off, usymm_off + m_ir
            u, v = coeff_off, coeff_off + (m_ir**2)
            usymm = molcas_usymm[i:j, :].T
            coeff = molcas_coeff[u:v].reshape(m_ir, m_ir).T
            mo_coeff[:, i:j] = np.dot(usymm, coeff)
    else:
        assert (molcas_coeff.shape == (
            nao**2, )), 'mo_vectors.shape = {} but {} AOs'.format(
                molcas_coeff.shape, nao)
        mo_coeff = molcas_coeff.reshape(nao, nao)[:, idx_ao].T

    # 'mergesort' keeps degenerate or active-space orbitals in the provided order!
    #  idx_ene = np.argsort (mo_energy, kind='mergesort')

    # modified by Dayou: sort by mo_occ first, then mo_energy
    sort_key = np.min(mo_energy) * 100000 * mo_occ + mo_energy
    idx_ene = np.argsort(sort_key, kind='mergesort')
    mo_coeff = mo_coeff[:, idx_ene]
    mo_occ = mo_occ[idx_ene]
    mo_energy = mo_energy[idx_ene]

    if mol.verbose > logger.INFO:
        fname = str(mol.output)[:-4] + "_h5debug.molden"
        molden.from_mo(mol, fname, mo_coeff, occ=mo_occ, ene=mo_energy)
    if mol.symmetry:  # assert (symmetry is right)
        try:
            orbsym = label_orb_symm(mol, mol.irrep_name, mol.symm_orb,
                                    mo_coeff)
        except ValueError as e:
            raise ValueError(("Problem understanding Molcas symmetry?\n"
                              "{}").format(str(e)))

    return mo_coeff
Esempio n. 27
0
    mf.verbose = 3
    mf.scf()

    #############################
    #   Build the Hamiltonian   #
    #############################
    L = mf.mol.nao_nr()
    N = mf.mol.nelectron
    CONST = mf.mol.energy_nuc()
    OEImo = np.dot(
        np.dot(mf.mo_coeff.T,
               mf.mol.intor('cint1e_kin_sph') +
               mf.mol.intor('cint1e_nuc_sph')), mf.mo_coeff)
    TEImo = ao2mo.outcore.full_iofree(mf.mol, mf.mo_coeff,
                                      compact=False).reshape(L, L, L, L)
    orb2irrep = np.array(symm.label_orb_symm(mf.mol, mf.mol.irrep_id,
                                             mf.mol.symm_orb, mf.mo_coeff),
                         dtype=ctypes.c_int)
    for cnt in range(len(orb2irrep)):
        orb2irrep[cnt] = orb2irrep[cnt] % 10

    #######################################
    #   PySCF FCI calculation and 4-RDM   #
    #######################################
    fci_solver = fci.FCI(mol, mf.mo_coeff)
    fci_energy, fci_vector = fci_solver.kernel()
    print "PySCF     FCI energy =", fci_energy + CONST
    pyscf_start = time.time()
    dm1, dm2, dm3, dm4 = fci.rdm.make_dm1234('FCI4pdm_kern_spin0', fci_vector,
                                             fci_vector, L, N)
    dm1, dm2, dm3, dm4 = fci.rdm.reorder_dm1234(dm1,
                                                dm2,
Esempio n. 28
0
def label_symmetry_(mc, mo_coeff, ci0=None):
    log = logger.Logger(mc.stdout, mc.verbose)
    #irrep_name = mc.mol.irrep_name
    irrep_name = mc.mol.irrep_id
    s = mc._scf.get_ovlp()
    try:
        orbsym = scf.hf_symm.get_orbsym(mc._scf.mol, mo_coeff, s, True)
    except ValueError:
        log.warn('mc1step_symm symmetrizes input orbitals')
        ncore = mc.ncore
        nocc = mc.ncore + mc.ncas
        mo_cor = symm.symmetrize_space(mc.mol, mo_coeff[:,    :ncore], s=s, check=False)
        mo_act = symm.symmetrize_space(mc.mol, mo_coeff[:,ncore:nocc], s=s, check=False)
        mo_vir = symm.symmetrize_space(mc.mol, mo_coeff[:,nocc:     ], s=s, check=False)
        mo_coeff = numpy.hstack((mo_cor,mo_act,mo_vir))
        orbsym = symm.label_orb_symm(mc.mol, irrep_name,
                                     mc.mol.symm_orb, mo_coeff, s=s)
    mo_coeff_with_orbsym = lib.tag_array(mo_coeff, orbsym=orbsym)

    active_orbsym = getattr(mc.fcisolver, 'orbsym', [])
    if (not hasattr(active_orbsym, '__len__')) or len(active_orbsym) == 0:
        ncore = mc.ncore
        nocc = mc.ncore + mc.ncas
        mc.fcisolver.orbsym = orbsym[ncore:nocc]
    log.debug('Active space irreps %s', str(mc.fcisolver.orbsym))

    wfnsym = 0
    if getattr(mc.fcisolver, 'wfnsym', None) is not None:
        wfnsym = mc.fcisolver.wfnsym

    elif ci0 is None:
        # Guess wfnsym based on HF determinant.  mo_coeff may not be HF
        # canonical orbitals.  Some checks are needed to ensure that mo_coeff
        # are derived from the symmetry adapted SCF calculations.
        if mo_coeff is mc._scf.mo_coeff:
            wfnsym = 0
            for ir in orbsym[mc._scf.mo_occ == 1]:
                wfnsym ^= ir
            mc.fcisolver.wfnsym = wfnsym
            log.debug('Set CASCI wfnsym %s based on HF determinant', wfnsym)
        elif hasattr(mo_coeff, 'orbsym'):  # It may be reordered SCF orbitals
            ncore = mc.ncore
            nocc = mc.ncore + mc.ncas
            cas_orb = mo_coeff[:,ncore:nocc]
            s = reduce(numpy.dot, (cas_orb.T, mc._scf.get_ovlp(), mc._scf.mo_coeff))
            if numpy.all(numpy.max(s, axis=1) > 1-1e-9):
                idx = numpy.argmax(s, axis=1)
                cas_orbsym = orbsym[ncore:nocc]
                cas_occ = mc._scf.mo_occ[idx]
                wfnsym = 0
                for ir in cas_orbsym[cas_occ == 1]:
                    wfnsym ^= ir
                mc.fcisolver.wfnsym = wfnsym
                log.debug('Active space are constructed from canonical SCF '
                          'orbitals %s', idx)
                log.debug('Set CASCI wfnsym %s based on HF determinant', wfnsym)

    elif hasattr(mc.fcisolver, 'guess_wfnsym'):
        wfnsym = mc.fcisolver.guess_wfnsym(mc.ncas, mc.nelecas, ci0, verbose=log)
        log.debug('CASCI wfnsym %s (based on CI initial guess)', wfnsym)

    if isinstance(wfnsym, (int, numpy.integer)):
        wfnsym = symm.irrep_id2name(mc.mol.groupname, wfnsym)

    log.info('Active space CI wfn symmetry = %s', wfnsym)

    return mo_coeff_with_orbsym
Esempio n. 29
0
        'B3': 2
    },
    'Cs': {
        "A'": 1,
        'A"': 2
    },
    'C2': {
        'A': 1,
        'B': 2
    },
    'Ci': {
        'Ag': 1,
        'Au': 2
    },
    'C1': {
        'A': 1,
    }
}

orbsym = [
    MOLPRO_ID[mol.groupname][i]
    for i in symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, c)
]
tools.fcidump.from_integrals('fcidump.example3',
                             h1e,
                             eri,
                             c.shape[1],
                             mol.nelectron,
                             ms=0,
                             orbsym=orbsym)
Esempio n. 30
0
 )
 fspt.write('La matriz D es:\n')
 for i in range(nmo):
     for j in range(nmo):
         fspt.write('%i %i %.16f\n' % ((i + 1), (j + 1), rdm1[i, j]))
 fspt.write('La matriz d es:\n')
 for i in range(nmo):
     for j in range(nmo):
         for k in range(nmo):
             for l in range(nmo):
                 if (abs(rdm2[i, j, k, l]) > 1e-12):
                     fspt.write('%i %i %i %i %.16f\n' %
                                ((i + 1), (j + 1), (k + 1),
                                 (l + 1), rdm2[i, j, k, l]))
 fspt.close()
 orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb,
                              mc.mo_coeff[:, :nmo])
 natocc, natorb = symm.eigh(-rdm1, orbsym)
 for i, k in enumerate(numpy.argmax(abs(natorb), axis=0)):
     if natorb[k, i] < 0:
         natorb[:, i] *= -1
 natorb = numpy.dot(mc.mo_coeff[:, :nmo], natorb)
 natocc = -natocc
 with open('n2_cas.det', 'w') as f3:
     write_ci(f3, mc.ci, mc.ncas, mc.nelecas, mc.ncore)
 with open('n2_ref_nat.mol', 'w') as f2:
     molden.header(mol, f2)
     molden.orbital_coeff(mol, f2, natorb, occ=natocc)
 with open('n2_ref.mol', 'w') as f2:
     molden.header(mol, f2)
     molden.orbital_coeff(mol,
                          f2,
Esempio n. 31
0
    def __init__(self, mol_or_hdf5, c=None, network=None, verbose=None):
        '''Initializing the T3NS calculation.

        Args:
            mol_or_hdf5: An instance of :class:`Mole` from PySCF
            or a string to a path of the hdf5 file. In this case c and network
            should be left as defaults.

            c: The orbital coefficients.
            The default are the RHF orbitals.

            network: Network of the tensor network.
            This can be the string 'DMRG' for a linear chain or 'T3NS' for a
            T3NS that is radially extended (i.e. the maximal distance between
            two sites is minimal). An instance of :class:`Network` is also
            accepted for custom networks or a path to a network file.
            Default is 'T3NS' if Mole instance was passed, else None.
        '''
        from pyscf import symm
        if isinstance(mol_or_hdf5, pyscf.gto.Mole):
            # Initialize with RHF
            mol = mol_or_hdf5
            if network is None:
                network = 'T3NS'

            if verbose is None:
                self.verbose = mol.verbose

            self.mol = mol

            # if no orbital coefficients are given, use RHF orbitals
            if c is None:
                myhf = pyscf.scf.RHF(mol)
                myhf.verbose = self.verbose
                myhf.kernel()
                c = myhf.mo_coeff

            self._c = c
            self._mol = mol
            self._eri = pyscf.ao2mo.kernel(mol, c)
            self.symmetries = ['Z2', 'U1', 'SU2']
            self.target = [int(mol.nelectron % 2), mol.nelectron, mol.spin]

            try:
                irrep_ids = symm.label_orb_symm(mol, mol.irrep_id,
                                                mol.symm_orb, c)
                newsym = mol.groupname
                if mol.groupname == 'Dooh' or mol.groupname == 'Coov':
                    newsym = 'D2h' if mol.groupname else 'C2v'
                    if self.verbose > 1:
                        print(f'Changed point group from {mol.groupname} to '
                              f'{newsym}')

                # mod 10 needed for translation Coov and Dooh
                # See https://sunqm.github.io/pyscf/symm.html
                self._pg_irrep = [
                    symm.irrep_id2name(newsym, int(ii % 10))
                    for ii in irrep_ids
                ]
                self.symmetries.append(newsym)
                self.target.append(symm.irrep_id2name(newsym, 0))
            except (ValueError, TypeError):
                self._pg_irrep = None

            if isinstance(network, netw.Network):
                self._netw = network
            elif network == 'DMRG' or network == 'T3NS':
                isDMRG = network == 'DMRG'
                self._netw = netw.Network(c.shape[1], isDMRG=isDMRG)

                # exchange matrix
                # Kij = numpy.zeros((c.shape[1],) * 2)
                # trids = numpy.tril_indices(c.shape[1], 0)
                # for el, r, c in zip(self._eri.diagonal(), trids[0], trids[1]):
                #     Kij[r, c] = el
                #     Kij[c, r] = el
                # cost = self._netw.optimize(Kij)
                # if self.verbose >= 2:
                #     print(f'Optimization Exchange-cost: {cost}')
            elif isinstance(network, str):
                self._netw = netw.Network()
                self._netw.readnetworkfile(network)
            else:
                raise ValueError(f'{network} is invalid for network')
            self._netw.pass_network()

        elif isinstance(mol_or_hdf5, str):
            # h5path = mol_or_hdf5
            if verbose is None:
                self.verbose = 1

            if c is not None or network is not None:
                raise ValueError(
                    'A hdf5 file does not expect a defined c or network')
            raise ValueError('Need to implement hdf5 readin still')
        else:
            raise ValueError(
                'Expects a Mole instance or a path to a hdf5 file')
Esempio n. 32
0
    def analyze(self, verbose=logger.DEBUG, **kwargs):
        from pyscf.lo import orth
        from pyscf.tools import dump_mat
        if not self.mol.symmetry:
            return rohf.ROHF.analyze(self, verbose, **kwargs)

        mo_energy = self.mo_energy
        mo_occ = self.mo_occ
        mo_coeff = self.mo_coeff
        log = logger.Logger(self.stdout, verbose)
        mol = self.mol
        nirrep = len(mol.irrep_id)
        ovlp_ao = self.get_ovlp()
        orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, mo_coeff,
                                     ovlp_ao, False)
        orbsym = numpy.array(orbsym)
        wfnsym = 0
        ndoccs = []
        nsoccs = []
        for k, ir in enumerate(mol.irrep_id):
            ndoccs.append(sum(orbsym[mo_occ == 2] == ir))
            nsoccs.append(sum(orbsym[mo_occ == 1] == ir))
            if nsoccs[k] % 2:
                wfnsym ^= ir
        if mol.groupname in ('Dooh', 'Coov'):
            log.info('TODO: total symmetry for %s', mol.groupname)
        else:
            log.info('total symmetry = %s',
                     symm.irrep_id2name(mol.groupname, wfnsym))
        log.info('occupancy for each irrep:  ' + (' %4s' * nirrep),
                 *mol.irrep_name)
        log.info('double occ                 ' + (' %4d' * nirrep), *ndoccs)
        log.info('single occ                 ' + (' %4d' * nirrep), *nsoccs)
        log.info('**** MO energy ****')
        irname_full = {}
        for k, ir in enumerate(mol.irrep_id):
            irname_full[ir] = mol.irrep_name[k]
        irorbcnt = {}
        if self._focka_ao is None:
            for k, j in enumerate(orbsym):
                if j in irorbcnt:
                    irorbcnt[j] += 1
                else:
                    irorbcnt[j] = 1
                log.note('MO #%-3d (%s #%-2d), energy= %-18.15g occ= %g',
                         k + 1, irname_full[j], irorbcnt[j], mo_energy[k],
                         mo_occ[k])
        else:
            mo_ea = numpy.einsum('ik,ik->k', mo_coeff,
                                 self._focka_ao.dot(mo_coeff))
            mo_eb = numpy.einsum('ik,ik->k', mo_coeff,
                                 self._fockb_ao.dot(mo_coeff))
            log.note(
                '                          Roothaan           | alpha              | beta'
            )
            for k, j in enumerate(orbsym):
                if j in irorbcnt:
                    irorbcnt[j] += 1
                else:
                    irorbcnt[j] = 1
                log.note(
                    'MO #%-4d(%-3s #%-2d) energy= %-18.15g | %-18.15g | %-18.15g occ= %g',
                    k + 1, irname_full[j], irorbcnt[j], mo_energy[k], mo_ea[k],
                    mo_eb[k], mo_occ[k])

        if verbose >= logger.DEBUG:
            label = mol.spheric_labels(True)
            molabel = []
            irorbcnt = {}
            for k, j in enumerate(orbsym):
                if j in irorbcnt:
                    irorbcnt[j] += 1
                else:
                    irorbcnt[j] = 1
                molabel.append('#%-d(%s #%d)' %
                               (k + 1, irname_full[j], irorbcnt[j]))
            log.debug(' ** MO coefficients (expansion on meta-Lowdin AOs) **')
            orth_coeff = orth.orth_ao(mol, 'meta_lowdin', s=ovlp_ao)
            c = reduce(numpy.dot, (orth_coeff.T, ovlp_ao, mo_coeff))
            dump_mat.dump_rec(self.stdout,
                              c,
                              label,
                              molabel,
                              start=1,
                              **kwargs)

        dm = self.make_rdm1(mo_coeff, mo_occ)
        return self.mulliken_meta(mol, dm, s=ovlp_ao, verbose=verbose)
Esempio n. 33
0
def run(b, dm_guess, mo_guess, ci=None):
    mol = gto.Mole()
    mol.verbose = 5
    mol.output = 'cr2-%3.2f.out' % b
    mol.atom = [
        ['Cr', (0., 0., -b / 2)],
        ['Cr', (0., 0., b / 2)],
    ]
    mol.basis = 'ccpvdzdk'
    mol.symmetry = True
    mol.build()

    mf = scf.RHF(mol).x2c()
    mf.max_cycle = 100
    mf.conv_tol = 1e-9
    mf.kernel(dm_guess)

    #---------------------
    # CAS(12,12)
    #
    # The active space of CAS(12,42) can be generated by function sort_mo_by_irrep,
    # or AVAS, dmet_cas methods.  Here we first run a CAS(12,12) calculation and
    # using the lowest CASSCF canonicalized orbitals in the CAS(12,42) calculation
    # as the core and valence orbitals.
    mc = mcscf.CASSCF(mf, 12, 12)
    if mo_guess is None:
        # the initial guess for first calculation
        ncas = {
            'A1g': 2,
            'E1gx': 1,
            'E1gy': 1,
            'E2gx': 1,
            'E2gy': 1,
            'A1u': 2,
            'E1ux': 1,
            'E1uy': 1,
            'E2ux': 1,
            'E2uy': 1
        }
        mo_guess = mcscf.sort_mo_by_irrep(mc, mf.mo_coeff, ncas, ncore)
    else:
        mo_guess = mcscf.project_init_guess(mc, mo_guess)

        # Projection may destroy the spatial symmetry of the MCSCF orbitals.
        try:
            print(
                'Irreps of the projected CAS(12,12) orbitals',
                symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, mo_guess))
        except:
            print('Projected CAS(12,12) orbitals does not have right symmetry')


# FCI solver with multi-threads is not stable enough for this sytem
    mc.fcisolver.threads = 1
    # To avoid spin contamination
    mc.fix_spin_()
    # By default, canonicalization as well as the CASSCF optimization do not
    # change the orbital symmetry labels. "Orbital energy" mc.mo_energy, the
    # diagonal elements of the general fock matrix, may have wrong ordering.
    # To use the lowest CASSCF orbitals as the core + active orbitals in the next
    # step, we have to sort the orbitals based on the "orbital energy". This
    # operation will change the orbital symmetry labels.
    mc.sorting_mo_energy = True
    # "mc.natorb = True" will transform the active space, to its natural orbital
    # representation.  By default, the active space orbitals are NOT reordered
    # even the option sorting_mo_energy is enabled.  Transforming the active space
    # orbitals is a dangerous operation because it needs also to update the CI
    # wavefunction. For DMRG solver (or other approximate FCI solver), the CI
    # wavefunction may not be able to consistently converged and it leads to
    # inconsistency between the orbital space and the CI wavefunction
    # representations.  Unless required by the following CAS calculation, setting
    # mc.natorb=True should be avoided
    #    mc.natorb = True

    mc.kernel(mo_guess, ci)
    mc.analyze()

    #---------------------
    # CAS(12,42)
    #
    # Using the lowest CASSCF canonicalized orbitals in the CAS(12,42) DMRG-CASSCF
    # calculation.
    norb = 42
    nelec = 12
    mc1 = DMRGSCF(mf, norb, nelec)
    mc1.fcisolver.maxM = 4000

    # Enable internal rotation since the bond dimension of DMRG calculation is
    # small, the active space energy can be optimized wrt to the orbital rotation
    # within the active space.
    mc1.internal_rotation = True
    # Sorting the orbital energy is not a step of must here.
    #    mc1.sorting_mo_energy = True
    #    mc1.natorb = True

    mc1.kernel()

    # Passing the results as an initial guess to the next point.
    return mf.make_rdm1(), mc.mo_coeff, mc.ci
Esempio n. 34
0
    def init(self,
             molecule,
             charge,
             spin,
             basis_set,
             orb_basis='scf',
             cas=False,
             cas_nstart=None,
             cas_nstop=None,
             cas_nel=None,
             loc_nstart=None,
             loc_nstop=None,
             scf_conv_tol=1e-14):
        # {{{
        import pyscf
        from pyscf import gto, scf, ao2mo, molden, lo
        pyscf.lib.num_threads(
            1
        )  #with degenerate states and multiple processors there can be issues
        #PYSCF inputs
        print(" ---------------------------------------------------------")
        print("                      Using Pyscf:")
        print(" ---------------------------------------------------------")
        print("                                                          ")

        mol = gto.Mole()
        mol.atom = molecule

        mol.max_memory = 1000  # MB
        mol.symmetry = True
        mol.charge = charge
        mol.spin = spin
        mol.basis = basis_set
        mol.build()
        print("symmertry")
        print(mol.topgroup)

        #SCF

        #mf = scf.RHF(mol).run(init_guess='atom')
        mf = scf.RHF(mol).run(conv_tol=scf_conv_tol)
        #C = mf.mo_coeff #MO coeffs
        enu = mf.energy_nuc()

        print(" SCF Total energy: %12.8f" % mf.e_tot)
        print(" SCF Elec  energy: %12.8f" % (mf.e_tot - enu))
        print(mf.get_fock())
        print(np.linalg.eig(mf.get_fock())[0])

        if mol.symmetry == True:
            from pyscf import symm
            mo = symm.symmetrize_orb(mol, mf.mo_coeff)
            osym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo)
            #symm.addons.symmetrize_space(mol, mo, s=None, check=True, tol=1e-07)
            for i in range(len(osym)):
                print("%4d %8s %16.8f" % (i + 1, osym[i], mf.mo_energy[i]))

        #orbitals and lectrons
        n_orb = mol.nao_nr()
        n_b, n_a = mol.nelec
        nel = n_a + n_b
        self.n_orb = mol.nao_nr()

        if cas == True:
            cas_norb = cas_nstop - cas_nstart
            from pyscf import mcscf
            assert (cas_nstart != None)
            assert (cas_nstop != None)
            assert (cas_nel != None)
        else:
            cas_nstart = 0
            cas_nstop = n_orb
            cas_nel = nel

        ##AO 2 MO Transformation: orb_basis or scf
        if orb_basis == 'scf':
            print("\nUsing Canonical Hartree Fock orbitals...\n")
            C = cp.deepcopy(mf.mo_coeff)
            print("C shape")
            print(C.shape)

        elif orb_basis == 'lowdin':
            assert (cas == False)
            S = mol.intor('int1e_ovlp_sph')
            print("Using lowdin orthogonalized orbitals")

            C = lowdin(S)
            #end

        elif orb_basis == 'boys':
            pyscf.lib.num_threads(
                1
            )  #with degenerate states and multiple processors there can be issues
            cl_c = mf.mo_coeff[:, :cas_nstart]
            cl_a = lo.Boys(mol,
                           mf.mo_coeff[:,
                                       cas_nstart:cas_nstop]).kernel(verbose=4)
            cl_v = mf.mo_coeff[:, cas_nstop:]
            C = np.column_stack((cl_c, cl_a, cl_v))

        elif orb_basis == 'boys2':
            pyscf.lib.num_threads(
                1
            )  #with degenerate states and multiple processors there can be issues
            cl_c = mf.mo_coeff[:, :loc_nstart]
            cl_a = lo.Boys(mol,
                           mf.mo_coeff[:,
                                       loc_nstart:loc_nstop]).kernel(verbose=4)
            cl_v = mf.mo_coeff[:, loc_nstop:]
            C = np.column_stack((cl_c, cl_a, cl_v))

        elif orb_basis == 'PM':
            pyscf.lib.num_threads(
                1
            )  #with degenerate states and multiple processors there can be issues
            cl_c = mf.mo_coeff[:, :cas_nstart]
            cl_a = lo.PM(mol,
                         mf.mo_coeff[:,
                                     cas_nstart:cas_nstop]).kernel(verbose=4)
            cl_v = mf.mo_coeff[:, cas_nstop:]
            C = np.column_stack((cl_c, cl_a, cl_v))

        elif orb_basis == 'PM2':
            pyscf.lib.num_threads(
                1
            )  #with degenerate states and multiple processors there can be issues
            cl_c = mf.mo_coeff[:, :loc_nstart]
            cl_a = lo.PM(mol,
                         mf.mo_coeff[:,
                                     loc_nstart:loc_nstop]).kernel(verbose=4)
            cl_v = mf.mo_coeff[:, loc_nstop:]
            C = np.column_stack((cl_c, cl_a, cl_v))

        elif orb_basis == 'ER':
            pyscf.lib.num_threads(
                1
            )  #with degenerate states and multiple processors there can be issues
            cl_c = mf.mo_coeff[:, :cas_nstart]
            cl_a = lo.PM(mol,
                         mf.mo_coeff[:,
                                     cas_nstart:cas_nstop]).kernel(verbose=4)
            cl_v = mf.mo_coeff[:, cas_nstop:]
            C = np.column_stack((cl_c, cl_a, cl_v))

        elif orb_basis == 'ER2':
            pyscf.lib.num_threads(
                1
            )  #with degenerate states and multiple processors there can be issues
            cl_c = mf.mo_coeff[:, :loc_nstart]
            cl_a = lo.ER(mol,
                         mf.mo_coeff[:,
                                     loc_nstart:loc_nstop]).kernel(verbose=4)
            cl_v = mf.mo_coeff[:, loc_nstop:]
            C = np.column_stack((cl_c, cl_a, cl_v))

        elif orb_basis == 'ibmo':
            loc_vstop = loc_nstop - n_a
            print(loc_vstop)

            mo_occ = mf.mo_coeff[:, mf.mo_occ > 0]
            mo_vir = mf.mo_coeff[:, mf.mo_occ == 0]
            c_core = mo_occ[:, :loc_nstart]
            iao_occ = lo.iao.iao(mol, mo_occ[:, loc_nstart:])
            iao_vir = lo.iao.iao(mol, mo_vir[:, :loc_vstop])
            c_out = mo_vir[:, loc_vstop:]

            # Orthogonalize IAO
            iao_occ = lo.vec_lowdin(iao_occ, mf.get_ovlp())
            iao_vir = lo.vec_lowdin(iao_vir, mf.get_ovlp())

            #
            # Method 1, using Knizia's alogrithm to localize IAO orbitals
            #
            '''
            Generate IBOS from orthogonal IAOs
            '''
            ibo_occ = lo.ibo.ibo(mol, mo_occ[:, loc_nstart:], iaos=iao_occ)
            ibo_vir = lo.ibo.ibo(mol, mo_vir[:, :loc_vstop], iaos=iao_vir)

            C = np.column_stack((c_core, ibo_occ, ibo_vir, c_out))

        else:
            print("Error:NO orbital basis defined")

        molden.from_mo(mol, 'orbitals.molden', C)

        if cas == True:
            print(C.shape)
            print(cas_norb)
            print(cas_nel)
            mycas = mcscf.CASSCF(mf, cas_norb, cas_nel)
            h1e_cas, ecore = mycas.get_h1eff(
                mo_coeff=C)  #core core orbs to form ecore and eff
            h2e_cas = ao2mo.kernel(mol,
                                   C[:, cas_nstart:cas_nstop],
                                   aosym='s4',
                                   compact=False).reshape(4 * ((cas_norb), ))
            print(h1e_cas)
            print(h1e_cas.shape)
            #return h1e_cas,h2e_cas,ecore,C,mol,mf
            self.h = h1e_cas
            self.g = h2e_cas
            self.ecore = ecore
            self.mf = mf
            self.mol = mol
            self.C = cp.deepcopy(C[:, cas_nstart:cas_nstop])
            J, K = mf.get_jk()
            self.J = self.C.T @ J @ self.C
            self.K = self.C.T @ J @ self.C

            #HF density
            if orb_basis == 'scf':
                #C = C[:,cas_nstart:cas_nstop]
                D = mf.make_rdm1(mo_coeff=C)
                S = mf.get_ovlp()
                sal, svec = np.linalg.eigh(S)
                idx = sal.argsort()[::-1]
                sal = sal[idx]
                svec = svec[:, idx]
                sal = sal**-0.5
                sal = np.diagflat(sal)
                X = svec @ sal @ svec.T
                C_ao2mo = np.linalg.inv(X) @ C
                Cocc = C_ao2mo[:, :n_a]
                D = Cocc @ Cocc.T
                DMO = C_ao2mo.T @ D @ C_ao2mo

                #only for cas space
                DMO = DMO[cas_nstart:cas_nstop, cas_nstart:cas_nstop]
                self.dm_aa = DMO
                self.dm_bb = DMO
                print("DENSITY")
                print(self.dm_aa.shape)

            if 0:
                h = C.T.dot(mf.get_hcore()).dot(C)
                g = ao2mo.kernel(mol, C, aosym='s4',
                                 compact=False).reshape(4 * ((n_orb), ))
                const, heff = get_eff_for_casci(cas_nstart, cas_nstop, h, g)
                print(heff)
                print("const", const)
                print("ecore", ecore)

                idx = range(cas_nstart, cas_nstop)
                h = h[:, idx]
                h = h[idx, :]
                g = g[:, :, :, idx]
                g = g[:, :, idx, :]
                g = g[:, idx, :, :]
                g = g[idx, :, :, :]

                self.ecore = const
                self.h = h + heff
                self.g = g

        elif cas == False:
            h = C.T.dot(mf.get_hcore()).dot(C)
            g = ao2mo.kernel(mol, C, aosym='s4',
                             compact=False).reshape(4 * ((n_orb), ))
            print(h)
            #return h, g, enu, C,mol,mf
            self.h = h
            self.g = g
            self.ecore = enu
            self.mf = mf
            self.mol = mol
            self.C = C
            J, K = mf.get_jk()
            self.J = self.C.T @ J @ self.C
            self.K = self.C.T @ J @ self.C

            #HF density
            if orb_basis == 'scf':
                D = mf.make_rdm1(mo_coeff=None)
                S = mf.get_ovlp()
                sal, svec = np.linalg.eigh(S)
                idx = sal.argsort()[::-1]
                sal = sal[idx]
                svec = svec[:, idx]
                sal = sal**-0.5
                sal = np.diagflat(sal)
                X = svec @ sal @ svec.T
                C_ao2mo = np.linalg.inv(X) @ C
                Cocc = C_ao2mo[:, :n_a]
                D = Cocc @ Cocc.T
                DMO = C_ao2mo.T @ D @ C_ao2mo
                self.dm_aa = DMO
                self.dm_bb = DMO
                print("DENSITY")
                print(self.dm_aa)
Esempio n. 35
0
def caslst_by_irrep(casscf, mo_coeff, cas_irrep_nocc,
                    cas_irrep_ncore=None, s=None, base=1):
    '''Given number of active orbitals for each irrep, return the orbital
    indices of active space

    Args:
        casscf : an :class:`CASSCF` or :class:`CASCI` object

        cas_irrep_nocc : list or dict
            Number of active orbitals for each irrep.  It can be a dict, eg
            {'A1': 2, 'B2': 4} to indicate the active space size based on
            irrep names, or {0: 2, 3: 4} for irrep Id,  or a list [2, 0, 0, 4]
            (identical to {0: 2, 3: 4}) in which the list index is served as
            the irrep Id.

    Kwargs:
        cas_irrep_ncore : list or dict
            Number of closed shells for each irrep.  It can be a dict, eg
            {'A1': 6, 'B2': 4} to indicate the closed shells based on
            irrep names, or {0: 6, 3: 4} for irrep Id,  or a list [6, 0, 0, 4]
            (identical to {0: 6, 3: 4}) in which the list index is served as
            the irrep Id.  If cas_irrep_ncore is not given, the program
            will generate a guess based on the lowest :attr:`CASCI.ncore`
            orbitals.
        s : ndarray
            overlap matrix
        base : int
            0-based (C-like) or 1-based (Fortran-like) caslst

    Returns:
        A list of orbital indices

    Examples:

    >>> from pyscf import gto, scf, mcscf
    >>> mol = gto.M(atom='N 0 0 0; N 0 0 1', basis='ccpvtz', symmetry=True, verbose=0)
    >>> mf = scf.RHF(mol)
    >>> mf.kernel()
    >>> mc = mcscf.CASSCF(mf, 12, 4)
    >>> mcscf.caslst_by_irrep(mc, mf.mo_coeff, {'E1gx':4, 'E1gy':4, 'E1ux':2, 'E1uy':2})
    [5, 7, 8, 10, 11, 14, 15, 20, 25, 26, 31, 32]
    '''
    mol = casscf.mol
    log = logger.Logger(casscf.stdout, casscf.verbose)
    if s is None:
        s = casscf._scf.get_ovlp()
    orbsym = symm.label_orb_symm(mol, mol.irrep_id,
                                 mol.symm_orb, mo_coeff, s)
    orbsym = numpy.asarray(orbsym)
    ncore = casscf.ncore

    irreps = set(orbsym)

    if cas_irrep_ncore is not None:
        irrep_ncore = {}
        for k, v in cas_irrep_ncore.items():
            if isinstance(k, str):
                irrep_ncore[symm.irrep_name2id(mol.groupname, k)] = v
            else:
                irrep_ncore[k] = v

        ncore_rest = casscf.ncore - sum(irrep_ncore.values())
        if ncore_rest > 0:  # guess core configuration
            mask = numpy.ones(len(orbsym), dtype=bool)
            for ir in irrep_ncore:
                mask[orbsym == ir] = False
            core_rest = orbsym[mask][:ncore_rest]
            core_rest = dict([(ir, numpy.count_nonzero(core_rest==ir))
                              for ir in set(core_rest)])
            log.info('Given core space %s < casscf core size %d',
                     cas_irrep_ncore, casscf.ncore)
            log.info('Add %s to core configuration', core_rest)
            irrep_ncore.update(core_rest)
        elif ncore_rest < 0:
            raise ValueError('Given core space %s > casscf core size %d'
                             % (cas_irrep_ncore, casscf.ncore))
    else:
        irrep_ncore = dict([(ir, sum(orbsym[:ncore]==ir)) for ir in irreps])

    if not isinstance(cas_irrep_nocc, dict):
        # list => dict
        cas_irrep_nocc = dict([(ir, n) for ir,n in enumerate(cas_irrep_nocc)
                               if n > 0])

    irrep_ncas = {}
    for k, v in cas_irrep_nocc.items():
        if isinstance(k, str):
            irrep_ncas[symm.irrep_name2id(mol.groupname, k)] = v
        else:
            irrep_ncas[k] = v

    ncas_rest = casscf.ncas - sum(irrep_ncas.values())
    if ncas_rest > 0:
        mask = numpy.ones(len(orbsym), dtype=bool)
# remove core and specified active space
        for ir in irrep_ncas:
            mask[orbsym == ir] = False
        for ir, ncore in irrep_ncore.items():
            idx = numpy.where(orbsym == ir)[0]
            mask[idx[:ncore]] = False

        cas_rest = orbsym[mask][:ncas_rest]
        cas_rest = dict([(ir, numpy.count_nonzero(cas_rest==ir))
                         for ir in set(cas_rest)])
        log.info('Given active space %s < casscf active space size %d',
                 cas_irrep_nocc, casscf.ncas)
        log.info('Add %s to active space', cas_rest)
        irrep_ncas.update(cas_rest)
    elif ncas_rest < 0:
        raise ValueError('Given active space %s > casscf active space size %d'
                         % (cas_irrep_nocc, casscf.ncas))

    caslst = []
    for ir, ncas in irrep_ncas.items():
        if ncas > 0:
            if ir in irrep_ncore:
                nc = irrep_ncore[ir]
            else:
                nc = 0
            no = nc + ncas
            idx = numpy.where(orbsym == ir)[0]
            caslst.extend(idx[nc:no])
    caslst = numpy.sort(numpy.asarray(caslst)) + base
    if len(caslst) < casscf.ncas:
        raise ValueError('Not enough orbitals found for core %s, cas %s' %
                         (cas_irrep_ncore, cas_irrep_nocc))

    if log.verbose >= logger.INFO:
        log.info('ncore for each irreps %s',
                 dict([(symm.irrep_id2name(mol.groupname, k), v)
                       for k,v in irrep_ncore.items()]))
        log.info('ncas for each irreps %s',
                 dict([(symm.irrep_id2name(mol.groupname, k), v)
                       for k,v in irrep_ncas.items()]))
        log.info('(%d-based) caslst = %s', base, caslst)
    return caslst
Esempio n. 36
0
      H     2.49475714   0.          -0.00736748
      H     1.24762314   2.16037824  -0.00925948
      H    -1.24752386   2.16043824  -0.01063248
      H    -2.49460686   0.          -0.00886348
    ''',
    basis = 'ccpvdz')
mf = scf.RHF(mol)
mf.kernel()

# Change error tolerence (to 0.1 Bohr, default is 1e-5 Bohr) for symmetry
# detection, so that the program can find the raw symmetry.
symm.geom.GEOM_THRESHOLD = .1
symm.geom.PLACE = 1
mol.symmetry = True
mol.build(False, False)
print('Pseudo symmetry %s' % mol.groupname)

# Call mol.build again to avoid the atom coordinates changed
mol.symmetry = mol.groupname
mol.build(False, False)

irname = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mf.mo_coeff, check=False)

s = mol.intor('cint1e_ovlp_sph')
print('MO  id  irreps  likely')
for i, ir in enumerate(irname):
    k = mol.irrep_name.index(ir)
    s1 = reduce(numpy.dot, (mol.symm_orb[k].T, s, mf.mo_coeff[:,i]))
    s0 = reduce(numpy.dot, (mol.symm_orb[k].T, s, mol.symm_orb[k]))
    print('MO %3d  %-3s    %8.5f' % (i, ir, numpy.dot(s1, numpy.linalg.solve(s0, s1))))
Esempio n. 37
0
def writeNevpt2Integrals(mc, dm1, dm2, dm1eff, aaavsplit, frozen):
    eris = _ERIS(mc, mc.mo_coeff)
    nocc = mc.ncore + mc.ncas
    ncore = mc.ncore
    nact = mc.ncas
    norbs = eris['ppaa'].shape[0]
    nvirt = norbs-ncore-nact
    eris_sp={}
    #eris_sp['cvcv']= numpy.zeros(shape=(1,1)) #numpy.zeros(shape=(mc.ncore, norbs-mc.ncore-mc.ncas, mc.ncore, norbs-mc.ncas-mc.ncore))
    eris_sp['h1eff']= 1.*eris['h1eff'] #numpy.zeros(shape=(norbs, norbs))
    int1 = reduce(numpy.dot, (mc.mo_coeff.T, mc.get_hcore(), mc.mo_coeff)) 
    #eris_sp['h1eff'] = makeheff(int1, eris['papa'], eris['ppaa'], dm1, ncore, nvirt)

    eris_sp['h1eff'][:mc.ncore,:mc.ncore] += numpy.einsum('abcd,cd', eris['ppaa'][:mc.ncore, :mc.ncore,:,:], dm1eff)
    eris_sp['h1eff'][:mc.ncore,:mc.ncore] -= numpy.einsum('abcd,bd', eris['papa'][:mc.ncore, :, :mc.ncore,:], dm1eff)*0.5
    eris_sp['h1eff'][mc.ncas+mc.ncore:,mc.ncas+mc.ncore:] += numpy.einsum('abcd,cd', eris['ppaa'][mc.ncas+mc.ncore:,mc.ncas+mc.ncore:,:,:], dm1eff)
    eris_sp['h1eff'][mc.ncas+mc.ncore:,mc.ncas+mc.ncore:] -= numpy.einsum('abcd,bd', eris['papa'][mc.ncas+mc.ncore:,:,mc.ncas+mc.ncore:,:], dm1eff)*0.5


    offdiagonal = 0.0
    #zero out off diagonal core
    for k in range(mc.ncore):
        for l in range(mc.ncore):
            if(k != l):
                offdiagonal = max(abs(offdiagonal), abs(eris_sp['h1eff'][k,l] ))
    #zero out off diagonal virtuals
    for k in range(mc.ncore+mc.ncas, norbs):
        for l in range(mc.ncore+mc.ncas,norbs):
            if(k != l):
                offdiagonal = max(abs(offdiagonal), abs(eris_sp['h1eff'][k,l] ))

    if (abs(offdiagonal) > 1e-6):
        print "WARNING ***** Have to use natorual orbitals from casscf ****"
        print "offdiagonal elements ", offdiagonal


    eriscvcv = eris['cvcv']
    if (not isinstance(eris['cvcv'], type(eris_sp['h1eff']))):
        #eriscvcv = h5py.File(eris['cvcv'].name,'r')["eri_mo"]
        eriscvcv = lib.chkfile.load(eris['cvcv'].name, "eri_mo")#h5py.File(eris['cvcv'].name,'r')["eri_mo"]
    eris_sp['cvcv'] = eriscvcv.reshape(mc.ncore, norbs-mc.ncore-mc.ncas, mc.ncore, norbs-mc.ncore-mc.ncas)


    import os
    os.system("mkdir int")    

    numpy.save("int/W:caac", numpy.asfortranarray(eris['papa'][frozen:mc.ncore, :, frozen:mc.ncore, :].transpose(0,3,1,2)))
    numpy.save("int/W:aeca", numpy.asfortranarray(eris['papa'][frozen:mc.ncore, :, mc.ncore+mc.ncas:, :].transpose(1,2,0,3)))
    numpy.save("int/W:ccaa", numpy.asfortranarray(eris['papa'][frozen:mc.ncore, :, frozen:mc.ncore, :].transpose(0,2,1,3)))
    numpy.save("int/W:eeaa", numpy.asfortranarray(eris['papa'][mc.ncore+mc.ncas:, :, mc.ncore+mc.ncas:, :].transpose(0,2,1,3)))
    numpy.save("int/W:caca", numpy.asfortranarray(eris['ppaa'][frozen:mc.ncore, frozen:mc.ncore, :, :].transpose(0,2,1,3))) 
    numpy.save("int/W:eaca", numpy.asfortranarray(eris['ppaa'][mc.ncore+mc.ncas:, frozen:mc.ncore, :, :].transpose(0,2,1,3))) 
    numpy.save("int/W:eecc", numpy.asfortranarray(eris_sp['cvcv'][frozen:,:,frozen:,:].transpose(1,3,0,2))) 
    numpy.save("int/W:ccae", numpy.asfortranarray(eris['pacv'][frozen:mc.ncore,:,frozen:,:].transpose(0,2,1,3))) 

    numpy.save("int/W:aaaa", numpy.asfortranarray(eris['ppaa'][mc.ncore:mc.ncore+mc.ncas, mc.ncore:mc.ncore+mc.ncas, :, :].transpose(0,2,1,3)))
    numpy.save("int/W:eeca", numpy.asfortranarray(eris['pacv'][mc.ncore+mc.ncas:, :, frozen:, :].transpose(3,0,2,1)))
    numpy.save("int/int1eff", numpy.asfortranarray(eris_sp['h1eff'][frozen:,frozen:]))
    numpy.save("int/E1.npy", numpy.asfortranarray(dm1))
    numpy.save("int/E2.npy", numpy.asfortranarray(dm2))
    #numpy.save("int/E3",dm3)
    #numpy.save("int/E3B.npy", dm3.transpose(0,3,1,4,2,5))
    #numpy.save("int/E3C.npy", dm3.transpose(5,0,2,4,1,3))

    nc = mc.ncore+mc.ncas
    energyE0 = 1.0*numpy.einsum('ij,ij', eris_sp['h1eff'][ncore:nc, ncore:nc], dm1)
    energyE0 += 0.5*numpy.einsum('ijkl,ijkl', eris['ppaa'][mc.ncore:mc.ncore+mc.ncas, mc.ncore:mc.ncore+mc.ncas, :, :].transpose(0,2,1,3), dm2)
    mo = mc.mo_coeff
    dmcore = numpy.dot(mo[:,:ncore], mo[:,:ncore].T)*2
    vj, vk = mc._scf.get_jk(mc.mol, dmcore)
    vhfcore = reduce(numpy.dot, (mo.T, vj-vk*0.5, mo))
    energyE0 += numpy.einsum('ij,ji', dmcore, mc.get_hcore()) \
                  + numpy.einsum('ij,ji', dmcore, vj-0.5*vk) * .5
    energyE0 += mc.mol.energy_nuc()
    print "Energy = ", energyE0

    from pyscf import symm
    mol = mc.mol
    orbsymout=[]
    orbsym = []
    if (mol.symmetry):
        orbsym = symm.label_orb_symm(mc.mol, mc.mol.irrep_id,
                                     mc.mol.symm_orb, mc.mo_coeff, s=mc._scf.get_ovlp())
    if mol.symmetry and orbsym:
        if mol.groupname.lower() == 'dooh':
            orbsymout = [dmrg_sym.IRREP_MAP['D2h'][i % 10] for i in orbsym]
        elif mol.groupname.lower() == 'coov':
            orbsymout = [dmrg_sym.IRREP_MAP['C2v'][i % 10] for i in orbsym]
        else:
            orbsymout = [dmrg_sym.IRREP_MAP[mol.groupname][i] for i in orbsym]
    else:
        orbsymout = []


    ncore = mc.ncore
    mo = mc.mo_coeff

    dmcore = numpy.dot(mo[:,:ncore], mo[:,:ncore].T)*2
    vj, vk = mc._scf.get_jk(mc.mol, dmcore)
    vhfcore = reduce(numpy.dot, (mo.T, vj-vk*0.5, mo))
    energy_core = numpy.einsum('ij,ji', dmcore, mc.get_hcore()) \
                  + numpy.einsum('ij,ji', dmcore, vj-0.5*vk) * .5
    print energy_core
    virtOrbs = range(ncore+mc.ncas, eris_sp['h1eff'].shape[0])
    chunks = len(virtOrbs)/aaavsplit
    virtRange = [virtOrbs[i:i+chunks] for i in xrange(0, len(virtOrbs), chunks)]
    for K in range(aaavsplit):
        currentOrbs = range(ncore, mc.ncas+ncore)+virtRange[K]
        fout = open('FCIDUMP_aaav%d'%(K),'w')
        #tools.fcidump.write_head(fout, eris_sp['h1eff'].shape[0]-ncore, mol.nelectron-2*ncore, orbsym= orbsymout[ncore:])

        tools.fcidump.write_head(fout, mc.ncas+len(virtRange[K]), mol.nelectron-2*ncore, orbsym= (orbsymout[ncore:ncore+mc.ncas]+orbsymout[virtRange[K][0]:virtRange[K][-1]+1]) )
        ij = ncore*(ncore+1)/2
        for i in range(len(currentOrbs)):
            for j in range(ncore, mc.ncas+ncore):
                for k in range(mc.ncas):
                    for l in range(k+1):
                        I = currentOrbs[i]
                        if abs(eris['ppaa'][I,j,k,l]) > 1.e-8 :
                            fout.write(' %17.9e %4d %4d %4d %4d\n' \
                                           % (eris['ppaa'][I,j,k,l], i+1, j+1-ncore, k+1, l+1))
    
        h1eff = numpy.zeros(shape=(mc.ncas+len(virtRange[K]), mc.ncas+len(virtRange[K])))
        h1eff[:mc.ncas, :mc.ncas] = eris_sp['h1eff'][ncore:ncore+mc.ncas,ncore:ncore+mc.ncas]
        h1eff[mc.ncas:, mc.ncas:] = eris_sp['h1eff'][virtRange[K][0]:virtRange[K][-1]+1, virtRange[K][0]:virtRange[K][-1]+1]
        h1eff[:mc.ncas, mc.ncas:] = eris_sp['h1eff'][ncore:ncore+mc.ncas, virtRange[K][0]:virtRange[K][-1]+1]
        h1eff[mc.ncas:, :mc.ncas] = eris_sp['h1eff'][virtRange[K][0]:virtRange[K][-1]+1, ncore:ncore+mc.ncas]

        tools.fcidump.write_hcore(fout, h1eff, mc.ncas+len(virtRange[K]), tol=1e-8)
        #tools.fcidump.write_hcore(fout, eris_sp['h1eff'][virtRange[K][0]:virtRange[K][-1]+1, virtRange[K][0]:virtRange[K][-1]+1], len(virtRange[K]), tol=1e-8)
        fout.write(' %17.9e  0  0  0  0\n' %( mol.energy_nuc()+energy_core-energyE0))
        fout.close()

    nc = ncore+mc.ncas
    fout = open('FCIDUMP_aaac','w')
    tools.fcidump.write_head(fout, nc-frozen, mol.nelectron-2*frozen, orbsym= orbsymout[frozen:nc])
    for i in range(frozen,nc):
        for j in range(ncore, nc):
            for k in range(ncore, nc):
                for l in range(ncore,k+1):
                    if abs(eris['ppaa'][i,j,k-ncore,l-ncore]) > 1.e-8 :
                        fout.write(' %17.9e %4d %4d %4d %4d\n' \
                                   % (eris['ppaa'][i,j,k-ncore,l-ncore], i+1-frozen, j+1-frozen, k+1-frozen, l+1-frozen))

    dmrge = energyE0-mol.energy_nuc()-energy_core

    ecore_aaac = 0.0;
    for i in range(frozen,ncore):
        ecore_aaac += 2.0*eris_sp['h1eff'][i,i]
    tools.fcidump.write_hcore(fout, eris_sp['h1eff'][frozen:nc,frozen:nc], nc-frozen, tol=1e-8)
    fout.write(' %17.9e  0  0  0  0\n' %( -dmrge-ecore_aaac))
    fout.close()


    return norbs, energyE0
Esempio n. 38
0
    mol.verbose = 0
    mol.atom = [
         ['O',    (0.000000,    0.000000,    1.210000)],
         ['C',    (0.000000,    0.000000,    0.000000)],
         ['H',    (0.000000,    0.943435,   -0.599878)],
         ['H',    (0.000000,   -0.943435,   -0.599878)],
     ]
    mol.basis = {'H': 'cc-pVTZ', 'C': 'cc-pVTZ', 'O': 'cc-pVTZ'}
    mol.symmetry = 'c1'
    mol.build()

    m = scf.RHF(mol)

    m.kernel()
    irrep_name = m.mol.irrep_id
    sym = symm.label_orb_symm(m.mol, irrep_name,m.mol.symm_orb,m.mo_coeff)
    orbsym = [IRREP_MAP['C1'][i % 10] for i in sym]

    m.verbose = 4
    ehf = m.scf()
    mc=mcscf.CASCI(m,16,16)
    mc.verbose = 4
#    ci_e = mc.kernel()[0]
#    print 'CI energy', ci_e
#    mc.casci()

    mo_cas_coeff = mc.mo_coeff[:,mc.ncore:mc.ncore+mc.ncas]
    AOdipInt = mol.intor('cint1e_r_sph', comp=3)

    MOdipInt = numpy.zeros([3,mo_cas_coeff.shape[1],mo_cas_coeff.shape[1]])
   
Esempio n. 39
0
    def get_occ(self, mo_energy=None, mo_coeff=None, orbsym=None):
        ''' We assumed mo_energy are grouped by symmetry irreps, (see function
        self.eig). The orbitals are sorted after SCF.
        '''
        if mo_energy is None: mo_energy = self.mo_energy
        mol = self.mol
        if orbsym is None:
            if mo_coeff is not None:
                orbsym = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb,
                                             mo_coeff, self.get_ovlp(), False)
                orbsym = numpy.asarray(orbsym)
            else:
                orbsym = [numpy.repeat(ir, mol.symm_orb[i].shape[1])
                          for i, ir in enumerate(mol.irrep_id)]
                orbsym = numpy.hstack(orbsym)
        else:
            orbsym = numpy.asarray(orbsym)
        assert(mo_energy.size == orbsym.size)

        mo_occ = numpy.zeros_like(mo_energy)
        rest_idx = []
        nelec_fix = 0
        for i, ir in enumerate(mol.irrep_id):
            irname = mol.irrep_name[i]
            ir_idx = numpy.where(orbsym == ir)[0]
            if irname in self.irrep_nelec:
                n = self.irrep_nelec[irname]
                occ_sort = numpy.argsort(mo_energy[ir_idx].round(9))
                occ_idx  = ir_idx[occ_sort[:n//2]]
                mo_occ[occ_idx] = 2
                nelec_fix += n
            else:
                rest_idx.append(ir_idx)
        nelec_float = mol.nelectron - nelec_fix
        assert(nelec_float >= 0)
        if nelec_float > 0:
            rest_idx = numpy.hstack(rest_idx)
            occ_sort = numpy.argsort(mo_energy[rest_idx].round(9))
            occ_idx  = rest_idx[occ_sort[:nelec_float//2]]
            mo_occ[occ_idx] = 2

        vir_idx = (mo_occ==0)
        if self.verbose >= logger.INFO and numpy.count_nonzero(vir_idx) > 0:
            ehomo = max(mo_energy[mo_occ>0 ])
            elumo = min(mo_energy[mo_occ==0])
            noccs = []
            for i, ir in enumerate(mol.irrep_id):
                irname = mol.irrep_name[i]
                ir_idx = (orbsym == ir)

                noccs.append(int(mo_occ[ir_idx].sum()))
                if ehomo in mo_energy[ir_idx]:
                    irhomo = irname
                if elumo in mo_energy[ir_idx]:
                    irlumo = irname
            logger.info(self, 'H**O (%s) = %.15g  LUMO (%s) = %.15g',
                        irhomo, ehomo, irlumo, elumo)

            logger.debug(self, 'irrep_nelec = %s', noccs)
            _dump_mo_energy(mol, mo_energy, mo_occ, ehomo, elumo, orbsym,
                            verbose=self.verbose)
        return mo_occ
Esempio n. 40
0
def label_symmetry_(mc, mo_coeff, ci0=None):
    log = logger.Logger(mc.stdout, mc.verbose)
    #irrep_name = mc.mol.irrep_name
    irrep_name = mc.mol.irrep_id
    s = mc._scf.get_ovlp()
    ncore = mc.ncore
    nocc = ncore + mc.ncas
    try:
        orbsym = scf.hf_symm.get_orbsym(mc._scf.mol, mo_coeff, s, True)
    except ValueError:
        log.warn('mc1step_symm symmetrizes input orbitals')
        mo_cor = symm.symmetrize_space(mc.mol, mo_coeff[:,    :ncore], s=s, check=False)
        mo_act = symm.symmetrize_space(mc.mol, mo_coeff[:,ncore:nocc], s=s, check=False)
        mo_vir = symm.symmetrize_space(mc.mol, mo_coeff[:,nocc:     ], s=s, check=False)
        mo_coeff = numpy.hstack((mo_cor,mo_act,mo_vir))
        orbsym = symm.label_orb_symm(mc.mol, irrep_name,
                                     mc.mol.symm_orb, mo_coeff, s=s)
    mo_coeff_with_orbsym = lib.tag_array(mo_coeff, orbsym=orbsym)

    active_orbsym = getattr(mc.fcisolver, 'orbsym', [])
    if (not getattr(active_orbsym, '__len__', None)) or len(active_orbsym) == 0:
        mc.fcisolver.orbsym = orbsym[ncore:nocc]
    log.debug('Active space irreps %s', str(mc.fcisolver.orbsym))

    wfnsym = 0
    if getattr(mc.fcisolver, 'wfnsym', None) is not None:
        wfnsym = mc.fcisolver.wfnsym

    elif ci0 is None:
        # Guess wfnsym based on HF determinant.  mo_coeff may not be HF
        # canonical orbitals.  Some checks are needed to ensure that mo_coeff
        # are derived from the symmetry adapted SCF calculations.
        if mo_coeff is mc._scf.mo_coeff:
            wfnsym = 0
            for ir in orbsym[mc._scf.mo_occ == 1]:
                wfnsym ^= ir
            mc.fcisolver.wfnsym = wfnsym
            log.debug('Set CASCI wfnsym %s based on HF determinant', wfnsym)
        elif getattr(mo_coeff, 'orbsym', None) is not None:  # It may be reordered SCF orbitals
            cas_orb = mo_coeff[:,ncore:nocc]
            s = reduce(numpy.dot, (cas_orb.T, mc._scf.get_ovlp(), mc._scf.mo_coeff))
            if numpy.all(numpy.max(s, axis=1) > 1-1e-9):
                idx = numpy.argmax(s, axis=1)
                cas_orbsym = orbsym[ncore:nocc]
                cas_occ = mc._scf.mo_occ[idx]
                wfnsym = 0
                for ir in cas_orbsym[cas_occ == 1]:
                    wfnsym ^= ir
                mc.fcisolver.wfnsym = wfnsym
                log.debug('Active space are constructed from canonical SCF '
                          'orbitals %s', idx)
                log.debug('Set CASCI wfnsym %s based on HF determinant', wfnsym)

    elif getattr(mc.fcisolver, 'guess_wfnsym', None):
        wfnsym = mc.fcisolver.guess_wfnsym(mc.ncas, mc.nelecas, ci0, verbose=log)
        log.debug('CASCI wfnsym %s (based on CI initial guess)', wfnsym)

    if isinstance(wfnsym, (int, numpy.integer)):
        wfnsym = symm.irrep_id2name(mc.mol.groupname, wfnsym)

    log.info('Active space CI wfn symmetry = %s', wfnsym)

    return mo_coeff_with_orbsym
Esempio n. 41
0
def writeNumpyforMRLCC(mc, E1, E2, frozen):
    ncore = mc.ncore
    nact = mc.ncas
    norbs = mc.mo_coeff.shape[1]
    nelec = mc.nelecas[0] + mc.nelecas[1]
    nvirt = norbs - ncore - nact
    nc = ncore + nact
    nactElec = nelec - 2 * ncore

    #this is chemistry notation
    int2popo = ao2mo.outcore.general_iofree(
        mc.mol,
        (mc.mo_coeff, mc.mo_coeff[:, :nc], mc.mo_coeff, mc.mo_coeff[:, :nc]),
        compact=False)
    int2ppoo = ao2mo.outcore.general_iofree(
        mc.mol,
        (mc.mo_coeff, mc.mo_coeff, mc.mo_coeff[:, :nc], mc.mo_coeff[:, :nc]),
        compact=False)
    int2popo.shape = (norbs, nc, norbs, nc)
    int2ppoo.shape = (norbs, norbs, nc, nc)

    mo = mc.mo_coeff

    dmcore = numpy.dot(mo[:, :frozen], mo[:, :frozen].T) * 2
    vj, vk = mc._scf.get_jk(mc.mol, dmcore)
    vhfcore = reduce(numpy.dot, (mo.T, vj - vk * 0.5, mo))
    int1 = reduce(numpy.dot,
                  (mc.mo_coeff.T, mc.get_hcore(), mc.mo_coeff)) + vhfcore

    dmcore = numpy.dot(mo[:, :ncore], mo[:, :ncore].T) * 2
    vj, vk = mc._scf.get_jk(mc.mol, dmcore)
    vhfcore = reduce(numpy.dot, (mo.T, vj - vk * 0.5, mo))
    int1_eff = reduce(numpy.dot,
                      (mc.mo_coeff.T, mc.get_hcore(), mc.mo_coeff)) + vhfcore

    #int1_eff = makeheff(int1, int2popo, int2ppoo, E1, ncore, nvirt, frozen)

    energy_frozen_core = numpy.einsum('ij,ji', dmcore, mc.get_hcore()) \
        + numpy.einsum('ij,ji', dmcore, vj-0.5*vk) * .5

    #numpy.save("int/E3",E3)
    #numpy.save("int/E3B.npy", E3.transpose(0,3,1,4,2,5))
    #numpy.save("int/E3C.npy", E3.transpose(5,0,2,4,1,3))
    numpy.save("int/E2", numpy.asfortranarray(E2))
    numpy.save("int/E1", numpy.asfortranarray(E1))
    #numpy.save("int/int2",int2)
    numpy.save("int/int1", numpy.asfortranarray(int1[frozen:, frozen:]))
    numpy.save("int/int1eff", numpy.asfortranarray(int1_eff[frozen:, frozen:]))

    numpy.save(
        "int/W:caca",
        numpy.asfortranarray(int2ppoo[frozen:ncore, frozen:ncore, ncore:nc,
                                      ncore:nc].transpose(0, 2, 1, 3)))
    numpy.save(
        "int/W:caac",
        numpy.asfortranarray(int2popo[frozen:ncore, ncore:nc, ncore:nc,
                                      frozen:ncore].transpose(0, 2, 1, 3)))

    numpy.save(
        "int/W:cece",
        numpy.asfortranarray(int2ppoo[nc:, nc:, frozen:ncore,
                                      frozen:ncore].transpose(2, 0, 3, 1)))
    numpy.save(
        "int/W:ceec",
        numpy.asfortranarray(int2popo[nc:, frozen:ncore, nc:,
                                      frozen:ncore].transpose(1, 2, 0, 3)))

    numpy.save(
        "int/W:aeae",
        numpy.asfortranarray(int2ppoo[nc:, nc:, ncore:nc,
                                      ncore:nc].transpose(2, 0, 3, 1)))
    numpy.save(
        "int/W:aeea",
        numpy.asfortranarray(int2popo[nc:, ncore:nc, nc:,
                                      ncore:nc].transpose(1, 2, 0, 3)))

    numpy.save(
        "int/W:cccc",
        numpy.asfortranarray(int2ppoo[frozen:ncore, frozen:ncore, frozen:ncore,
                                      frozen:ncore].transpose(0, 2, 1, 3)))
    numpy.save(
        "int/W:aaaa",
        numpy.asfortranarray(int2ppoo[ncore:nc, ncore:nc, ncore:nc,
                                      ncore:nc].transpose(0, 2, 1, 3)))

    feri = h5py.File("int/int2eeee.hdf5", 'w')
    ao2mo.full(mc.mol, mc.mo_coeff[:, nc:], feri, compact=False)

    for o in range(nvirt):
        int2eee = feri['eri_mo'][o * (norbs - nc):(o + 1) * (norbs - nc), :]
        numpy.asfortranarray(int2eee).tofile("int/W:eeee%04d" % (o))

    #store perturbers
    numpy.save(
        "int/W:eecc",
        numpy.asfortranarray(int2popo[nc:, frozen:ncore, nc:,
                                      frozen:ncore].transpose(0, 2, 1, 3)))
    numpy.save(
        "int/W:eeca",
        numpy.asfortranarray(int2popo[nc:, frozen:ncore, nc:,
                                      ncore:nc].transpose(0, 2, 1, 3)))
    numpy.save(
        "int/W:ccaa",
        numpy.asfortranarray(int2popo[frozen:ncore, ncore:nc, frozen:ncore,
                                      ncore:nc].transpose(0, 2, 1, 3)))
    numpy.save(
        "int/W:eeaa",
        numpy.asfortranarray(int2popo[nc:, ncore:nc, nc:,
                                      ncore:nc].transpose(0, 2, 1, 3)))
    numpy.save(
        "int/W:eaca",
        numpy.asfortranarray(int2popo[nc:, frozen:ncore, ncore:nc,
                                      ncore:nc].transpose(0, 2, 1, 3)))
    numpy.save(
        "int/W:aeca",
        numpy.asfortranarray(int2popo[ncore:nc, frozen:ncore, nc:,
                                      ncore:nc].transpose(0, 2, 1, 3)))
    numpy.save(
        "int/W:ccae",
        numpy.asfortranarray(int2popo[frozen:ncore, ncore:nc, nc:,
                                      frozen:ncore].transpose(0, 3, 1, 2)))

    #write FCIDUMP_AAAV and FCIDUMP_AAAC
    from pyscf import symm
    mol = mc.mol
    orbsymout = []
    orbsym = []
    if (mol.symmetry):
        orbsym = symm.label_orb_symm(mc.mol,
                                     mc.mol.irrep_id,
                                     mc.mol.symm_orb,
                                     mc.mo_coeff,
                                     s=mc._scf.get_ovlp())
    if mol.symmetry and orbsym:
        if mol.groupname.lower() == 'dooh':
            orbsymout = [dmrg_sym.IRREP_MAP['D2h'][i % 10] for i in orbsym]
        elif mol.groupname.lower() == 'coov':
            orbsymout = [dmrg_sym.IRREP_MAP['C2v'][i % 10] for i in orbsym]
        else:
            orbsymout = [dmrg_sym.IRREP_MAP[mol.groupname][i] for i in orbsym]
    else:
        orbsymout = []
    '''
    dmcore = numpy.dot(mo[:,frozen:ncore], mo[:,frozen:ncore].T)*2
    vj, vk = mc._scf.get_jk(mc.mol, dmcore)
    vhfcore = reduce(numpy.dot, (mo.T, vj-vk*0.5, mo))
    h1eff = int1+vhfcore
    energy_core = numpy.einsum('ij,ji', dmcore, mc.get_hcore()) \
                  + numpy.einsum('ij,ji', dmcore, vj-0.5*vk) * .5\
                  +energy_frozen_core
    '''
    dmcore = numpy.dot(mo[:, :ncore], mo[:, :ncore].T) * 2
    vj, vk = mc._scf.get_jk(mc.mol, dmcore)
    vhfcore = reduce(numpy.dot, (mo.T, vj - vk * 0.5, mo))
    h1eff = int1_eff
    energy_core = numpy.einsum('ij,ji', dmcore, mc.get_hcore()) \
        + numpy.einsum('ij,ji', dmcore, vj-0.5*vk) * .5

    #print energy_core2+mc.mol.energy_nuc(), energy_core+mc.mol.energy_nuc(), energy_frozen_core+mc.mol.energy_nuc()
    nc = mc.ncore + mc.ncas
    energyE0 = 1.0 * numpy.einsum('ij,ij', h1eff[ncore:nc, ncore:nc], E1)
    #+ 0.5*numpy.einsum('ikjl,ijkl', E2, int2ppoo[ncore:,ncore:,ncore:,ncore:])
    for i in range(mc.ncas):
        for j in range(mc.ncas):
            for k in range(mc.ncas):
                for l in range(mc.ncas):
                    I, J = max(i, j) + ncore, min(i, j) + ncore
                    K, L = max(k, l) + ncore, min(k, l) + ncore
                    energyE0 += 0.5 * E2[i, k, j,
                                         l] * int2ppoo[i + ncore, j + ncore,
                                                       k + ncore, l + ncore]

    energyE0 += energy_core
    energyE0 += mc.mol.energy_nuc()
    print "Energy = ", energyE0

    fout = open('FCIDUMP_aaav0', 'w')
    tools.fcidump.write_head(fout,
                             int1.shape[0] - ncore,
                             mc.mol.nelectron - 2 * ncore,
                             orbsym=orbsymout[ncore:])

    for i in range(ncore, int1.shape[0]):
        for j in range(ncore, i + 1):
            for k in range(mc.ncas):
                for l in range(k + 1):
                    if abs(int2ppoo[i, j, k + ncore, l + ncore]) > 1.e-8:
                        fout.write(' %17.9e %4d %4d %4d %4d\n' \
                                   % (int2ppoo[i,j, k+ncore,l+ncore], i+1-ncore, j+1-ncore, k+1, l+1))
                    if (j >= nc and
                            abs(int2popo[i, k + ncore, j, l + ncore]) > 1.e-8):
                        fout.write(' %17.9e %4d %4d %4d %4d\n' \
                                       % (int2popo[i,k+ncore,j, l+ncore], i+1-ncore, k+1, l+1, j+1-ncore))
                    if (j >= nc and
                            abs(int2popo[i, l + ncore, j, k + ncore]) > 1.e-8):
                        fout.write(' %17.9e %4d %4d %4d %4d\n' \
                                       % (int2popo[i,l+ncore, j, k+ncore], i+1-ncore, l+1, k+1, j+1-ncore))

    tools.fcidump.write_hcore(fout,
                              h1eff[ncore:, ncore:],
                              int1.shape[0] - ncore,
                              tol=1e-8)
    fout.write(' %17.9e  0  0  0  0\n' %
               (mc.mol.energy_nuc() + energy_core - energyE0))
    fout.close()

    nc = ncore + mc.ncas
    eri1cas = ao2mo.outcore.general_iofree(
        mc.mol, (mc.mo_coeff[:, frozen:nc], mc.mo_coeff[:, frozen:nc],
                 mc.mo_coeff[:, frozen:nc], mc.mo_coeff[:, frozen:nc]),
        compact=True)
    tools.fcidump.from_integrals("FCIDUMP_aaac",
                                 int1[frozen:nc, frozen:nc],
                                 eri1cas,
                                 nc - frozen,
                                 mc.mol.nelectron - 2 * frozen,
                                 nuc=mc.mol.energy_nuc() - energyE0,
                                 orbsym=orbsymout[frozen:nc],
                                 tol=1e-8)

    return energyE0, norbs
Esempio n. 42
0
def analyze(mf, verbose=logger.DEBUG):
    from pyscf.lo import orth
    from pyscf.tools import dump_mat
    mo_energy = mf.mo_energy
    mo_occ = mf.mo_occ
    mo_coeff = mf.mo_coeff
    mol = mf.mol
    log = pyscf.lib.logger.Logger(mf.stdout, verbose)
    nirrep = len(mol.irrep_id)
    ovlp_ao = mf.get_ovlp()
    orbsyma = symm.label_orb_symm(mol,
                                  mol.irrep_id,
                                  mol.symm_orb,
                                  mo_coeff[0],
                                  s=ovlp_ao)
    orbsymb = symm.label_orb_symm(mol,
                                  mol.irrep_id,
                                  mol.symm_orb,
                                  mo_coeff[1],
                                  s=ovlp_ao)
    orbsyma = numpy.array(orbsyma)
    orbsymb = numpy.array(orbsymb)
    tot_sym = 0
    noccsa = [sum(orbsyma[mo_occ[0] > 0] == ir) for ir in mol.irrep_id]
    noccsb = [sum(orbsymb[mo_occ[1] > 0] == ir) for ir in mol.irrep_id]
    for i, ir in enumerate(mol.irrep_id):
        if (noccsa[i] + noccsb[i]) % 2:
            tot_sym ^= ir
    if mol.groupname in ('Dooh', 'Coov', 'SO3'):
        log.note('TODO: total symmetry for %s', mol.groupname)
    else:
        log.note('total symmetry = %s',
                 symm.irrep_id2name(mol.groupname, tot_sym))
    log.note('alpha occupancy for each irrep:  ' + (' %4s' * nirrep),
             *mol.irrep_name)
    log.note('                                 ' + (' %4d' * nirrep), *noccsa)
    log.note('beta  occupancy for each irrep:  ' + (' %4s' * nirrep),
             *mol.irrep_name)
    log.note('                                 ' + (' %4d' * nirrep), *noccsb)

    ss, s = mf.spin_square(
        (mo_coeff[0][:, mo_occ[0] > 0], mo_coeff[1][:, mo_occ[1] > 0]),
        ovlp_ao)
    log.note('multiplicity <S^2> = %.8g  2S+1 = %.8g', ss, s)

    if verbose >= logger.NOTE:
        log.note('**** MO energy ****')
        irname_full = {}
        for k, ir in enumerate(mol.irrep_id):
            irname_full[ir] = mol.irrep_name[k]
        irorbcnt = {}
        for k, j in enumerate(orbsyma):
            if j in irorbcnt:
                irorbcnt[j] += 1
            else:
                irorbcnt[j] = 1
            log.note('alpha MO #%d (%s #%d), energy= %.15g occ= %g', k + 1,
                     irname_full[j], irorbcnt[j], mo_energy[0][k],
                     mo_occ[0][k])
        irorbcnt = {}
        for k, j in enumerate(orbsymb):
            if j in irorbcnt:
                irorbcnt[j] += 1
            else:
                irorbcnt[j] = 1
            log.note('beta  MO #%d (%s #%d), energy= %.15g occ= %g', k + 1,
                     irname_full[j], irorbcnt[j], mo_energy[1][k],
                     mo_occ[1][k])

    ovlp_ao = mf.get_ovlp()
    if mf.verbose >= logger.DEBUG:
        label = mol.spheric_labels(True)
        molabel = []
        irorbcnt = {}
        for k, j in enumerate(orbsyma):
            if j in irorbcnt:
                irorbcnt[j] += 1
            else:
                irorbcnt[j] = 1
            molabel.append('#%-d(%s #%d)' %
                           (k + 1, irname_full[j], irorbcnt[j]))
        log.debug(
            ' ** alpha MO coefficients (expansion on meta-Lowdin AOs) **')
        orth_coeff = orth.orth_ao(mol, 'meta_lowdin', s=ovlp_ao)
        c_inv = numpy.dot(orth_coeff.T, ovlp_ao)
        dump_mat.dump_rec(mol.stdout,
                          c_inv.dot(mo_coeff[0]),
                          label,
                          molabel,
                          start=1)

        molabel = []
        irorbcnt = {}
        for k, j in enumerate(orbsymb):
            if j in irorbcnt:
                irorbcnt[j] += 1
            else:
                irorbcnt[j] = 1
            molabel.append('#%-d(%s #%d)' %
                           (k + 1, irname_full[j], irorbcnt[j]))
        log.debug(' ** beta MO coefficients (expansion on meta-Lowdin AOs) **')
        dump_mat.dump_rec(mol.stdout,
                          c_inv.dot(mo_coeff[1]),
                          label,
                          molabel,
                          start=1)

    dm = mf.make_rdm1(mo_coeff, mo_occ)
    return mf.mulliken_meta(mol, dm, s=ovlp_ao, verbose=log)
Esempio n. 43
0
def caslst_by_irrep(casscf,
                    mo_coeff,
                    cas_irrep_nocc,
                    cas_irrep_ncore=None,
                    s=None,
                    base=1):
    '''Given number of active orbitals for each irrep, return the orbital
    indices of active space

    Args:
        casscf : an :class:`CASSCF` or :class:`CASCI` object

        cas_irrep_nocc : list or dict
            Number of active orbitals for each irrep.  It can be a dict, eg
            {'A1': 2, 'B2': 4} to indicate the active space size based on
            irrep names, or {0: 2, 3: 4} for irrep Id,  or a list [2, 0, 0, 4]
            (identical to {0: 2, 3: 4}) in which the list index is served as
            the irrep Id.

    Kwargs:
        cas_irrep_ncore : list or dict
            Number of closed shells for each irrep.  It can be a dict, eg
            {'A1': 6, 'B2': 4} to indicate the closed shells based on
            irrep names, or {0: 6, 3: 4} for irrep Id,  or a list [6, 0, 0, 4]
            (identical to {0: 6, 3: 4}) in which the list index is served as
            the irrep Id.  If cas_irrep_ncore is not given, the program
            will generate a guess based on the lowest :attr:`CASCI.ncore`
            orbitals.
        s : ndarray
            overlap matrix
        base : int
            0-based (C-like) or 1-based (Fortran-like) caslst

    Returns:
        A list of orbital indices

    Examples:

    >>> from pyscf import gto, scf, mcscf
    >>> mol = gto.M(atom='N 0 0 0; N 0 0 1', basis='ccpvtz', symmetry=True, verbose=0)
    >>> mf = scf.RHF(mol)
    >>> mf.kernel()
    >>> mc = mcscf.CASSCF(mf, 12, 4)
    >>> mcscf.caslst_by_irrep(mc, mf.mo_coeff, {'E1gx':4, 'E1gy':4, 'E1ux':2, 'E1uy':2})
    [5, 7, 8, 10, 11, 14, 15, 20, 25, 26, 31, 32]
    '''
    mol = casscf.mol
    log = logger.Logger(casscf.stdout, casscf.verbose)
    if s is None:
        s = casscf._scf.get_ovlp()
    orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, mo_coeff, s)
    orbsym = numpy.asarray(orbsym)
    ncore = casscf.ncore

    irreps = set(orbsym)

    if cas_irrep_ncore is not None:
        irrep_ncore = {}
        for k, v in cas_irrep_ncore.items():
            if isinstance(k, str):
                irrep_ncore[symm.irrep_name2id(mol.groupname, k)] = v
            else:
                irrep_ncore[k] = v

        ncore_rest = casscf.ncore - sum(irrep_ncore.values())
        if ncore_rest > 0:  # guess core configuration
            mask = numpy.ones(len(orbsym), dtype=bool)
            for ir in irrep_ncore:
                mask[orbsym == ir] = False
            core_rest = orbsym[mask][:ncore_rest]
            core_rest = dict([(ir, numpy.count_nonzero(core_rest == ir))
                              for ir in set(core_rest)])
            log.info('Given core space %s < casscf core size %d',
                     cas_irrep_ncore, casscf.ncore)
            log.info('Add %s to core configuration', core_rest)
            irrep_ncore.update(core_rest)
        elif ncore_rest < 0:
            raise ValueError('Given core space %s > casscf core size %d' %
                             (cas_irrep_ncore, casscf.ncore))
    else:
        irrep_ncore = dict([(ir, sum(orbsym[:ncore] == ir)) for ir in irreps])

    if not isinstance(cas_irrep_nocc, dict):
        # list => dict
        cas_irrep_nocc = dict([(ir, n) for ir, n in enumerate(cas_irrep_nocc)
                               if n > 0])

    irrep_ncas = {}
    for k, v in cas_irrep_nocc.items():
        if isinstance(k, str):
            irrep_ncas[symm.irrep_name2id(mol.groupname, k)] = v
        else:
            irrep_ncas[k] = v

    ncas_rest = casscf.ncas - sum(irrep_ncas.values())
    if ncas_rest > 0:
        mask = numpy.ones(len(orbsym), dtype=bool)
        # remove core and specified active space
        for ir in irrep_ncas:
            mask[orbsym == ir] = False
        for ir, ncore in irrep_ncore.items():
            idx = numpy.where(orbsym == ir)[0]
            mask[idx[:ncore]] = False

        cas_rest = orbsym[mask][:ncas_rest]
        cas_rest = dict([(ir, numpy.count_nonzero(cas_rest == ir))
                         for ir in set(cas_rest)])
        log.info('Given active space %s < casscf active space size %d',
                 cas_irrep_nocc, casscf.ncas)
        log.info('Add %s to active space', cas_rest)
        irrep_ncas.update(cas_rest)
    elif ncas_rest < 0:
        raise ValueError(
            'Given active space %s > casscf active space size %d' %
            (cas_irrep_nocc, casscf.ncas))

    caslst = []
    for ir, ncas in irrep_ncas.items():
        if ncas > 0:
            if ir in irrep_ncore:
                nc = irrep_ncore[ir]
            else:
                nc = 0
            no = nc + ncas
            idx = numpy.where(orbsym == ir)[0]
            caslst.extend(idx[nc:no])
    caslst = numpy.sort(numpy.asarray(caslst)) + base
    if len(caslst) < casscf.ncas:
        raise ValueError('Not enough orbitals found for core %s, cas %s' %
                         (cas_irrep_ncore, cas_irrep_nocc))

    if log.verbose >= logger.INFO:
        log.info(
            'ncore for each irreps %s',
            dict([(symm.irrep_id2name(mol.groupname, k), v)
                  for k, v in irrep_ncore.items()]))
        log.info(
            'ncas for each irreps %s',
            dict([(symm.irrep_id2name(mol.groupname, k), v)
                  for k, v in irrep_ncas.items()]))
        log.info('(%d-based) caslst = %s', base, caslst)
    return caslst
Esempio n. 44
0
    def analyze(self, verbose=logger.DEBUG):
        from pyscf.lo import orth
        from pyscf.tools import dump_mat
        mo_energy = self.mo_energy
        mo_occ = self.mo_occ
        mo_coeff = self.mo_coeff
        log = logger.Logger(self.stdout, verbose)
        mol = self.mol
        nirrep = len(mol.irrep_id)
        ovlp_ao = self.get_ovlp()
        orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, mo_coeff,
                                     s=ovlp_ao)
        orbsym = numpy.array(orbsym)
        wfnsym = 0
        ndoccs = []
        nsoccs = []
        for k,ir in enumerate(mol.irrep_id):
            ndoccs.append(sum(orbsym[mo_occ==2] == ir))
            nsoccs.append(sum(orbsym[mo_occ==1] == ir))
            if nsoccs[k] % 2:
                wfnsym ^= ir
        if mol.groupname in ('Dooh', 'Coov'):
            log.info('TODO: total symmetry for %s', mol.groupname)
        else:
            log.info('total symmetry = %s',
                     symm.irrep_id2name(mol.groupname, wfnsym))
        log.info('occupancy for each irrep:  ' + (' %4s'*nirrep),
                 *mol.irrep_name)
        log.info('double occ                 ' + (' %4d'*nirrep), *ndoccs)
        log.info('single occ                 ' + (' %4d'*nirrep), *nsoccs)
        log.info('**** MO energy ****')
        irname_full = {}
        for k,ir in enumerate(mol.irrep_id):
            irname_full[ir] = mol.irrep_name[k]
        irorbcnt = {}
        if self._focka_ao is None:
            for k, j in enumerate(orbsym):
                if j in irorbcnt:
                    irorbcnt[j] += 1
                else:
                    irorbcnt[j] = 1
                log.note('MO #%-3d (%s #%-2d), energy= %-18.15g occ= %g',
                         k+1, irname_full[j], irorbcnt[j],
                         mo_energy[k], mo_occ[k])
        else:
            mo_ea = numpy.einsum('ik,ik->k', mo_coeff, self._focka_ao.dot(mo_coeff))
            mo_eb = numpy.einsum('ik,ik->k', mo_coeff, self._fockb_ao.dot(mo_coeff))
            log.note('                          Roothaan           | alpha              | beta')
            for k, j in enumerate(orbsym):
                if j in irorbcnt:
                    irorbcnt[j] += 1
                else:
                    irorbcnt[j] = 1
                log.note('MO #%-4d(%-3s #%-2d) energy= %-18.15g | %-18.15g | %-18.15g occ= %g',
                         k+1, irname_full[j], irorbcnt[j],
                         mo_energy[k], mo_ea[k], mo_eb[k], mo_occ[k])

        if verbose >= logger.DEBUG:
            label = mol.spheric_labels(True)
            molabel = []
            irorbcnt = {}
            for k, j in enumerate(orbsym):
                if j in irorbcnt:
                    irorbcnt[j] += 1
                else:
                    irorbcnt[j] = 1
                molabel.append('#%-d(%s #%d)' % (k+1, irname_full[j], irorbcnt[j]))
            log.debug(' ** MO coefficients (expansion on meta-Lowdin AOs) **')
            orth_coeff = orth.orth_ao(mol, 'meta_lowdin', s=ovlp_ao)
            c = reduce(numpy.dot, (orth_coeff.T, ovlp_ao, mo_coeff))
            dump_mat.dump_rec(self.stdout, c, label, molabel, start=1)

        dm = self.make_rdm1(mo_coeff, mo_occ)
        return self.mulliken_meta(mol, dm, s=ovlp_ao, verbose=verbose)
Esempio n. 45
0
    def get_occ(self, mo_energy=None, mo_coeff=None, orbsym=None):
        ''' We assumed mo_energy are grouped by symmetry irreps, (see function
        self.eig). The orbitals are sorted after SCF.
        '''
        if mo_energy is None: mo_energy = self.mo_energy
        mol = self.mol
        if not mol.symmetry:
            return hf.RHF.get_occ(self, mo_energy, mo_coeff)

        if orbsym is None:
            if mo_coeff is not None:
                orbsym = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb,
                                             mo_coeff, self.get_ovlp(), False)
                orbsym = numpy.asarray(orbsym)
            else:
                orbsym = [
                    numpy.repeat(ir, mol.symm_orb[i].shape[1])
                    for i, ir in enumerate(mol.irrep_id)
                ]
                orbsym = numpy.hstack(orbsym)
        else:
            orbsym = numpy.asarray(orbsym)
        assert (mo_energy.size == orbsym.size)

        mo_occ = numpy.zeros_like(mo_energy)
        rest_idx = []
        nelec_fix = 0
        for i, ir in enumerate(mol.irrep_id):
            irname = mol.irrep_name[i]
            ir_idx = numpy.where(orbsym == ir)[0]
            if irname in self.irrep_nelec:
                n = self.irrep_nelec[irname]
                occ_sort = numpy.argsort(mo_energy[ir_idx].round(9))
                occ_idx = ir_idx[occ_sort[:n // 2]]
                mo_occ[occ_idx] = 2
                nelec_fix += n
            else:
                rest_idx.append(ir_idx)
        nelec_float = mol.nelectron - nelec_fix
        assert (nelec_float >= 0)
        if nelec_float > 0:
            rest_idx = numpy.hstack(rest_idx)
            occ_sort = numpy.argsort(mo_energy[rest_idx].round(9))
            occ_idx = rest_idx[occ_sort[:nelec_float // 2]]
            mo_occ[occ_idx] = 2

        vir_idx = (mo_occ == 0)
        if self.verbose >= logger.INFO and numpy.count_nonzero(vir_idx) > 0:
            ehomo = max(mo_energy[mo_occ > 0])
            elumo = min(mo_energy[mo_occ == 0])
            noccs = []
            for i, ir in enumerate(mol.irrep_id):
                irname = mol.irrep_name[i]
                ir_idx = (orbsym == ir)

                noccs.append(int(mo_occ[ir_idx].sum()))
                if ehomo in mo_energy[ir_idx]:
                    irhomo = irname
                if elumo in mo_energy[ir_idx]:
                    irlumo = irname
            logger.info(self, 'H**O (%s) = %.15g  LUMO (%s) = %.15g', irhomo,
                        ehomo, irlumo, elumo)

            logger.debug(self, 'irrep_nelec = %s', noccs)
            _dump_mo_energy(mol,
                            mo_energy,
                            mo_occ,
                            ehomo,
                            elumo,
                            orbsym,
                            verbose=self.verbose)
        return mo_occ
Esempio n. 46
0
def writeNumpyforMRLCC(mc, E1, E2, frozen) :
    ncore = mc.ncore
    nact = mc.ncas
    norbs = mc.mo_coeff.shape[1]
    nelec = mc.nelecas[0]+mc.nelecas[1]
    nvirt = norbs - ncore-nact
    nc = ncore+nact
    nactElec = nelec - 2*ncore

    #this is chemistry notation
    int2popo = ao2mo.outcore.general_iofree(mc.mol, (mc.mo_coeff, mc.mo_coeff[:,:nc], mc.mo_coeff, mc.mo_coeff[:,:nc]), compact=False)
    int2ppoo = ao2mo.outcore.general_iofree(mc.mol, (mc.mo_coeff, mc.mo_coeff, mc.mo_coeff[:,:nc], mc.mo_coeff[:,:nc]), compact=False)
    int2popo.shape=(norbs, nc, norbs, nc)
    int2ppoo.shape=(norbs, norbs, nc, nc)

    mo = mc.mo_coeff

    dmcore = numpy.dot(mo[:,:frozen], mo[:,:frozen].T)*2
    vj, vk = mc._scf.get_jk(mc.mol, dmcore)
    vhfcore = reduce(numpy.dot, (mo.T, vj-vk*0.5, mo))
    int1 = reduce(numpy.dot, (mc.mo_coeff.T, mc.get_hcore(), mc.mo_coeff)) +vhfcore 

    dmcore = numpy.dot(mo[:,:ncore], mo[:,:ncore].T)*2
    vj, vk = mc._scf.get_jk(mc.mol, dmcore)
    vhfcore = reduce(numpy.dot, (mo.T, vj-vk*0.5, mo))
    int1_eff = reduce(numpy.dot, (mc.mo_coeff.T, mc.get_hcore(), mc.mo_coeff)) +vhfcore 

    #int1_eff = makeheff(int1, int2popo, int2ppoo, E1, ncore, nvirt, frozen)

    energy_frozen_core = numpy.einsum('ij,ji', dmcore, mc.get_hcore()) \
        + numpy.einsum('ij,ji', dmcore, vj-0.5*vk) * .5


    #numpy.save("int/E3",E3)
    #numpy.save("int/E3B.npy", E3.transpose(0,3,1,4,2,5))
    #numpy.save("int/E3C.npy", E3.transpose(5,0,2,4,1,3))
    numpy.save("int/E2",numpy.asfortranarray(E2))
    numpy.save("int/E1",numpy.asfortranarray(E1))
    #numpy.save("int/int2",int2)
    numpy.save("int/int1",numpy.asfortranarray(int1[frozen:,frozen:]))
    numpy.save("int/int1eff",numpy.asfortranarray(int1_eff[frozen:, frozen:]))
    
    numpy.save("int/W:caca", numpy.asfortranarray(int2ppoo[frozen:ncore, frozen:ncore, ncore:nc, ncore:nc].transpose(0,2,1,3)))
    numpy.save("int/W:caac", numpy.asfortranarray(int2popo[frozen:ncore,ncore:nc, ncore:nc, frozen:ncore].transpose(0,2,1,3)))
    
    numpy.save("int/W:cece", numpy.asfortranarray(int2ppoo[nc:, nc:, frozen:ncore, frozen:ncore].transpose(2,0,3,1)))
    numpy.save("int/W:ceec", numpy.asfortranarray(int2popo[nc:, frozen:ncore, nc:, frozen:ncore].transpose(1,2,0,3)))
    
    numpy.save("int/W:aeae", numpy.asfortranarray(int2ppoo[nc:, nc:, ncore:nc,ncore:nc].transpose(2,0,3,1)))
    numpy.save("int/W:aeea", numpy.asfortranarray(int2popo[nc:, ncore:nc,nc:, ncore:nc].transpose(1,2,0,3)))
    
    numpy.save("int/W:cccc", numpy.asfortranarray(int2ppoo[frozen:ncore,frozen:ncore, frozen:ncore, frozen:ncore].transpose(0,2,1,3)))
    numpy.save("int/W:aaaa", numpy.asfortranarray(int2ppoo[ncore:nc,ncore:nc, ncore:nc, ncore:nc].transpose(0,2,1,3)))

    feri = h5py.File("int/int2eeee.hdf5", 'w')
    ao2mo.full(mc.mol, mc.mo_coeff[:,nc:], feri, compact=False)

    for o in range(nvirt):
        int2eee = feri['eri_mo'][o*(norbs-nc):(o+1)*(norbs-nc),:]
        numpy.asfortranarray(int2eee).tofile("int/W:eeee%04d"%(o))

    #store perturbers
    numpy.save("int/W:eecc", numpy.asfortranarray(int2popo[nc:,frozen:ncore,nc:,frozen:ncore].transpose(0,2,1,3)))
    numpy.save("int/W:eeca", numpy.asfortranarray(int2popo[nc:,frozen:ncore, nc:, ncore:nc].transpose(0,2,1,3)))
    numpy.save("int/W:ccaa", numpy.asfortranarray(int2popo[frozen:ncore,ncore:nc, frozen:ncore, ncore:nc].transpose(0,2,1,3)))
    numpy.save("int/W:eeaa", numpy.asfortranarray(int2popo[nc:,ncore:nc, nc:, ncore:nc].transpose(0,2,1,3)))
    numpy.save("int/W:eaca", numpy.asfortranarray(int2popo[nc:,frozen:ncore, ncore:nc, ncore:nc].transpose(0,2,1,3)))
    numpy.save("int/W:aeca", numpy.asfortranarray(int2popo[ncore:nc,frozen:ncore, nc:,ncore:nc].transpose(0,2,1,3)))
    numpy.save("int/W:ccae", numpy.asfortranarray(int2popo[frozen:ncore,ncore:nc, nc:, frozen:ncore].transpose(0,3,1,2)))

    #write FCIDUMP_AAAV and FCIDUMP_AAAC
    from pyscf import symm
    mol = mc.mol
    orbsymout=[]
    orbsym = []
    if (mol.symmetry):
        orbsym = symm.label_orb_symm(mc.mol, mc.mol.irrep_id,
                                     mc.mol.symm_orb, mc.mo_coeff, s=mc._scf.get_ovlp())
    if mol.symmetry and orbsym:
        if mol.groupname.lower() == 'dooh':
            orbsymout = [dmrg_sym.IRREP_MAP['D2h'][i % 10] for i in orbsym]
        elif mol.groupname.lower() == 'coov':
            orbsymout = [dmrg_sym.IRREP_MAP['C2v'][i % 10] for i in orbsym]
        else:
            orbsymout = [dmrg_sym.IRREP_MAP[mol.groupname][i] for i in orbsym]
    else:
        orbsymout = []

    '''
    dmcore = numpy.dot(mo[:,frozen:ncore], mo[:,frozen:ncore].T)*2
    vj, vk = mc._scf.get_jk(mc.mol, dmcore)
    vhfcore = reduce(numpy.dot, (mo.T, vj-vk*0.5, mo))
    h1eff = int1+vhfcore
    energy_core = numpy.einsum('ij,ji', dmcore, mc.get_hcore()) \
                  + numpy.einsum('ij,ji', dmcore, vj-0.5*vk) * .5\
                  +energy_frozen_core
    '''
    dmcore = numpy.dot(mo[:,:ncore], mo[:,:ncore].T)*2
    vj, vk = mc._scf.get_jk(mc.mol, dmcore)
    vhfcore = reduce(numpy.dot, (mo.T, vj-vk*0.5, mo))
    h1eff = int1_eff
    energy_core = numpy.einsum('ij,ji', dmcore, mc.get_hcore()) \
        + numpy.einsum('ij,ji', dmcore, vj-0.5*vk) * .5

    #print energy_core2+mc.mol.energy_nuc(), energy_core+mc.mol.energy_nuc(), energy_frozen_core+mc.mol.energy_nuc()
    nc = mc.ncore+mc.ncas
    energyE0 = 1.0*numpy.einsum('ij,ij', h1eff[ncore:nc, ncore:nc], E1)
        #+ 0.5*numpy.einsum('ikjl,ijkl', E2, int2ppoo[ncore:,ncore:,ncore:,ncore:])
    for i in range(mc.ncas):
        for j in range(mc.ncas):
            for k in range(mc.ncas):
                for l in range(mc.ncas):
                    I,J = max(i,j)+ncore, min(i,j)+ncore
                    K,L = max(k,l)+ncore, min(k,l)+ncore
                    energyE0 += 0.5*E2[i,k,j,l] * int2ppoo[i+ncore, j+ncore, k+ncore, l+ncore]

    energyE0 += energy_core
    energyE0 += mc.mol.energy_nuc()
    print "Energy = ", energyE0

    fout = open('FCIDUMP_aaav0','w')
    tools.fcidump.write_head(fout, int1.shape[0]-ncore, mc.mol.nelectron-2*ncore, orbsym= orbsymout[ncore:])

    for i in range(ncore,int1.shape[0]):
        for j in range(ncore, i+1):
            for k in range(mc.ncas):
                for l in range(k+1):
                    if abs(int2ppoo[i,j, k+ncore,l+ncore]) > 1.e-8 :
                        fout.write(' %17.9e %4d %4d %4d %4d\n' \
                                   % (int2ppoo[i,j, k+ncore,l+ncore], i+1-ncore, j+1-ncore, k+1, l+1))
                    if (j >= nc and abs(int2popo[i, k+ncore, j, l+ncore]) > 1.e-8):
                        fout.write(' %17.9e %4d %4d %4d %4d\n' \
                                       % (int2popo[i,k+ncore,j, l+ncore], i+1-ncore, k+1, l+1, j+1-ncore))
                    if (j >= nc and abs(int2popo[i, l+ncore, j, k+ncore]) > 1.e-8):
                        fout.write(' %17.9e %4d %4d %4d %4d\n' \
                                       % (int2popo[i,l+ncore, j, k+ncore], i+1-ncore, l+1, k+1, j+1-ncore))


    tools.fcidump.write_hcore(fout, h1eff[ncore:,ncore:], int1.shape[0]-ncore, tol=1e-8)
    fout.write(' %17.9e  0  0  0  0\n' %( mc.mol.energy_nuc()+energy_core-energyE0))
    fout.close()

    nc = ncore+mc.ncas
    eri1cas = ao2mo.outcore.general_iofree(mc.mol, (mc.mo_coeff[:,frozen:nc], mc.mo_coeff[:,frozen:nc], mc.mo_coeff[:,frozen:nc], mc.mo_coeff[:,frozen:nc]), compact=True)
    tools.fcidump.from_integrals("FCIDUMP_aaac", int1[frozen:nc,frozen:nc], eri1cas, nc-frozen, mc.mol.nelectron-2*frozen, nuc=mc.mol.energy_nuc()-energyE0, orbsym = orbsymout[frozen:nc], tol=1e-8)

    return energyE0, norbs
Esempio n. 47
0
#
# call mol.build to construct symmetry adapted basis.
#
# NOTE the molecule orientation.  Simply assigning mol.build(symmetry=True)
# may change the orientation of the molecule.  If the orientation is different
# to the orientation of the orbital space, the orbitals cannot be symmetrized.
# To keep the molecule orientation fixed, we need specify the molecular
# symmetry.
#
mol.build(0, 0, symmetry='D2')

#
# H**O-2 H**O-1 H**O are degenerated.  They may not be properly symmetrized.
#
try:
    irrep_ids = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo)
except ValueError:
    print('The orbital symmetry cannot be labelled because some '
          'degenerated orbitals are not symmetrized.\n'
          'Degenerated H**O energy: %s' % mf.mo_energy[2:5])

nocc = mol.nelectron // 2
occ_orb = symm.symmetrize_space(mol, mo[:,:nocc])
irrep_ids = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, occ_orb)
print('Occupied orbital symmetry: %s' % irrep_ids)

virt_orb = symm.symmetrize_space(mol, mo[:,nocc:])
irrep_ids = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, virt_orb)
print('Virtual orbital symmetry: %s' % irrep_ids)

Esempio n. 48
0
                 'O': 'sto-3g',}
    mol.symmetry = 1
    mol.build()
    m = scf.RHF(mol)
    ehf = m.scf()

    norb = m.mo_coeff.shape[1]
    nelec = mol.nelectron
    h1e = reduce(numpy.dot, (m.mo_coeff.T, scf.hf.get_hcore(mol), m.mo_coeff))
    eri = ao2mo.incore.full(m._eri, m.mo_coeff)
    numpy.random.seed(1)
    na = cistring.num_strings(norb, nelec//2)
    fcivec = numpy.random.random((na,na))
    fcivec = fcivec + fcivec.T

    orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, m.mo_coeff)
    print(numpy.allclose(orbsym, [0, 0, 2, 0, 3, 0, 2]))
    cis = FCISolver(mol)
    cis.orbsym = cis.orbsym
    ci1 = cis.contract_2e(eri, fcivec, norb, nelec)
    ci1ref = direct_spin0.contract_2e(eri, fcivec, norb, nelec)
    print(numpy.allclose(ci1ref, ci1))

    mol.atom = [['H', (0, 0, i)] for i in range(8)]
    mol.basis = {'H': 'sto-3g'}
    mol.symmetry = True
    mol.build()
    m = scf.RHF(mol)
    ehf = m.scf()

    norb = m.mo_coeff.shape[1]
Esempio n. 49
0
def dmrgci(mf, TwoS, Nelec, Irrep, DSU2, Econv, MaxSweeps, NoisePrefac, frozen,
           active):

    ###  Check whether the frozen and active arrays make sense  ###
    Norbs = mf.mol.nao_nr()
    assert (np.sum(frozen < Norbs) == len(frozen))
    assert (np.sum(active < Norbs) == len(active))
    assert (np.sum(frozen >= 0) == len(frozen))
    assert (np.sum(active >= 0) == len(active))
    mo_occ = mf.mo_occ
    for item in frozen:
        assert (mo_occ[item] == 2)
        for item2 in active:
            assert (item != item2)
    frozen = frozen[frozen.argsort()]
    active = active[active.argsort()]

    ###  Get orbital information  ###
    if (len(frozen) > 0):
        mo_fro = mf.mo_coeff[:, frozen]
    mo_act = mf.mo_coeff[:, active]
    Orbsym = np.array(
        symm.label_orb_symm(
            mf.mol, mf.mol.irrep_id, mf.mol.symm_orb,
            mf.mo_coeff))[active]  # Same conventions in PySCF and CheMPS2
    for cnt in range(len(Orbsym)):
        # https://github.com/sunqm/pyscf/blob/master/symm/basis.py#L128
        Orbsym[cnt] = Orbsym[cnt] % 10

    ###  Get the JK matrix for the doubly occupied frozen orbitals  ###
    if (len(frozen) > 0):
        DM_docc = np.zeros([Norbs], dtype=float)
        DM_docc[frozen] = 2.0
        JK_docc = fetchJK_mo(mf, np.diag(DM_docc), mf.mo_coeff)
        JK_fro = (JK_docc[:, frozen])[frozen, :]
        JK_act = (JK_docc[:, active])[active, :]

    ###  Build the rotated MO matrix elements  ###
    Lrot = len(active)
    OEIao = mf.mol.intor('cint1e_kin_sph') + mf.mol.intor('cint1e_nuc_sph')
    CONST = mf.mol.energy_nuc()
    OEImo = np.dot(np.dot(mo_act.T, OEIao), mo_act)
    if (len(frozen) > 0):
        CONST += np.einsum(
            'ii->', 2 * np.dot(np.dot(mo_fro.T, OEIao), mo_fro) + JK_fro)
        OEImo += JK_act
    #TEINT in chemical notation; also possible to pass different shapes; see http://www.sunqm.net/pyscf/tutorial.html#hf-mp2-mcscf
    TEImo = ao2mo.outcore.full_iofree(mf.mol, mo_act, compact=False).reshape(
        Lrot, Lrot, Lrot, Lrot)

    ###  Reorder per irrep  ### --> not strictly necessary for CheMPS2, but converges faster
    idx = Orbsym.argsort()
    OEImo = OEImo[:, idx]
    OEImo = OEImo[idx, :]
    TEImo = TEImo[:, :, :, idx]
    TEImo = TEImo[:, :, idx, :]
    TEImo = TEImo[:, idx, :, :]
    TEImo = TEImo[idx, :, :, :]
    Orbsym = Orbsym[idx]

    ###  Do DMRG calculation with CheMPS2  ###
    EnergyDMRG, TwoRDM = call_chemps2(Lrot, mf.mol.groupname, Orbsym, CONST,
                                      OEImo, TEImo, TwoS,
                                      Nelec - 2 * len(frozen), Irrep, DSU2,
                                      Econv, MaxSweeps, NoisePrefac)

    ###  Reorder back to original ordering  ###
    idx2 = idx.argsort()
    assert (np.linalg.norm(idx[idx2] - idx2[idx]) < 1e-10)
    TwoRDM = TwoRDM[:, :, :, idx2]
    TwoRDM = TwoRDM[:, :, idx2, :]
    TwoRDM = TwoRDM[:, idx2, :, :]
    TwoRDM = TwoRDM[idx2, :, :, :]

    return (EnergyDMRG, TwoRDM)
Esempio n. 50
0
    idx = ordering_diatomics(mol, C, basis_set=basis_set)
    norb = cas_nstop - cas_nstart
    h, g = reorder_integrals(idx, h, g)
    C = C[:, idx]
    mo_energy = mo_energy[idx]
    dm_aa = dm_aa[:, idx]
    dm_aa = dm_aa[idx, :]
    dm_bb = dm_bb[:, idx]
    dm_bb = dm_bb[idx, :]

    print(h)
    print(dm_aa)

    from pyscf import symm
    mo = symm.symmetrize_orb(mol, C)
    osym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo)
    #symm.addons.symmetrize_space(mol, mo, s=None, check=True, tol=1e-07)
    for i in range(len(osym)):
        print("%4d %8s %16.8f" % (i, osym[i], mo_energy[i]))
    print("r:", r0)
    print(h)

    if do_tci:

        oocmf = CmfSolver(h, g, ecore, blocks, init_fspace, C, max_roots=100)
        oocmf.init((dm_aa, dm_bb))
        oocmf.form_extra_fspace()  #form excited fock space configurations

        h = oocmf.h
        g = oocmf.g
Esempio n. 51
0
#
# Symmetry adapted FCI solver can be called with arbitrary Hamiltonian.  In the
# following example, you need to prepare 1-electron and 2-electron integrals,
# core energy shift, and the symmetry of orbitals.
#
cas_idx = numpy.arange(2, 10)
core_idx = numpy.arange(2)
mo_cas = m.mo_coeff[:, cas_idx]
mo_core = m.mo_coeff[:, core_idx]
dm_core = mo_core.dot(mo_core.T) * 2
vhf_core = m.get_veff(mol, dm_core)
h1 = mo_cas.T.dot(m.get_hcore() + vhf_core).dot(mo_cas)
h2 = ao2mo.kernel(mol, mo_cas)
ecore = (numpy.einsum('ij,ji', dm_core, m.get_hcore()) +
         .5 * numpy.einsum('ij,ji', dm_core, vhf_core) + m.energy_nuc())
orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, mo_cas)

norb = mo_cas.shape[1]
ncore = mo_core.shape[1]
nelec = mol.nelectron - ncore * 2
fs = fci.direct_spin0_symm.FCI(mol)
fs.wfnsym = 'A2'
e, c = fs.kernel(h1, h2, norb, nelec, ecore=ecore, orbsym=orbsym, verbose=5)
print('Energy of %s state %.12f' % (fs.wfnsym, e))

#
# mcscf module has a function h1e_for_cas to generate 1-electron Hamiltonian and
# core energy.
#
cas_idx = numpy.arange(2, 10)
core_idx = numpy.arange(2)
Esempio n. 52
0
    def get_occ(self, mo_energy=None, mo_coeff=None, orbsym=None):
        if mo_energy is None: mo_energy = self.mo_energy
        mol = self.mol
        if mo_coeff is None or self._focka_ao is None:
            mo_ea = mo_eb = mo_energy
        else:
            mo_ea = numpy.einsum('ik,ik->k', mo_coeff, self._focka_ao.dot(mo_coeff))
            mo_eb = numpy.einsum('ik,ik->k', mo_coeff, self._fockb_ao.dot(mo_coeff))
        nmo = mo_ea.size
        mo_occ = numpy.zeros(nmo)
        if orbsym is None:
            if mo_coeff is not None:
                orbsym = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb,
                                             mo_coeff, self.get_ovlp(), False)
                orbsym = numpy.asarray(orbsym)
            else:
                orbsym = [numpy.repeat(ir, mol.symm_orb[i].shape[1])
                          for i, ir in enumerate(mol.irrep_id)]
                orbsym = numpy.hstack(orbsym)
        else:
            orbsym = numpy.asarray(orbsym)
        assert(mo_energy.size == orbsym.size)

        float_idx = []
        neleca_fix = 0
        nelecb_fix = 0
        for i, ir in enumerate(mol.irrep_id):
            irname = mol.irrep_name[i]
            ir_idx = numpy.where(orbsym == ir)[0]
            if irname in self.irrep_nelec:
                if isinstance(self.irrep_nelec[irname], (int, numpy.integer)):
                    nelecb = self.irrep_nelec[irname] // 2
                    neleca = self.irrep_nelec[irname] - nelecb
                else:
                    neleca, nelecb = self.irrep_nelec[irname]
                mo_occ[ir_idx] = rohf._fill_rohf_occ(mo_energy[ir_idx],
                                                     mo_ea[ir_idx], mo_eb[ir_idx],
                                                     nelecb, neleca-nelecb)
                neleca_fix += neleca
                nelecb_fix += nelecb
            else:
                float_idx.append(ir_idx)

        nelec_float = mol.nelectron - neleca_fix - nelecb_fix
        assert(nelec_float >= 0)
        if len(float_idx) > 0:
            float_idx = numpy.hstack(float_idx)
            nopen = mol.spin - (neleca_fix - nelecb_fix)
            ncore = (nelec_float - nopen)//2
            mo_occ[float_idx] = rohf._fill_rohf_occ(mo_energy[float_idx],
                                                    mo_ea[float_idx],
                                                    mo_eb[float_idx],
                                                    ncore, nopen)

        ncore = self.nelec[1]
        nocc  = self.nelec[0]
        nopen = nocc - ncore
        vir_idx = (mo_occ==0)
        if self.verbose >= logger.INFO and nocc < nmo and ncore > 0:
            ehomo = max(mo_energy[mo_occ> 0])
            elumo = min(mo_energy[mo_occ==0])
            ndoccs = []
            nsoccs = []
            for i, ir in enumerate(mol.irrep_id):
                irname = mol.irrep_name[i]
                ir_idx = (orbsym == ir)

                ndoccs.append(numpy.count_nonzero(mo_occ[ir_idx]==2))
                nsoccs.append(numpy.count_nonzero(mo_occ[ir_idx]==1))
                if ehomo in mo_energy[ir_idx]:
                    irhomo = irname
                if elumo in mo_energy[ir_idx]:
                    irlumo = irname

            # to help self.eigh compute orbital energy
            self._irrep_doccs = ndoccs
            self._irrep_soccs = nsoccs

            logger.info(self, 'H**O (%s) = %.15g  LUMO (%s) = %.15g',
                        irhomo, ehomo, irlumo, elumo)

            logger.debug(self, 'double occ irrep_nelec = %s', ndoccs)
            logger.debug(self, 'single occ irrep_nelec = %s', nsoccs)
            #_dump_mo_energy(mol, mo_energy, mo_occ, ehomo, elumo, orbsym,
            #                verbose=self.verbose)
            if nopen > 0:
                core_idx = mo_occ == 2
                open_idx = mo_occ == 1
                vir_idx = mo_occ == 0
                logger.debug(self, '                  Roothaan           | alpha              | beta')
                logger.debug(self, '  Highest 2-occ = %18.15g | %18.15g | %18.15g',
                             max(mo_energy[core_idx]),
                             max(mo_ea[core_idx]), max(mo_eb[core_idx]))
                logger.debug(self, '  Lowest 0-occ =  %18.15g | %18.15g | %18.15g',
                             min(mo_energy[vir_idx]),
                             min(mo_ea[vir_idx]), min(mo_eb[vir_idx]))
                for i in numpy.where(open_idx)[0]:
                    logger.debug(self, '  1-occ =         %18.15g | %18.15g | %18.15g',
                                 mo_energy[i], mo_ea[i], mo_eb[i])

            numpy.set_printoptions(threshold=nmo)
            logger.debug(self, '  Roothaan mo_energy =\n%s', mo_energy)
            logger.debug1(self, '  alpha mo_energy =\n%s', mo_ea)
            logger.debug1(self, '  beta  mo_energy =\n%s', mo_eb)
            numpy.set_printoptions(threshold=1000)
        return mo_occ
Esempio n. 53
0
    def get_occ(self, mo_energy=None, mo_coeff=None, orbsym=None):
        ''' We assumed mo_energy are grouped by symmetry irreps, (see function
        self.eig). The orbitals are sorted after SCF.
        '''
        if mo_energy is None: mo_energy = self.mo_energy
        mol = self.mol
        if orbsym is None:
            if mo_coeff is not None:  # due to linear-dep
                ovlp_ao = self.get_ovlp()
                orbsyma = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb,
                                              mo_coeff[0], ovlp_ao, False)
                orbsymb = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb,
                                              mo_coeff[1], ovlp_ao, False)
                orbsyma = numpy.asarray(orbsyma)
                orbsymb = numpy.asarray(orbsymb)
            else:
                ovlp_ao = None
                orbsyma = [
                    numpy.repeat(ir, mol.symm_orb[i].shape[1])
                    for i, ir in enumerate(mol.irrep_id)
                ]
                orbsyma = orbsymb = numpy.hstack(orbsyma)
        else:
            orbsyma = numpy.asarray(orbsym[0])
            orbsymb = numpy.asarray(orbsym[1])
        assert (mo_energy[0].size == orbsyma.size)

        mo_occ = numpy.zeros_like(mo_energy)
        idx_ea_left = []
        idx_eb_left = []
        neleca_fix = nelecb_fix = 0
        for i, ir in enumerate(mol.irrep_id):
            irname = mol.irrep_name[i]
            ir_idxa = numpy.where(orbsyma == ir)[0]
            ir_idxb = numpy.where(orbsymb == ir)[0]
            if irname in self.irrep_nelec:
                if isinstance(self.irrep_nelec[irname], (int, numpy.integer)):
                    nelecb = self.irrep_nelec[irname] // 2
                    neleca = self.irrep_nelec[irname] - nelecb
                else:
                    neleca, nelecb = self.irrep_nelec[irname]
                ea_idx = numpy.argsort(mo_energy[0][ir_idxa])
                eb_idx = numpy.argsort(mo_energy[1][ir_idxb])
                mo_occ[0, ir_idxa[ea_idx[:neleca]]] = 1
                mo_occ[1, ir_idxb[eb_idx[:nelecb]]] = 1
                neleca_fix += neleca
                nelecb_fix += nelecb
            else:
                idx_ea_left.append(ir_idxa)
                idx_eb_left.append(ir_idxb)

        neleca_float = self.nelec[0] - neleca_fix
        nelecb_float = self.nelec[1] - nelecb_fix
        assert (neleca_float >= 0)
        assert (nelecb_float >= 0)
        if len(idx_ea_left) > 0:
            idx_ea_left = numpy.hstack(idx_ea_left)
            ea_left = mo_energy[0][idx_ea_left]
            ea_sort = numpy.argsort(ea_left)
            occ_idx = idx_ea_left[ea_sort][:neleca_float]
            mo_occ[0][occ_idx] = 1
        if len(idx_eb_left) > 0:
            idx_eb_left = numpy.hstack(idx_eb_left)
            eb_left = mo_energy[1][idx_eb_left]
            eb_sort = numpy.argsort(eb_left)
            occ_idx = idx_eb_left[eb_sort][:nelecb_float]
            mo_occ[1][occ_idx] = 1

        vir_idx = (mo_occ[0] == 0)
        if self.verbose >= logger.INFO and numpy.count_nonzero(vir_idx) > 0:
            ehomoa = max(mo_energy[0][mo_occ[0] > 0])
            elumoa = min(mo_energy[0][mo_occ[0] == 0])
            ehomob = max(mo_energy[1][mo_occ[1] > 0])
            elumob = min(mo_energy[1][mo_occ[1] == 0])
            noccsa = []
            noccsb = []
            p0 = 0
            for i, ir in enumerate(mol.irrep_id):
                irname = mol.irrep_name[i]
                ir_idxa = orbsyma == ir
                ir_idxb = orbsymb == ir

                noccsa.append(numpy.count_nonzero(mo_occ[0][ir_idxa]))
                noccsb.append(numpy.count_nonzero(mo_occ[1][ir_idxb]))
                if ehomoa in mo_energy[0][ir_idxa]:
                    irhomoa = irname
                if elumoa in mo_energy[0][ir_idxa]:
                    irlumoa = irname
                if ehomob in mo_energy[1][ir_idxb]:
                    irhomob = irname
                if elumob in mo_energy[1][ir_idxb]:
                    irlumob = irname

            logger.info(self, 'alpha H**O (%s) = %.15g  LUMO (%s) = %.15g',
                        irhomoa, ehomoa, irlumoa, elumoa)
            logger.info(self, 'beta  H**O (%s) = %.15g  LUMO (%s) = %.15g',
                        irhomob, ehomob, irlumob, elumob)

            ehomo = max(ehomoa, ehomob)
            elumo = min(elumoa, elumob)
            logger.debug(self, 'alpha irrep_nelec = %s', noccsa)
            logger.debug(self, 'beta  irrep_nelec = %s', noccsb)
            hf_symm._dump_mo_energy(mol,
                                    mo_energy[0],
                                    mo_occ[0],
                                    ehomo,
                                    elumo,
                                    orbsyma,
                                    'alpha-',
                                    verbose=self.verbose)
            hf_symm._dump_mo_energy(mol,
                                    mo_energy[1],
                                    mo_occ[1],
                                    ehomo,
                                    elumo,
                                    orbsymb,
                                    'beta-',
                                    verbose=self.verbose)

            if mo_coeff is not None and self.verbose >= logger.DEBUG:
                if ovlp_ao is None:
                    ovlp_ao = self.get_ovlp()
                ss, s = self.spin_square((mo_coeff[0][:, mo_occ[0] > 0],
                                          mo_coeff[1][:, mo_occ[1] > 0]),
                                         ovlp_ao)
                logger.debug(self, 'multiplicity <S^2> = %.8g  2S+1 = %.8g',
                             ss, s)
        return mo_occ
Esempio n. 54
0
    }
    mol.symmetry = 1
    mol.build()
    m = scf.RHF(mol)
    ehf = m.scf()

    norb = m.mo_coeff.shape[1]
    nelec = mol.nelectron - 1
    h1e = reduce(numpy.dot, (m.mo_coeff.T, scf.hf.get_hcore(mol), m.mo_coeff))
    eri = ao2mo.incore.full(m._eri, m.mo_coeff)
    numpy.random.seed(1)
    na = cistring.num_strings(norb, nelec // 2 + 1)
    nb = cistring.num_strings(norb, nelec // 2)
    fcivec = numpy.random.random((na, nb))

    orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, m.mo_coeff)
    cis = FCISolver(mol)
    cis.orbsym = orbsym
    fcivec = addons.symmetrize_wfn(fcivec, norb, nelec, cis.orbsym, wfnsym=0)

    ci1 = cis.contract_2e(eri,
                          fcivec,
                          norb,
                          nelec,
                          orbsym=cis.orbsym,
                          wfnsym=0)
    ci1ref = direct_spin1.contract_2e(eri, fcivec, norb, nelec)
    print(numpy.allclose(ci1ref, ci1))

    ci1 = contract_2e(eri, fcivec, norb, nelec, orbsym=orbsym)
    ci1ref = direct_spin1.contract_2e(eri, fcivec, norb, nelec)
Esempio n. 55
0
def test_1():
    ###     PYSCF INPUT
    r0 = 2.0
    molecule = '''
    C  -4.308669   0.197146   0.000000
    C   4.308669  -0.197146   0.000000
    C  -3.110874  -0.411353   0.000000
    C   3.110874   0.411353   0.000000
    H  -4.394907   1.280613   0.000000
    H   4.394907  -1.280613   0.000000
    H  -5.234940  -0.367304   0.000000
    H   5.234940   0.367304   0.000000
    H  -3.069439  -1.500574   0.000000
    H   3.069439   1.500574   0.000000
    C  -1.839087   0.279751   0.000000
    C   1.839087  -0.279751   0.000000
    C  -0.634371  -0.341144   0.000000
    C   0.634371   0.341144   0.000000
    H  -1.871161   1.369551   0.000000
    H   1.871161  -1.369551   0.000000
    H  -0.607249  -1.431263   0.000000
    H   0.607249   1.431263   0.000000
    '''
    charge = 0
    spin  = 0
    basis_set = 'sto-3g'

    npoly = 4
    na = npoly
    nb = npoly

    ###     TPSCI BASIS INPUT
    orb_basis = 'PM'
    cas_nel = 2*npoly
    cas_norb = 2*npoly

    #Integrals from pyscf
    import pyscf
    from pyscf import gto, scf, ao2mo, molden, lo
    pyscf.lib.num_threads(1)  #with degenerate states and multiple processors there can be issues
    #PYSCF inputs

    mol = gto.Mole()
    mol.atom = molecule

    mol.max_memory = 1000 # MB
    mol.symmetry = True
    mol.charge = charge
    mol.spin = spin
    mol.basis = basis_set
    mol.build()
    print("symmertry")
    print(mol.topgroup)

    #SCF

    #mf = scf.RHF(mol).run(init_guess='atom')
    mf = scf.RHF(mol).run(conv_tol=1e-14)
    #C = mf.mo_coeff #MO coeffs
    enu = mf.energy_nuc()

    if mol.symmetry == True:
        from pyscf import symm
        mo = symm.symmetrize_orb(mol, mf.mo_coeff)
        osym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo)
        #symm.addons.symmetrize_space(mol, mo, s=None, check=True, tol=1e-07)
        for i in range(len(osym)):
            print("%4d %8s %16.8f"%(i+1,osym[i],mf.mo_energy[i]))

    h,ecore,g,C = get_pi_space(mol,mf,cas_norb,cas_nel,local=True)

    print("ecore %16.8f"%ecore)

    print("MULLIKEN")
    m1 = mulliken_ordering(mol,h.shape[0],C)

    ppp = np.column_stack(np.where(m1>.90))
    print(ppp)
    idx = list(ppp[:,1])
    m2 = np.where(m1>.90)
    idx = m2[1]
    C = C[:,idx]
    h,g = reorder_integrals(idx,h,g)
    #molden.from_mo(mol, 'cas.molden', C)

    blocks = [[0,1,2,3],[4,5],[6,7]]
    init_fspace = ((2,2),(1,1),(1,1))
    #blocks = [[0,1,2,3],[4,5,6,7]]
    #init_fspace = ((2,2),(2,2))


    from scipy import optimize

    oocmf = CmfSolver(h, g, ecore, blocks, init_fspace,C)
    oocmf.init()

    x = np.zeros_like(h)
    min_options = {'gtol': 1e-8, 'disp':False}
    opt_result = scipy.optimize.minimize(oocmf.energy, x, jac=oocmf.grad, method = 'BFGS', options=min_options )
    #opt_result = scipy.optimize.minimize(oocmf.energy, x, jac=oocmf.grad, method = 'BFGS', callback=oocmf.callback)
    print(opt_result.x)
    Kpq = opt_result.x.reshape(h.shape)
    print(Kpq)

    e_fcmf = oocmf.energy_dps()
    oocmf.rotate(Kpq)
    e_ocmf = oocmf.energy_dps()
    print("Orbital Frozen    CMF:%12.8f"%e_fcmf)
    print("Orbital Optimized CMF:%12.8f"%e_ocmf)

    h = oocmf.h
    g = oocmf.g
    clustered_ham = oocmf.clustered_ham
    ci_vector = oocmf.ci_vector

    edps = build_hamiltonian_diagonal(clustered_ham,ci_vector)
    print("%16.10f"%edps)

    #ref_grad = np.array([[-0.,      -0.,      -0.,      -0.,      -0.136637, -0.001116, -0.00094,   0.030398],
    #            [ 0.,       0.,      -0.,      -0.,      -0.001116, -0.136637,  0.030398, -0.00094 ],
    #            [ 0.,       0.,       0.,       0.,       0.001942, -0.033806,  0.123316, -0.002399],
    #            [ 0.,       0.,      -0.,      -0.,      -0.033806,  0.001942, -0.002399,  0.123316],
    #            [ 0.136637,  0.001116, -0.001942,  0.033806,  0.,       0.,       0.,       0.      ],
    #            [ 0.001116,  0.136637,  0.033806, -0.001942,  0.,      -0.,       0.,       0.      ],
    #            [ 0.00094,  -0.030398, -0.123316,  0.002399, -0.,      -0.,       0.,       0.      ],
    #            [-0.030398,  0.00094,   0.002399, -0.123316, -0.,      -0.,       0.,       0.      ]])

    ref_angles= np.array([[ 0.,      -0.,       -0.,       -0.,       -0.097782,  0.002467, -0.005287,  0.00192 ],
                         [ 0.,       -0.,       -0.,       -0.,        0.002467, -0.097782,  0.00192,  -0.005287],
                         [ 0.,        0.,        0.,        0.,       -0.002466, -0.123235,  0.155944, -0.004683],
                         [ 0.,        0.,       -0.,        0.,       -0.123235, -0.002466, -0.004683,  0.155944],
                         [ 0.097782, -0.002467,  0.002466,  0.123235,  0.,        0.,       -0.002248,  0.581917],
                         [-0.002467,  0.097782,  0.123235,  0.002466, -0.,       -0.,        0.581917, -0.002248],
                         [ 0.005287, -0.00192,  -0.155944,  0.004683,  0.002248, -0.581917,  0.,       -0.      ],
                         [-0.00192,   0.005287,  0.004683, -0.155944, -0.581917,  0.002248,  0.,        0.      ]])
    print(Kpq)                                                  
    print(ref_angles)
    try:
        assert(np.allclose(Kpq,ref_angles,atol=1e-5))
    except:
        assert(np.allclose(-1*Kpq,ref_angles,atol=1e-5))

    assert(abs(e_fcmf - -8.266997040181 ) <1e-8)
    assert(abs(e_ocmf - -8.528879972678 ) <1e-8)