コード例 #1
0
ファイル: hf_symm.py プロジェクト: matk86/pyscf
    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
コード例 #2
0
ファイル: ghf_symm.py プロジェクト: chrinide/pyscf
    def build(self, mol=None):
        if mol is None: mol = self.mol
        if mol.symmetry:
            for irname in self.irrep_nelec:
                if irname not in mol.irrep_name:
                    logger.warn(self, 'Molecule does not have irrep %s', irname)

            nelec_fix = self.irrep_nelec.values()
            if any(isinstance(x, (tuple, list)) for x in nelec_fix):
                msg =('Number of alpha/beta electrons cannot be assigned '
                      'separately in GHF.  irrep_nelec = %s' % self.irrep_nelec)
                raise ValueError(msg)
            nelec_fix = sum(nelec_fix)
            float_irname = set(mol.irrep_name) - set(self.irrep_nelec)
            if nelec_fix > mol.nelectron:
                msg =('More electrons defined by irrep_nelec than total num electrons. '
                      'mol.nelectron = %d  irrep_nelec = %s' %
                      (mol.nelectron, self.irrep_nelec))
                raise ValueError(msg)
            else:
                logger.info(mol, 'Freeze %d electrons in irreps %s',
                            nelec_fix, self.irrep_nelec.keys())

            if len(float_irname) == 0 and nelec_fix != mol.nelectron:
                msg =('Num electrons defined by irrep_nelec != total num electrons. '
                      'mol.nelectron = %d  irrep_nelec = %s' %
                      (mol.nelectron, self.irrep_nelec))
                raise ValueError(msg)
            else:
                logger.info(mol, '    %d free electrons in irreps %s',
                            mol.nelectron-nelec_fix, ' '.join(float_irname))
        return ghf.GHF.build(self, mol)
コード例 #3
0
ファイル: ccsd_eom.py プロジェクト: ncrubin/pyscf
 def init_amps(self, eris):
     time0 = time.clock(), time.time()
     mo_e = eris.fock.diagonal()
     nocc = self.nocc()
     nvir = mo_e.size - nocc
     t1 = np.zeros((nocc,nvir), eris.dtype)
     #eia = mo_e[:nocc,None] - mo_e[None,nocc:]
     #t1 = eris.fock[:nocc,nocc:] / eia
     t2 = np.zeros((nocc,nocc,nvir,nvir), eris.dtype)
     self.emp2 = 0
     foo = eris.fock[:nocc,:nocc]
     fvv = eris.fock[nocc:,nocc:]
     eia = np.zeros((nocc,nvir))
     eijab = np.zeros((nocc,nocc,nvir,nvir))
     for i in range(nocc):
         for a in range(nvir):
             eia[i,a] = (foo[i,i] - fvv[a,a]).real
             for j in range(nocc):
                 for b in range(nvir):
                     eijab[i,j,a,b] = ( foo[i,i] + foo[j,j]
                                      - fvv[a,a] - fvv[b,b] ).real
                     t2[i,j,a,b] = eris.oovv[i,j,a,b]/eijab[i,j,a,b]
     eris_oovv = _cp(eris.oovv)
     self.emp2 = 0.25*einsum('ijab,ijab',t2,eris_oovv.conj()).real
     logger.info(self, 'Init t2, MP2 energy = %.15g', self.emp2)
     logger.timer(self, 'init mp2', *time0)
     return self.emp2, t1, t2
コード例 #4
0
ファイル: dmet_hf.py プロジェクト: BB-Goldstein/pydmet-1
    def build_(self):
        mol = self.mol
        self.orth_coeff = self.get_orth_ao(mol)
        self.bas_on_frag = select_ao_on_fragment(mol, self.imp_atoms, \
                                                 self.imp_basidx)
        c_inv = numpy.dot(self.orth_coeff.T, self.entire_scf.get_ovlp(self.mol))
        mo_a, mo_b = self.entire_scf.mo_coeff
        occ_a, occ_b = self.entire_scf.mo_occ
        mo_orth_a = numpy.dot(c_inv, mo_a[:,self.entire_scf.mo_occ[0]>1e-15])
        mo_orth_b = numpy.dot(c_inv, mo_b[:,self.entire_scf.mo_occ[1]>1e-15])
        # self.imp_site, self.bath_orb, self.env_orb are based on orth-orbitals
        self.imp_site, self.bath_orb, self.env_orb = \
                self.decompose_orbital((mo_orth_a,mo_orth_b))
        ovlp = numpy.dot(self.bath_orb[0].T,self.bath_orb[1])[:4,:4]
        for i,c in enumerate(ovlp):
            log.debug(self, ('<bath_alpha_%d|bath_beta> = ' % i) \
                      + '%10.5f'*len(c), *c)
        self.impbas_coeff = self.cons_impurity_basis()
        self.nelectron_alpha = self.entire_scf.nelectron_alpha \
                - self.env_orb[0].shape[1]
        self.nelectron_beta = mol.nelectron \
                - self.entire_scf.nelectron_alpha \
                - self.env_orb[1].shape[1]
        log.info(self, 'alpha / beta electrons = %d / %d', \
                 self.nelectron_alpha, self.nelectron_beta)

        self.energy_by_env, self._vhf_env = self.init_vhf_env(self.env_orb)
コード例 #5
0
ファイル: kccsd.py プロジェクト: eronca/pyscf
    def init_amps(self, eris):
        time0 = time.clock(), time.time()
        nocc = self.nocc()
        nvir = self.nmo() - nocc
        nkpts = self.nkpts
        t1 = numpy.zeros((nkpts,nocc,nvir), dtype=numpy.complex128)
        t2 = numpy.zeros((nkpts,nkpts,nkpts,nocc,nocc,nvir,nvir), dtype=numpy.complex128)
        self.emp2 = 0
        foo = eris.fock[:,:nocc,:nocc].copy()
        fvv = eris.fock[:,nocc:,nocc:].copy()
        eris_oovv = eris.oovv.copy()
        eia = numpy.zeros((nocc,nvir))
        eijab = numpy.zeros((nocc,nocc,nvir,nvir))

        kconserv = tools.get_kconserv(self._scf.cell,self.kpts)
        for ki in range(nkpts):
          for kj in range(nkpts):
            for ka in range(nkpts):
                kb = kconserv[ki,ka,kj]
                for i in range(nocc):
                    for a in range(nvir):
                        eia[i,a] = foo[ki,i,i] - fvv[ka,a,a]
                        for j in range(nocc):
                            for b in range(nvir):
                                eijab[i,j,a,b] = ( foo[ki,i,i] + foo[kj,j,j]
                                                 - fvv[ka,a,a] - fvv[kb,b,b] )
                                t2[ki,kj,ka,i,j,a,b] = eris_oovv[ki,kj,ka,i,j,a,b]/eijab[i,j,a,b]

        t2 = numpy.conj(t2)
        self.emp2 = 0.25*numpy.einsum('pqrijab,pqrijab',t2,eris_oovv).real
        self.emp2 /= nkpts
        logger.info(self, 'Init t2, MP2 energy = %.15g', self.emp2.real)
        logger.timer(self, 'init mp2', *time0)
        print "MP2 energy =", self.emp2
        return self.emp2, t1, t2
コード例 #6
0
ファイル: dmrgci.py プロジェクト: pengdl/pyscf
    def kernel(self, h1e, eri, norb, nelec, fciRestart=None, **kwargs):
        if self.nroots == 1:
            roots = 0
        else:
            roots = range(self.nroots)
        if fciRestart is None:
            fciRestart = self.restart or self._restart

        writeIntegralFile(self, h1e, eri, norb, nelec)
        writeDMRGConfFile(self, nelec, fciRestart)
        if self.verbose >= logger.DEBUG1:
            inFile = os.path.join(self.runtimeDir, self.configFile)
            logger.debug1(self, 'Block Input conf')
            logger.debug1(self, open(inFile, 'r').read())
        if self.onlywriteIntegral:
            logger.info(self, 'Only write integral')
            try:
                calc_e = readEnergy(self)
            except IOError:
                if self.nroots == 1:
                    calc_e = 0.0
                else :
                    calc_e = [0.0] * self.nroots
            return calc_e, roots

        executeBLOCK(self)
        if self.verbose >= logger.DEBUG1:
            outFile = os.path.join(self.runtimeDir, self.outputFile)
            logger.debug1(self, open(outFile).read())
        calc_e = readEnergy(self)

        return calc_e, roots
コード例 #7
0
ファイル: dhf.py プロジェクト: BB-Goldstein/pyscf
 def get_occ(self, mo_energy=None, mo_coeff=None):
     if mo_energy is None:
         mo_energy = self.mo_energy
     mol = self.mol
     n4c = len(mo_energy)
     n2c = n4c // 2
     mo_occ = numpy.zeros(n2c * 2)
     if mo_energy[n2c] > -1.999 * mol.light_speed ** 2:
         mo_occ[n2c : n2c + mol.nelectron] = 1
     else:
         n = 0
         for i, e in enumerate(mo_energy):
             if e > -1.999 * mol.light_speed ** 2 and n < mol.nelectron:
                 mo_occ[i] = 1
                 n += 1
     if self.verbose >= logger.INFO:
         logger.info(
             self,
             "H**O %d = %.12g, LUMO %d = %.12g,",
             (n2c + mol.nelectron) // 2,
             mo_energy[n2c + mol.nelectron - 1],
             (n2c + mol.nelectron) // 2 + 1,
             mo_energy[n2c + mol.nelectron],
         )
         logger.debug(self, "NES  mo_energy = %s", mo_energy[:n2c])
         logger.debug(self, "PES  mo_energy = %s", mo_energy[n2c:])
     return mo_occ
コード例 #8
0
ファイル: uccsd.py プロジェクト: eronca/pyscf
    def ccsd(self, t1=None, t2=None, eris=None, mbpt2=False):
        '''Ground-state unrestricted (U)CCSD.

        Kwargs:
            mbpt2 : bool
                Use one-shot MBPT2 approximation to CCSD.
        '''
        if eris is None: eris = self.ao2mo(self.mo_coeff)
        self.eris = eris
        self.dump_flags()
        if mbpt2:
            cctyp = 'MBPT2'
            self.e_corr, self.t1, self.t2 = self.init_amps(eris)
        else:
            cctyp = 'CCSD'
            self.converged, self.e_corr, self.t1, self.t2 = \
                    kernel(self, eris, t1, t2, max_cycle=self.max_cycle,
                           tol=self.conv_tol, tolnormt=self.conv_tol_normt,
                           verbose=self.verbose)
            if self.converged:
                logger.info(self, 'CCSD converged')
            else:
                logger.info(self, 'CCSD not converged')
        if self._scf.e_tot == 0:
            logger.note(self, 'E_corr = %.16g', self.e_corr)
        else:
            logger.note(self, 'E(%s) = %.16g  E_corr = %.16g',
                        cctyp, self.e_tot, self.e_corr)
        return self.e_corr, self.t1, self.t2
コード例 #9
0
ファイル: addons.py プロジェクト: chrinide/pyscf
    def get_occ(mo_energy_kpts=None, mo_coeff=None):
        if mo_energy_kpts is None: mo_energy_kpts = mf.mo_energy

        if nelec is None:
            cell_nelec = mf.cell.nelec
        else:
            cell_nelec = nelec

        h**o=[-1e8,-1e8]
        lumo=[1e8,1e8]
        mo_occ_kpts = [[], []]
        for s in [0,1]:
            for k, mo_energy in enumerate(mo_energy_kpts[s]):
                e_idx = numpy.argsort(mo_energy)
                e_sort = mo_energy[e_idx]
                n = cell_nelec[s]
                mo_occ = numpy.zeros_like(mo_energy)
                mo_occ[e_idx[:n]] = 1
                h**o[s] = max(h**o[s], e_sort[n-1])
                lumo[s] = min(lumo[s], e_sort[n])
                mo_occ_kpts[s].append(mo_occ)

        for nm,s in zip(['alpha','beta'],[0,1]):
            logger.info(mf, nm+' H**O = %.12g  LUMO = %.12g', h**o[s], lumo[s])
            if h**o[s] > lumo[s]:
                logger.warn(mf, "WARNING! H**O is greater than LUMO! "
                            "This may lead to incorrect canonical occupation.")

        return mo_occ_kpts
コード例 #10
0
ファイル: rohf.py プロジェクト: chrinide/pyscf
def get_occ(mf, mo_energy=None, mo_coeff=None):
    '''Label the occupancies for each orbital.
    NOTE the occupancies are not assigned based on the orbital energy ordering.
    The first N orbitals are assigned to be occupied orbitals.

    Examples:

    >>> mol = gto.M(atom='H 0 0 0; O 0 0 1.1', spin=1)
    >>> mf = scf.hf.SCF(mol)
    >>> energy = numpy.array([-10., -1., 1, -2., 0, -3])
    >>> mf.get_occ(energy)
    array([2, 2, 2, 2, 1, 0])
    '''

    if mo_energy is None: mo_energy = mf.mo_energy
    if getattr(mo_energy, 'mo_ea', None) is not None:
        mo_ea = mo_energy.mo_ea
        mo_eb = mo_energy.mo_eb
    else:
        mo_ea = mo_eb = mo_energy
    nmo = mo_ea.size
    mo_occ = numpy.zeros(nmo)
    if getattr(mf, 'nelec', None) is None:
        nelec = mf.mol.nelec
    else:
        nelec = mf.nelec
    ncore = nelec[1]
    nocc  = nelec[0]
    nopen = abs(nocc - ncore)
    mo_occ = _fill_rohf_occ(mo_energy, mo_ea, mo_eb, ncore, nopen)

    if mf.verbose >= logger.INFO and nocc < nmo and ncore > 0:
        ehomo = max(mo_energy[mo_occ> 0])
        elumo = min(mo_energy[mo_occ==0])
        if ehomo+1e-3 > elumo:
            logger.warn(mf, 'H**O %.15g >= LUMO %.15g', ehomo, elumo)
        else:
            logger.info(mf, '  H**O = %.15g  LUMO = %.15g', ehomo, elumo)
        if nopen > 0 and mf.verbose >= logger.DEBUG:
            core_idx = mo_occ == 2
            open_idx = mo_occ == 1
            vir_idx = mo_occ == 0
            logger.debug(mf, '                  Roothaan           | alpha              | beta')
            logger.debug(mf, '  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(mf, '  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(mf, '  1-occ =         %18.15g | %18.15g | %18.15g',
                             mo_energy[i], mo_ea[i], mo_eb[i])

        if mf.verbose >= logger.DEBUG:
            numpy.set_printoptions(threshold=nmo)
            logger.debug(mf, '  Roothaan mo_energy =\n%s', mo_energy)
            logger.debug1(mf, '  alpha mo_energy =\n%s', mo_ea)
            logger.debug1(mf, '  beta  mo_energy =\n%s', mo_eb)
            numpy.set_printoptions(threshold=1000)
    return mo_occ
コード例 #11
0
ファイル: uccsd.py プロジェクト: wmizukami/pyscf
    def init_amps(self, eris=None):
        time0 = time.clock(), time.time()
        if eris is None:
            eris = self.ao2mo(self.mo_coeff)
        nocca, noccb = self.nocc

        fova = eris.focka[:nocca,nocca:]
        fovb = eris.fockb[:noccb,noccb:]
        mo_ea_o = eris.mo_energy[0][:nocca]
        mo_ea_v = eris.mo_energy[0][nocca:]
        mo_eb_o = eris.mo_energy[1][:noccb]
        mo_eb_v = eris.mo_energy[1][noccb:]
        eia_a = lib.direct_sum('i-a->ia', mo_ea_o, mo_ea_v)
        eia_b = lib.direct_sum('i-a->ia', mo_eb_o, mo_eb_v)

        t1a = fova.conj() / eia_a
        t1b = fovb.conj() / eia_b

        eris_ovov = np.asarray(eris.ovov)
        eris_OVOV = np.asarray(eris.OVOV)
        eris_ovOV = np.asarray(eris.ovOV)
        t2aa = eris_ovov.transpose(0,2,1,3) / lib.direct_sum('ia+jb->ijab', eia_a, eia_a)
        t2ab = eris_ovOV.transpose(0,2,1,3) / lib.direct_sum('ia+jb->ijab', eia_a, eia_b)
        t2bb = eris_OVOV.transpose(0,2,1,3) / lib.direct_sum('ia+jb->ijab', eia_b, eia_b)
        t2aa = t2aa - t2aa.transpose(0,1,3,2)
        t2bb = t2bb - t2bb.transpose(0,1,3,2)
        e  =      np.einsum('iJaB,iaJB', t2ab, eris_ovOV)
        e += 0.25*np.einsum('ijab,iajb', t2aa, eris_ovov)
        e -= 0.25*np.einsum('ijab,ibja', t2aa, eris_ovov)
        e += 0.25*np.einsum('ijab,iajb', t2bb, eris_OVOV)
        e -= 0.25*np.einsum('ijab,ibja', t2bb, eris_OVOV)
        self.emp2 = e.real
        logger.info(self, 'Init t2, MP2 energy = %.15g', self.emp2)
        logger.timer(self, 'init mp2', *time0)
        return self.emp2, (t1a,t1b), (t2aa,t2ab,t2bb)
コード例 #12
0
    def init_amps(self, eris):
        time0 = time.clock(), time.time()
        nocc = self.nocc()
        nvir = self.nmo() - nocc
        nkpts = self.nkpts
        t1 = numpy.zeros((nkpts, nocc, nvir), dtype=numpy.complex128)
        t2 = numpy.zeros((nkpts, nkpts, nkpts, nocc, nocc, nvir, nvir), dtype=numpy.complex128)
        woovv = numpy.empty((nkpts, nkpts, nkpts, nocc, nocc, nvir, nvir), dtype=numpy.complex128)
        self.emp2 = 0
        foo = eris.fock[:, :nocc, :nocc].copy()
        fvv = eris.fock[:, nocc:, nocc:].copy()
        eris_oovv = eris.oovv.copy()
        eia = numpy.zeros((nocc, nvir))
        eijab = numpy.zeros((nocc, nocc, nvir, nvir))

        kconserv = self.kconserv
        for ki in range(nkpts):
            for kj in range(nkpts):
                for ka in range(nkpts):
                    kb = kconserv[ki, ka, kj]
                    eia = np.diagonal(foo[ki]).reshape(-1, 1) - np.diagonal(fvv[ka])
                    ejb = np.diagonal(foo[kj]).reshape(-1, 1) - np.diagonal(fvv[kb])
                    eijab = lib.direct_sum("ia,jb->ijab", eia, ejb)
                    woovv[ki, kj, ka] = 2 * eris_oovv[ki, kj, ka] - eris_oovv[ki, kj, kb].transpose(0, 1, 3, 2)
                    t2[ki, kj, ka] = eris_oovv[ki, kj, ka] / eijab

        t2 = numpy.conj(t2)
        self.emp2 = numpy.einsum("pqrijab,pqrijab", t2, woovv).real
        self.emp2 /= nkpts
        logger.info(self, "Init t2, MP2 energy = %.15g", self.emp2)
        logger.timer(self, "init mp2", *time0)
        return self.emp2, t1, t2
コード例 #13
0
ファイル: addons.py プロジェクト: chrinide/pyscf
def remove_linear_dep_(mf, threshold=LINEAR_DEP_THRESHOLD,
                       lindep=LINEAR_DEP_TRIGGER):
    '''
    Args:
        threshold : float
            The threshold under which the eigenvalues of the overlap matrix are
            discarded to avoid numerical instability.
        lindep : float
            The threshold that triggers the special treatment of the linear
            dependence issue.
    '''
    s = mf.get_ovlp()
    cond = numpy.max(lib.cond(s))
    if cond < 1./lindep:
        return mf

    logger.info(mf, 'Applying remove_linear_dep_ on SCF obejct.')
    logger.debug(mf, 'Overlap condition number %g', cond)
    def eigh(h, s):
        d, t = numpy.linalg.eigh(s)
        x = t[:,d>threshold] / numpy.sqrt(d[d>threshold])
        xhx = reduce(numpy.dot, (x.T.conj(), h, x))
        e, c = numpy.linalg.eigh(xhx)
        c = numpy.dot(x, c)
        return e, c
    mf._eigh = eigh
    return mf
コード例 #14
0
ファイル: dmet_nonsc.py プロジェクト: BB-Goldstein/pydmet-1
    def energy_calc(self):
        log.info(self, '==== Calculating DMET E_corr with read-in v_fit ====')
        mol = self.mol
        self.init_embsys(mol)
        emb = self.embs[0]
        emb.verbose = self.verbose
        emb.imp_scf()
        nimp = len(emb.bas_on_frag)

        print('Correlation potential: ')
        print(self._init_v)
        
        etot, e2frag, dm1 = self.solver.run(emb, emb._eri, self._init_v, with_1pdm=True,
                                            with_e2frag=nimp)
        log.debug(self,'Total energy returned from solver: %.11g',etot)
        e_tot = etot + emb.energy_by_env
        e_frag, nelec_frag = self.extract_frag_energy(emb, dm1, e2frag)
        hfdm = emb.make_rdm1(emb.mo_coeff_on_imp, emb.mo_occ)
        vhf = emb.get_veff(mol, hfdm)
        nelechf = hfdm[:nimp].trace()
        ehfinhf = (hfdm[:nimp]*(emb._pure_hcore)[:nimp]).sum() \
                + (hfdm[:nimp]*(vhf+emb._vhf_env)[:nimp]).sum() * .5
        log.debug(self, 'without further fitting, e_tot = %.11g, e_frag = %.11g, nelec_frag = %.11g',
                  e_tot, e_frag, nelec_frag)
        log.debug(self, '              HF-in-HF, frag energy = %.12g, nelec = %.9g',
                 ehfinhf, nelechf)
        log.debug(self, '             FCI-in-HF, frag energy = %.12g, E_corr = %.12g, nelec = %.9g', \
                  e_frag, e_frag-ehfinhf, nelec_frag)
        log.log(self, 'dmet_nonsc.energy_calc: e_tot = %.11g, (+nuc=%.11g)', \
                e_tot, e_tot+mol.energy_nuc())
        log.log(self, 'e_frag = %.11g, nelec_frag = %.11g', e_frag, nelec_frag)
        return e_tot
コード例 #15
0
    def get_occ(mo_energy=None, mo_coeff=None): 
        if mo_energy is None: mo_energy = mf.mo_energy
        if mo_coeff is None: mo_coeff = mf.mo_coeff
        if isinstance(mf, pyscf.scf.rohf.ROHF): mo_coeff = numpy.array([mo_coeff, mo_coeff])
        mo_occ = numpy.zeros_like(setocc)
        nocc_a = int(numpy.sum(setocc[0]))
        nocc_b = int(numpy.sum(setocc[1]))
        s_a = reduce(numpy.dot, (coef_occ_a.T, mf.get_ovlp(), mo_coeff[0])) 
        s_b = reduce(numpy.dot, (coef_occ_b.T, mf.get_ovlp(), mo_coeff[1]))
        #choose a subset of mo_coeff, which maximizes <old|now>
        idx_a = numpy.argsort(numpy.einsum('ij,ij->j', s_a, s_a))
        idx_b = numpy.argsort(numpy.einsum('ij,ij->j', s_b, s_b))
        mo_occ[0][idx_a[-nocc_a:]] = 1.
        mo_occ[1][idx_b[-nocc_b:]] = 1.

        if mf.verbose >= logger.DEBUG: 
            logger.info(mf, ' New alpha occ pattern: %s', mo_occ[0]) 
            logger.info(mf, ' New beta occ pattern: %s', mo_occ[1]) 
        if mf.verbose >= logger.DEBUG1:
            if mo_energy.ndim == 2: 
                logger.info(mf, ' Current alpha mo_energy(sorted) = %s', mo_energy[0]) 
                logger.info(mf, ' Current beta mo_energy(sorted) = %s', mo_energy[1])
            elif mo_energy.ndim == 1:
                logger.info(mf, ' Current mo_energy(sorted) = %s', mo_energy)

        if (int(numpy.sum(mo_occ[0])) != nocc_a):
            log.error(self, 'mom alpha electron occupation numbers do not match: %d, %d', 
                      nocc_a, int(numpy.sum(mo_occ[0])))
        if (int(numpy.sum(mo_occ[1])) != nocc_b):
            log.error(self, 'mom alpha electron occupation numbers do not match: %d, %d', 
                      nocc_b, int(numpy.sum(mo_occ[1])))

        #output 1-dimension occupation number for restricted open-shell
        if isinstance(mf, pyscf.scf.rohf.ROHF): mo_occ = mo_occ[0, :] + mo_occ[1, :]
        return mo_occ
コード例 #16
0
ファイル: casci.py プロジェクト: chrinide/pyscf
    def kernel(self, mo_coeff=None, ci=None, atmlst=None, mf_grad=None,
               state=None, verbose=None):
        cput0 = (time.clock(), time.time())
        log = logger.new_logger(self, verbose)
        if ci is None: ci = self.base.ci
        if isinstance(ci, (list, tuple)):
            if state is None:
                state = self.state
            else:
                self.state = state

            ci = ci[state]
            logger.info(self, 'Multiple roots are found in CASCI solver. '
                        'Nuclear gradients of root %d are computed.', state)

        if atmlst is None:
            atmlst = self.atmlst
        else:
            self.atmlst = atmlst

        if self.verbose >= logger.WARN:
            self.check_sanity()
        if self.verbose >= logger.INFO:
            self.dump_flags()

        self.de = kernel(self.base, mo_coeff, ci, atmlst, mf_grad, log)
        log.timer('CASCI gradients', *cput0)
        self._finalize()
        return self.de
コード例 #17
0
ファイル: dhf.py プロジェクト: pengdl/pyscf
    def get_jk(self, mol=None, dm=None, hermi=1):
        if mol is None: mol = self.mol
        if dm is None: dm = self.make_rdm1()
        t0 = (time.clock(), time.time())
        verbose_bak, mol.verbose = mol.verbose, self.verbose
        stdout_bak,  mol.stdout  = mol.stdout , self.stdout
        if self.direct_scf and self.opt[0] is None:
            self.opt = self.init_direct_scf(mol)
        opt_llll, opt_ssll, opt_ssss, opt_gaunt = self.opt

        vj, vk = get_jk_coulomb(mol, dm, hermi, self._coulomb_now,
                                opt_llll, opt_ssll, opt_ssss)

        if self.with_breit:
            if 'SSSS' in self._coulomb_now.upper() or not self.with_ssss:
                vj1, vk1 = _call_veff_gaunt_breit(mol, dm, hermi, opt_gaunt, True)
                logger.info(self, 'Add Breit term')
                vj += vj1
                vk += vk1
        elif self.with_gaunt and 'SS' in self._coulomb_now.upper():
            logger.info(self, 'Add Gaunt term')
            vj1, vk1 = _call_veff_gaunt_breit(mol, dm, hermi, opt_gaunt, False)
            vj += vj1
            vk += vk1

        mol.verbose = verbose_bak
        mol.stdout  = stdout_bak
        logger.timer(self, 'vj and vk', *t0)
        return vj, vk
コード例 #18
0
 def dump_flags(self, verbose=None):
     direct_spin1.FCISolver.dump_flags(self, verbose)
     if isinstance(self.wfnsym, str):
         logger.info(self, 'specified total symmetry = %s', self.wfnsym)
     elif isinstance(self.wfnsym, (int, numpy.integer)):
         logger.info(self, 'specified total symmetry = %s',
                     symm.irrep_id2name(self.mol.groupname, self.wfnsym))
コード例 #19
0
ファイル: hf.py プロジェクト: diradical/pyscf
    def get_occ(self, mo_energy=None, mo_coeff=None):
        '''Label the occupancies for each orbital

        Kwargs:
            mo_energy : 1D ndarray
                Obital energies

            mo_coeff : 2D ndarray
                Obital coefficients

        Examples:

        >>> from pyscf import gto, scf
        >>> mol = gto.M(atom='H 0 0 0; F 0 0 1.1')
        >>> mf = scf.hf.SCF(mol)
        >>> mf.get_occ(numpy.arange(mol.nao_nr()))
        array([2, 2, 2, 2, 2, 0])
        '''
        if mo_energy is None: mo_energy = self.mo_energy
        mo_occ = numpy.zeros_like(mo_energy)
        nocc = self.mol.nelectron // 2
        mo_occ[:nocc] = 2
        if nocc < mo_occ.size:
            logger.info(self, 'H**O = %.12g, LUMO = %.12g,',
                        mo_energy[nocc-1], mo_energy[nocc])
            if mo_energy[nocc-1]+1e-3 > mo_energy[nocc]:
                logger.warn(self, '!! H**O %.12g == LUMO %.12g',
                            mo_energy[nocc-1], mo_energy[nocc])
        else:
            logger.info(self, 'H**O = %.12g,', mo_energy[nocc-1])
        if self.verbose >= logger.DEBUG:
            numpy.set_printoptions(threshold=len(mo_energy))
            logger.debug(self, '  mo_energy = %s', mo_energy)
            numpy.set_printoptions()
        return mo_occ
コード例 #20
0
ファイル: hf.py プロジェクト: berquist/pyscf
 def get_init_guess(self, mol=None, key='minao'):
     if mol is None:
         mol = self.mol
     if callable(key):
         dm = key(mol)
     elif key.lower() == '1e':
         dm = self.init_guess_by_1e(mol)
     elif getattr(mol, 'natm', 0) == 0:
         logger.info(self, 'No atom found in mol. Use 1e initial guess')
         dm = self.init_guess_by_1e(mol)
     elif key.lower() == 'atom':
         dm = self.init_guess_by_atom(mol)
     elif key.lower() == 'chkfile':
         try:
             dm = self.init_guess_by_chkfile()
         except (IOError, KeyError):
             logger.warn(self, 'Fail in reading %s. Use MINAO initial guess',
                         self.chkfile)
             dm = self.init_guess_by_minao(mol)
     else:
         dm = self.init_guess_by_minao(mol)
     if self.verbose >= logger.DEBUG1:
         logger.debug1(self, 'Nelec from initial guess = %g',
                       (dm*self.get_ovlp()).sum().real)
     return dm
コード例 #21
0
ファイル: nevpt2.py プロジェクト: chrinide/pyscf
    def compress_approx(self,maxM=500, nevptsolver=None, tol=1e-7, stored_integral =False):
        '''SC-NEVPT2 with compressed perturber

        Kwargs :
            maxM : int
                DMRG bond dimension

        Examples:

        >>> mf = gto.M('N 0 0 0; N 0 0 1.4', basis='6-31g').apply(scf.RHF).run()
        >>> mc = dmrgscf.DMRGSCF(mf, 4, 4).run()
        >>> NEVPT(mc, root=0).compress_approx(maxM=100).kernel()
        -0.14058324991532101
        '''
        #TODO
        #Some preprocess for compressed perturber
        if getattr(self.fcisolver, 'nevpt_intermediate', None):
            logger.info(self, 'Use compressed mps perturber as an approximation')
        else:
            msg = 'Compressed mps perturber can be only used with DMRG wave function'
            logger.error(self, msg)
            raise RuntimeError(msg)

        self.nevptsolver = nevptsolver
        self.maxM = maxM
        self.tol = tol
        self.stored_integral = stored_integral

        self.canonicalized = True
        self.compressed_mps = True
        return self
コード例 #22
0
ファイル: rohf.py プロジェクト: cheaps10/pyscf
    def get_occ(self, mo_energy=None, mo_coeff=None):
        '''Label the occupancies for each orbital.
        NOTE the occupancies are not assigned based on the orbital energy ordering.
        The first N orbitals are assigned to be occupied orbitals.

        Examples:

        >>> mol = gto.M(atom='H 0 0 0; O 0 0 1.1', spin=1)
        >>> mf = scf.hf.SCF(mol)
        >>> energy = numpy.array([-10., -1., 1, -2., 0, -3])
        >>> mf.get_occ(energy)
        array([2, 2, 2, 2, 1, 0])
        '''

        if mo_energy is None: mo_energy = self.mo_energy
        mo_occ = numpy.zeros_like(mo_energy)
        ncore = self.nelec[1]
        nopen = self.nelec[0] - ncore
        nocc = ncore + nopen
        mo_occ[:ncore] = 2
        mo_occ[ncore:nocc] = 1
        if nocc < len(mo_energy):
            logger.info(self, 'H**O = %.12g  LUMO = %.12g',
                        mo_energy[nocc-1], mo_energy[nocc])
            if mo_energy[nocc-1]+1e-3 > mo_energy[nocc]:
                logger.warn(self.mol, '!! H**O %.12g == LUMO %.12g',
                            mo_energy[nocc-1], mo_energy[nocc])
        else:
            logger.info(self, 'H**O = %.12g  no LUMO', mo_energy[nocc-1])
        if nopen > 0:
            for i in range(ncore, nocc):
                logger.debug(self, 'singly occupied orbital energy = %.12g',
                             mo_energy[i])
        logger.debug(self, '  mo_energy = %s', mo_energy)
        return mo_occ
コード例 #23
0
ファイル: fciqmc.py プロジェクト: v1j4y/pyscf
def read_energy(fciqmcci):
    '''Read and return the final RDM energy from a NECI output file.

    Args:
        fciqmcci : an instance of :class:`FCIQMCCI`
            Specifies the FCIQMC calculation. Used to locate the FCIQMC output
            file.

    Returns:
        rdm_energy : float
            The final RDM energy printed to the output file.
    '''

    out_file = open(os.path.join(fciqmcci.scratchDirectory,
                 fciqmcci.outputFileCurrent), "r")

    for line in out_file:
        # Lookup the RDM energy from the output.
        if "*TOTAL ENERGY* CALCULATED USING THE" in line:
            rdm_energy = float(line.split()[-1])
            break
    logger.info(fciqmcci, 'Total energy from FCIQMC: %.15f', rdm_energy)
    out_file.close()

    return rdm_energy
コード例 #24
0
ファイル: nevpt2.py プロジェクト: pengdl/pyscf
    def compress_approx(self,maxM=500, compress_schedule=None, tol=1e-7, stored_integral =False):
        '''SC-NEVPT2 with compressed perturber

        Kwargs :
            maxM : int
                DMRG bond dimension

        Examples:

        >>> mf = gto.M('N 0 0 0; N 0 0 1.4', basis='6-31g').apply(scf.RHF).run()
        >>> mc = dmrgscf.DMRGSCF(mf, 4, 4).run()
        >>> NEVPT(mc, root=0).compress_approx(maxM=100).kernel()
        -0.14058324991532101
        '''
        #TODO
        #Some preprocess for compressed perturber
        if hasattr(self.fcisolver, 'nevpt_intermediate'):
            logger.info(self, 'Use compressed mps perturber as an aaproximation')
        else:
            logger.error(self, 'Compressed mps perturber can be only used for DMRG wave function')
            exit()

        from pyscf.dmrgscf.nevpt_mpi import DMRG_COMPRESS_NEVPT
        if stored_integral: #Stored perturbation integral and read them again. For debugging purpose.
            DMRG_COMPRESS_NEVPT('nevpt_perturb_integral',maxM= maxM, root= self.root, nevptsolver= compress_schedule, tol= tol)
        else:
            DMRG_COMPRESS_NEVPT(self,maxM= maxM, root= self.root, nevptsolver= compress_schedule, tol= tol)

        self.canonicalized = True
        self.compressed_mps = True
        return self
コード例 #25
0
ファイル: uhf.py プロジェクト: eronca/pyscf
 def dump_flags(self):
     pyscf.scf.uhf.UHF.dump_flags(self)
     logger.info(self, '******** PBC SCF flags ********')
     logger.info(self, 'kpt = %s', self.kpt)
     logger.info(self, 'DF object = %s', self.with_df)
     logger.info(self, 'Exchange divergence treatment (exxdiv) = %s', self.exxdiv)
     logger.info(self, 'number electrons alpha = %d  beta = %d', *self.nelec)
コード例 #26
0
ファイル: dmet_hf.py プロジェクト: BB-Goldstein/pydmet-1
    def frag_mulliken_pop(self):
        '''Mulliken M_ij = D_ij S_ji, Mulliken chg_i = \sum_j M_ij'''
        mol = self.mol
        log.info(self, ' ** Mulliken pop (on impurity basis)  **')
        s1e = mol.intor_symmetric('cint1e_ovlp_sph')
        c_inv = numpy.dot(self.orth_coeff.T, s1e)
        c_frag = numpy.dot(c_inv, self.impbas_coeff)
        dm = self.make_rdm1(self.mo_coeff_on_imp, self.mo_occ)
        nimp = len(self.bas_on_frag)
        dm[nimp:] = 0
        dm = reduce(numpy.dot, (c_frag, dm, c_frag.T.conj()))
        pop = dm.diagonal()
        label = mol.spheric_labels()

        for i, s in enumerate(label):
            if s[0] in self.imp_atoms:
                log.info(self, 'pop of  %d%s %s%4s ' % s \
                         + ' %10.5f' % pop[i])

        log.info(self, ' ** Mulliken atomic charges  **')
        chg = numpy.zeros(mol.natm)
        for i, s in enumerate(label):
            if s[0] in self.imp_atoms:
                chg[s[0]] += pop[i]
        frag_charge = 0
        for ia in self.imp_atoms:
            symb = mol.atom_symbol(ia)
            nuc = mol.atom_charge(ia)
            log.info(self, 'charge of  %d%s =   %10.5f', \
                     ia, symb, nuc - chg[ia])
            frag_charge += nuc - chg[ia]
        log.info(self, 'charge of embsys = %10.5f', frag_charge)
コード例 #27
0
ファイル: dmet_sc.py プロジェクト: BB-Goldstein/pydmet-1
    def assemble_frag_energy(self, mol):
        e_tot = 0
        nelec = 0
        e_corr = 0

        last_frag = -1
        for m, _, _ in self.all_frags:
            if m != last_frag:
                emb = self.embs[m]
                nimp = len(emb.bas_on_frag)
                _, e2frag, dm1 = \
                        self.solver.run(emb, emb._eri, emb.vfit_ci,
                                        with_1pdm=True, with_e2frag=nimp)
                e_frag, nelec_frag = \
                        self.extract_frag_energy(emb, dm1, e2frag)

                log.debug(self, 'fragment %d FCI-in-HF, frag energy = %.12g, E_corr = %.12g, nelec = %.9g', \
                          m, e_frag, e_frag-emb._ehfinhf, nelec_frag)
            e_corr += e_frag-emb._ehfinhf
            e_tot += e_frag
            nelec += nelec_frag
            last_frag = m
        log.info(self, 'sum(e_frag), e_tot = %.9g, nelec_tot = %.9g', \
                  e_tot, nelec)
        return e_tot, e_corr, nelec
コード例 #28
0
ファイル: rks_grad.py プロジェクト: berquist/pyscf
 def dump_flags(self):
     rhf_grad.Gradients.dump_flags(self)
     if callable(self._scf.grids.prune):
         logger.info(self, 'Grid pruning %s may affect DFT gradients accuracy.'
                     'Call mf.grids.run(prune=False) to mute grid pruning',
                     self._scf.grids.prune)
     return self
コード例 #29
0
ファイル: dmet_sc_part.py プロジェクト: BB-Goldstein/pydmet-1
    def assemble_frag_fci_energy(self, mol, dm_ref=0):
        if len(self.bas_off_frags) == 0:
            e_tot = 0
            nelec = 0
        else:
            if dm_ref is 0:
                eff_scf = self.entire_scf
                sc = numpy.dot(eff_scf.get_ovlp(mol), self.orth_coeff)
                mo = numpy.dot(sc.T,eff_scf.mo_coeff)
                dm_ref = eff_scf.make_rdm1(mo, eff_scf.mo_occ)
            e_tot, nelec = self.off_frags_energy(mol, dm_ref)

        last_frag = -1
        for m, _, _ in self.all_frags:
            if m != last_frag:
                emb = self.embs[m]
                nimp = len(emb.bas_on_frag)
                _, e2frag, dm1 = \
                        self.solver.run(emb, emb._eri, emb.vfit_ci,
                                        with_1pdm=True, with_e2frag=nimp)
                e_frag, nelec_frag = \
                        self.extract_frag_energy(emb, dm1, e2frag)
                log.debug(self, 'e_frag = %.12g, nelec_frag = %.12g', \
                          e_frag, nelec_frag)
            e_tot += e_frag
            nelec += nelec_frag
            last_frag = m
        log.info(self, 'DMET-FCI-in-HF of entire system, e_tot = %.9g, nelec_tot = %.9g', \
                  e_tot, nelec)
        return e_tot, nelec
コード例 #30
0
ファイル: rohf.py プロジェクト: berquist/pyscf
 def init_guess_by_1e(self, mol=None):
     if mol is None: mol = self.mol
     logger.info(self, 'Initial guess from hcore.')
     h1e = self.get_hcore(mol)
     s1e = self.get_ovlp(mol)
     mo_energy, mo_coeff = hf.RHF.eig(self, h1e, s1e)
     mo_occ = self.get_occ(mo_energy, mo_coeff)
     return self.make_rdm1(mo_coeff, mo_occ)
コード例 #31
0
 def dump_flags(self, verbose=None):
     direct_spin1.FCISolver.dump_flags(self, verbose)
     logger.info(self, 'ci_coeff_cutoff %g', self.ci_coeff_cutoff)
     logger.info(self, 'select_cutoff   %g', self.select_cutoff)
コード例 #32
0
    def eeccsd(self, nroots=1, koopmans=False, guess=None, partition=None):
        '''Calculate N-electron neutral excitations via EE-EOM-CCSD.

        Kwargs:
            nroots : int
                Number of roots (eigenvalues) requested
            partition : bool or str
                Use a matrix-partitioning for the doubles-doubles block.
                Can be None, 'mp' (Moller-Plesset, i.e. orbital energies on the diagonal),
                or 'full' (full diagonal elements).
            koopmans : bool
                Calculate Koopmans'-like (1p1h) excitations only, targeting via
                overlap.
            guess : list of ndarray
                List of guess vectors to use for targeting via overlap.
        '''
        cput0 = (time.clock(), time.time())
        log = logger.Logger(self.stdout, self.verbose)
        size = self.nee()
        nroots = min(nroots, size)
        if partition:
            partition = partition.lower()
            assert partition in ['mp', 'full']
        self.ee_partition = partition
        if partition == 'full':
            self._eeccsd_diag_matrix2 = self.vector_to_amplitudes_ee(
                self.eeccsd_diag())[1]

        nvir = self.nmo - self.nocc
        adiag = self.eeccsd_diag()
        user_guess = False
        if guess:
            user_guess = True
            assert len(guess) == nroots
            for g in guess:
                assert g.size == size
        else:
            guess = []
            idx = adiag.argsort()
            n = 0
            for i in idx:
                g = np.zeros(size)
                g[i] = 1.0
                if koopmans:
                    if np.linalg.norm(g[:self.nocc * nvir])**2 > 0.8:
                        guess.append(g)
                        n += 1
                else:
                    guess.append(g)
                    n += 1
                if n == nroots:
                    break

        def precond(r, e0, x0):
            return r / (e0 - adiag + 1e-12)

        eig = linalg_helper.eig
        if user_guess or koopmans:

            def pickeig(w, v, nr, envs):
                x0 = linalg_helper._gen_x0(envs['v'], envs['xs'])
                idx = np.argmax(np.abs(
                    np.dot(np.array(guess).conj(),
                           np.array(x0).T)),
                                axis=1)
                return w[idx].real, v[:, idx].real, idx

            eee, evecs = eig(self.eeccsd_matvec,
                             guess,
                             precond,
                             pick=pickeig,
                             tol=self.conv_tol,
                             max_cycle=self.max_cycle,
                             max_space=self.max_space,
                             nroots=nroots,
                             verbose=self.verbose)
        else:
            eee, evecs = eig(self.eeccsd_matvec,
                             guess,
                             precond,
                             tol=self.conv_tol,
                             max_cycle=self.max_cycle,
                             max_space=self.max_space,
                             nroots=nroots,
                             verbose=self.verbose)

        self.eee = eee.real

        if nroots == 1:
            eee, evecs = [self.eee], [evecs]
        for n, en, vn in zip(range(nroots), eee, evecs):
            logger.info(self, 'EE root %d E = %.16g  qpwt = %0.6g', n, en,
                        np.linalg.norm(vn[:self.nocc * nvir])**2)
        log.timer('EE-CCSD', *cput0)
        if nroots == 1:
            return eee[0], evecs[0]
        else:
            return eee, evecs
コード例 #33
0
ファイル: umc2step.py プロジェクト: zzy2014/pyscf
def kernel(casscf, mo_coeff, tol=1e-7, conv_tol_grad=None,
           ci0=None, callback=None, verbose=None, dump_chk=True):
    if verbose is None:
        verbose = casscf.verbose
    log = logger.Logger(casscf.stdout, verbose)
    cput0 = (time.clock(), time.time())
    log.debug('Start 2-step CASSCF')

    mo = mo_coeff
    nmo = mo[0].shape[1]
    ncore = casscf.ncore
    eris = casscf.ao2mo(mo)
    e_tot, e_cas, fcivec = casscf.casci(mo, ci0, eris, log, locals())
    if casscf.ncas == nmo and not casscf.internal_rotation:
        return True, e_tot, e_cas, fcivec, mo

    if conv_tol_grad is None:
        conv_tol_grad = numpy.sqrt(tol)
        logger.info(casscf, 'Set conv_tol_grad to %g', conv_tol_grad)
    conv_tol_ddm = conv_tol_grad * 3
    conv = False
    de, elast = e_tot, e_tot
    totmicro = totinner = 0
    casdm1 = (0,0)
    r0 = None

    t2m = t1m = log.timer('Initializing 2-step CASSCF', *cput0)
    imacro = 0
    while not conv and imacro < casscf.max_cycle_macro:
        imacro += 1
        njk = 0
        t3m = t2m
        casdm1_old = casdm1
        casdm1, casdm2 = casscf.fcisolver.make_rdm12s(fcivec, casscf.ncas, casscf.nelecas)
        norm_ddm =(numpy.linalg.norm(casdm1[0] - casdm1_old[0]) +
                   numpy.linalg.norm(casdm1[1] - casdm1_old[1]))
        t3m = log.timer('update CAS DM', *t3m)
        max_cycle_micro = 1 # casscf.micro_cycle_scheduler(locals())
        max_stepsize = casscf.max_stepsize_scheduler(locals())
        for imicro in range(max_cycle_micro):
            rota = casscf.rotate_orb_cc(mo, lambda:fcivec, lambda:casdm1, lambda:casdm2,
                                        eris, r0, conv_tol_grad*.3, max_stepsize, log)
            u, g_orb, njk1, r0 = next(rota)
            rota.close()
            njk += njk1
            norm_t = numpy.linalg.norm(u-numpy.eye(nmo))
            norm_gorb = numpy.linalg.norm(g_orb)
            if imicro == 0:
                norm_gorb0 = norm_gorb
            t3m = log.timer('orbital rotation', *t3m)

            eris = None
            u = copy.copy(u)
            g_orb = copy.copy(g_orb)
            mo = casscf.rotate_mo(mo, u, log)
            eris = casscf.ao2mo(mo)
            t3m = log.timer('update eri', *t3m)

            log.debug('micro %d  |u-1|=%5.3g  |g[o]|=%5.3g  |dm1|=%5.3g',
                      imicro, norm_t, norm_gorb, norm_ddm)

            if callable(callback):
                callback(locals())

            t2m = log.timer('micro iter %d'%imicro, *t2m)
            if norm_t < 1e-4 or norm_gorb < conv_tol_grad*.5:
                break

        totinner += njk
        totmicro += imicro+1

        e_tot, e_cas, fcivec = casscf.casci(mo, fcivec, eris, log, locals())
        log.timer('CASCI solver', *t3m)
        t2m = t1m = log.timer('macro iter %d'%imacro, *t1m)

        de, elast = e_tot - elast, e_tot
        if (abs(de) < tol and
            norm_gorb < conv_tol_grad and norm_ddm < conv_tol_ddm):
            conv = True

        if dump_chk:
            casscf.dump_chk(locals())

        if callable(callback):
            callback(locals())

    if conv:
        log.info('2-step CASSCF converged in %d macro (%d JK %d micro) steps',
                 imacro+1, totinner, totmicro)
    else:
        log.info('2-step CASSCF not converged, %d macro (%d JK %d micro) steps',
                 imacro+1, totinner, totmicro)
    log.timer('2-step CASSCF', *cput0)
    return conv, e_tot, e_cas, fcivec, mo
コード例 #34
0
ファイル: kccsd.py プロジェクト: quansilong/pyscf
 def dump_flags(self, verbose=None):
     logger.info(self, '\n')
     logger.info(self, '******** PBC CC flags ********')
     gccsd.GCCSD.dump_flags(self, verbose)
     return self
コード例 #35
0
 def dump_flags(self, verbose=None):
     hf.SCF.dump_flags(self, verbose)
     logger.info(self, 'number electrons alpha = %d  beta = %d',
                 *self.nelec)
コード例 #36
0
def check_irrep_nelec(mol, irrep_nelec, nelec):
    for irname in irrep_nelec:
        if irname not in mol.irrep_name:
            logger.warn(mol, 'Molecule does not have irrep %s', irname)

    float_irname = []
    fix_na = 0
    fix_nb = 0
    free_irrep_norbs = []
    for i, irname in enumerate(mol.irrep_name):
        if irname in irrep_nelec:
            if isinstance(irrep_nelec[irname], (int, numpy.integer)):
                nelecb = irrep_nelec[irname] // 2
                neleca = irrep_nelec[irname] - nelecb
            else:
                neleca, nelecb = irrep_nelec[irname]
            norb = mol.symm_orb[i].shape[1]
            if neleca > norb or nelecb > norb:
                msg = ('More electrons than orbitals for irrep %s '
                       'nelec = %d + %d, norb = %d' %
                       (irname, neleca, nelecb, norb))
                raise ValueError(msg)
            fix_na += neleca
            fix_nb += nelecb
        else:
            float_irname.append(irname)
            free_irrep_norbs.append(mol.symm_orb[i].shape[1])

    if isinstance(nelec, (int, numpy.integer)):
        nelecb = nelec // 2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    fix_ne = fix_na + fix_nb
    float_neleca = neleca - fix_na
    float_nelecb = nelecb - fix_nb
    free_norb = sum(free_irrep_norbs)
    if ((fix_na > neleca) or (fix_nb > nelecb)
            or (fix_na + nelecb > mol.nelectron)
            or (fix_nb + neleca > mol.nelectron)):
        msg = (
            'More electrons defined by irrep_nelec than total num electrons. '
            'mol.nelectron = %d  irrep_nelec = %s' %
            (mol.nelectron, irrep_nelec))
        raise ValueError(msg)
    else:
        logger.info(mol, 'Freeze %d electrons in irreps %s', fix_ne,
                    list(irrep_nelec.keys()))

    if len(set(float_irname)) == 0 and fix_ne != mol.nelectron:
        msg = ('Num electrons defined by irrep_nelec != total num electrons. '
               'mol.nelectron = %d  irrep_nelec = %s' %
               (mol.nelectron, irrep_nelec))
        raise ValueError(msg)
    elif float_neleca > free_norb or float_nelecb > free_norb:
        raise ValueError(
            'Not enough orbitals for (%d, %d) electrons in irreps %s '
            '(irrep_norb: %s)' %
            (float_neleca, float_nelecb, ' '.join(float_irname), free_norb))
    else:
        logger.info(mol, '    %d free electrons in irreps %s',
                    mol.nelectron - fix_ne, ' '.join(float_irname))
    return fix_na, fix_nb, float_irname
コード例 #37
0
 def dump_flags(self, verbose=None):
     ragf2.RAGF2.dump_flags(self, verbose=verbose)
     logger.info(self, 'nmom = %s', repr(self.nmom))
     return self
コード例 #38
0
def kernel(casscf,
           mo_coeff,
           tol=1e-7,
           conv_tol_grad=None,
           ci0=None,
           callback=None,
           verbose=None,
           dump_chk=True):
    from pyscf.mcscf.addons import StateAverageMCSCFSolver
    if verbose is None:
        verbose = casscf.verbose
    if callback is None:
        callback = casscf.callback

    log = logger.Logger(casscf.stdout, verbose)
    cput0 = (logger.process_clock(), logger.perf_counter())
    log.debug('Start 2-step CASSCF')

    mo = mo_coeff
    nmo = mo.shape[1]
    ncore = casscf.ncore
    ncas = casscf.ncas
    nocc = ncore + ncas
    eris = casscf.ao2mo(mo)
    e_tot, e_cas, fcivec = casscf.casci(mo, ci0, eris, log, locals())
    if ncas == nmo and not casscf.internal_rotation:
        if casscf.canonicalization:
            log.debug('CASSCF canonicalization')
            mo, fcivec, mo_energy = casscf.canonicalize(
                mo,
                fcivec,
                eris,
                casscf.sorting_mo_energy,
                casscf.natorb,
                verbose=log)
        else:
            mo_energy = None
        return True, e_tot, e_cas, fcivec, mo, mo_energy

    if conv_tol_grad is None:
        conv_tol_grad = numpy.sqrt(tol)
        logger.info(casscf, 'Set conv_tol_grad to %g', conv_tol_grad)
    conv_tol_ddm = conv_tol_grad * 3
    conv = False
    de, elast = e_tot, e_tot
    totmicro = totinner = 0
    casdm1 = 0
    r0 = None

    t2m = t1m = log.timer('Initializing 2-step CASSCF', *cput0)
    imacro = 0
    while not conv and imacro < casscf.max_cycle_macro:
        imacro += 1
        njk = 0
        t3m = t2m
        casdm1_old = casdm1
        casdm1, casdm2 = casscf.fcisolver.make_rdm12(fcivec, ncas,
                                                     casscf.nelecas)
        norm_ddm = numpy.linalg.norm(casdm1 - casdm1_old)
        t3m = log.timer('update CAS DM', *t3m)
        max_cycle_micro = 1  # casscf.micro_cycle_scheduler(locals())
        max_stepsize = casscf.max_stepsize_scheduler(locals())
        for imicro in range(max_cycle_micro):
            rota = casscf.rotate_orb_cc(mo, lambda: fcivec, lambda: casdm1,
                                        lambda: casdm2, eris, r0,
                                        conv_tol_grad * .3, max_stepsize, log)
            u, g_orb, njk1, r0 = next(rota)
            rota.close()
            njk += njk1
            norm_t = numpy.linalg.norm(u - numpy.eye(nmo))
            norm_gorb = numpy.linalg.norm(g_orb)
            if imicro == 0:
                norm_gorb0 = norm_gorb
            de = numpy.dot(casscf.pack_uniq_var(u), g_orb)
            t3m = log.timer('orbital rotation', *t3m)

            eris = None
            u = u.copy()
            g_orb = g_orb.copy()
            mo = casscf.rotate_mo(mo, u, log)
            eris = casscf.ao2mo(mo)
            t3m = log.timer('update eri', *t3m)

            log.debug(
                'micro %d  ~dE=%5.3g  |u-1|=%5.3g  |g[o]|=%5.3g  |dm1|=%5.3g',
                imicro, de, norm_t, norm_gorb, norm_ddm)

            if callable(callback):
                callback(locals())

            t2m = log.timer('micro iter %d' % imicro, *t2m)
            if norm_t < 1e-4 or abs(
                    de) < tol * .4 or norm_gorb < conv_tol_grad * .2:
                break

        totinner += njk
        totmicro += imicro + 1

        max_offdiag_u = numpy.abs(numpy.triu(u, 1)).max()
        if max_offdiag_u < casscf.small_rot_tol:
            small_rot = True
            log.debug(
                'Small orbital rotation, restart CI if supported by solver')
        else:
            small_rot = False
        if not isinstance(casscf, StateAverageMCSCFSolver):
            # The fcivec from builtin FCI solver is a numpy.ndarray
            if not isinstance(fcivec, numpy.ndarray):
                fcivec = small_rot
        else:
            newvecs = []
            for subvec in fcivec:
                if not isinstance(subvec, numpy.ndarray):
                    newvecs.append(small_rot)
                else:
                    newvecs.append(subvec)
            fcivec = newvecs

        e_tot, e_cas, fcivec = casscf.casci(mo, fcivec, eris, log, locals())
        log.timer('CASCI solver', *t3m)
        t2m = t1m = log.timer('macro iter %d' % imacro, *t1m)

        de, elast = e_tot - elast, e_tot
        if (abs(de) < tol and norm_gorb < conv_tol_grad
                and norm_ddm < conv_tol_ddm
                and (max_offdiag_u < casscf.small_rot_tol
                     or casscf.small_rot_tol == 0)):
            conv = True
        else:
            elast = e_tot

        if dump_chk:
            casscf.dump_chk(locals())

        if callable(callback):
            callback(locals())

    if conv:
        log.info('2-step CASSCF converged in %d macro (%d JK %d micro) steps',
                 imacro, totinner, totmicro)
    else:
        log.info(
            '2-step CASSCF not converged, %d macro (%d JK %d micro) steps',
            imacro, totinner, totmicro)

    if casscf.canonicalization:
        log.info('CASSCF canonicalization')
        mo, fcivec, mo_energy = \
                casscf.canonicalize(mo, fcivec, eris, casscf.sorting_mo_energy,
                                    casscf.natorb, casdm1, log)
        if casscf.natorb and dump_chk:  # dump_chk may save casdm1
            occ, ucas = casscf._eig(-casdm1, ncore, nocc)
            casdm1 = numpy.diag(-occ)
    else:
        if casscf.natorb:
            # FIXME (pyscf-2.0): Whether to transform natural orbitals in
            # active space when this flag is enabled?
            log.warn(
                'The attribute natorb of mcscf object affects only the '
                'orbital canonicalization.\n'
                'If you would like to get natural orbitals in active space '
                'without touching core and external orbitals, an explicit '
                'call to mc.cas_natorb_() is required')
        mo_energy = None

    if dump_chk:
        casscf.dump_chk(locals())

    log.timer('2-step CASSCF', *cput0)
    return conv, e_tot, e_cas, fcivec, mo, mo_energy
コード例 #39
0
 def dump_flags(self):
     ghf.GHF.dump_flags(self)
     if self.irrep_nelec:
         logger.info(self, 'irrep_nelec %s', self.irrep_nelec)
     return self
コード例 #40
0
 def init_guess_by_huckel(self, mol=None):
     if mol is None: mol = self.mol
     logger.info(self, 'Initial guess from on-the-fly Huckel, doi:10.1021/acs.jctc.8b01089.')
     return init_guess_by_huckel(mol)
コード例 #41
0
ファイル: dks.py プロジェクト: zwgsyntax/pyscf
 def dump_flags(self, verbose=None):
     dhf.UHF.dump_flags(self, verbose)
     logger.info(self, 'XC functionals = %s', self.xc)
     logger.info(self, 'small_rho_cutoff = %g', self.small_rho_cutoff)
     self.grids.dump_flags(verbose)
コード例 #42
0
 def init_guess_by_atom(self, mol=None):
     if mol is None: mol = self.mol
     logger.info(self, 'Initial guess from the superpostion of atomic densties.')
     return init_guess_by_atom(mol)
コード例 #43
0
 def dump_flags(self, verbose=None):
     hf.SCF.dump_flags(self, verbose)
     nelec = self.nelec
     logger.info(self, 'num. doubly occ = %d  num. singly occ = %d',
                 nelec[1], nelec[0]-nelec[1])
コード例 #44
0
def get_occ(mf, mo_energy=None, mo_coeff=None):
    '''Label the occupancies for each orbital.
    NOTE the occupancies are not assigned based on the orbital energy ordering.
    The first N orbitals are assigned to be occupied orbitals.

    Examples:

    >>> mol = gto.M(atom='H 0 0 0; O 0 0 1.1', spin=1)
    >>> mf = scf.hf.SCF(mol)
    >>> energy = numpy.array([-10., -1., 1, -2., 0, -3])
    >>> mf.get_occ(energy)
    array([2, 2, 2, 2, 1, 0])
    '''

    if mo_energy is None: mo_energy = mf.mo_energy
    if getattr(mo_energy, 'mo_ea', None) is not None:
        mo_ea = mo_energy.mo_ea
        mo_eb = mo_energy.mo_eb
    else:
        mo_ea = mo_eb = mo_energy
    nmo = mo_ea.size
    mo_occ = numpy.zeros(nmo)
    if getattr(mf, 'nelec', None) is None:
        nelec = mf.mol.nelec
    else:
        nelec = mf.nelec
    if nelec[0] > nelec[1]:
        nocc, ncore = nelec
    else:
        ncore, nocc = nelec
    nopen = nocc - ncore
    mo_occ = _fill_rohf_occ(mo_energy, mo_ea, mo_eb, ncore, nopen)

    if mf.verbose >= logger.INFO and nocc < nmo and ncore > 0:
        ehomo = max(mo_energy[mo_occ> 0])
        elumo = min(mo_energy[mo_occ==0])
        if ehomo+1e-3 > elumo:
            logger.warn(mf, 'H**O %.15g >= LUMO %.15g', ehomo, elumo)
        else:
            logger.info(mf, '  H**O = %.15g  LUMO = %.15g', ehomo, elumo)
        if nopen > 0 and mf.verbose >= logger.DEBUG:
            core_idx = mo_occ == 2
            open_idx = mo_occ == 1
            vir_idx = mo_occ == 0
            logger.debug(mf, '                  Roothaan           | alpha              | beta')
            logger.debug(mf, '  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(mf, '  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(mf, '  1-occ =         %18.15g | %18.15g | %18.15g',
                             mo_energy[i], mo_ea[i], mo_eb[i])

        if mf.verbose >= logger.DEBUG:
            numpy.set_printoptions(threshold=nmo)
            logger.debug(mf, '  Roothaan mo_energy =\n%s', mo_energy)
            logger.debug1(mf, '  alpha mo_energy =\n%s', mo_ea)
            logger.debug1(mf, '  beta  mo_energy =\n%s', mo_eb)
            numpy.set_printoptions(threshold=1000)
    return mo_occ
コード例 #45
0
    def get_occ(self, mo_energy=None, mo_coeff=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 getattr(mo_energy, 'mo_ea', None) is not None:
            mo_ea = mo_energy.mo_ea
            mo_eb = mo_energy.mo_eb
        else:
            mo_ea = mo_eb = mo_energy
        nmo = mo_ea.size
        mo_occ = numpy.zeros(nmo)

        orbsym = self.get_orbsym(mo_coeff, self.get_ovlp())

        rest_idx = numpy.ones(mo_occ.size, dtype=bool)
        neleca_fix = 0
        nelecb_fix = 0
        for i, ir in enumerate(mol.irrep_id):
            irname = mol.irrep_name[i]
            if irname in self.irrep_nelec:
                ir_idx = numpy.where(orbsym == ir)[0]
                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]
                if neleca > nelecb:
                    ncore, nopen = nelecb, neleca - nelecb
                else:
                    ncore, nopen = neleca, nelecb - neleca
                mo_occ[ir_idx] = rohf._fill_rohf_occ(mo_energy[ir_idx],
                                                     mo_ea[ir_idx],
                                                     mo_eb[ir_idx], ncore,
                                                     nopen)
                neleca_fix += neleca
                nelecb_fix += nelecb
                rest_idx[ir_idx] = False

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

        nocc, ncore = self.nelec
        nopen = nocc - ncore
        vir_idx = (mo_occ == 0)
        if self.verbose >= logger.INFO and nocc < nmo and ncore > 0:
            ehomo = max(mo_energy[~vir_idx])
            elumo = min(mo_energy[vir_idx])
            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
コード例 #46
0
    def get_occ(self, mo_energy=None, mo_coeff=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 ghf.GHF.get_occ(self, mo_energy, mo_coeff)

        orbsym = get_orbsym(mol, mo_coeff)
        mo_occ = numpy.zeros_like(mo_energy)
        rest_idx = numpy.ones(mo_occ.size, dtype=bool)
        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),
                                         kind='mergesort')
                occ_idx = ir_idx[occ_sort[:n]]
                mo_occ[occ_idx] = 1
                nelec_fix += n
                rest_idx[ir_idx] = False
        nelec_float = mol.nelectron - nelec_fix
        assert (nelec_float >= 0)
        if nelec_float > 0:
            rest_idx = numpy.where(rest_idx)[0]
            occ_sort = numpy.argsort(mo_energy[rest_idx].round(9),
                                     kind='mergesort')
            occ_idx = rest_idx[occ_sort[:nelec_float]]
            mo_occ[occ_idx] = 1

        vir_idx = (mo_occ == 0)
        if self.verbose >= logger.INFO and numpy.count_nonzero(vir_idx) > 0:
            ehomo = max(mo_energy[~vir_idx])
            elumo = min(mo_energy[vir_idx])
            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)
            hf_symm._dump_mo_energy(mol,
                                    mo_energy,
                                    mo_occ,
                                    ehomo,
                                    elumo,
                                    orbsym,
                                    verbose=self.verbose)

            if mo_coeff is not None and self.verbose >= logger.DEBUG:
                ss, s = self.spin_square(mo_coeff[:, mo_occ > 0],
                                         self.get_ovlp())
                logger.debug(self, 'multiplicity <S^2> = %.8g  2S+1 = %.8g',
                             ss, s)
        return mo_occ
コード例 #47
0
 def dump_flags(self, verbose=None):
     rohf.ROHF.dump_flags(self, verbose)
     if self.irrep_nelec:
         logger.info(self, 'irrep_nelec %s', self.irrep_nelec)
     return self
コード例 #48
0
 def dump_flags(self, verbose=None):
     logger.info(self, '** DFTD3 parameter **')
     logger.info(self, 'func %s', self.xc)
     logger.info(self, 'version %s', self.version)
     return self
コード例 #49
0
 def dump_flags(self):
     hf.SCF.dump_flags(self)
     logger.info(self, 'with_ssss %s, with_gaunt %s, with_breit %s',
                 self.with_ssss, self.with_gaunt, self.with_breit)
コード例 #50
0
 def dump_flags(self):
     logger.info(self, 'radial grids: %s', self.radi_method.__doc__)
     logger.info(self, 'becke partition: %s', self.becke_scheme.__doc__)
     logger.info(self, 'pruning grids: %s', self.prune)
     logger.info(self, 'grids dens level: %d', self.level)
     logger.info(self, 'symmetrized grids: %d', self.symmetry)
     if self.radii_adjust is not None:
         logger.info(self, 'atomic radii adjust function: %s',
                     self.radii_adjust)
         logger.debug2(self, 'atomic_radii : %s', self.atomic_radii)
     if self.atom_grid:
         logger.info(self, 'User specified grid scheme %s',
                     str(self.atom_grid))
     return self
コード例 #51
0
ファイル: kuhf.py プロジェクト: rvexiau/pyscf
 def dump_flags(self, verbose=None):
     khf.KSCF.dump_flags(self, verbose)
     logger.info(self, 'number of electrons per unit cell  '
                 'alpha = %d beta = %d', *self.nelec)
     return self
コード例 #52
0
ファイル: ccsd_moms.py プロジェクト: ghb24/pyscf
def make_moms_hole(mycc, nmom_max_h, t1, t2, l1, l2, ao_repr=False, ns_def=True):
    '''
    Spin-traced one-hole moment in MO basis.

    mom_h[p,q] = \sum_{sigma} <q_sigma^\dagger (H-E_0)^n p_sigma>

    ns_def defines the terms according to the Nooijen & Snijders definitions given
    in IJQC 48 15-48 (1993).
    The alternate definition simply changes the tensor which is antisymmetrized in the spin integration for products of tensors
    They should be identical.
    '''
        
    #partition : bool or str
    #    Use a matrix-partitioning for the doubles-doubles block.
    #    Can be None, 'mp' (Moller-Plesset, i.e. orbital energies on the diagonal),
    #    or 'full' (full diagonal elements).
    partition = getattr(__config__, 'eom_rccsd_EOM_partition', None)
    logger.info(mycc, 'partition = %s', partition)
    #print "Partition value is: ", partition
    if partition is not None: assert partition.lower() in ['mp','full']
    # ns_def breaks sum rules
    #assert(not ns_def)

    nocc, nvir = t1.shape
    nmo = mycc.nmo
    dtype = np.result_type(t1, t2)
    vector_size = nocc + nocc*nocc*nvir

    imds = eom_rccsd._IMDS(mycc)
    imds.make_ip(partition)
    diag = ipccsd_diag(imds, partition)
    theta = t2 * 2 - t2.transpose(0,1,3,2)
    theta_lam = l2 * 2 - l2.transpose(1,0,2,3)

    # Construct RHS (b) vector as a_p + [a_p, T] |phi>
    # Construct LHS (e) vector as <phi|(1+L)(a_q^\dagger + [a_q^\dagger , T])
    b_vecs = np.zeros((vector_size, nmo), dtype)
    e_vecs = np.zeros((vector_size, nmo), dtype)

    # Improve this so no explicit looping
    for p in range(nocc):
        b1 = np.zeros((nocc), dtype)
        b2 = np.zeros((nocc, nocc, nvir), dtype)
        e1 = np.zeros((nocc), dtype)
        e2 = np.zeros((nocc, nocc, nvir), dtype)

        b1[p] = -1.0
        
        e1[p] = 1.
        e1 -= np.einsum('ic, c -> i', l1, t1[p,:])
        e1 -= np.einsum('jlcd, lcd -> j', l2, theta[p,:,:,:])

        if ns_def:
            # N-S result
            e2[p,:,:] = 2. * l1[:,:]
            e2[:,p,:] -= l1[:,:]
            e2 -= np.einsum('c, ijcb -> ijb', t1[p,:], theta_lam)
        else:
            # Result for consistency with pyscf cc-rdm (lambda values antisymmetrized!?)
            e2[:,p,:] = l1
            e2 -= np.einsum('c, jicb -> ijb', t1[p,:], l2)
        
        b_vecs[:,p] = amplitudes_to_vector_ip(b1, b2)
        e_vecs[:,p] = amplitudes_to_vector_ip(e1, e2)

    for p in range(nvir):
        
        b1 = -t1[:,p]
        if ns_def:
            b2 = -t2[:,:,p,:]           # This is in Nooijen paper
        else:
            b2 = -theta[:,:,:,p]
        
        e1 = l1[:,p]
        if ns_def:
            e2 = theta_lam[:,:,p,:]   # This is in Nooijen paper
        else:
            e2 = l2[:,:,:,p]   

        b_vecs[:,p+nocc] = amplitudes_to_vector_ip(b1, b2)
        e_vecs[:,p+nocc] = amplitudes_to_vector_ip(e1, e2)

    # Now, apply {\bar H} to each b
    hole_moms = [np.zeros((nmo, nmo)) for i in range(nmom_max_h+1)]
    # TODO: Would this work for complex?
    hole_moms[0] = np.dot(e_vecs.T.conj(),b_vecs)
    hole_moms[0] += hole_moms[0].conj().T
    #hole_moms[0] = -2.*np.dot(e_vecs.T.conj(),b_vecs)

    h_RHS = np.zeros_like(b_vecs)
    for h_app in range(nmom_max_h):
        if h_app == 0:
            for p in range(nmo):
                h_RHS[:,p] = ipccsd_matvec(b_vecs[:,p], imds, diag, nocc, nmo, partition)
        else:
            for p in range(nmo):
                h_RHS[:,p] = ipccsd_matvec(h_RHS[:,p], imds, diag, nocc, nmo, partition)

        hole_moms[h_app+1] = -np.dot(e_vecs.conj().T,h_RHS)
        hole_moms[h_app+1] += hole_moms[h_app+1].conj().T 

    if ao_repr:
        mo = mycc.mo_coeff
        hole_moms = [lib.einsum('pi,ij,qj->pq', mo, mom, mo.conj()) for mom in hole_moms]

    return hole_moms
コード例 #53
0
ファイル: mole.py プロジェクト: theorychemyang/pyscf
    def build(self, quantum_nuc='all', q_nuc_occ=None, **kwargs):
        '''assign which nuclei are treated quantum mechanically by quantum_nuc (list)'''
        super().build(self, **kwargs)

        self.quantum_nuc = [False] * self.natm

        if quantum_nuc == 'all':
            self.quantum_nuc = [True] * self.natm
            logger.info(self, 'All atoms are treated quantum-mechanically by default.')
        elif isinstance(quantum_nuc, list):
            for i in quantum_nuc:
                self.quantum_nuc[i] = True
                logger.info(self, 'The %s(%i) atom is treated quantum-mechanically' %(self.atom_symbol(i), i))
        else:
            raise TypeError('Unsupported parameter %s' %(quantum_nuc))

        self.nuc_num = len([i for i in self.quantum_nuc if i == True])

        self.mass = self.atom_mass_list(isotope_avg=True)
        for i in range(self.natm):
            if self.atom_symbol(i) == 'H@2': # Deuterium (from Wikipedia)
                self.mass[i] = 2.01410177811
            elif self.atom_symbol(i) == 'H@0': # Muonium (TODO: precise mass)
                self.mass[i] = 0.114
            elif self.atom_pure_symbol(i) == 'H': # Proton (from Wikipedia)
                self.mass[i] = 1.007276466621

        # build the Mole object for electrons and classical nuclei
        self.elec = gto.Mole()
        self.elec.super_mol = self
        self.elec.build(**kwargs)

        # deal with fractional number of nuclei
        if q_nuc_occ is not None:
            q_nuc_occ = numpy.array(q_nuc_occ)
            if q_nuc_occ.size != self.nuc_num:
                raise ValueError('q_nuc_occ must match the dimension of quantum_nuc')
            unocc = numpy.ones_like(q_nuc_occ) - q_nuc_occ
            unocc_Z = 0
            idx = 0
        # set all quantum nuclei to have zero charges
        quantum_nuclear_charge = 0
        for i in range(self.natm):
            if self.quantum_nuc[i] is True:
                quantum_nuclear_charge -= self.elec._atm[i, 0]
                if q_nuc_occ is not None:
                    unocc_Z += unocc[idx] * self.elec._atm[i, 0]
                    idx += 1
                self.elec._atm[i, 0] = 0 # set nuclear charges of quantum nuclei to 0
        self.elec.charge += quantum_nuclear_charge # charge determines the number of electrons
        if q_nuc_occ is not None:
            # remove excessive electrons to make the system neutral
            self.elec.charge += numpy.floor(unocc_Z)
            self.elec.nhomo = 1.0 - (unocc_Z - numpy.floor(unocc_Z))
        else:
            self.elec.nhomo = None

        # build a list of Mole objects for quantum nuclei
        if q_nuc_occ is None:
            q_nuc_occ = [None] * self.nuc_num
        idx = 0
        for i in range(self.natm):
            if self.quantum_nuc[i] == True:
                self.nuc.append(self.build_nuc_mole(i, frac=q_nuc_occ[idx]))
                idx += 1
コード例 #54
0
ファイル: ccsd_moms.py プロジェクト: ghb24/pyscf
def make_moms_part(mycc, nmom_max_p, t1, t2, l1, l2, ao_repr=False):
    '''
    Spin-traced one-particle moment (EA) in MO basis.

    mom_h[p,q] = \sum_{sigma} <q_sigma (H-E_0)^n p_sigma^\dagger>
        
    '''
        
    #partition : bool or str
    #    Use a matrix-partitioning for the doubles-doubles block.
    #    Can be None, 'mp' (Moller-Plesset, i.e. orbital energies on the diagonal),
    #    or 'full' (full diagonal elements).
    partition = getattr(__config__, 'eom_rccsd_EOM_partition', None)
    logger.info(mycc, 'partition = %s', partition)
    #print "Partition value is: ", partition
    if partition is not None: assert partition.lower() in ['mp','full']

    nocc, nvir = t1.shape
    nmo = mycc.nmo
    dtype = np.result_type(t1, t2)
    vector_size = nvir + nocc*nvir*nvir

    imds = eom_rccsd._IMDS(mycc)
    imds.make_ea(partition)
    diag = eaccsd_diag(imds, partition)
    theta = t2 * 2 - t2.transpose(0,1,3,2)
    theta_lam = l2 * 2 - l2.transpose(1,0,2,3)

    # Construct RHS (b) vector as a_p^\dagger + [a_p^\dagger, T] |phi>
    # Construct LHS (e) vector as <phi|(1+L)(a_q + [a_q , T])
    b_vecs = np.zeros((vector_size, nmo), dtype)
    e_vecs = np.zeros((vector_size, nmo), dtype)

    # Improve this so no explicit looping
    for p in range(nocc):

        b1 = -t1[p,:].copy()
        b2 = -t2[p,:,:,:].copy()
        e1 = l1[p,:].copy()
        e2 = 2.*l2[p,:,:,:].copy()
        e2 -= l2[:,p,:,:]

        b_vecs[:,p] = amplitudes_to_vector_ea(b1, b2)
        e_vecs[:,p] = amplitudes_to_vector_ea(e1, e2)

    for p in range(nvir):
        b1 = np.zeros((nvir), dtype)
        b2 = np.zeros((nocc, nvir, nvir), dtype)
        e1 = np.zeros((nvir), dtype)
        e2 = np.zeros((nocc, nvir, nvir), dtype)

        b1[p] = 1.0

        e1[p] = -1.0
        e1 += np.einsum('ia,i -> a', l1,t1[:,p])
        e1 += 2.*np.einsum('klca,klc -> a',l2, t2[:,:,:,p])
        e1 -= np.einsum('klca,lkc -> a',l2, t2[:,:,:,p])

        e2[:,p,:] = -2.*l1
        e2[:,:,p] += l1
        e2 += 2.*np.einsum('k,jkba -> jab', t1[:,p], l2)
        e2 -= np.einsum('k,jkab -> jab', t1[:,p], l2)

        b_vecs[:,p+nocc] = amplitudes_to_vector_ea(b1, b2)
        e_vecs[:,p+nocc] = amplitudes_to_vector_ea(e1, e2)

    # Now, apply {\bar H} to each b
    part_moms = [np.zeros((nmo, nmo)) for i in range(nmom_max_p+1)]
    # TODO: Would this work for complex?
    part_moms[0] = np.dot(e_vecs.T.conj(),b_vecs)
    part_moms[0] += part_moms[0].conj().T
    #hole_moms[0] = -2.*np.dot(e_vecs.T.conj(),b_vecs)

    p_RHS = np.zeros_like(b_vecs)
    for h_app in range(nmom_max_p):
        if h_app == 0:
            for p in range(nmo):
                p_RHS[:,p] = eaccsd_matvec(b_vecs[:,p], imds, diag, nocc, nmo, partition)
        else:
            for p in range(nmo):
                p_RHS[:,p] = eaccsd_matvec(p_RHS[:,p], imds, diag, nocc, nmo, partition)

        part_moms[h_app+1] = -np.dot(e_vecs.conj().T,p_RHS)
        part_moms[h_app+1] += part_moms[h_app+1].conj().T 

    if ao_repr:
        mo = mycc.mo_coeff
        part_moms = [lib.einsum('pi,ij,qj->pq', mo, mom, mo.conj()) for mom in part_moms]

    return part_moms
コード例 #55
0
ファイル: uhf.py プロジェクト: pulkin/pyscf
def dia(gobj, mol, dm0, gauge_orig=None):
    if isinstance(dm0, numpy.ndarray) and dm0.ndim == 2:  # RHF DM
        return numpy.zeros((3, 3))

    dma, dmb = dm0
    spindm = dma - dmb
    effspin = mol.spin * .5
    alpha2 = lib.param.ALPHA**2
    # FIXME: see JPC, 101, 3388, why?
    g_so = (lib.param.G_ELECTRON - 1) * 2

    # relativistic mass correction (RMC)
    rmc = -numpy.einsum('ij,ji', mol.intor('int1e_kin'), spindm)
    rmc *= lib.param.G_ELECTRON / 2 / effspin * alpha2
    logger.info(gobj, 'RMC = %s', rmc)

    # GC(1e)
    if gauge_orig is not None:
        mol.set_common_origin(gauge_orig)
    h11 = 0
    for ia in range(mol.natm):
        mol.set_rinv_origin(mol.atom_coord(ia))
        Z = mol.atom_charge(ia)
        #FIXME: when ECP is enabled
        if gobj.with_so_eff_charge:
            Z = koseki_charge(Z)


# GC(1e) = 1/4c^2 Z/(2r_N^3) [vec{r}_N dot r sigma dot B - B dot vec{r}_N r dot sigma]
# a11part = (B dot) -1/2 frac{\vec{r}_N}{r_N^3} r (dot sigma)
        if gauge_orig is None:
            h11 += Z * mol.intor('int1e_giao_a11part', 9)
        else:
            h11 += Z * mol.intor('int1e_cg_a11part', 9)
    trh11 = h11[0] + h11[4] + h11[8]
    h11[0] -= trh11
    h11[4] -= trh11
    h11[8] -= trh11
    if gauge_orig is None:
        for ia in range(mol.natm):
            mol.set_rinv_origin(mol.atom_coord(ia))
            Z = mol.atom_charge(ia)
            #FIXME: when ECP is enabled
            if gobj.with_so_eff_charge:
                Z = koseki_charge(Z)
            h11 += Z * mol.intor('int1e_a01gp', 9)
    gc1e = numpy.einsum('xij,ji->x', h11, spindm).reshape(3, 3)

    if 0:  # correction of order c^{-2} from MB basis or DPT (JCP,115,7356), does it exist?
        gc1e += numpy.einsum('ij,ji', mol.intor('int1e_nuc'),
                             spindm) * numpy.eye(3)

    gc1e *= g_so * (alpha2 / 4) / effspin
    _write(gobj, gc1e, 'GC(1e)')

    if gobj.with_sso or gobj.with_soo:
        gc2e = make_dia_gc2e(gobj, dm0, gauge_orig)
        _write(gobj, gc2e, 'GC(2e)')
    else:
        gc2e = 0

    gdia = gc1e + gc2e + rmc * numpy.eye(3)
    return gdia
コード例 #56
0
    def build(self):

        t0 = (time.clock(), time.time())
        lib.logger.TIMER_LEVEL = 3

        mol = lib.chkfile.load_mol(self.chkfile)
        self.mol = mol
        self.nelectron = self.mol.nelectron
        self.charge = self.mol.charge
        self.spin = self.mol.spin
        self.natm = self.mol.natm
        self.mo_coeff = lib.chkfile.load(self.chkfile, 'scf/mo_coeff')
        self.mo_occ = lib.chkfile.load(self.chkfile, 'scf/mo_occ')
        self.n2c = self.mol.nao_2c()
        self.atm = numpy.asarray(self.mol._atm, dtype=numpy.int32, order='C')
        self.bas = numpy.asarray(self.mol._bas, dtype=numpy.int32, order='C')
        self.env = numpy.asarray(self.mol._env, dtype=numpy.double, order='C')
        self.nbas = self.bas.shape[0]
        self.ao_loc = self.mol.ao_loc_2c()
        self.shls_slice = (0, self.nbas)
        sh0, sh1 = self.shls_slice
        self.nao = self.ao_loc[sh1] - self.ao_loc[sh0]
        self.non0tab = numpy.ones((1, self.nbas), dtype=numpy.int8)
        self.coords = numpy.asarray([(numpy.asarray(atom[1])).tolist()
                                     for atom in self.mol._atom])
        self.charges = self.mol.atom_charges()
        nprims, nmo = self.mo_coeff.shape
        self.nprims = nprims
        self.nmo = nmo
        self.cart = mol.cart
        if (not self.leb):
            self.npang = self.npphi * self.nptheta

        nocc = self.mo_occ[abs(self.mo_occ) > self.occdrop]
        self.nocc = len(nocc)
        pos = abs(self.mo_occ) > self.occdrop
        n2c = self.n2c
        self.mo_coeffL = self.mo_coeff[:n2c, pos]
        c1 = 0.5 / self.cspeed
        self.mo_coeffS = self.mo_coeff[n2c:, n2c:n2c + self.nocc] * c1

        if (self.ntrial % 2 == 0): self.ntrial += 1
        geofac = numpy.power(((self.rmaxsurf - 0.1) / self.rprimer),
                             (1.0 / (self.ntrial - 1.0)))
        self.rpru = numpy.zeros((self.ntrial))
        for i in range(self.ntrial):
            self.rpru[i] = self.rprimer * numpy.power(geofac, (i + 1) - 1)
        self.rsurf = numpy.zeros((self.npang, self.ntrial), order='C')
        self.nlimsurf = numpy.zeros((self.npang), dtype=numpy.int32)

        if self.verbose >= logger.WARN:
            self.check_sanity()
        if self.verbose > logger.NOTE:
            self.dump_input()

        if (self.iqudt == 'legendre'):
            self.iqudt = 1

        if (self.leb):
            self.grids = grid.lebgrid(self.npang)
        else:
            self.grids = grid.anggrid(self.iqudt, self.nptheta, self.npphi)

        self.xyzrho = numpy.zeros((self.natm, 3))
        t = time.time()
        for i in range(self.natm):
            self.xyzrho[i], gradmod = gradrho(self, self.coords[i] + 0.1,
                                              self.step)
            if (gradmod > 1e-4):
                if (self.charges[i] > 2.0):
                    logger.info(self, 'Good rho position %.6f %.6f %.6f',
                                *self.xyzrho[i])
                else:
                    raise RuntimeError('Failed finding nucleus:',
                                       *self.xyzrho[i])
            else:
                logger.info(self, 'Check rho position %.6f %.6f %.6f',
                            *self.xyzrho[i])
                logger.info(self, 'Setting xyzrho for atom to imput coords')
                self.xyzrho[i] = self.coords[i]
        self.xnuc = numpy.asarray(self.xyzrho[self.inuc])
        logger.info(self,
                    'Time finding nucleus %.3f (sec)' % (time.time() - t))

        if (self.backend == 'rkck'):
            backend = 1
        elif (self.backend == 'rkdp'):
            backend = 2
        else:
            raise NotImplementedError(
                'Only rkck or rkdp ODE solver yet available')

        ct_ = numpy.asarray(self.grids[:, 0], order='C')
        st_ = numpy.asarray(self.grids[:, 1], order='C')
        cp_ = numpy.asarray(self.grids[:, 2], order='C')
        sp_ = numpy.asarray(self.grids[:, 3], order='C')

        t = time.time()
        feval = 'surf_driver4c'
        drv = getattr(libaim, feval)
        with lib.with_omp_threads(self.nthreads):
            drv(ctypes.c_int(self.inuc),
                self.xyzrho.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_int(self.npang), ct_.ctypes.data_as(ctypes.c_void_p),
                st_.ctypes.data_as(ctypes.c_void_p),
                cp_.ctypes.data_as(ctypes.c_void_p),
                sp_.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(self.ntrial),
                self.rpru.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_double(self.epsiscp), ctypes.c_double(self.epsroot),
                ctypes.c_double(self.rmaxsurf), ctypes.c_int(backend),
                ctypes.c_double(self.epsilon), ctypes.c_double(self.step),
                ctypes.c_int(self.mstep), ctypes.c_int(self.natm),
                self.coords.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_int(self.cart), ctypes.c_int(self.nocc),
                ctypes.c_int(self.nprims),
                self.atm.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_int(self.nbas),
                self.bas.ctypes.data_as(ctypes.c_void_p),
                self.env.ctypes.data_as(ctypes.c_void_p),
                self.ao_loc.ctypes.data_as(ctypes.c_void_p),
                self.mo_coeffL.ctypes.data_as(ctypes.c_void_p),
                self.mo_coeffS.ctypes.data_as(ctypes.c_void_p),
                self.nlimsurf.ctypes.data_as(ctypes.c_void_p),
                self.rsurf.ctypes.data_as(ctypes.c_void_p))
        logger.info(self,
                    'Time finding surface %.3f (sec)' % (time.time() - t))
        #print rhograd(self,[0,0,0])
        #print rhograd2(self,[0,0,0])

        self.rmin = 1000.0
        self.rmax = 0.0
        for i in range(self.npang):
            nsurf = int(self.nlimsurf[i])
            self.rmin = numpy.minimum(self.rmin, self.rsurf[i, 0])
            self.rmax = numpy.maximum(self.rmax, self.rsurf[i, nsurf - 1])
        logger.info(self, 'Rmin for surface %.6f', self.rmin)
        logger.info(self, 'Rmax for surface %.6f', self.rmax)

        logger.info(self, 'Write HDF5 surface file')
        atom_dic = {
            'inuc': self.inuc,
            'xnuc': self.xnuc,
            'xyzrho': self.xyzrho,
            'coords': self.grids,
            'npang': self.npang,
            'ntrial': self.ntrial,
            'rmin': self.rmin,
            'rmax': self.rmax,
            'nlimsurf': self.nlimsurf,
            'rsurf': self.rsurf
        }
        lib.chkfile.save(self.surfile, 'atom' + str(self.inuc), atom_dic)
        logger.info(self, 'Surface of atom %d saved', self.inuc)
        logger.timer(self, 'BaderSurf build', *t0)

        return self
コード例 #57
0
    def eaccsd(self,
               nroots=1,
               left=False,
               koopmans=False,
               guess=None,
               partition=None):
        '''Calculate (N+1)-electron charged excitations via EA-EOM-CCSD.

        Kwargs:
            See ipccd()
        '''
        cput0 = (time.clock(), time.time())
        log = logger.Logger(self.stdout, self.verbose)
        size = self.nea()
        nroots = min(nroots, size)
        if partition:
            partition = partition.lower()
            assert partition in ['mp', 'full']
        self.ea_partition = partition
        if partition == 'full':
            self._eaccsd_diag_matrix2 = self.vector_to_amplitudes_ea(
                self.eaccsd_diag())[1]

        adiag = self.eaccsd_diag()
        user_guess = False
        if guess:
            user_guess = True
            assert len(guess) == nroots
            for g in guess:
                assert g.size == size
        else:
            guess = []
            if koopmans:
                for n in range(nroots):
                    g = np.zeros(size)
                    g[n] = 1.0
                    guess.append(g)
            else:
                idx = adiag.argsort()[:nroots]
                for i in idx:
                    g = np.zeros(size)
                    g[i] = 1.0
                    guess.append(g)

        def precond(r, e0, x0):
            return r / (e0 - adiag + 1e-12)

        if left:
            matvec = self.leaccsd_matvec
        else:
            matvec = self.eaccsd_matvec
        eig = linalg_helper.eig
        if user_guess or koopmans:

            def pickeig(w, v, nr, envs):
                x0 = linalg_helper._gen_x0(envs['v'], envs['xs'])
                idx = np.argmax(np.abs(
                    np.dot(np.array(guess).conj(),
                           np.array(x0).T)),
                                axis=1)
                return w[idx].real, v[:, idx].real, idx

            eea, evecs = eig(matvec,
                             guess,
                             precond,
                             pick=pickeig,
                             tol=self.conv_tol,
                             max_cycle=self.max_cycle,
                             max_space=self.max_space,
                             nroots=nroots,
                             verbose=self.verbose)
        else:
            eea, evecs = eig(matvec,
                             guess,
                             precond,
                             tol=self.conv_tol,
                             max_cycle=self.max_cycle,
                             max_space=self.max_space,
                             nroots=nroots,
                             verbose=self.verbose)

        self.eea = eea.real

        if nroots == 1:
            eea, evecs = [self.eea], [evecs]
        nvir = self.nmo - self.nocc
        for n, en, vn in zip(range(nroots), eea, evecs):
            logger.info(self, 'EA root %d E = %.16g  qpwt = %0.6g', n, en,
                        np.linalg.norm(vn[:nvir])**2)
        log.timer('EA-CCSD', *cput0)
        if nroots == 1:
            return eea[0], evecs[0]
        else:
            return eea, evecs
コード例 #58
0
    def dump_input(self):

        if self.verbose < logger.INFO:
            return self

        logger.info(self, '')
        logger.info(self, '******** %s flags ********', self.__class__)
        logger.info(self, '* General Info')
        logger.info(self, 'Date %s' % time.ctime())
        logger.info(self, 'Python %s' % sys.version)
        logger.info(self, 'Numpy %s' % numpy.__version__)
        logger.info(self, 'Number of threads %d' % self.nthreads)
        logger.info(self, 'Verbose level %d' % self.verbose)
        logger.info(self, 'Scratch dir %s' % self.scratch)
        logger.info(self, 'Input data file %s' % self.chkfile)
        logger.info(self, 'Max_memory %d MB (current use %d MB)',
                    self.max_memory,
                    lib.current_memory()[0])

        logger.info(self, '* Mol Info')
        logger.info(self, 'Speed light value %f' % self.cspeed)
        logger.info(self, 'Num atoms %d' % self.natm)
        logger.info(self, 'Num electrons %d' % self.nelectron)
        logger.info(self, 'Total charge %d' % self.charge)
        logger.info(self, 'Spin %d ' % self.spin)
        logger.info(self, 'Atom Coordinates (Bohr)')
        for i in range(self.natm):
            logger.info(
                self, 'Nuclei %d with charge %d position : %.6f  %.6f  %.6f',
                i, self.charges[i], *self.coords[i])

        logger.info(self, '* Basis Info')
        logger.info(self, 'Is cartesian %s' % self.cart)
        logger.info(self, 'Number of molecular orbitals %d' % self.nmo)
        logger.info(self, 'Orbital EPS occ criterion %e' % self.occdrop)
        logger.info(self,
                    'Number of occupied molecular orbitals %d' % self.nocc)
        logger.info(self, 'Number of molecular primitives %d' % self.nprims)
        logger.debug(self, 'Occs : %s' % self.mo_occ)

        logger.info(self, '* Surface Info')
        if (self.leb):
            logger.info(self, 'Lebedev quadrature')
        else:
            logger.info(self, 'Theta quadrature %s' % self.iqudt)
            logger.info(self, 'Phi is always trapezoidal')
            logger.info(
                self, 'N(theta,phi) points %d %d' % (self.nptheta, self.npphi))
        logger.info(self, 'Npang points %d' % self.npang)
        logger.info(self, 'Surface file %s' % self.surfile)
        logger.info(self, 'Surface for nuc %d' % self.inuc)
        logger.info(self, 'Rmaxsurface %f' % self.rmaxsurf)
        logger.info(self, 'Ntrial %d' % self.ntrial)
        logger.info(self, 'Rprimer %f' % self.rprimer)
        logger.debug(self, 'Rpru : %s' % self.rpru)
        logger.info(self, 'Epsiscp %f' % self.epsiscp)
        logger.info(self, 'Epsroot %e' % self.epsroot)
        logger.info(self, 'ODE solver %s' % self.backend)
        logger.info(self, 'ODE tool %e' % self.epsilon)
        logger.info(self, 'Max steps in ODE solver %d' % self.mstep)
        logger.info(self, '')

        return self
コード例 #59
0
ファイル: krkspu.py プロジェクト: theorychemyang/pyscf
def get_veff(ks,
             cell=None,
             dm=None,
             dm_last=0,
             vhf_last=0,
             hermi=1,
             kpts=None,
             kpts_band=None):
    """
    Coulomb + XC functional + Hubbard U terms.

    .. note::
        This is a replica of pyscf.dft.rks.get_veff with kpts added.
        This function will change the ks object.

    Args:
        ks : an instance of :class:`RKS`
            XC functional are controlled by ks.xc attribute.  Attribute
            ks.grids might be initialized.
        dm : ndarray or list of ndarrays
            A density matrix or a list of density matrices

    Returns:
        Veff : (nkpts, nao, nao) or (*, nkpts, nao, nao) ndarray
        Veff = J + Vxc + V_U.
    """
    if cell is None: cell = ks.cell
    if dm is None: dm = ks.make_rdm1()
    if kpts is None: kpts = ks.kpts

    # J + V_xc
    vxc = krks.get_veff(ks,
                        cell=cell,
                        dm=dm,
                        dm_last=dm_last,
                        vhf_last=vhf_last,
                        hermi=hermi,
                        kpts=kpts,
                        kpts_band=kpts_band)

    # V_U
    C_ao_lo = ks.C_ao_lo
    ovlp = ks.get_ovlp()
    nkpts = len(kpts)
    nlo = C_ao_lo.shape[-1]

    rdm1_lo = np.zeros((nkpts, nlo, nlo), dtype=np.complex128)
    for k in range(nkpts):
        C_inv = np.dot(C_ao_lo[k].conj().T, ovlp[k])
        rdm1_lo[k] = mdot(C_inv, dm[k], C_inv.conj().T)

    E_U = 0.0
    weight = 1.0 / nkpts
    logger.info(ks, "-" * 79)
    with np.printoptions(precision=5, suppress=True, linewidth=1000):
        for idx, val, lab in zip(ks.U_idx, ks.U_val, ks.U_lab):
            lab_string = " "
            for l in lab:
                lab_string += "%9s" % (l.split()[-1])
            lab_sp = lab[0].split()
            logger.info(ks, "local rdm1 of atom %s: ",
                        " ".join(lab_sp[:2]) + " " + lab_sp[2][:2])
            U_mesh = np.ix_(idx, idx)
            P_loc = 0.0
            for k in range(nkpts):
                S_k = ovlp[k]
                C_k = C_ao_lo[k][:, idx]
                P_k = rdm1_lo[k][U_mesh]
                SC = np.dot(S_k, C_k)
                vxc[k] += mdot(SC, (np.eye(P_k.shape[-1]) - P_k) * (val * 0.5),
                               SC.conj().T).astype(vxc[k].dtype, copy=False)
                E_U += (val * 0.5) * (P_k.trace() -
                                      np.dot(P_k, P_k).trace() * 0.5)
                P_loc += P_k
            P_loc = P_loc.real / nkpts
            logger.info(ks, "%s\n%s", lab_string, P_loc)
            logger.info(ks, "-" * 79)

    E_U *= weight
    if E_U.real < 0.0 and all(np.asarray(ks.U_val) > 0):
        logger.warn(ks, "E_U (%s) is negative...", E_U.real)
    vxc = lib.tag_array(vxc, E_U=E_U)
    return vxc
コード例 #60
0
ファイル: khf.py プロジェクト: rodrigobogossian/pyscf
 def dump_flags(self, verbose=None):
     mol_hf.SCF.dump_flags(self, verbose)
     logger.info(self, '\n')
     logger.info(self, '******** PBC SCF flags ********')
     logger.info(self, 'N kpts = %d', len(self.kpts))
     logger.debug(self, 'kpts = %s', self.kpts)
     logger.info(self, 'Exchange divergence treatment (exxdiv) = %s',
                 self.exxdiv)
     #if self.exxdiv == 'vcut_ws':
     #    if self.exx_built is False:
     #        self.precompute_exx()
     #    logger.info(self, 'WS alpha = %s', self.exx_alpha)
     cell = self.cell
     if ((cell.dimension >= 2 and cell.low_dim_ft_type != 'inf_vacuum')
             and isinstance(self.exxdiv, str)
             and self.exxdiv.lower() == 'ewald'):
         madelung = tools.pbc.madelung(cell, [self.kpts])
         logger.info(self,
                     '    madelung (= occupied orbital energy shift) = %s',
                     madelung)
         nkpts = len(self.kpts)
         # FIXME: consider the fractional num_electron or not? This maybe
         # relates to the charged system.
         nelectron = float(self.cell.tot_electrons(nkpts)) / nkpts
         logger.info(
             self, '    Total energy shift due to Ewald probe charge'
             ' = -1/2 * Nelec*madelung = %.12g', madelung * nelectron * -.5)
     logger.info(self, 'DF object = %s', self.with_df)
     if not getattr(self.with_df, 'build', None):
         # .dump_flags() is called in pbc.df.build function
         self.with_df.dump_flags(verbose)
     return self