def build_locops(mol_frag, mol_env, ints, core1PDM_loc, Kcoeff = 1.0, Ne_core=0): t0 = tools.time0() locKin = ints.frag_kin_loc() locVnuc1 = ints.frag_vnuc_loc(mol_frag) locVnuc2 = ints.frag_vnuc_loc(mol_env) # locVnuc_bound1 = 0.0 # locVnuc_bound2 = 0.0 locCoreJK = 0.0 if(Ne_core>0): locCoreJK = ints.coreJK_loc(core1PDM_loc, Kcoeff) locTEI = ints.tei_loc() ops = {"locKin":locKin} ops["locVnuc1"] = locVnuc1 ops["locVnuc2"] = locVnuc2 # ops["locVnuc_bound1"] = locVnuc_bound1 # ops["locVnuc_bound2"] = locVnuc_bound2 ops["locCoreJK"] = locCoreJK ops["locTEI"] = locTEI tools.timer("libgen.ops.build_locops",t0) return ops
def get_vxc(ks, mol, dm, n_core_elec=0.0, hermi=1): t0 = tools.time0() ground_state = (isinstance(dm, np.ndarray) and dm.ndim == 2) if (not ground_state): raise Exception("fatal error") if ks.grids.coords is None: ks.grids.build(with_non0tab=True) if ks.small_rho_cutoff > 1e-20 and ground_state: # Filter grids the first time setup grids #t0 = (time.clock(), time.time()) ks.grids = prune_small_rho_grids_(ks, mol, dm, ks.grids, n_core_elec=n_core_elec) #t1 = tools.timer("prune grid",t0) if hermi == 2: # because rho = 0 n, exc, vxc = 0, 0, 0 else: n, exc, vxc = ks._numint.nr_rks(mol, ks.grids, ks.xc, dm, hermi=hermi) hyb = ks._numint.hybrid_coeff(ks.xc, spin=mol.spin) t1 = tools.timer("vxc construction", t0) return n, exc, vxc, hyb
def build_subops(impAtom, mol_frag, mol_env, boundary_atoms1, boundary_atoms2, ints, loc2sub, core1PDM_loc, dim, Kcoeff = 1.0, Ne_core=0): t0 = tools.time0() subKin = frag_kin_sub( ints, loc2sub, dim ) #subVnuc1 = frag_vnuc_sub( ints, impAtom, loc2sub, dim) #subVnuc2 = frag_vnuc_sub( ints, 1-impAtom, loc2sub, dim ) subVnuc1 = frag_vnuc_sub(mol_frag, ints, loc2sub, dim) subVnuc2 = frag_vnuc_sub(mol_env, ints, loc2sub, dim) subVnuc_bound1 = 0.0 subVnuc_bound2 = 0.0 if(boundary_atoms1 is not None): subVnuc_bound1 += ints.bound_vnuc_sub(boundary_atoms1, loc2sub, dim ) if(boundary_atoms2 is not None): subVnuc_bound2 += ints.bound_vnuc_sub(boundary_atoms2, loc2sub, dim ) #tools.MatPrint(subVnuc_bound1,"subVnuc_bound1") #tools.MatPrint(subVnuc_bound2,"subVnuc_bound2") subCoreJK = coreJK_sub( ints, loc2sub, dim, core1PDM_loc, Ne_core, Kcoeff ) subTEI = ints.tei_sub( loc2sub, dim ) ops = {"subKin":subKin} ops["subVnuc1"] = subVnuc1 ops["subVnuc2"] = subVnuc2 ops["subVnuc_bound1"] = subVnuc_bound1 ops["subVnuc_bound2"] = subVnuc_bound2 ops["subCoreJK"] = subCoreJK ops["subTEI"] = subTEI tools.timer("libgen.ops.build_subops",t0) return ops
def coreJK_sub(ints, loc2sub, numActive, coreDMloc, Ne_core, Kcoeff = 1.0): t0 = tools.time0() sub_coreJK = None if(Ne_core == 0): sub_coreJK = 0.0 else: loc_coreJK = ints.coreJK_loc(coreDMloc, Kcoeff) sub_coreJK = tools.op_loc2sub(loc_coreJK, loc2sub[:,:numActive]) t1 = tools.timer("coreJK_sub",t0) return sub_coreJK
def oep_calc_diffP_derivative(self, x, dim, Ne_frag, Ne_env, P_ref, ops): t0 = tools.time0() size = dim * (dim + 1) // 2 hess_frag = oep_calc_dPdV(self.frag_mo[:, :-1], self.frag_mo[:, -1], size, self.Ne_frag // 2, dim) hess_env = oep_calc_dPdV(self.env_mo[:, :-1], self.env_mo[:, -1], size, self.Ne_env // 2, dim) t1 = tools.timer("hessian", t0) return hess_frag + hess_env
def oep_hess(jCa, orb_Ea, size, NOrb, NAlpha=None, mo_occ=None, smear=0.0, sym_tab=None): mo_coeff = np.reshape(jCa, (NOrb * NOrb), 'F') hess = np.ndarray((size, size), dtype=float, order='F') nthread = lib.num_threads() e_tol = 1e-4 occ_tol = 1e-8 #this should be small enough? t0 = tools.time0() if smear < 1e-8: if NAlpha is None: raise ValueError("NAlpha has to be set") libhess.calc_hess_dm_fast(hess.ctypes.data_as(ctypes.c_void_p), \ mo_coeff.ctypes.data_as(ctypes.c_void_p), orb_Ea.ctypes.data_as(ctypes.c_void_p), \ ctypes.c_int(size), ctypes.c_int(NOrb), ctypes.c_int(NAlpha), ctypes.c_int(nthread)) else: if mo_occ is None: raise ValueError("mo_occ has to be set") libhess.calc_hess_dm_fast_frac(hess.ctypes.data_as(ctypes.c_void_p), \ mo_coeff.ctypes.data_as(ctypes.c_void_p), orb_Ea.ctypes.data_as(ctypes.c_void_p), \ mo_occ.ctypes.data_as(ctypes.c_void_p),\ ctypes.c_int(size), ctypes.c_int(NOrb), ctypes.c_int(nthread),\ ctypes.c_double(smear), ctypes.c_double(e_tol), ctypes.c_double(occ_tol)) #tools.MatPrint(hess,"hess") t1 = tools.timer("hessian construction", t0) #if sym_tab is not None: # return symmtrize_hess(hess,sym_tab,size) return hess
def oep_loop(self, umat0, do_leastsq=False): ''' oep with split loops ''' t0 = tools.time0() params = self.params gtol0 = copy.copy(params.options["gtol"]) gtol_min = 1e6 dim = self.dim threshold = params.diffP_tol maxit = params.outer_maxit it = 0 umat = copy.copy(umat0) while it < maxit: it += 1 print(" OEP iteration ", it) P_imp_old = copy.copy(self.P_imp) P_bath_old = copy.copy(self.P_bath) diffP = (self.P_imp + self.P_bath - self.P_ref) gtol = np.amax(np.absolute(diffP)) gtol_min = min(gtol, gtol_min) self.params.options["gtol"] = max(gtol_min / 5.0, gtol0) #gradually reduce gtol ''' if self.use_suborb and it ==1: gtol_min = 0.25 #hack self.params.options["gtol"] = max(gtol_min/5.0, gtol0) ''' if do_leastsq: umat = self.oep_leastsq(umat, nonscf=True, dm0_frag=P_imp_old, dm0_env=P_bath_old) else: umat = self.oep_old(umat, nonscf=True, dm0_frag=P_imp_old, dm0_env=P_bath_old) if self.use_suborb: #sdmfet ao2sub = self.ao2sub[:, :dim] scf_args_frag = {'mol':self.mol_frag, 'Ne':self.Ne_frag, 'Norb':dim, 'method':self.mf_method,\ 'vext_1e':umat, 'oei':self.oei_frag, 'vhxc':self.vhxc_frag, 'tei':self.tei, 'dm0':P_imp_old, 'coredm':0.0, \ 'ao2sub':ao2sub, 'smear_sigma':self.smear_sigma, 'max_cycle':self.scf_max_cycle} mf_frag = qcwrap.qc_scf(True, nonscf=True, **scf_args_frag) mf_frag.kernel() self.P_imp = mf_frag.rdm1 scf_args_env = {'mol':self.mol_env, 'Ne':self.Ne_env, 'Norb':dim, 'method':self.mf_method,\ 'vext_1e':umat, 'oei':self.oei_env, 'vhxc':self.vhxc_env, 'tei':self.tei, 'dm0':P_bath_old, 'coredm':self.core1PDM_ao, \ 'ao2sub':ao2sub, 'smear_sigma':self.smear_sigma, 'max_cycle':self.scf_max_cycle} mf_env = qcwrap.qc_scf(True, nonscf=True, **scf_args_env) mf_env.kernel() self.P_bath = mf_env.rdm1 else: #dmfet scf_args_frag = {'mol':self.mol_frag, 'xc_func':self.mf_method, 'dm0':P_imp_old, \ 'vext_1e':umat, 'extra_oei':self.vnuc_bound_frag_ao, 'smear_sigma':self.smear_sigma,\ 'max_cycle':self.scf_max_cycle} mf_frag = qcwrap.qc_scf(False, nonscf=True, **scf_args_frag) mf_frag.kernel() self.P_imp = mf_frag.rdm1 scf_args_env = {'mol':self.mol_env, 'xc_func':self.mf_method, 'dm0':P_bath_old, \ 'vext_1e':umat, 'extra_oei':self.vnuc_bound_env_ao, 'smear_sigma':self.smear_sigma,\ 'max_cycle':self.scf_max_cycle} mf_env = qcwrap.qc_scf(False, nonscf=True, **scf_args_env) mf_env.kernel() self.P_bath = mf_env.rdm1 gmax_imp = tools.mat_diff_max(self.P_imp, P_imp_old) gmax_bath = tools.mat_diff_max(self.P_bath, P_bath_old) print("diffP_max_imp, diffP_max_bath ") print(gmax_imp, gmax_bath) del (P_imp_old) del (P_bath_old) #convergence check if gmax_imp < threshold and gmax_bath < threshold: print("embedding potential optimization converged") break if it == maxit: print( "STOP: embedding potential optimization exceeds max No. of iterations" ) t1 = tools.timer("embedding potential optimization (split loops)", t0) self.params.options["gtol"] = gtol0 return umat
def oep_old(self, umat0, nonscf=False, dm0_frag=None, dm0_env=None): ''' Extended Wu-Yang method JCP, 134, 154110 (2011) ''' t0 = tools.time0() params = self.params print("gtol = ", params.options["gtol"]) dim = self.dim sym_tab = self.sym_tab x0 = self.v2m(umat0, dim, False, sym_tab) func = ObjFunc_WuYang scf_solver = qcwrap.qc_scf if self.use_suborb: #sdmfet ao2sub = self.ao2sub[:, :dim] scf_args_frag = {'mol':self.mol_frag, 'Ne':self.Ne_frag, 'Norb':dim, 'method':self.mf_method,\ 'oei':self.oei_frag, 'tei':self.tei, 'dm0':dm0_frag, 'coredm':0.0, \ 'ao2sub':ao2sub, 'smear_sigma':self.smear_sigma, 'max_cycle':self.scf_max_cycle} scf_args_env = {'mol':self.mol_env, 'Ne':self.Ne_env, 'Norb':dim, 'method':self.mf_method,\ 'oei':self.oei_env, 'tei':self.tei, 'dm0':dm0_env, 'coredm':self.core1PDM_ao, \ 'ao2sub':ao2sub, 'smear_sigma':self.smear_sigma, 'max_cycle':self.scf_max_cycle} if nonscf: #hack to compute vhxc here from pydmfet.qcwrap.pyscf_rks_nonscf import rks_nonscf mf_frag = rks_nonscf(self.Ne_frag, dim, self.mf_method.lower(), mol=self.mol_frag,\ oei=self.oei_frag,tei=self.tei,dm0=dm0_frag,coredm=0.0,\ ao2sub=ao2sub,smear_sigma=self.smear_sigma,max_cycle=self.scf_max_cycle) self.vhxc_frag = copy.copy(mf_frag.vhxc) scf_args_frag.update({'vhxc': self.vhxc_frag}) mf_env = rks_nonscf(self.Ne_env, dim, self.mf_method.lower(), mol=self.mol_env,\ oei=self.oei_env,tei=self.tei,dm0=dm0_env,coredm=self.core1PDM_ao,\ ao2sub=ao2sub,smear_sigma=self.smear_sigma,max_cycle=self.scf_max_cycle) self.vhxc_env = copy.copy(mf_env.vhxc) scf_args_env.update({'vhxc': self.vhxc_env}) else: #dmfet (no frozen density) scf_args_frag = {'mol':self.mol_frag, 'xc_func':self.mf_method, 'dm0':dm0_frag, \ 'extra_oei':self.vnuc_bound_frag_ao, 'smear_sigma':self.smear_sigma, 'max_cycle':self.scf_max_cycle} scf_args_env = {'mol':self.mol_env, 'xc_func':self.mf_method, 'dm0':dm0_env, \ 'extra_oei':self.vnuc_bound_env_ao, 'smear_sigma':self.smear_sigma, 'max_cycle':self.scf_max_cycle} use_hess = False jac = True hess = None if params.opt_method.lower().startswith( "trust") or params.opt_method.lower() == "newton": use_hess = True func = Memoize_Jac_Hess(ObjFunc_WuYang) jac = func.derivative hess = func.hessian func_args = ( self.v2m, sym_tab, scf_solver, self.P_ref, dim, self.use_suborb, nonscf, scf_args_frag, scf_args_env, use_hess, ) ovlp = np.eye(dim) if not self.use_suborb: ovlp = self.mol_full.intor_symmetric('int1e_ovlp') shift = self.v2m(ovlp, dim, False, sym_tab) shift = shift / np.linalg.norm(shift) optimizer = OEP_Optimize(params.opt_method, params.options, x0, func, func_args, jac, hess) x = optimizer.kernel(const_shift=shift) umat = self.v2m(x, dim, True, sym_tab) t1 = tools.timer("embedding potential optimization (extended Wu-Yang)", t0) return umat
from pydmfet import locints, sdmfet, oep, tools from pydmfet.qcwrap.pyscf_rks_ao import rks_ao from pyscf import gto, scf, ao2mo import numpy as np from pyscf.tools import molden t0 = tools.time0() bas = '6-31G*' temp = 0.005 mol = gto.Mole() mol.atom = open('O2-C24.xyz').read() mol.basis = bas mol.charge = 0 mol.build(max_memory=24000, verbose=4) dm_guess = None _, _, mo_coeff, mo_occ, _, _ = molden.load("MO_pbe.molden") dm_guess = np.dot(mo_coeff * mo_occ, mo_coeff.T) mf = rks_ao(mol, smear_sigma=temp) mf.xc = "pbe,pbe" mf.max_cycle = 50 mf.scf(dm0=dm_guess) myInts = locints.LocalIntegrals(mf, range(mol.nao_nr()), 'meta_lowdin') natoms = mol.natm impAtom = np.zeros([natoms], dtype=int) for i in range(8):