Beispiel #1
0
def init_guess_by_atom(mol):
    '''Generate initial guess density matrix from superposition of atomic HF
    density matrix.  The atomic HF is occupancy averaged RHF

    Returns:
        Density matrix, 2D ndarray
    '''
    import copy
    from pyscf.scf import atom_hf
    from pyscf.scf import addons
    atm_scf = atom_hf.get_atm_nrhf(mol)
    mo = []
    mo_occ = []
    for ia in range(mol.natm):
        symb = mol.atom_symbol(ia)
        if symb != 'GHOST':
            if symb in atm_scf:
                e_hf, e, c, occ = atm_scf[symb]
            else:
                symb = mol.atom_pure_symbol(ia)
                e_hf, e, c, occ = atm_scf[symb]
            mo.append(c)
            mo_occ.append(occ)
    mo = scipy.linalg.block_diag(*mo)
    mo_occ = numpy.hstack(mo_occ)

    pmol = copy.copy(mol)
    pmol.cart = False
    c = addons.project_mo_nr2nr(pmol, mo, mol)
    dm = numpy.dot(c * mo_occ, c.T)

    for k, v in atm_scf.items():
        logger.debug1(mol, 'Atom %s, E = %.12g', k, v[0])
    return dm
Beispiel #2
0
def init_guess_by_atom(mol):
    '''Generate initial guess density matrix from superposition of atomic HF
    density matrix.  The atomic HF is occupancy averaged RHF

    Returns:
        Density matrix, 2D ndarray
    '''
    from pyscf.scf import atom_hf
    atm_scf = atom_hf.get_atm_nrhf(mol)
    nbf = mol.nao_nr()
    dm = numpy.zeros((nbf, nbf))
    p0 = 0
    for ia in range(mol.natm):
        symb = mol.atom_symbol(ia)
        if symb in atm_scf:
            e_hf, mo_e, mo_c, mo_occ = atm_scf[symb]
        else:
            symb = mol.atom_pure_symbol(ia)
            e_hf, mo_e, mo_c, mo_occ = atm_scf[symb]
        p1 = p0 + mo_e.__len__()
        dm[p0:p1,p0:p1] = numpy.dot(mo_c*mo_occ, mo_c.T.conj())
        p0 = p1

    for k, v in atm_scf.items():
        logger.debug1(mol, 'Atom %s, E = %.12g', k, v[0])
    return dm
Beispiel #3
0
def init_guess_by_atom(mol):
    '''Generate initial guess density matrix from superposition of atomic HF
    density matrix.  The atomic HF is occupancy averaged RHF

    Returns:
        Density matrix, 2D ndarray
    '''
    from pyscf.scf import atom_hf
    atm_scf = atom_hf.get_atm_nrhf(mol)
    nbf = mol.nao_nr()
    dm = numpy.zeros((nbf, nbf))
    p0 = 0
    for ia in range(mol.natm):
        symb = mol.atom_symbol(ia)
        if symb in atm_scf:
            e_hf, mo_e, mo_c, mo_occ = atm_scf[symb]
        else:
            symb = mol.atom_pure_symbol(ia)
            e_hf, mo_e, mo_c, mo_occ = atm_scf[symb]
        p1 = p0 + mo_e.__len__()
        dm[p0:p1,p0:p1] = numpy.dot(mo_c*mo_occ, mo_c.T.conj())
        p0 = p1

    for k, v in atm_scf.items():
        logger.debug1(mol, 'Atom %s, E = %.12g', k, v[0])
    return dm
Beispiel #4
0
    def get_dm(self):  #, cycle=1):
        '''
          Get DM in configuration-adapted basis
          
        steps:
        1) Guess density matrix from superposition 
           of atomic HF density matrix
        2) build Fock matrix
        3) update DM by diagonalizing corresponding
           Fock matrix
        4) construct new DM

        Note that the initial atomic DM was obtained through solving
        the occupancy averaged RHF

        Returns:
            Density matrix, 2D ndarray
        '''
        mol = self.mol
        atm_scf = atom_hf.get_atm_nrhf(mol)
        aoslice = mol.aoslice_by_atom()
        atm_dms = []
        for ia in range(mol.natm):
            symb = mol.atom_symbol(ia)
            if symb not in atm_scf:
                symb = mol.atom_pure_symbol(ia)
            if symb in atm_scf:
                e_hf, e, c, occ = atm_scf[symb]
                dm = np.dot(c * occ, c.conj().T)
            else:  # symb's basis is not specified in the input
                nao_atm = aoslice[ia, 3] - aoslice[ia, 2]
                dm = np.zeros((nao_atm, nao_atm))
            atm_dms.append(dm)

        dm = scipy.linalg.block_diag(*atm_dms)
        if mol.cart:
            cart2sph = mol.cart2sph_coeff(normalized='sp')
            dm = reduce(np.dot, (cart2sph, dm, cart2sph.T))

        mf = self.mf
        #if cycle > 0:
        vhf = mf.get_veff(mol, dm)
        fock = mf.get_fock(self.h1e, self.s, vhf, dm)
        mo_energy, mo_coeff = mf.eig(fock, self.s)
        mo_occ = mf.get_occ(mo_energy, mo_coeff)
        dm = mf.make_rdm1(mo_coeff, mo_occ)

        return dm
Beispiel #5
0
 def test_atom_hf_with_ecp(self):
     mol = gto.M(verbose=7,
                 output='/dev/null',
                 atom='Cu 0 0 0; Ba 0 0 2',
                 basis={
                     'Ba': 'def2-svp',
                     'Cu': 'lanl2dz'
                 },
                 ecp={
                     'Ba': 'def2-svp',
                     'Cu': 'lanl2dz'
                 },
                 spin=None)
     scf_result = atom_hf.get_atm_nrhf(mol)
     self.assertAlmostEqual(scf_result['Ba'][0], -25.07089468572715, 9)
     self.assertAlmostEqual(scf_result['Cu'][0], -194.92388639203045, 9)
Beispiel #6
0
def pre_orth_ao_atm_scf(mol):
    from pyscf.scf import atom_hf
    atm_scf = atom_hf.get_atm_nrhf(mol)
    nbf = mol.nao_nr()
    c = numpy.zeros((nbf, nbf))
    p0 = 0
    for ia in range(mol.natm):
        symb = mol.atom_symbol(ia)
        if symb in atm_scf:
            e_hf, mo_e, mo_c, mo_occ = atm_scf[symb]
        else:
            symb = mol.atom_pure_symbol(ia)
            e_hf, mo_e, mo_c, mo_occ = atm_scf[symb]
        p1 = p0 + mo_e.size
        c[p0:p1,p0:p1] = mo_c
        p0 = p1
    return c
Beispiel #7
0
def pre_orth_ao_atm_scf(mol):
    from pyscf.scf import atom_hf
    atm_scf = atom_hf.get_atm_nrhf(mol)
    nbf = mol.nao_nr()
    c = numpy.zeros((nbf, nbf))
    p0 = 0
    for ia in range(mol.natm):
        symb = mol.atom_symbol(ia)
        if symb in atm_scf:
            e_hf, mo_e, mo_c, mo_occ = atm_scf[symb]
        else:
            symb = mol.atom_pure_symbol(ia)
            e_hf, mo_e, mo_c, mo_occ = atm_scf[symb]
        p1 = p0 + mo_e.size
        c[p0:p1, p0:p1] = mo_c
        p0 = p1
    return c
Beispiel #8
0
def pre_orth_ao_atm_scf(mol):
    assert (not mol.cart)
    from pyscf.scf import atom_hf
    atm_scf = atom_hf.get_atm_nrhf(mol)
    aoslice = mol.aoslice_by_atom()
    coeff = []
    for ia in range(mol.natm):
        symb = mol.atom_symbol(ia)
        if symb not in atm_scf:
            symb = mol.atom_pure_symbol(ia)

        if symb in atm_scf:
            e_hf, e, c, occ = atm_scf[symb]
        else:  # symb's basis is not specified in the input
            nao_atm = aoslice[ia, 3] - aoslice[ia, 2]
            c = numpy.zeros((nao_atm, nao_atm))
        coeff.append(c)
    return scipy.linalg.block_diag(*coeff)