Exemplo n.º 1
0
def init_guess_by_wolfsberg_helmholtz(mol):
    """Diagonal will be taken from core hamiltonian, the off diagonal elements
    are interpolated by wolfsberg helmholtz scheme. 
    
        H_ji = k_ji (H_ii + H_ij) S_ij / 2, with k_ij =1.75
    
    (Generalized Wolfsberg Helmholtz GWH). See here:
    http://www.q-chem.com/qchem-website/manual/qchem50_manual/sect-initialguess.html

    M. Wolfsberg and L. Helmholz, J. Chem. Phys. 20, 837 (1952). 
    """
    from pyscf.scf.hf import eig, get_hcore, get_ovlp, get_occ, make_rdm1, SCF
    import numpy

    H = numpy.diag(get_hcore(mol))

    k = numpy.ones((len(H), len(H))) * 1.75 - \
        numpy.diag(numpy.ones(H.shape)) * 0.75
    S = get_ovlp(mol)

    H = k * numpy.add.outer(H, H) * S / 2

    mo_energy, mo_coeff = eig(H, S)
    mo_occ = get_occ(SCF(mol), mo_energy, mo_coeff)

    return make_rdm1(mo_coeff, mo_occ)
Exemplo n.º 2
0
def make_rdm1(mo_coeff_kpts, mo_occ_kpts, **kwargs):
    '''One particle density matrices for all k-points.

    Returns:
        dm_kpts : (nkpts, nao, nao) ndarray
    '''
    nkpts = len(mo_occ_kpts)
    dm_kpts = [mol_hf.make_rdm1(mo_coeff_kpts[k], mo_occ_kpts[k])
               for k in range(nkpts)]
    return lib.asarray(dm_kpts)
Exemplo n.º 3
0
Arquivo: hf.py Projeto: pulkin/pyscf
def init_guess_by_chkfile(cell, chkfile_name, project=True, kpt=None):
    '''Read the HF results from checkpoint file, then project it to the
    basis defined by ``cell``

    Returns:
        Density matrix, (nao,nao) ndarray
    '''
    chk_cell, scf_rec = chkfile.load_scf(chkfile_name)
    mo = scf_rec['mo_coeff']
    mo_occ = scf_rec['mo_occ']
    if kpt is None:
        kpt = np.zeros(3)
    if 'kpt' in scf_rec:
        chk_kpt = scf_rec['kpt']
    elif 'kpts' in scf_rec:
        kpts = scf_rec['kpts']  # the closest kpt from KRHF results
        where = np.argmin(lib.norm(kpts - kpt, axis=1))
        chk_kpt = kpts[where]
        if mo.ndim == 3:  # KRHF:
            mo = mo[where]
            mo_occ = mo_occ[where]
        else:
            mo = mo[:, where]
            mo_occ = mo_occ[:, where]
    else:  # from molecular code
        chk_kpt = np.zeros(3)

    def fproj(mo):
        if project:
            return addons.project_mo_nr2nr(chk_cell, mo, cell, chk_kpt - kpt)
        else:
            return mo

    if mo.ndim == 2:
        dm = make_rdm1(fproj(mo), mo_occ)
    else:  # UHF
        dm = (make_rdm1(fproj(mo[0]), mo_occ[0]) +
              make_rdm1(fproj(mo[1]), mo_occ[1]))

    # Real DM for gamma point
    if kpt is None or np.allclose(kpt, 0):
        dm = dm.real
    return dm
Exemplo n.º 4
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.'
     )
     mo_energy, mo_coeff = hf.init_guess_by_huckel(mol)
     mo_occ = hf.get_occ(self, mo_energy, mo_coeff)
     dm = hf.make_rdm1(mo_coeff, mo_occ)
     return _from_rhf_init_dm(dm)
Exemplo n.º 5
0
def make_rdm1(mo_coeff_kpts, mo_occ_kpts):
    '''One particle density matrices for all k-points.

    Returns:
        dm_kpts : (nkpts, nao, nao) ndarray
    '''
    nkpts = len(mo_occ_kpts)
    dm_kpts = [hf.make_rdm1(mo_coeff_kpts[k], mo_occ_kpts[k])
               for k in range(nkpts)]
    return lib.asarray(dm_kpts)
Exemplo n.º 6
0
Arquivo: hf.py Projeto: eronca/pyscf
def init_guess_by_chkfile(cell, chkfile_name, project=True, kpt=None):
    '''Read the HF results from checkpoint file, then project it to the
    basis defined by ``cell``

    Returns:
        Density matrix, (nao,nao) ndarray
    '''
    chk_cell, scf_rec = chkfile.load_scf(chkfile_name)
    mo = scf_rec['mo_coeff']
    mo_occ = scf_rec['mo_occ']
    if kpt is None:
        kpt = np.zeros(3)
    if 'kpt' in scf_rec:
        chk_kpt = scf_rec['kpt']
    elif 'kpts' in scf_rec:
        kpts = scf_rec['kpts'] # the closest kpt from KRHF results
        where = np.argmin(lib.norm(kpts-kpt, axis=1))
        chk_kpt = kpts[where]
        if mo.ndim == 3:  # KRHF:
            mo = mo[where]
            mo_occ = mo_occ[where]
        else:
            mo = mo[:,where]
            mo_occ = mo_occ[:,where]
    else:  # from molecular code
        chk_kpt = np.zeros(3)

    def fproj(mo):
        if project:
            return addons.project_mo_nr2nr(chk_cell, mo, cell, chk_kpt-kpt)
        else:
            return mo
    if mo.ndim == 2:
        dm = make_rdm1(fproj(mo), mo_occ)
    else:  # UHF
        dm =(make_rdm1(fproj(mo[0]), mo_occ[0]) +
             make_rdm1(fproj(mo[1]), mo_occ[1]))

    # Real DM for gamma point
    if kpt is None or np.allclose(kpt, 0):
        dm = dm.real
    return dm
Exemplo n.º 7
0
def init_guess_by_chkfile(mol, chkfile_name, project=None):
    '''Read SCF chkfile and make the density matrix for GHF initial guess.

    Kwargs:
        project : None or bool
            Whether to project chkfile's orbitals to the new basis.  Note when
            the geometry of the chkfile and the given molecule are very
            different, this projection can produce very poor initial guess.
            In PES scanning, it is recommended to swith off project.

            If project is set to None, the projection is only applied when the
            basis sets of the chkfile's molecule are different to the basis
            sets of the given molecule (regardless whether the geometry of
            the two molecules are different).  Note the basis sets are
            considered to be different if the two molecules are derived from
            the same molecule with different ordering of atoms.
    '''
    from pyscf.scf import addons
    chk_mol, scf_rec = chkfile.load_scf(chkfile_name)
    if project is None:
        project = not gto.same_basis_set(chk_mol, mol)

    # Check whether the two molecules are similar
    if abs(mol.inertia_moment() - chk_mol.inertia_moment()).sum() > 0.5:
        logger.warn(
            mol, "Large deviations found between the input "
            "molecule and the molecule from chkfile\n"
            "Initial guess density matrix may have large error.")

    if project:
        s = hf.get_ovlp(mol)

    def fproj(mo):
        if project:
            mo = addons.project_mo_nr2nr(chk_mol, mo, mol)
            norm = numpy.einsum('pi,pi->i', mo.conj(), s.dot(mo))
            mo /= numpy.sqrt(norm)
        return mo

    nao = chk_mol.nao_nr()
    mo = scf_rec['mo_coeff']
    mo_occ = scf_rec['mo_occ']
    if getattr(mo[0], 'ndim', None) == 1:  # RHF/GHF/DHF
        if nao * 2 == mo.shape[0]:  # GHF or DHF
            if project:
                raise NotImplementedError('Project initial guess from '
                                          'different geometry')
            else:
                dm = hf.make_rdm1(mo, mo_occ)
        else:  # RHF
            mo_coeff = fproj(mo)
            mo_occa = (mo_occ > 1e-8).astype(numpy.double)
            mo_occb = mo_occ - mo_occa
            dma, dmb = uhf.make_rdm1([mo_coeff] * 2, (mo_occa, mo_occb))
            dm = scipy.linalg.block_diag(dma, dmb)
    else:  #UHF
        if getattr(mo[0][0], 'ndim', None) == 2:  # KUHF
            logger.warn(
                mol, 'k-point UHF results are found.  Density matrix '
                'at Gamma point is used for the molecular SCF initial guess')
            mo = mo[0]
        dma, dmb = uhf.make_rdm1([fproj(mo[0]), fproj(mo[1])], mo_occ)
        dm = scipy.linalg.block_diag(dma, dmb)
    return dm
Exemplo n.º 8
0
    def project_init_guess (self, mo_coeff=None, cas_ao=None, prev_mol=None):

        if mo_coeff is None:
            mo_coeff = self.mo_coeff
        if prev_mol is not None:
            mo_coeff = addons.project_init_guess (self, mo_coeff, prev_mol)
        if cas_ao is None:
            cas_ao = self.cas_ao
        else:
            self.cas_ao, self.casrot_coeff, self.ncasrot = self.build_casrot (cas_ao)
        ncas = self.ncas
        ncore = self.ncore
        nocc = self.mol.nelectron // 2
        dm0 = 2 * np.dot (mo_coeff[:,:nocc], mo_coeff[:,:nocc].conjugate ().T)
        self._scf.kernel (dm0)
        nocc = ncas + ncore

        ovlp_ao = self._scf.get_ovlp ()
        fock_ao = self._scf.get_fock ()
        ncasrot = self.ncasrot
        u_casrot = self.casrot_coeff[:,:ncasrot]
        assert (np.allclose (u_casrot[~cas_ao,:], 0))
        projector = np.dot (u_casrot, u_casrot.conjugate ().T)

        # Project active orbitals
        mo_coeff[:,ncore:nocc] = reduce (np.dot, [projector, ovlp_ao, mo_coeff[:,ncore:nocc]])
        assert (np.allclose (mo_coeff[~cas_ao,ncore:nocc], 0))
        mo_coeff[:,ncore:nocc] = orth_orb (mo_coeff[:,ncore:nocc], ovlp_ao)
        # Remove active component of core orbitals
        mo_coeff[:,:ncore] -= reduce (np.dot, [mo_coeff[:,ncore:nocc], mo_coeff[:,ncore:nocc].conjugate ().T, ovlp_ao, mo_coeff[:,:ncore]])
        mo_coeff[:,:ncore] = orth_orb (mo_coeff[:,:ncore], ovlp_ao)
        # Remove core-active component of virtual orbitals
        mo_coeff[:,nocc:] -= reduce (np.dot, [mo_coeff[:,:nocc], mo_coeff[:,:nocc].conjugate ().T, ovlp_ao, mo_coeff[:,nocc:]])
        mo_coeff[:,nocc:] = orth_orb (mo_coeff[:,nocc:], ovlp_ao)
        assert (np.allclose (mo_coeff[~cas_ao,ncore:nocc], 0))
        assert (is_basis_orthonormal (mo_coeff, ovlp_ao))

        # sort active orbitals by energy
        mo_energy = np.einsum ('ip,ij,jp->p', mo_coeff.conjugate (), fock_ao, mo_coeff.T)
        amo_energy = mo_energy[ncore:nocc]
        amo_coeff = mo_coeff[:,ncore:nocc]
        idx = amo_energy.argsort ()
        amo_energy = amo_energy[idx]
        amo_coeff = amo_coeff[:,idx]
        mo_energy[ncore:nocc] = amo_energy
        mo_coeff[:,ncore:nocc] = amo_coeff

        # fc-scf to get the correct core
        nelecb = self.mol.nelectron // 2
        neleca = nelecb + (self.mol.nelectron % 2)
        mo_occ = np.zeros (mo_coeff.shape[1])
        mo_occ[:neleca] += 1
        mo_occ[:nelecb] += 1
        casdm1 = np.diag (mo_occ[ncore:nocc])
        self._scf.build_frozen_from_mo (mo_coeff, ncore, ncas)
        self._scf.diis = None
        dm0 = hf.make_rdm1 (mo_coeff, mo_occ)
        self._scf.kernel (dm0)
        amo_ovlp = reduce (np.dot, [mo_coeff[:,ncore:nocc].conjugate ().T, ovlp_ao, self._scf.mo_coeff[:,ncore:nocc]])
        amo_ovlp = np.dot (amo_ovlp, amo_ovlp.conjugate ().T)
        err = np.trace (amo_ovlp) - ncas
        assert (abs (err) < 1e-10), "{0}".format (amo_ovlp)
        assert (np.allclose (self._scf.mo_coeff[~cas_ao,ncore:nocc], 0))

        return self._scf.mo_coeff