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
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
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
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)
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
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
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)