def hess_wuyang(self, x, P_ref, dim, Ne_frag, Ne_env, impJK_sub, bathJK_sub): size = dim * (dim + 1) // 2 umat = tools.vec2mat(x, dim) ops = self.ops subKin = ops["subKin"] subVnuc1 = ops["subVnuc1"] subVnuc2 = ops["subVnuc2"] subVnuc_bound1 = ops["subVnuc_bound1"] subVnuc_bound2 = ops["subVnuc_bound2"] subCoreJK = ops["subCoreJK"] subTEI = ops["subTEI"] subOEI1 = subKin + subVnuc1 + subVnuc_bound1 + impJK_sub + umat subOEI2 = subKin + subVnuc2 + subVnuc_bound2 + subCoreJK + bathJK_sub + umat FRAG_energy, FRAG_1RDM, mo_coeff_frag, mo_energy_frag, mo_occ_frag = qcwrap.pyscf_rhf.scf_oei( subOEI1, dim, Ne_frag, self.smear_sigma) hess_frag = oep_hess(mo_coeff_frag, mo_energy_frag, size, dim, self.Ne_frag // 2, mo_occ_frag, self.smear_sigma) ENV_energy, ENV_1RDM, mo_coeff_env, mo_energy_env, mo_occ_env = qcwrap.pyscf_rhf.scf_oei( subOEI2, dim, Ne_env, self.smear_sigma) hess_env = oep_hess(mo_coeff_env, mo_energy_env, size, dim, self.Ne_env // 2, mo_occ_env, self.smear_sigma) hess = hess_frag + hess_env return hess
def oep_calc_diffP(self, x, dim, Ne_frag, Ne_env, P_ref, ops): umat = tools.vec2mat(x, dim) #print "|umat| = ", np.linalg.norm(umat) if (self.params.oep_print >= 3): #print "sum(diag(umat)) = ", np.sum(np.diag(umat)) tools.MatPrint(umat, 'umat') FRAG_1RDM = np.zeros([dim, dim], dtype=float) ENV_1RDM = np.zeros([dim, dim], dtype=float) FRAG_energy = 0.0 ENV_energy = 0.0 frag_mo = np.zeros([dim, dim], dtype=float) env_mo = np.zeros([dim, dim], dtype=float) subKin = ops["subKin"] subVnuc1 = ops["subVnuc1"] subVnuc2 = ops["subVnuc2"] subVnuc_bound1 = ops["subVnuc_bound1"] subVnuc_bound2 = ops["subVnuc_bound2"] subCoreJK = ops["subCoreJK"] subTEI = ops["subTEI"] subOEI1 = subKin + subVnuc1 + subVnuc_bound1 + umat subOEI2 = subKin + subVnuc2 + subVnuc_bound2 + subCoreJK + umat if (Ne_frag > 0): frag_coredm_guess, mo_coeff = tools.fock2onedm( subOEI1, Ne_frag // 2) FRAG_energy, FRAG_1RDM, frag_mo = qcwrap.pyscf_rhf.scf( subOEI1, subTEI, dim, Ne_frag, frag_coredm_guess, mf_method=self.mf_method) if (Ne_env > 0): env_coredm_guess, mo_coeff = tools.fock2onedm(subOEI2, Ne_env // 2) ENV_energy, ENV_1RDM, env_mo = qcwrap.pyscf_rhf.scf( subOEI2, subTEI, dim, Ne_env, env_coredm_guess, mf_method=self.mf_method) self.frag_mo = frag_mo self.env_mo = env_mo self.P_imp = FRAG_1RDM self.P_bath = ENV_1RDM diffP = FRAG_1RDM + ENV_1RDM - P_ref grad = tools.mat2vec(diffP, dim) #print "2-norm (grad), max(grad):" #print np.linalg.norm(grad), ", ", np.amax(np.absolute(grad)) return grad
def opt_umat_homo_diff(self, umat, gtol=1e-6): ops = self.ops Ne_frag = self.Ne_frag Ne_env = self.Ne_env dim = self.dim subTEI = ops["subTEI"] subOEI1 = ops["subKin"] + ops["subVnuc1"] + ops["subVnuc_bound1"] + umat subOEI2 = ops["subKin"] + ops["subVnuc2"] + ops[ "subVnuc_bound2"] + ops["subCoreJK"] + umat coredm = self.core1PDM_ao ao2sub = self.ao2sub[:, :dim] #frag_coredm_guess = tools.fock2onedm(subOEI1, Ne_frag//2)[0] frag_coredm_guess = self.P_imp mf_frag = qcwrap.qc_scf(Ne_frag,dim,self.mf_method,mol=self.mol,oei=subOEI1,tei=subTEI,\ dm0=frag_coredm_guess,coredm=0.0,ao2sub=ao2sub, smear_sigma = 0.0) mf_frag.runscf() #env_coredm_guess = tools.fock2onedm(subOEI2, Ne_env//2)[0] env_coredm_guess = self.P_bath mf_env = qcwrap.qc_scf(Ne_env,dim,self.mf_method,mol=self.mol,oei=subOEI2,tei=subTEI,\ dm0=env_coredm_guess,coredm=coredm,ao2sub=ao2sub, smear_sigma = 0.0) mf_env.runscf() print(np.linalg.norm(mf_frag.rdm1 - self.P_imp)) print(np.linalg.norm(mf_env.rdm1 - self.P_bath)) diffP = mf_frag.rdm1 + mf_env.rdm1 - self.P_ref print("|P_frag + P_env - P_ref| = ", np.linalg.norm(diffP)) print("max element of (P_frag + P_env - P_ref) = ", np.amax(np.absolute(diffP))) self.P_imp = mf_frag.rdm1 self.P_bath = mf_env.rdm1 #build null space vint = self.build_null_space(mf_frag, mf_env, Ne_frag, Ne_env, dim) if vint is None: return umat #minimize |ehomo_A-ehomo_B|^2 x0 = tools.mat2vec(umat, dim) n = vint.shape[-1] c = np.zeros((n)) res = self.minimize_ehomo_2(c, x0, vint, gtol) c = res.x #print '|c| = ', np.linalg.norm(c) for i in range(n): x0 += c[i] * vint[:, i] umat = tools.vec2mat(x0, dim) #xmat = xmat - np.eye( xmat.shape[ 0 ] ) * np.average( np.diag( xmat ) ) #tools.MatPrint(umat,'umat') #print '|umat| = ', np.linalg.norm(umat) return umat
def cost_hess_wuyang(self, x, P_ref, dim, Ne_frag, Ne_env, impJK_sub, bathJK_sub, calc_hess=False): size = dim * (dim + 1) // 2 umat = tools.vec2mat(x, dim) print("|umat| = ", np.linalg.norm(umat)) #if(self.params.oep_print >= 3): # print "sum(diag(umat)) = ", np.sum(np.diag(umat)) # tools.MatPrint(umat, 'umat') FRAG_1RDM = np.zeros([dim, dim], dtype=float) ENV_1RDM = np.zeros([dim, dim], dtype=float) FRAG_energy = 0.0 ENV_energy = 0.0 ops = self.ops subKin = ops["subKin"] subVnuc1 = ops["subVnuc1"] subVnuc2 = ops["subVnuc2"] subVnuc_bound1 = ops["subVnuc_bound1"] subVnuc_bound2 = ops["subVnuc_bound2"] subCoreJK = ops["subCoreJK"] subTEI = ops["subTEI"] if (impJK_sub is not None): subOEI1 = subKin + subVnuc1 + subVnuc_bound1 + impJK_sub + umat subOEI2 = subKin + subVnuc2 + subVnuc_bound2 + subCoreJK + bathJK_sub + umat FRAG_energy, FRAG_1RDM, frag_mo_coeff, frag_mo_energy, frag_mo_occ = \ qcwrap.pyscf_rhf.scf_oei( subOEI1, dim, Ne_frag, self.smear_sigma) if (Ne_env > 0): ENV_energy, ENV_1RDM, env_mo_coeff, env_mo_energy, env_mo_occ =\ qcwrap.pyscf_rhf.scf_oei( subOEI2, dim, Ne_env, self.smear_sigma) if (calc_hess): hess_frag = oep_hess(frag_mo_coeff, frag_mo_energy, size, dim, Ne_frag // 2, frag_mo_occ, self.smear_sigma) hess_env = oep_hess(env_mo_coeff, env_mo_energy, size, dim, Ne_env // 2, env_mo_occ, self.smear_sigma) hess = hess_frag + hess_env else: raise Exception("NYI") diffP = FRAG_1RDM + ENV_1RDM - P_ref energy = FRAG_energy + ENV_energy - np.trace(np.dot(P_ref, umat)) grad = tools.mat2vec(diffP, dim) #grad = tools.mat2vec_hchain(diffP, dim) grad = -1.0 * grad print("2-norm (grad), max(grad):") print(np.linalg.norm(grad), ", ", np.amax(np.absolute(grad))) f = -energy print('-W = ', f) #test #f = np.linalg.norm(grad) if (calc_hess): return (f, grad, hess) else: return (f, grad)
def cost_ehomo_2(self, c, x0, vint): x = x0.copy() n = len(c) for i in range(n): x += c[i] * vint[:, i] ops = self.ops Ne_frag = self.Ne_frag Ne_env = self.Ne_env dim = self.dim umat = tools.vec2mat(x, dim) subTEI = ops["subTEI"] subOEI1 = ops["subKin"] + ops["subVnuc1"] + ops["subVnuc_bound1"] + umat subOEI2 = ops["subKin"] + ops["subVnuc2"] + ops[ "subVnuc_bound2"] + ops["subCoreJK"] + umat coredm = self.core1PDM_ao ao2sub = self.ao2sub[:, :dim] frag_coredm_guess = self.P_imp mf_frag = qcwrap.qc_scf(Ne_frag,dim,self.mf_method,mol=self.mol,oei=subOEI1,tei=subTEI,\ dm0=frag_coredm_guess,coredm=0.0,ao2sub=ao2sub, smear_sigma = 0.0) mf_frag.runscf() env_coredm_guess = self.P_bath mf_env = qcwrap.qc_scf(Ne_env,dim,self.mf_method,mol=self.mol,oei=subOEI2,tei=subTEI,\ dm0=env_coredm_guess,coredm=coredm,ao2sub=ao2sub, smear_sigma = 0.0) mf_env.runscf() diffP = mf_frag.rdm1 + mf_env.rdm1 - self.P_ref #print "|P_frag + P_env - P_ref| = ", np.linalg.norm(diffP) #print "max element of (P_frag + P_env - P_ref) = ", np.amax(np.absolute(diffP) ) ehomo_A = mf_frag.mo_energy[Ne_frag // 2 - 1] ehomo_B = mf_env.mo_energy[Ne_env // 2 - 1] delta_ehomo = ehomo_A - ehomo_B #print 'ehomo_A=',ehomo_A,' ehomo_B=',ehomo_B, ' delta_ehomo=', delta_ehomo elumo_A = mf_frag.mo_energy[Ne_frag // 2] elumo_B = mf_env.mo_energy[Ne_env // 2] delta_elumo = elumo_A - elumo_B #print 'elumo_A=',elumo_A,' elumo_B=',elumo_B, ' delta_elumo=', delta_elumo #objective function f = delta_ehomo * delta_ehomo + delta_elumo * delta_elumo #+ (elumo_A-ehomo_A-0.3)**2 homo_A = mf_frag.mo_coeff[:, Ne_frag // 2 - 1] homo_B = mf_env.mo_coeff[:, Ne_env // 2 - 1] lumo_A = mf_frag.mo_coeff[:, Ne_frag // 2] lumo_B = mf_env.mo_coeff[:, Ne_env // 2] #gradient g = np.zeros((n)) for i in range(n): tmp = tools.vec2mat(vint[:, i], dim) EA = np.dot(homo_A, np.dot(tmp, homo_A)) EB = np.dot(homo_B, np.dot(tmp, homo_B)) g[i] = 2.0 * delta_ehomo * (EA - EB) EA = np.dot(lumo_A, np.dot(tmp, lumo_A)) EB = np.dot(lumo_B, np.dot(tmp, lumo_B)) g[i] += 2.0 * delta_elumo * (EA - EB) #EB=np.dot(homo_A,np.dot(tmp,homo_A)) #g[i] += 2.0*(elumo_A-ehomo_A-0.3)*(EA-EB) return (f, g)