def update_embs(self, mol, embs, eff_scf, orth_coeff): sc = numpy.dot(eff_scf.get_ovlp(), eff_scf.mo_coeff) c_inv = numpy.dot(eff_scf.get_ovlp(), orth_coeff).T fock0 = numpy.dot(sc*eff_scf.mo_energy, sc.T.conj()) hcore = eff_scf.get_hcore() nocc = int(eff_scf.mo_occ.sum()) / 2 for ifrag, emb in enumerate(embs): mo_orth = numpy.dot(c_inv, eff_scf.mo_coeff[:,eff_scf.mo_occ>1e-15]) emb.imp_site, emb.bath_orb, emb.env_orb = \ dmet_hf.decompose_orbital(emb, mo_orth, emb.bas_on_frag) emb.impbas_coeff = emb.cons_impurity_basis() emb.nelectron = mol.nelectron - emb.env_orb.shape[1] * 2 log.debug(emb, 'nelec of emb %d = %d', ifrag, emb.nelectron) emb._eri = emb.eri_on_impbas(mol) emb.energy_by_env, emb._vhf_env = emb.init_vhf_env(emb.env_orb) emb._project_fock = emb.mat_ao2impbas(fock0) emb.mo_energy, emb.mo_coeff_on_imp = scipy.linalg.eigh(emb._project_fock) emb.mo_coeff = numpy.dot(emb.impbas_coeff, emb.mo_coeff_on_imp) emb.mo_occ = numpy.zeros_like(emb.mo_energy) emb.mo_occ[:emb.nelectron/2] = 2 emb.hf_energy = 0 nimp = emb.imp_site.shape[1] cimp = numpy.dot(emb.impbas_coeff[:,:nimp].T, sc[:,:nocc]) emb._pure_hcore = emb.mat_ao2impbas(hcore) emb._project_nelec_frag = numpy.linalg.norm(cimp)**2*2 log.debug(self, 'project_nelec_frag = %f', emb._project_nelec_frag) # if isinstance(self.vfit_mf, numpy.ndarray): # v1 = emb.mat_orthao2impbas(self.vfit_mf) # v1[:nimp,:nimp] = 0 # emb._vhf_env += v1 return embs
def update_embs(self, mol, embs, eff_scf, orth_coeff): sc = numpy.dot(eff_scf.get_ovlp(mol), eff_scf.mo_coeff) c_inv = numpy.dot(eff_scf.get_ovlp(mol), orth_coeff).T fock0 = numpy.dot(sc*eff_scf.mo_energy, sc.T.conj()) hcore = eff_scf.get_hcore(mol) vhfwhole = eff_scf.get_veff(mol, eff_scf.make_rdm1()) nocc = int(eff_scf.mo_occ.sum()) / 2 for ifrag, emb in enumerate(embs): mo_orth = numpy.dot(c_inv, eff_scf.mo_coeff[:,eff_scf.mo_occ>1e-15]) emb.imp_site, emb.bath_orb, emb.env_orb = \ dmet_hf.decompose_orbital(emb, mo_orth, emb.bas_on_frag) emb.impbas_coeff = emb.cons_impurity_basis() emb.nelectron = mol.nelectron - emb.env_orb.shape[1] * 2 log.debug(emb, 'nelec of emb %d = %d', ifrag, emb.nelectron) emb._eri = emb.eri_on_impbas(mol) emb.energy_by_env, emb._vhf_env = emb.init_vhf_env(emb.env_orb) emb._project_fock = emb.mat_ao2impbas(fock0) emb.mo_energy, emb.mo_coeff_on_imp = scipy.linalg.eigh(emb._project_fock) emb.mo_coeff = numpy.dot(emb.impbas_coeff, emb.mo_coeff_on_imp) emb.mo_occ = numpy.zeros_like(emb.mo_energy) emb.mo_occ[:emb.nelectron/2] = 2 emb.e_tot = 0 nimp = emb.imp_site.shape[1] cimp = numpy.dot(emb.impbas_coeff[:,:nimp].T, sc[:,:nocc]) emb._pure_hcore = emb.mat_ao2impbas(hcore) emb._project_nelec_frag = numpy.linalg.norm(cimp)**2*2 # the energy _ehfinhf is defined on emb.entire_scf, which is not the same as # the pure SCF of the entire system, because dmet-scf will update # emb.entire_scf with fitting potential vfit_mf hfdm = emb.make_rdm1(emb.mo_coeff_on_imp, emb.mo_occ) vhf = emb.mat_ao2impbas(vhfwhole) return embs
def update_embs(self, mol, embs, eff_scf, orth_coeff=None): # local SCF will be carried out in self.update_embs_vfit_ci #ABORT for emb in embs: #ABORT emb.imp_scf() #ABORT hcore = self.entire_scf.get_hcore(mol) #ABORT for emb in embs: #ABORT emb._pure_hcore = emb.mat_ao2impbas(hcore) #ABORT return embs # * If entire_scf is converged, the embedding HF results can be projected from # entire_scf as follows. # * OneImpNI cannot use the enitre_scf results, since the 2e parts are # screened. if orth_coeff is None: orth_coeff = self.orth_coeff t0 = time.clock() sc = numpy.dot(eff_scf.get_ovlp(mol), eff_scf.mo_coeff) c_inv = numpy.dot(eff_scf.get_ovlp(mol), orth_coeff).T fock0 = numpy.dot(sc*eff_scf.mo_energy, sc.T.conj()) hcore = eff_scf.get_hcore(mol) vhfwhole = eff_scf.get_veff(mol, eff_scf.make_rdm1()) nocc = int(eff_scf.mo_occ.sum()) / 2 for ifrag, emb in enumerate(embs): mo_orth = numpy.dot(c_inv, eff_scf.mo_coeff[:,eff_scf.mo_occ>1e-15]) emb.imp_site, emb.bath_orb, emb.env_orb = \ dmet_hf.decompose_orbital(emb, mo_orth, emb.bas_on_frag) emb.impbas_coeff = emb.cons_impurity_basis() emb.nelectron = mol.nelectron - emb.env_orb.shape[1] * 2 log.debug(emb, 'nelec of emb %d = %d', ifrag, emb.nelectron) #TODO: optimize ._eri and ._vhf_env, they can be generated together emb._eri = emb.eri_on_impbas(mol) emb.energy_by_env, emb._vhf_env = emb.init_vhf_env(emb.env_orb) # project entire-sys SCF results to embedding-sys SCF results # This is the results of embedded-HF which are projected from entire HF. # Generally, the local fitting potential is not consistent to the global # potential (which is not linearly transformed from the global potential), the # embedded-HF results can be different from the projected HF results. So the # local impurity solver CANNOT directly use the projected HF orbitals and # energies, local-SCF is required. # * the relevant embedding-SCF lies in self.update_embs_vfit_ci emb._project_fock = emb.mat_ao2impbas(fock0) emb.mo_energy, emb.mo_coeff_on_imp = scipy.linalg.eigh(emb._project_fock) emb.mo_coeff = numpy.dot(emb.impbas_coeff, emb.mo_coeff_on_imp) emb.mo_occ = numpy.zeros_like(emb.mo_energy) emb.mo_occ[:emb.nelectron/2] = 2 emb.hf_energy = 0 nimp = emb.imp_site.shape[1] cimp = numpy.dot(emb.impbas_coeff[:,:nimp].T, sc[:,:nocc]) emb._pure_hcore = emb.mat_ao2impbas(hcore) emb._project_nelec_frag = numpy.linalg.norm(cimp)**2*2 # the energy _ehfinhf is defined on emb.entire_scf, which is not the same as # the pure SCF of the entire system, because dmet-scf will update # emb.entire_scf with fitting potential vfit_mf hfdm = emb.make_rdm1(emb.mo_coeff_on_imp, emb.mo_occ) vhf = emb.mat_ao2impbas(vhfwhole) emb._ehfinhf = numpy.dot(hfdm[:nimp].flatten(), emb._pure_hcore[:nimp].flatten()) \ + numpy.dot(hfdm[:nimp].flatten(), vhf[:nimp].flatten()) * .5 log.debug(self, 'fragment %d ehfinhf = %.12g', ifrag, emb._ehfinhf) log.debug(self, 'CPU time for set up embsys.embs: %.8g sec', \ time.clock()-t0) return embs