def h_op(x): x1 = numpy.zeros_like(focka) x1[mask] = x x1 = x1 - x1.T x2 = numpy.zeros_like(focka) #: x2[nb:,:na] = numpy.einsum('sp,qs->pq', focka[:na,nb:], x1[:na,:na]) #: x2[nb:,:na] += numpy.einsum('rq,rp->pq', focka[:na,:na], x1[:na,nb:]) #: x2[na:,:na] -= numpy.einsum('sp,rp->rs', focka[:na,:na], x1[na:,:na]) #: x2[na:,:na] -= numpy.einsum('ps,qs->pq', focka[na:], x1[:na]) * 2 #: x2[nb:na,:nb] += numpy.einsum('qr,pr->pq', focka[:nb], x1[nb:na]) #: x2[nb:na,:nb] -= numpy.einsum('rq,sq->rs', focka[nb:na], x1[:nb]) #: x2[nb:,:na] += numpy.einsum('sp,qs->pq', fockb[:nb,nb:], x1[:na,:nb]) #: x2[nb:,:na] += numpy.einsum('rq,rp->pq', fockb[:nb,:na], x1[:nb,nb:]) #: x2[nb:,:nb] -= numpy.einsum('sp,rp->rs', fockb[:nb], x1[nb:]) #: x2[nb:,:nb] -= numpy.einsum('rq,sq->rs', fockb[nb:], x1[:nb]) * 2 x2[viridxb[:,None],occidxa] = \ (numpy.einsum('sp,qs->pq', focka[occidxa[:,None],viridxb], x1[occidxa[:,None],occidxa]) +numpy.einsum('rq,rp->pq', focka[occidxa[:,None],occidxa], x1[occidxa[:,None],viridxb])) x2[viridxa[:,None],occidxa] -= \ (numpy.einsum('sp,rp->rs', focka[occidxa[:,None],occidxa], x1[viridxa[:,None],occidxa]) +numpy.einsum('ps,qs->pq', focka[viridxa], x1[occidxa]) * 2) x2[occidxa[:,None],occidxb] += \ (numpy.einsum('qr,pr->pq', focka[occidxb], x1[occidxa]) -numpy.einsum('rq,sq->rs', focka[occidxa], x1[occidxb])) x2[viridxb[:,None],occidxa] += \ (numpy.einsum('sp,qs->pq', fockb[occidxb[:,None],viridxb], x1[occidxa[:,None],occidxb]) +numpy.einsum('rq,rp->pq', fockb[occidxb[:,None],occidxa], x1[occidxb[:,None],viridxb])) x2[viridxb[:,None],occidxb] -= \ (numpy.einsum('sp,rp->rs', fockb[occidxb], x1[viridxb]) +numpy.einsum('rq,sq->rs', fockb[viridxb], x1[occidxb]) * 2) x2 *= .5 d1a = reduce(numpy.dot, (mo_coeff[:,viridxa], x1[viridxa[:,None],occidxa], mo_coeff[:,occidxa].T)) d1b = reduce(numpy.dot, (mo_coeff[:,viridxb], x1[viridxb[:,None],occidxb], mo_coeff[:,occidxb].T)) if hasattr(mf, 'xc'): if APPROX_XC_HESSIAN: vj, vk = mf.get_jk(mol, numpy.array((d1a+d1a.T,d1b+d1b.T))) if abs(hyb) < 1e-10: dvhf = vj[0] + vj[1] else: dvhf = (vj[0] + vj[1]) - vk * hyb else: from pyscf.dft import uks if save_for_dft[0] is None: save_for_dft[0] = mf.make_rdm1(mo_coeff, mo_occ) save_for_dft[1] = mf.get_veff(mol, save_for_dft[0]) dm1 = numpy.array((save_for_dft[0][0]+d1a+d1a.T, save_for_dft[0][1]+d1b+d1b.T)) vhf1 = uks.get_veff_(mf, mol, dm1, dm_last=save_for_dft[0], vhf_last=save_for_dft[1]) dvhf = (vhf1[0]-save_for_dft[1][0], vhf1[1]-save_for_dft[1][1]) save_for_dft[0] = dm1 save_for_dft[1] = vhf1 else: dvhf = mf.get_veff(mol, numpy.array((d1a+d1a.T,d1b+d1b.T))) x2[viridxa[:,None],occidxa] += reduce(numpy.dot, (mo_coeff[:,viridxa].T, dvhf[0], mo_coeff[:,occidxa])) x2[viridxb[:,None],occidxb] += reduce(numpy.dot, (mo_coeff[:,viridxb].T, dvhf[1], mo_coeff[:,occidxb])) return x2[mask]
def get_veff(self, mol=None, dm=None, dm_last=0, vhf_last=0, hermi=1): """Coulomb + XC functional""" if mol is None: mol = self.mol if dm is None: dm = self.make_rdm1() return uks.get_veff_(self, mol, dm, dm_last, vhf_last, hermi)
def get_veff(self, mol=None, dm=None, dm_last=0, vhf_last=0, hermi=1): '''Coulomb + XC functional''' from pyscf.dft import uks if mol is None: mol = self.mol if dm is None: dm = self.make_rdm1() return uks.get_veff_(self, mol, dm, dm_last, vhf_last, hermi)