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
def kernel(self, mo_energy=None, mo_coeff=None): if mo_coeff is None: mo_coeff = self._scf.mo_coeff if mo_energy is None: mo_energy = self._scf.mo_energy self.egw = kernel(self, mo_energy, mo_coeff, verbose=self.verbose) logger.log(self, 'GW bandgap = %.15g', self.egw[self.nocc/2]-self.egw[self.nocc/2-1]) return self.egw
def one_shot(self): log.info(self, '==== one-shot ====') mol = self.mol self.init_embsys(mol) emb = self.embs[0] emb.verbose = self.verbose emb.imp_scf() nimp = len(emb.bas_on_frag) log.info(self, '') log.info(self, '===== CI/CC before Fitting =====') etot, e2frag, dm1 = self.solver.run(emb, emb._eri, 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, 'before 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.info(self, '') log.info(self, '===== Fitting chemical potential =====') vfit_ci = self.fitmethod_1shot(mol, emb, self) #self.update_embs_vfit_ci(mol, [emb], [vfit_ci]) etot, e2frag, dm1 = self.solver.run(emb, emb._eri, vfit_ci, with_1pdm=True, with_e2frag=nimp) 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.info(self, 'after fitting, e_tot = %.11g, e_frag = %.11g, nelec_frag = %.11g', e_tot, e_frag, nelec_frag) log.info(self, ' HF-in-HF, frag energy = %.12g, nelec = %.9g', ehfinhf, nelechf) log.info(self, ' FCI-in-HF, frag energy = %.12g, E_corr = %.12g, nelec = %.9g', \ e_frag, e_frag-ehfinhf, nelec_frag) log.info(self, '====================') if self.verbose >= param.VERBOSE_DEBUG: log.debug(self, 'vfit_ci = %s', vfit_ci) log.debug(self, 'impurity dm = %s', dm1) log.log(self, 'dmet_nonsc.one_shot: 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) self._final_v = vfit_ci return e_tot
def kernel(self, mo_energy=None, mo_coeff=None): if mo_coeff is None: mo_coeff = self._scf.mo_coeff if mo_energy is None: mo_energy = self._scf.mo_energy self.egw = kernel(self, mo_energy, mo_coeff, verbose=self.verbose) logger.log(self, 'GW bandgap = %.15g', self.egw[self.nocc / 2] - self.egw[self.nocc / 2 - 1]) return self.egw
def kernel(self, mo_energy=None, mo_coeff=None): if mo_coeff is None: mo_coeff = self._scf.mo_coeff if mo_energy is None: mo_energy = self._scf.mo_energy self.emp2, self.t2 = \ kernel(self, mo_energy, mo_coeff, verbose=self.verbose) logger.log(self, 'RMP2 energy = %.15g', self.emp2) return self.emp2, self.t2
def kernelin(self, mo_energy=None, mo_coeff=None, nocc=None): if mo_coeff is None: mo_coeff = self._scf.mo_coeff if mo_energy is None: mo_energy = self._scf.mo_energy if nocc is None: nocc = self.mol.nelectron // 2 self.emp2, self.t2 = \ kernel(self, mo_energy, mo_coeff, nocc, verbose=self.verbose) logger.log(self, 'RMP2 energy = %.15g', self.emp2) return self.emp2, self.t2
def scdmet(self, sav_v=None): log.info(self, '==== start DMET self-consistency ====') self.dump_flags() mol = self.mol #if self.verbose >= param.VERBOSE_DEBUG: # log.debug(self, '** DM of MF sys (on orthogonal AO) **') # c = numpy.dot(numpy.linalg.inv(self.orth_coeff), \ # self.entire_scf.mo_coeff) # nocc = mol.nelectron / 2 # dm = numpy.dot(c[:,:nocc],c[:,:nocc].T) * 2 # fmt = ' %10.5f' * dm.shape[1] + '\n' # for c in numpy.array(dm): # mol.stdout.write(fmt % tuple(c)) e_tot, v_mf_group, v_ci_group = dmet_sc_cycle(mol, self) log.info(self, '====================') if self.verbose >= param.VERBOSE_DEBUG: for m,emb in enumerate(self.embs): log.debug(self, 'vfit_mf of frag %d = %s', m, v_mf_group[m]) log.debug(self, 'vfit_ci of frag %d = %s', m, v_ci_group[m]) if self.with_hopping: v_add = self.assemble_to_fullmat(v_mf_group) else: v_add = self.assemble_to_blockmat(v_mf_group) log.debug(self, 'mean-field V_fitting in orth AO representation') fmt = ' %10.5f' * v_add.shape[1] + '\n' for c in numpy.array(v_add): mol.stdout.write(fmt % tuple(c)) if self.verbose >= log.DEBUG2: log.debug(self, '** mo_coeff of MF sys (on orthogonal AO) **') c = numpy.dot(numpy.linalg.inv(self.orth_coeff), \ self.entire_scf.mo_coeff) label = ['%d%3s %s%-4s' % x for x in mol.spheric_labels()] tools.dump_mat.dump_rec(self.stdout, c, label, start=1) log.debug(self, '** mo_coeff of MF sys (on non-orthogonal AO) **') tools.dump_mat.dump_rec(self.stdout, self.entire_scf.mo_coeff, label, start=1) e_tot, e_corr, nelec = self.assemble_frag_energy(mol) log.log(self, 'macro iter = X, e_tot = %.11g, e_tot(corr) = %.12g, +nuc = %.11g, nelec = %.8g', \ e_tot, e_corr, e_tot+mol.energy_nuc(), nelec) if isinstance(sav_v, str): if self.with_hopping: v_add = self.assemble_to_fullmat(v_mf_group) else: v_add = self.assemble_to_blockmat(v_mf_group) v_add_ao = self.mat_orthao2ao(v_add) with open(sav_v, 'w') as f: pickle.dump((v_add,v_add_ao), f) return e_tot
def kernel(self, mo_energy=None, mo_coeff=None, nocc=None): if mo_coeff is None: mo_coeff = self._scf.mo_coeff if mo_energy is None: mo_energy = self._scf.mo_energy if nocc is None: nocc = self.mol.nelectron // 2 self.emp2, self.t2 = \ kernel(self, mo_energy, mo_coeff, nocc, verbose=self.verbose) logger.log(self, 'RMP2 energy = %.15g', self.emp2) return self.emp2, self.t2
def kernel(self, mo_energy=None, mo_coeff=None): if mo_coeff is None: mo_coeff = self._scf.mo_coeff if mo_energy is None: mo_energy = self._scf.mo_energy if mo_coeff is None: log.warn("mo_coeff, mo_energy are not given.\n" "You may need mf.kernel() to generate them.") raise RuntimeError self.emp2, self.t2 = kernel(self, mo_energy, mo_coeff, verbose=self.verbose) logger.log(self, "RMP2 energy = %.15g", self.emp2) self.e_corr = self.emp2 return self.emp2, self.t2
def kernel(self, mo_coeff=None): if mo_coeff is None: mo_coeff = self._scf.mo_coeff if mo_coeff is None: log = logger.Logger(self.stdout, self.verbose) log.warn('mo_coeff is not given.\n' 'You may need mf.kernel() to generate it.') raise RuntimeError self.emp2, self.t2 = \ kernel(self, mo_coeff, verbose=self.verbose) logger.log(self, 'UMP2 energy = %.15g', self.emp2) self.e_corr = self.emp2 return self.emp2, self.t2
def kernel(self, mo_energy=None, mo_coeff=None): if mo_coeff is None: mo_coeff = self._scf.mo_coeff if mo_energy is None: mo_energy = self._scf.mo_energy if mo_coeff is None: log.warn('mo_coeff, mo_energy are not given.\n' 'You may need mf.kernel() to generate them.') raise RuntimeError self.emp2, self.t2 = \ kernel(self, mo_energy, mo_coeff, verbose=self.verbose) logger.log(self, 'RMP2 energy = %.15g', self.emp2) return self.emp2, self.t2
def kernel(self, mo_energy=None, mo_coeff=None): if mo_coeff is None: mo_coeff = self._scf.mo_coeff if mo_energy is None: mo_energy = self._scf.mo_energy if mo_coeff is None: log.warn('mo_coeff, mo_energy are not given.\n' 'You may need mf.kernel() to generate them.') raise RuntimeError self.emp2, self.t2 = \ kernel(self, mo_energy, mo_coeff, verbose=self.verbose) logger.log(self, 'RMP2 energy = %.15g', self.emp2) self.e_corr = self.emp2 return self.emp2, self.t2
def kernel(self, mo_energy=None, mo_coeff=None): if mo_energy is None: mo_energy = self.mo_energy if mo_coeff is None: mo_coeff = self.mo_coeff if mo_energy is None or mo_coeff is None: log = logger.Logger(self.stdout, self.verbose) log.warn('mo_coeff, mo_energy are not given.\n' 'You may need to call mf.kernel() to generate them.') raise RuntimeError self.e_corr, self.t2 = \ kernel(self, mo_energy, mo_coeff, verbose=self.verbose) logger.log(self, 'KMP2 energy = %.15g', self.e_corr) return self.e_corr, self.t2
def kernel(self, mo_energy=None, mo_coeff=None): if mo_energy is not None: self.mo_energy = mo_energy if mo_coeff is not None: self.mo_coeff = mo_coeff if self.mo_energy is None or self.mo_coeff is None: raise RuntimeError( 'mo_coeff, mo_energy are not initialized.\n' 'You may need to call scf.kernel() to generate them.') if self.verbose >= logger.WARN: self.check_sanity() self.dump_flags() self.e_corr = kernel(self, mo_energy, mo_coeff, self.verbose) logger.log(self, 'E(%s)=%.15g E_corr=%.15g', self.__class__.__name__, self.e_tot, self.e_corr) return self.e_corr
def kernel(self, mo_energy=None, mo_coeff=None): if mo_energy is None: mo_energy = self.mo_energy if mo_coeff is None: mo_coeff = self.mo_coeff if mo_energy is None or mo_coeff is None: log = logger.Logger(self.stdout, self.verbose) log.warn('mo_coeff, mo_energy are not given.\n' 'You may need to call mf.kernel() to generate them.') raise RuntimeError mo_coeff, mo_energy = _add_padding(self, mo_coeff, mo_energy) self.e_corr, self.t2 = \ kernel(self, mo_energy, mo_coeff, verbose=self.verbose) logger.log(self, 'KMP2 energy = %.15g', self.e_corr) return self.e_corr, self.t2
def prop(self, fmat, c_am, v_lm, rho, output): """ The main tdscf propagation loop. Args: fmat: complex Fock matrix in Lowdin AO basis c_am: complex Transformation Matrix |AO><MO| v_lm: complex Transformation Matrix |LAO><MO| rho: complex MO density matrix. output: str name of the file with result of propagation Saved results: f: file output file with |t, dipole(x,y,z), energy| """ it = 0 tnow = 0 rhom12 = rho.copy() n_occ = int(sum(self.ks.mo_occ) / 2) f = open(output, "a") logger.log(self, "\n\nPropagation Begins") start = time.time() while (it < self.params["MaxIter"]): rho, rhom12, c_am, v_lm, fmat, jmat, kmat = self.tddftstep( fmat, c_am, v_lm, rho, rhom12, tnow) # rho = newrho.copy() # rhom12 = newrhom12.copy() #self.log.append(self.loginstant(it)) f.write( self.loginstant(rho, c_am, v_lm, fmat, jmat, kmat, tnow, it) + "\n") # Do logging. tnow = tnow + self.params["dt"] if it%self.params["StatusEvery"] ==0 or \ it == self.params["MaxIter"]-1: end = time.time() logger.log(self, "%f hr/ps", \ (end - start)/(60*60*tnow * FSPERAU * 0.001)) it = it + 1 f.close()
def initialcondition(self, prm): """ Prepare the variables/Matrices needed for propagation The SCF is done here to make matrices that are not accessable from pyscf.scf Args: prm: str string object with |variable value| on each line Returns: fmat: float or complex Fock matrix in Lowdin AO basis c_am: float Transformation Matrix |AO><MO| v_lm: float Transformation Matrix |LAO><MO| rho: float or complex Initial MO density matrix. """ from pyscf.rt import tdfields self.auxmol_set(self.ks.mol, auxbas=self.auxbas) self.params = dict() logger.log( self, """ =================================== | Realtime TDSCF module | =================================== | J. Parkhill, T. Nguyen | | J. Koh, J. Herr, K. Yao | =================================== | Refs: 10.1021/acs.jctc.5b00262 | | 10.1063/1.4916822 | =================================== """) n_ao = self.ks.mol.nao_nr() n_occ = int(sum(self.ks.mo_occ) / 2) logger.log(self,"n_ao: %d n_occ: %d", n_ao,\ n_occ) self.readparams(prm) fmat, c_am, v_lm = self.initfockbuild() # updates self.C rho = 0.5 * np.diag(self.ks.mo_occ).astype(complex) self.field = tdfields.FIELDS(self, self.params) self.field.initializeexpectation(rho, c_am) return fmat, c_am, v_lm, rho
def initialcondition(self,prm): """ Prepare the variables/Matrices needed for propagation The SCF is done here to make matrices that are not accessable from pyscf.scf Args: prm: str string object with |variable value| on each line Returns: fmat: float or complex Fock matrix in Lowdin AO basis c_am: float Transformation Matrix |AO><MO| v_lm: float Transformation Matrix |LAO><MO| rho: float or complex Initial MO density matrix. """ from pyscf.rt import tdfields self.auxmol_set(self.ks.mol, auxbas = self.auxbas) self.params = dict() logger.log(self,""" =================================== | Realtime TDSCF module | =================================== | J. Parkhill, T. Nguyen | | J. Koh, J. Herr, K. Yao | =================================== | Refs: 10.1021/acs.jctc.5b00262 | | 10.1063/1.4916822 | =================================== """) n_ao = self.ks.mol.nao_nr() n_occ = int(sum(self.ks.mo_occ)/2) logger.log(self,"n_ao: %d n_occ: %d", n_ao,\ n_occ) self.readparams(prm) fmat, c_am, v_lm = self.initfockbuild() # updates self.C rho = 0.5*np.diag(self.ks.mo_occ).astype(complex) self.field = tdfields.FIELDS(self, self.params) self.field.initializeexpectation(rho, c_am) return fmat, c_am, v_lm, rho
def kernel(self, mo_energy=None, mo_coeff=None, with_t2=WITH_T2): if mo_energy is None: mo_energy = self.mo_energy if mo_coeff is None: mo_coeff = self.mo_coeff if mo_energy is None or mo_coeff is None: log = logger.Logger(self.stdout, self.verbose) log.warn('mo_coeff, mo_energy are not given.\n' 'You may need to call mf.kernel() to generate them.') raise RuntimeError mo_coeff, mo_energy = _add_padding(self, mo_coeff, mo_energy) # TODO: compute e_hf for non-canonical SCF self.e_hf = self._scf.e_tot self.e_corr, self.t2 = \ kernel(self, mo_energy, mo_coeff, verbose=self.verbose, with_t2=with_t2) logger.log(self, 'KMP2 energy = %.15g', self.e_corr) return self.e_corr, self.t2
def kernel(self, mo_energy=None, mo_coeff=None, eris=None, with_t2=True): ''' Args: with_t2 : bool Whether to generate and hold t2 amplitudes in memory. ''' if mo_energy is None: mo_energy = self.mo_energy if mo_coeff is None: mo_coeff = self.mo_coeff if mo_energy is None or mo_coeff is None: log.warn('mo_coeff, mo_energy are not given.\n' 'You may need to call mf.kernel() to generate them.') raise RuntimeError self.emp2, self.t2 = \ kernel(self, mo_energy, mo_coeff, eris, with_t2, verbose=self.verbose) logger.log(self, 'RMP2 energy = %.15g', self.emp2) self.e_corr = self.emp2 return self.emp2, self.t2
def prop(self, fmat, c_am, v_lm, rho, output): """ The main tdscf propagation loop. Args: fmat: complex Fock matrix in Lowdin AO basis c_am: complex Transformation Matrix |AO><MO| v_lm: complex Transformation Matrix |LAO><MO| rho: complex MO density matrix. output: str name of the file with result of propagation Saved results: f: file output file with |t, dipole(x,y,z), energy| """ it = 0 tnow = 0 rhom12 = rho.copy() n_occ = int(sum(self.ks.mo_occ)/2) f = open(output,"a") logger.log(self,"\n\nPropagation Begins") start = time.time() while (it<self.params["MaxIter"]): rho, rhom12, c_am, v_lm, fmat, jmat, kmat = self.tddftstep(fmat, c_am, v_lm, rho, rhom12, tnow) # rho = newrho.copy() # rhom12 = newrhom12.copy() #self.log.append(self.loginstant(it)) f.write(self.loginstant(rho, c_am, v_lm, fmat, jmat, kmat, tnow, it)+"\n") # Do logging. tnow = tnow + self.params["dt"] if it%self.params["StatusEvery"] ==0 or \ it == self.params["MaxIter"]-1: end = time.time() logger.log(self, "%f hr/ps", \ (end - start)/(60*60*tnow * FSPERAU * 0.001)) it = it + 1 f.close()
def imp_scf(self): self.build_() self.dump_flags() self.scf_conv, self.hf_energy, self.mo_energy, \ self.mo_coeff_on_imp, self.mo_occ \ = scf.hf.kernel(self, self.conv_tol, dump_chk=False) log.info(self, 'impurity MO energy') for i in range(self.mo_energy.size): if self.mo_occ[i] > 0: log.info(self, 'impurity occupied MO %d energy = %.15g occ=%g', \ i+1, self.mo_energy[i], self.mo_occ[i]) else: log.info(self, 'impurity virtual MO %d energy = %.15g occ=%g', \ i+1, self.mo_energy[i], self.mo_occ[i]) #e_nuc = self.energy_nuc(self.mol) #log.log(self, 'impurity sys nuclear repulsion = %.15g', e_nuc) if self.scf_conv: log.log(self, 'converged impurity sys electronic energy = %.15g', \ self.hf_energy) else: log.log(self, 'SCF not converge.') log.log(self, 'electronic energy = %.15g after %d cycles.', \ self.hf_energy, self.max_cycle) # mo_coeff_on_imp based on embedding basis # mo_coeff based on AOs self.mo_coeff = numpy.dot(self.impbas_coeff, self.mo_coeff_on_imp) dm = self.make_rdm1(self.mo_coeff_on_imp, self.mo_occ) vhf = self.get_veff(self.mol, dm) self.hf_energy, self.e_frag, self.nelec_frag = \ self.calc_frag_elec_energy(self.mol, vhf, dm) log.log(self, 'fragment electronic energy = %.15g', self.e_frag) log.log(self, 'fragment electron number = %.15g', self.nelec_frag) self.frag_mulliken_pop() return self.e_frag
def loginstant(self, rho, c_am, v_lm, fmat, jmat, kmat, tnow, it): """ time is logged in atomic units. Args: rho: complex MO density matrix. c_am: complex Transformation Matrix |AO><MO| v_lm: complex Transformation Matrix |LAO><MO| fmat: complex Fock matrix in Lowdin AO basis jmat: complex Coulomb matrix in AO basis kmat: complex Exact Exchange in AO basis tnow: float Current time in propagation in A.U. it: int Number of iteration of propagation Returns: tore: str |t, dipole(x,y,z), energy| """ np.set_printoptions(precision=7) tore = str(tnow)+" "+str(self.dipole(rho, c_am).real).rstrip("]").lstrip("[")+\ " " +str(self.energy(transmat(rho,v_lm,-1),fmat, jmat, kmat)) if it % self.params["StatusEvery"] == 0 or it == self.params[ "MaxIter"] - 1: logger.log(self, "t: %f fs Energy: %f a.u. Total Density: %f",\ tnow*FSPERAU,self.energy(transmat(rho,v_lm,-1),fmat, jmat, kmat), \ 2*np.trace(rho)) logger.log(self, "Dipole moment(X, Y, Z, au): %8.5f, %8.5f, %8.5f",\ self.dipole(rho, c_am).real[0],self.dipole(rho, c_am).real[1],\ self.dipole(rho, c_am).real[2]) return tore
def imp_scf(self): self.dump_flags() self.build_() self.scf_conv, self.hf_energy, self.mo_energy, \ self.mo_coeff_on_imp, self.mo_occ \ = scf.hf.kernel(self.mol, self, self.conv_tol, \ dump_chk=False) def dump_mo_energy(mo_energy, mo_occ, title=''): log.info(self, 'impurity %s MO energy', title) for i in range(mo_energy.size): if mo_occ[i] > 0: log.info(self, 'impurity %s occupied MO %d energy = %.15g', \ title, i+1, mo_energy[i]) else: log.info(self, 'impurity %s virtual MO %d energy = %.15g', \ title, i+1, mo_energy[i]) dump_mo_energy(self.mo_energy[0], self.mo_occ[0], 'alpha') dump_mo_energy(self.mo_energy[1], self.mo_occ[1], 'beta') if self.scf_conv: log.log(self, 'converged impurity sys electronic energy = %.15g', \ self.hf_energy) else: log.log(self, 'SCF not converge.') log.log(self, 'electronic energy = %.15g after %d cycles.', \ self.hf_energy, self.max_cycle) dm = self.make_rdm1(self.mo_coeff_on_imp, self.mo_occ) vhf = self.get_veff(self.mol, dm) self.hf_energy, self.e_frag, self.nelec_frag = \ self.calc_frag_elec_energy(self.mol, vhf, dm) log.log(self, 'fragment electronic energy = %.15g', self.e_frag) log.log(self, 'fragment electron number = %.15g', self.nelec_frag) self.frag_mulliken_pop() return self.e_frag
def loginstant(self, rho, c_am, v_lm, fmat, jmat, kmat, tnow, it): """ time is logged in atomic units. Args: rho: complex MO density matrix. c_am: complex Transformation Matrix |AO><MO| v_lm: complex Transformation Matrix |LAO><MO| fmat: complex Fock matrix in Lowdin AO basis jmat: complex Coulomb matrix in AO basis kmat: complex Exact Exchange in AO basis tnow: float Current time in propagation in A.U. it: int Number of iteration of propagation Returns: tore: str |t, dipole(x,y,z), energy| """ np.set_printoptions(precision = 7) tore = str(tnow)+" "+str(self.dipole(rho, c_am).real).rstrip("]").lstrip("[")+\ " " +str(self.energy(transmat(rho,v_lm,-1),fmat, jmat, kmat)) if it%self.params["StatusEvery"] ==0 or it == self.params["MaxIter"]-1: logger.log(self, "t: %f fs Energy: %f a.u. Total Density: %f",\ tnow*FSPERAU,self.energy(transmat(rho,v_lm,-1),fmat, jmat, kmat), \ 2*np.trace(rho)) logger.log(self, "Dipole moment(X, Y, Z, au): %8.5f, %8.5f, %8.5f",\ self.dipole(rho, c_am).real[0],self.dipole(rho, c_am).real[1],\ self.dipole(rho, c_am).real[2]) return tore
def imp_scf(self): self.orth_coeff = self.get_orth_ao(self.mol) self.dump_flags() self.build_(self.mol) self.scf_conv, self.hf_energy, self.mo_energy, \ self.mo_coeff_on_imp, self.mo_occ \ = scf.hf.kernel(self, self.conv_tol, dump_chk=False) #self.mo_coeff = numpy.dot(self.impbas_coeff, self.mo_coeff_on_imp) self.mo_coeff = self.mo_coeff_on_imp # because the integrals are read from FCIDUMP if self.scf_conv: log.log(self, 'converged impurity sys electronic energy = %.15g', \ self.hf_energy) else: log.log(self, 'SCF not converge.') log.log(self, 'electronic energy = %.15g after %d cycles.', \ self.hf_energy, self.max_cycle) dm = self.make_rdm1(self.mo_coeff_on_imp, self.mo_occ) vhf = self.get_veff(self.mol, dm) self.hf_energy, self.e_frag, self.nelec_frag = \ self.calc_frag_elec_energy(self.mol, vhf, dm) return self.hf_energy
def readparams(self, prm): """ Set Defaults, Read the file and fill the params dictionary Args: prm: str string object with |variable value| on each line """ self.params["Model"] = "TDDFT" self.params["Method"] = "MMUT" self.params["BBGKY"] = 0 self.params["TDCIS"] = 1 self.params["dt"] = 0.02 self.params["MaxIter"] = 15000 self.params["ExDir"] = 1.0 self.params["EyDir"] = 1.0 self.params["EzDir"] = 1.0 self.params["FieldAmplitude"] = 0.01 self.params["FieldFreq"] = 0.9202 self.params["Tau"] = 0.07 self.params["tOn"] = 7.0 * self.params["Tau"] self.params["ApplyImpulse"] = 1 self.params["ApplyCw"] = 0 self.params["StatusEvery"] = 5000 self.params["Print"] = 0 # Here they should be read from disk. if (prm != None): for line in prm.splitlines(): s = line.split() if len(s) > 1: if s[0] == "MaxIter" or s[0] == str("ApplyImpulse") or \ s[0] == str("ApplyCw") or s[0] == str("StatusEvery"): self.params[s[0]] = int(s[1]) elif s[0] == "Model" or s[0] == "Method": self.params[s[0]] = s[1].upper() else: self.params[s[0]] = float(s[1]) logger.log(self, "=============================") logger.log(self, " Parameters") logger.log(self, "=============================") logger.log(self, "Model: " + self.params["Model"].upper()) logger.log(self, "Method: " + self.params["Method"].upper()) logger.log(self, "dt: %.2f", self.params["dt"]) logger.log(self, "MaxIter: %d", self.params["MaxIter"]) logger.log(self, "ExDir: %.2f", self.params["ExDir"]) logger.log(self, "EyDir: %.2f", self.params["EyDir"]) logger.log(self, "EzDir: %.2f", self.params["EzDir"]) logger.log(self, "FieldAmplitude: %.4f", self.params["FieldAmplitude"]) logger.log(self, "FieldFreq: %.4f", self.params["FieldFreq"]) logger.log(self, "Tau: %.2f", self.params["Tau"]) logger.log(self, "tOn: %.2f", self.params["tOn"]) logger.log(self, "ApplyImpulse: %d", self.params["ApplyImpulse"]) logger.log(self, "ApplyCw: %d", self.params["ApplyCw"]) logger.log(self, "StatusEvery: %d", self.params["StatusEvery"]) logger.log(self, "=============================\n\n") return
def initfockbuild(self): """ Using Roothan's equation to build a Initial Fock matrix and Transformation Matrices Returns: fmat: float or complex Fock matrix in Lowdin AO basis c_am: float Transformation Matrix |AO><MO| v_lm: float Transformation Matrix |LAO><MO| """ start = time.time() n_occ = int(sum(self.ks.mo_occ) / 2) err = 100 it = 0 self.h = self.ks.get_hcore() s = self.s.copy() x = self.x.copy() sx = np.dot(s, x) dm_lao = 0.5*transmat(self.ks.get_init_guess(self.ks.mol, \ self.ks.init_guess), sx).astype(complex) if isinstance(self.ks.diis, lib.diis.DIIS): self.adiis = self.ks.diis elif self.ks.diis: self.adiis = diis.SCF_DIIS(self.ks, self.ks.diis_file) self.adiis.space = self.ks.diis_space self.adiis.rollback = self.ks.diis_space_rollback else: self.adiis = None fmat, jmat, kmat = self.fockbuild(dm_lao) etot = self.energy(dm_lao, fmat, jmat, kmat) + self.enuc while (err > self.conv_tol): # Diagonalize F in the lowdin basis eigs, v_lm = np.linalg.eig(fmat) idx = eigs.argsort() eigs.sort() v_lm = v_lm[:, idx].copy() # Fill up the density in the MO basis and then Transform back rho = 0.5 * np.diag(self.ks.mo_occ).astype(complex) dm_lao = transmat(rho, v_lm, -1) etot_old = etot etot = self.energy(dm_lao, fmat, jmat, kmat) fmat, jmat, kmat = self.fockbuild(dm_lao, it) err = abs(etot - etot_old) logger.debug(self, "Ne: %f", np.trace(rho)) logger.debug( self, "Iteration: %d Energy: %.11f \ Error = %.11f", it, etot, err) it += 1 if it > self.ks.max_cycle: logger.log( self, "Max cycle of SCF reached: %d\n Exiting TDSCF. Please raise ks.max_cycle", it) quit() rho = 0.5 * np.diag(self.ks.mo_occ).astype(complex) dm_lao = transmat(rho, v_lm, -1) c_am = np.dot(self.x, v_lm) logger.log(self, "Ne: %f", np.trace(rho)) logger.log(self, "Converged Energy: %f", etot) # logger.log(self, "Eigenvalues: %f", eigs.real) # print "Eigenvalues: ", eigs.real end = time.time() logger.info(self, "Initial Fock Built time: %f", end - start) return fmat, c_am, v_lm
def initfockbuild(self): """ Using Roothan's equation to build a Initial Fock matrix and Transformation Matrices Returns: fmat: float or complex Fock matrix in Lowdin AO basis c_am: float Transformation Matrix |AO><MO| v_lm: float Transformation Matrix |LAO><MO| """ start = time.time() n_occ = int(sum(self.ks.mo_occ)/2) err = 100 it = 0 self.h = self.ks.get_hcore() s = self.s.copy() x = self.x.copy() sx = np.dot(s,x) dm_lao = 0.5*transmat(self.ks.get_init_guess(self.ks.mol, \ self.ks.init_guess), sx).astype(complex) if isinstance(self.ks.diis, lib.diis.DIIS): self.adiis = self.ks.diis elif self.ks.diis: self.adiis = diis.SCF_DIIS(self.ks, self.ks.diis_file) self.adiis.space = self.ks.diis_space self.adiis.rollback = self.ks.diis_space_rollback else: self.adiis = None fmat, jmat, kmat = self.fockbuild(dm_lao) dm_lao_old = dm_lao etot = self.energy(dm_lao,fmat, jmat, kmat)+ self.enuc while (err > self.conv_tol): # Diagonalize F in the lowdin basis eigs, v_lm = np.linalg.eig(fmat) idx = eigs.argsort() eigs.sort() v_lm = v_lm[:,idx].copy() # Fill up the density in the MO basis and then Transform back rho = 0.5*np.diag(self.ks.mo_occ).astype(complex) dm_lao = transmat(rho,v_lm,-1) etot_old = etot etot = self.energy(dm_lao,fmat, jmat, kmat) fmat, jmat, kmat = self.fockbuild(dm_lao,it) err = abs(etot-etot_old) logger.debug(self, "Ne: %f", np.trace(rho)) logger.debug(self, "Iteration: %d Energy: %.11f \ Error = %.11f", it, etot, err) it += 1 if it > self.ks.max_cycle: logger.log(self, "Max cycle of SCF reached: %d\n Exiting TDSCF. Please raise ks.max_cycle", it) quit() rho = 0.5*np.diag(self.ks.mo_occ).astype(complex) dm_lao = transmat(rho,v_lm,-1) c_am = np.dot(self.x,v_lm) logger.log(self, "Ne: %f", np.trace(rho)) logger.log(self, "Converged Energy: %f", etot) # logger.log(self, "Eigenvalues: %f", eigs.real) # print "Eigenvalues: ", eigs.real end = time.time() logger.info(self, "Initial Fock Built time: %f", end-start) return fmat, c_am, v_lm
def readparams(self,prm): """ Set Defaults, Read the file and fill the params dictionary Args: prm: str string object with |variable value| on each line """ self.params["Model"] = "TDDFT" self.params["Method"] = "MMUT" self.params["BBGKY"]=0 self.params["TDCIS"]=1 self.params["dt"] = 0.02 self.params["MaxIter"] = 15000 self.params["ExDir"] = 1.0 self.params["EyDir"] = 1.0 self.params["EzDir"] = 1.0 self.params["FieldAmplitude"] = 0.01 self.params["FieldFreq"] = 0.9202 self.params["Tau"] = 0.07 self.params["tOn"] = 7.0*self.params["Tau"] self.params["ApplyImpulse"] = 1 self.params["ApplyCw"] = 0 self.params["StatusEvery"] = 5000 self.params["Print"]=0 # Here they should be read from disk. if(prm != None): for line in prm.splitlines(): s = line.split() if len(s) > 1: if s[0] == "MaxIter" or s[0] == str("ApplyImpulse") or \ s[0] == str("ApplyCw") or s[0] == str("StatusEvery"): self.params[s[0]] = int(s[1]) elif s[0] == "Model" or s[0] == "Method": self.params[s[0]] = s[1].upper() else: self.params[s[0]] = float(s[1]) logger.log(self,"=============================") logger.log(self," Parameters") logger.log(self,"=============================") logger.log(self,"Model: " + self.params["Model"].upper()) logger.log(self,"Method: "+ self.params["Method"].upper()) logger.log(self,"dt: %.2f", self.params["dt"]) logger.log(self,"MaxIter: %d", self.params["MaxIter"]) logger.log(self,"ExDir: %.2f", self.params["ExDir"]) logger.log(self,"EyDir: %.2f", self.params["EyDir"]) logger.log(self,"EzDir: %.2f", self.params["EzDir"]) logger.log(self,"FieldAmplitude: %.4f", self.params["FieldAmplitude"]) logger.log(self,"FieldFreq: %.4f", self.params["FieldFreq"]) logger.log(self,"Tau: %.2f", self.params["Tau"]) logger.log(self,"tOn: %.2f", self.params["tOn"]) logger.log(self,"ApplyImpulse: %d", self.params["ApplyImpulse"]) logger.log(self,"ApplyCw: %d", self.params["ApplyCw"]) logger.log(self,"StatusEvery: %d", self.params["StatusEvery"]) logger.log(self,"=============================\n\n") return