def response_dm1(cc, t1, t2, l1, l2, eris=None, IX=None): from pyscf.scf import cphf if eris is None: # Note eris are in Chemist's notation eris = ccsd._ERIS(cc) if IX is None: Ioo, Ivv, Ivo, Xvo = IX_intermediates(cc, t1, t2, l1, l2, eris) else: Ioo, Ivv, Ivo, Xvo = IX nocc, nvir = t1.shape nmo = nocc + nvir def fvind(x): x = x.reshape(Xvo.shape) if eris is None: mo_coeff = cc.mo_coeff dm = reduce(numpy.dot, (mo_coeff[:,nocc:], x, mo_coeff[:,:nocc].T)) v = reduce(numpy.dot, (mo_coeff[:,nocc:].T, cc._scf.get_veff(mol, dm), mo_coeff[:,:nocc])) else: v = numpy.einsum('iajb,bj->ai', eris.ovov, x) * 4 v -= numpy.einsum('jiab,bj->ai', eris.oovv, x) v -= numpy.einsum('ibja,bj->ai', eris.ovov, x) return v mo_energy = eris.fock.diagonal() mo_occ = numpy.zeros_like(mo_energy) mo_occ[:nocc] = 2 dvo = cphf.solve(fvind, mo_energy, mo_occ, Xvo, max_cycle=30)[0] dm1 = numpy.zeros((nmo,nmo)) dm1[nocc:,:nocc] = dvo dm1[:nocc,nocc:] = dvo.T return dm1
def kernel(cc, eris=None, t1=None, t2=None, l1=None, l2=None, max_cycle=50, tol=1e-8, max_memory=2000, verbose=logger.INFO): cput0 = (time.clock(), time.time()) if isinstance(verbose, logger.Logger): log = verbose else: log = logger.Logger(cc.stdout, verbose) if eris is None: eris = ccsd._ERIS(cc) if t1 is None: t1 = cc.t1 if t2 is None: t2 = cc.t2 if l1 is None: l1 = t1 if l2 is None: l2 = t2 nocc, nvir = t1.shape saved = make_intermediates(cc, t1, t2, eris) if cc.diis: adiis = lib.diis.DIIS(cc, cc.diis_file) adiis.space = cc.diis_space else: adiis = lambda l1, l2, *args: (l1, l2) cput0 = log.timer('CCSD lambda initialization', *cput0) conv = False for istep in range(max_cycle): l1new, l2new = update_amps(cc, t1, t2, l1, l2, eris, saved) normt = numpy.linalg.norm(l1new - l1) + numpy.linalg.norm(l2new - l2) l1, l2 = l1new, l2new l1new = l2new = None if cc.diis: l1, l2 = cc.diis(l1, l2, istep, normt, 0, adiis) log.info('istep = %d norm(lambda1,lambda2) = %.6g', istep, normt) cput0 = log.timer('CCSD iter', *cput0) if normt < tol: conv = True break return conv, l1, l2
def kernel(cc, eris=None, t1=None, t2=None, l1=None, l2=None, max_cycle=50, tol=1e-8, max_memory=2000, verbose=logger.INFO): cput0 = (time.clock(), time.time()) if isinstance(verbose, logger.Logger): log = verbose else: log = logger.Logger(cc.stdout, verbose) if eris is None: eris = ccsd._ERIS(cc) if t1 is None: t1 = cc.t1 if t2 is None: t2 = cc.t2 if l1 is None: l1 = t1 if l2 is None: l2 = t2 nocc, nvir = t1.shape blksize = max(BLKMIN, int(max_memory*.95e6/8/(nvir**3*6))) log.debug('block size = %d, nocc = %d is divided into %d blocks', blksize, nocc, int((nocc+blksize-1)/blksize)) saved = make_intermediates(mcc, t1, t2, eris) if cc.diis: adiis = lib.diis.DIIS(cc, cc.diis_file) adiis.space = cc.diis_space else: adiis = lambda l1,l2,*args: (l1,l2) cput0 = log.timer('CCSD lambda initialization', *cput0) conv = False for istep in range(max_cycle): l1new, l2new = update_amps(cc, t1, t2, l1, l2, eris, saved, blksize) normt = numpy.linalg.norm(l1new-l1) + numpy.linalg.norm(l2new-l2) l1, l2 = l1new, l2new l1new = l2new = None if cc.diis: l1, l2 = cc.diis(l1, l2, istep, normt, 0, adiis) log.info('istep = %d norm(lambda1,lambda2) = %.6g', istep, normt) cput0 = log.timer('CCSD iter', *cput0) if normt < tol: conv = True break return conv, l1, l2
def IX_intermediates(cc, t1, t2, l1, l2, eris=None, d1=None, d2=None): if eris is None: # Note eris are in Chemist's notation eris = ccsd._ERIS(cc) if d1 is None: doo, dvv = ccsd_rdm.gamma1_intermediates(cc, t1, t2, l1, l2) else: doo, dvv = d1 if d2 is None: # Note gamma2 are in Chemist's notation d2 = ccsd_rdm.gamma2_intermediates(cc, t1, t2, l1, l2) dovov, dvvvv, doooo, doovv, dovvo, dvvov, dovvv, dooov = d2 dvvov = dovvv.transpose(2,3,0,1) nocc, nvir = t1.shape dvvvv = pyscf.ao2mo.restore(1, dvvvv, nvir).reshape((nvir,)*4) # Note Ioo is not hermitian Ioo =(numpy.einsum('jakb,iakb->ij', dovov, eris.ovov) + numpy.einsum('kbja,iakb->ij', dovov, eris.ovov)) Ioo +=(numpy.einsum('jabk,iakb->ij', dovvo, eris.ovov) + numpy.einsum('kbaj,iakb->ij', dovvo, eris.ovov) + numpy.einsum('jkab,ikab->ij', doovv, eris.oovv) + numpy.einsum('kjba,ikab->ij', doovv, eris.oovv)) Ioo +=(numpy.einsum('jmlk,imlk->ij', doooo, eris.oooo) * 2 + numpy.einsum('mjkl,imlk->ij', doooo, eris.oooo) * 2) Ioo +=(numpy.einsum('jlka,ilka->ij', dooov, eris.ooov) + numpy.einsum('klja,klia->ij', dooov, eris.ooov)) Ioo += numpy.einsum('abjc,icab->ij', dvvov, eris.ovvv) Ioo += numpy.einsum('ljka,lika->ij', dooov, eris.ooov) Ioo *= -1 # Note Ivv is not hermitian Ivv =(numpy.einsum('ibjc,iajc->ab', dovov, eris.ovov) + numpy.einsum('jcib,iajc->ab', dovov, eris.ovov)) Ivv +=(numpy.einsum('jcbi,iajc->ab', dovvo, eris.ovov) + numpy.einsum('ibcj,iajc->ab', dovvo, eris.ovov) + numpy.einsum('jibc,jiac->ab', doovv, eris.oovv) + numpy.einsum('ijcb,jiac->ab', doovv, eris.oovv)) Ivv +=(numpy.einsum('bced,aced->ab', dvvvv, eris.vvvv) * 2 + numpy.einsum('cbde,aced->ab', dvvvv, eris.vvvv) * 2) Ivv +=(numpy.einsum('dbic,icda->ab', dvvov, eris.ovvv) + numpy.einsum('dcib,iadc->ab', dvvov, eris.ovvv)) Ivv += numpy.einsum('bcid,idac->ab', dvvov, eris.ovvv) Ivv += numpy.einsum('jikb,jika->ab', dooov, eris.ooov) Ivv *= -1 Ivo =(numpy.einsum('kajb,kijb->ai', dovov, eris.ooov) + numpy.einsum('kbja,jikb->ai', dovov, eris.ooov)) Ivo +=(numpy.einsum('acbd,icbd->ai', dvvvv, eris.ovvv) * 2 + numpy.einsum('cadb,icbd->ai', dvvvv, eris.ovvv) * 2) Ivo +=(numpy.einsum('jbak,jbik->ai', dovvo, eris.ovoo) + numpy.einsum('kabj,jbik->ai', dovvo, eris.ovoo) + numpy.einsum('jkab,jkib->ai', doovv, eris.ooov) + numpy.einsum('kjba,jkib->ai', doovv, eris.ooov)) Ivo +=(numpy.einsum('dajc,idjc->ai', dvvov, eris.ovov) + numpy.einsum('dcja,jidc->ai', dvvov, eris.oovv)) Ivo += numpy.einsum('abjc,ibjc->ai', dvvov, eris.ovov) Ivo += numpy.einsum('jlka,jlki->ai', dooov, eris.oooo) Ivo *= -1 Xvo =(numpy.einsum('kj,kjia->ai', doo, eris.ooov) * 2 + numpy.einsum('kj,kjia->ai', doo, eris.ooov) * 2 - numpy.einsum('kj,kija->ai', doo, eris.ooov) - numpy.einsum('kj,ijka->ai', doo, eris.ooov)) Xvo +=(numpy.einsum('cb,iacb->ai', dvv, eris.ovvv) * 2 + numpy.einsum('cb,iacb->ai', dvv, eris.ovvv) * 2 - numpy.einsum('cb,icab->ai', dvv, eris.ovvv) - numpy.einsum('cb,ibca->ai', dvv, eris.ovvv)) Xvo +=(numpy.einsum('icjb,jbac->ai', dovov, eris.ovvv) + numpy.einsum('jcib,jcab->ai', dovov, eris.ovvv)) Xvo +=(numpy.einsum('iklj,ljka->ai', doooo, eris.ooov) * 2 + numpy.einsum('kijl,ljka->ai', doooo, eris.ooov) * 2) Xvo +=(numpy.einsum('ibcj,jcab->ai', dovvo, eris.ovvv) + numpy.einsum('jcbi,jcab->ai', dovvo, eris.ovvv) + numpy.einsum('ijcb,jacb->ai', doovv, eris.ovvv) + numpy.einsum('jibc,jacb->ai', doovv, eris.ovvv)) Xvo +=(numpy.einsum('ijkb,jakb->ai', dooov, eris.ovov) + numpy.einsum('kjib,kjab->ai', dooov, eris.oovv)) Xvo += numpy.einsum('dbic,dbac->ai', dvvov, eris.vvvv) Xvo += numpy.einsum('jikb,jakb->ai', dooov, eris.ovov) Xvo += Ivo return Ioo, Ivv, Ivo, Xvo
def kernel(cc, t1=None, t2=None, l1=None, l2=None, eris=None, atmlst=None): if t1 is None: t1 = cc.t1 if t2 is None: t2 = cc.t2 if l1 is None: l1 = cc.l1 if l2 is None: l2 = cc.l2 if eris is None: eris = ccsd._ERIS(cc) mol = cc.mol mo_coeff = cc.mo_coeff #FIXME: ensure cc.mo_coeff is canonical orbital mo_energy = cc.mo_energy nocc, nvir = t1.shape nao, nmo = mo_coeff.shape doo, dvv = ccsd_rdm.gamma1_intermediates(cc, t1, t2, l1, l2) d2 = ccsd_rdm.gamma2_intermediates(cc, t1, t2, l1, l2) Ioo, Ivv, Ivo, Xvo = IX_intermediates(cc, t1, t2, l1, l2, eris, (doo,dvv), d2) dovov, dvvvv, doooo, doovv, dovvo, dvvov, dovvv, dooov = d2 dvvov = dovvv.transpose(2,3,0,1) dvvvv = pyscf.ao2mo.restore(1, dvvvv, nvir).reshape((nvir,)*4) dm1mo = response_dm1(cc, t1, t2, l1, l2, eris, (Ioo, Ivv, Ivo, Xvo)) dm1mo[:nocc,:nocc] = doo * 2 dm1mo[nocc:,nocc:] = dvv * 2 dm1ao = reduce(numpy.dot, (mo_coeff, dm1mo, mo_coeff.T)) im1 = numpy.zeros_like(dm1ao) im1[:nocc,:nocc] = Ioo im1[nocc:,nocc:] = Ivv im1[nocc:,:nocc] = Ivo im1[:nocc,nocc:] = Ivo.T im1 = reduce(numpy.dot, (mo_coeff, im1, mo_coeff.T)) h1 =-(mol.intor('cint1e_ipkin_sph', comp=3) +mol.intor('cint1e_ipnuc_sph', comp=3)) s1 =-mol.intor('cint1e_ipovlp_sph', comp=3) zeta = lib.direct_sum('i+j->ij', mo_energy, mo_energy) * .5 zeta[nocc:,:nocc] = mo_energy[:nocc] zeta[:nocc,nocc:] = mo_energy[:nocc].reshape(-1,1) zeta = reduce(numpy.dot, (mo_coeff, zeta*dm1mo, mo_coeff.T)) eri0 = mol.intor('cint2e_ip1_sph', 3).reshape(3,nao,nao,nao,nao) dm2 = numpy.zeros((nmo,)*4) dm2[:nocc,nocc:,:nocc,nocc:] = dovov dm2[nocc:,nocc:,nocc:,nocc:] = dvvvv dm2[:nocc,:nocc,:nocc,:nocc] = doooo dm2[:nocc,nocc:,nocc:,:nocc] = dovvo dm2[:nocc,:nocc,nocc:,nocc:] = doovv dm2[nocc:,nocc:,:nocc,nocc:] = dvvov dm2[:nocc,:nocc,:nocc,nocc:] = dooov for i in range(nocc): dm2[i,i,:,:] += dm1mo dm2[:,i,i,:] -= dm1mo * .5 dm2 = numpy.einsum('pjkl,ip->ijkl', dm2, mo_coeff) dm2 = numpy.einsum('ipkl,jp->ijkl', dm2, mo_coeff) dm2 = numpy.einsum('ijpl,kp->ijkl', dm2, mo_coeff) dm2 = numpy.einsum('ijkp,lp->ijkl', dm2, mo_coeff) if atmlst is None: atmlst = range(mol.natm) offsetdic = aorange_by_atom(mol) de = numpy.empty((mol.natm,3)) for k,ia in enumerate(atmlst): p0, p1 = offsetdic[ia] # s[1] dot I, note matrix im1 is not hermitian de[k] =(numpy.einsum('xij,ij->x', s1[:,p0:p1], im1[p0:p1]) + numpy.einsum('xji,ij->x', s1[:,p0:p1], im1[:,p0:p1])) # h[1] \dot DM, *2 for +c.c., contribute to f1 mol.set_rinv_origin_(mol.atom_coord(k)) vrinv = -mol.atom_charge(k) * mol.intor('cint1e_iprinv_sph', comp=3) de[k] +=(numpy.einsum('xij,ij->x', h1[:,p0:p1], dm1ao[p0:p1]) + numpy.einsum('xji,ij->x', h1[:,p0:p1], dm1ao[:,p0:p1])) de[k] +=(numpy.einsum('xij,ij->x', vrinv, dm1ao) + numpy.einsum('xji,ij->x', vrinv, dm1ao)) # -s[1]*e \dot DM, contribute to f1 de[k] -=(numpy.einsum('xij,ij->x', s1[:,p0:p1], zeta[p0:p1]) + numpy.einsum('xji,ij->x', s1[:,p0:p1], zeta[:,p0:p1])) s1ij = [] for i in range(3): mocc = mo_coeff[:,:nocc] s1mo = reduce(numpy.dot, (mocc[p0:p1].T, s1[i,p0:p1], mocc)) s1mo = s1mo + s1mo.T s1ij.append(reduce(numpy.dot, (mocc, s1mo, mocc.T))) # -vhf[s_ij[1]], contribute to f1, *2 because get_veff returns J-.5K de[k] -= numpy.einsum('xij,ij->x', cc._scf.get_veff(mol, s1ij), dm1ao)*2 # 2e AO integrals dot 2pdm de[k] -= numpy.einsum('xijkl,ijkl->x', eri0[:,p0:p1], dm2[p0:p1]) * 2 de[k] -= numpy.einsum('xjikl,ijkl->x', eri0[:,p0:p1], dm2[:,p0:p1]) * 2 de[k] -= numpy.einsum('xklij,ijkl->x', eri0[:,p0:p1], dm2[:,:,p0:p1]) * 2 de[k] -= numpy.einsum('xlkij,ijkl->x', eri0[:,p0:p1], dm2[:,:,:,p0:p1]) * 2 return de
def IX_intermediates(cc, t1, t2, l1, l2, eris=None, d1=None, d2=None): if eris is None: # Note eris are in Chemist's notation eris = ccsd._ERIS(cc) if d1 is None: doo, dov, dvo, dvv = ccsd_rdm.gamma1_intermediates(cc, t1, t2, l1, l2) else: doo, dov, dvo, dvv = d1 if d2 is None: # Note gamma2 are in Chemist's notation d2 = ccsd_rdm.gamma2_intermediates(cc, t1, t2, l1, l2) dovov, dvvvv, doooo, doovv, dovvo, dvvov, dovvv, dooov = d2 dvvov = dovvv.transpose(2,3,0,1) nocc, nvir = t1.shape dvvvv = pyscf.ao2mo.restore(1, dvvvv, nvir).reshape((nvir,)*4) # Note Ioo is not hermitian Ioo =(numpy.einsum('jakb,iakb->ij', dovov, eris.ovov) + numpy.einsum('kbja,iakb->ij', dovov, eris.ovov)) Ioo +=(numpy.einsum('jabk,iakb->ij', dovvo, eris.ovov) + numpy.einsum('kbaj,iakb->ij', dovvo, eris.ovov) + numpy.einsum('jkab,ikab->ij', doovv, eris.oovv) + numpy.einsum('kjba,ikab->ij', doovv, eris.oovv)) Ioo +=(numpy.einsum('jmlk,imlk->ij', doooo, eris.oooo) * 2 + numpy.einsum('mjkl,imlk->ij', doooo, eris.oooo) * 2) Ioo +=(numpy.einsum('jlka,ilka->ij', dooov, eris.ooov) + numpy.einsum('klja,klia->ij', dooov, eris.ooov)) Ioo += numpy.einsum('abjc,icab->ij', dvvov, eris.ovvv) Ioo += numpy.einsum('ljka,lika->ij', dooov, eris.ooov) Ioo *= -1 # Note Ivv is not hermitian Ivv =(numpy.einsum('ibjc,iajc->ab', dovov, eris.ovov) + numpy.einsum('jcib,iajc->ab', dovov, eris.ovov)) Ivv +=(numpy.einsum('jcbi,iajc->ab', dovvo, eris.ovov) + numpy.einsum('ibcj,iajc->ab', dovvo, eris.ovov) + numpy.einsum('jibc,jiac->ab', doovv, eris.oovv) + numpy.einsum('ijcb,jiac->ab', doovv, eris.oovv)) Ivv +=(numpy.einsum('bced,aced->ab', dvvvv, eris.vvvv) * 2 + numpy.einsum('cbde,aced->ab', dvvvv, eris.vvvv) * 2) Ivv +=(numpy.einsum('dbic,icda->ab', dvvov, eris.ovvv) + numpy.einsum('dcib,iadc->ab', dvvov, eris.ovvv)) Ivv += numpy.einsum('bcid,idac->ab', dvvov, eris.ovvv) Ivv += numpy.einsum('jikb,jika->ab', dooov, eris.ooov) Ivv *= -1 Ivo =(numpy.einsum('kajb,kijb->ai', dovov, eris.ooov) + numpy.einsum('kbja,jikb->ai', dovov, eris.ooov)) Ivo +=(numpy.einsum('acbd,icbd->ai', dvvvv, eris.ovvv) * 2 + numpy.einsum('cadb,icbd->ai', dvvvv, eris.ovvv) * 2) Ivo +=(numpy.einsum('jbak,jbik->ai', dovvo, eris.ovoo) + numpy.einsum('kabj,jbik->ai', dovvo, eris.ovoo) + numpy.einsum('jkab,jkib->ai', doovv, eris.ooov) + numpy.einsum('kjba,jkib->ai', doovv, eris.ooov)) Ivo +=(numpy.einsum('dajc,idjc->ai', dvvov, eris.ovov) + numpy.einsum('dcja,jidc->ai', dvvov, eris.oovv)) Ivo += numpy.einsum('abjc,ibjc->ai', dvvov, eris.ovov) Ivo += numpy.einsum('jlka,jlki->ai', dooov, eris.oooo) Ivo *= -1 Xvo =(numpy.einsum('kj,kjia->ai', doo, eris.ooov) * 2 + numpy.einsum('kj,kjia->ai', doo, eris.ooov) * 2 - numpy.einsum('kj,kija->ai', doo, eris.ooov) - numpy.einsum('kj,ijka->ai', doo, eris.ooov)) Xvo +=(numpy.einsum('cb,iacb->ai', dvv, eris.ovvv) * 2 + numpy.einsum('cb,iacb->ai', dvv, eris.ovvv) * 2 - numpy.einsum('cb,icab->ai', dvv, eris.ovvv) - numpy.einsum('cb,ibca->ai', dvv, eris.ovvv)) Xvo +=(numpy.einsum('icjb,jbac->ai', dovov, eris.ovvv) + numpy.einsum('jcib,jcab->ai', dovov, eris.ovvv)) Xvo +=(numpy.einsum('iklj,ljka->ai', doooo, eris.ooov) * 2 + numpy.einsum('kijl,ljka->ai', doooo, eris.ooov) * 2) Xvo +=(numpy.einsum('ibcj,jcab->ai', dovvo, eris.ovvv) + numpy.einsum('jcbi,jcab->ai', dovvo, eris.ovvv) + numpy.einsum('ijcb,jacb->ai', doovv, eris.ovvv) + numpy.einsum('jibc,jacb->ai', doovv, eris.ovvv)) Xvo +=(numpy.einsum('ijkb,jakb->ai', dooov, eris.ovov) + numpy.einsum('kjib,kjab->ai', dooov, eris.oovv)) Xvo += numpy.einsum('dbic,dbac->ai', dvvov, eris.vvvv) Xvo += numpy.einsum('jikb,jakb->ai', dooov, eris.ovov) Xvo += Ivo return Ioo, Ivv, Ivo, Xvo
def kernel(cc, t1=None, t2=None, l1=None, l2=None, eris=None, atmlst=None): if t1 is None: t1 = cc.t1 if t2 is None: t2 = cc.t2 if l1 is None: l1 = cc.l1 if l2 is None: l2 = cc.l2 if eris is None: eris = ccsd._ERIS(cc) mol = cc.mol mo_coeff = cc.mo_coeff #FIXME: ensure cc.mo_coeff is canonical orbital mo_energy = cc.mo_energy nocc, nvir = t1.shape nao, nmo = mo_coeff.shape d1 = ccsd_rdm.gamma1_intermediates(cc, t1, t2, l1, l2) d2 = ccsd_rdm.gamma2_intermediates(cc, t1, t2, l1, l2) Ioo, Ivv, Ivo, Xvo = IX_intermediates(cc, t1, t2, l1, l2, eris, d1, d2) doo, dov, dvo, dvv = d1 dovov, dvvvv, doooo, doovv, dovvo, dvvov, dovvv, dooov = d2 dvvov = dovvv.transpose(2,3,0,1) dvvvv = pyscf.ao2mo.restore(1, dvvvv, nvir).reshape((nvir,)*4) dm1mo = response_dm1(cc, t1, t2, l1, l2, eris, (Ioo, Ivv, Ivo, Xvo)) dm1mo[:nocc,:nocc] = doo * 2 dm1mo[nocc:,nocc:] = dvv * 2 dm1ao = reduce(numpy.dot, (mo_coeff, dm1mo, mo_coeff.T)) dm0 = numpy.dot(mo_coeff[:,:nocc], mo_coeff[:,:nocc].T)*2 im1 = numpy.zeros_like(dm1ao) im1[:nocc,:nocc] = Ioo im1[nocc:,nocc:] = Ivv im1[nocc:,:nocc] = Ivo im1[:nocc,nocc:] = Ivo.T im1 = reduce(numpy.dot, (mo_coeff, im1, mo_coeff.T)) dme0 = grad.rhf.make_rdm1e(cc._scf.mo_energy, mo_coeff, cc._scf.mo_occ) h1 =-(mol.intor('cint1e_ipkin_sph', comp=3) +mol.intor('cint1e_ipnuc_sph', comp=3)) s1 =-mol.intor('cint1e_ipovlp_sph', comp=3) zeta = lib.direct_sum('i+j->ij', mo_energy, mo_energy) * .5 zeta[nocc:,:nocc] = mo_energy[:nocc] zeta[:nocc,nocc:] = mo_energy[:nocc].reshape(-1,1) zeta = reduce(numpy.dot, (mo_coeff, zeta*dm1mo, mo_coeff.T)) eri0 = mol.intor('cint2e_ip1_sph', 3).reshape(3,nao,nao,nao,nao) dm2 = numpy.zeros((nmo,)*4) dm2[:nocc,nocc:,:nocc,nocc:] = dovov dm2[nocc:,nocc:,nocc:,nocc:] = dvvvv dm2[:nocc,:nocc,:nocc,:nocc] = doooo dm2[:nocc,nocc:,nocc:,:nocc] = dovvo dm2[:nocc,:nocc,nocc:,nocc:] = doovv dm2[nocc:,nocc:,:nocc,nocc:] = dvvov dm2[:nocc,:nocc,:nocc,nocc:] = dooov for i in range(nocc): dm2[i,i,:,:] += dm1mo dm2[:,i,i,:] -= dm1mo * .5 for i in range(nocc): # for HF gradeint for j in range(nocc): dm2[i,i,j,j] += 1 dm2[i,j,j,i] -= .5 dm2 = numpy.einsum('pjkl,ip->ijkl', dm2, mo_coeff) dm2 = numpy.einsum('ipkl,jp->ijkl', dm2, mo_coeff) dm2 = numpy.einsum('ijpl,kp->ijkl', dm2, mo_coeff) dm2 = numpy.einsum('ijkp,lp->ijkl', dm2, mo_coeff) if atmlst is None: atmlst = range(mol.natm) offsetdic = aorange_by_atom(mol) de = numpy.empty((mol.natm,3)) for k,ia in enumerate(atmlst): p0, p1 = offsetdic[ia] # s[1] dot I, note matrix im1 is not hermitian de[k] =(numpy.einsum('xij,ij->x', s1[:,p0:p1], im1[p0:p1]) + numpy.einsum('xji,ij->x', s1[:,p0:p1], im1[:,p0:p1])) # h[1] \dot DM, *2 for +c.c., contribute to f1 mol.set_rinv_origin(mol.atom_coord(k)) vrinv = -mol.atom_charge(k) * mol.intor('cint1e_iprinv_sph', comp=3) de[k] +=(numpy.einsum('xij,ij->x', h1[:,p0:p1], dm1ao[p0:p1]) + numpy.einsum('xji,ij->x', h1[:,p0:p1], dm1ao[:,p0:p1])) de[k] +=(numpy.einsum('xij,ij->x', vrinv, dm1ao) + numpy.einsum('xji,ij->x', vrinv, dm1ao)) # -s[1]*e \dot DM, contribute to f1 de[k] -=(numpy.einsum('xij,ij->x', s1[:,p0:p1], zeta[p0:p1]) + numpy.einsum('xji,ij->x', s1[:,p0:p1], zeta[:,p0:p1])) s1ij = [] for i in range(3): mocc = mo_coeff[:,:nocc] s1mo = reduce(numpy.dot, (mocc[p0:p1].T, s1[i,p0:p1], mocc)) s1mo = s1mo + s1mo.T s1ij.append(reduce(numpy.dot, (mocc, s1mo, mocc.T))) # -vhf[s_ij[1]], contribute to f1, *2 because get_veff returns J-.5K de[k] -= numpy.einsum('xij,ij->x', cc._scf.get_veff(mol, s1ij), dm1ao)*2 # 2e AO integrals dot 2pdm de[k] -= numpy.einsum('xijkl,ijkl->x', eri0[:,p0:p1], dm2[p0:p1]) * 2 de[k] -= numpy.einsum('xijkl,jikl->x', eri0[:,p0:p1], dm2[:,p0:p1]) * 2 de[k] -= numpy.einsum('xijkl,klij->x', eri0[:,p0:p1], dm2[:,:,p0:p1]) * 2 de[k] -= numpy.einsum('xijkl,klji->x', eri0[:,p0:p1], dm2[:,:,:,p0:p1]) * 2 # HF gradients, J1*2-K1 was merged into previous contraction to dm2 de[k] +=(numpy.einsum('xij,ij->x', h1[:,p0:p1], dm0[p0:p1]) + numpy.einsum('xji,ij->x', h1[:,p0:p1], dm0[:,p0:p1])) de[k] +=(numpy.einsum('xij,ij->x', vrinv, dm0) + numpy.einsum('xji,ij->x', vrinv, dm0)) de[k] -=(numpy.einsum('xij,ij->x', s1[:,p0:p1], dme0[p0:p1]) + numpy.einsum('xji,ij->x', s1[:,p0:p1], dme0[:,p0:p1])) return de