def update_amps(cc, t1, t2, eris): time0 = time.clock(), time.time() log = logger.Logger(cc.stdout, cc.verbose) nkpts, nocc, nvir = t1.shape fock = eris.fock mo_e_o = [e[:nocc] for e in eris.mo_energy] mo_e_v = [e[nocc:] + cc.level_shift for e in eris.mo_energy] # Get location of padded elements in occupied and virtual space nonzero_opadding, nonzero_vpadding = padding_k_idx(cc, kind="split") fov = fock[:, :nocc, nocc:].copy() foo = fock[:, :nocc, :nocc].copy() fvv = fock[:, nocc:, nocc:].copy() # Get the momentum conservation array # Note: chemist's notation for momentum conserving t2(ki,kj,ka,kb), even though # integrals are in physics notation kconserv = kpts_helper.get_kconserv(cc._scf.cell, cc.kpts) tau = imdk.make_tau(cc, t2, t1, t1, kconserv) Fvv = imdk.cc_Fvv(cc, t1, t2, eris, kconserv) Foo = imdk.cc_Foo(cc, t1, t2, eris, kconserv) Fov = imdk.cc_Fov(cc, t1, t2, eris, kconserv) Woooo = imdk.cc_Woooo(cc, t1, t2, eris, kconserv) Wvvvv = imdk.cc_Wvvvv(cc, t1, t2, eris, kconserv) Wovvo = imdk.cc_Wovvo(cc, t1, t2, eris, kconserv) # Move energy terms to the other side for k in range(nkpts): Foo[k][numpy.diag_indices(nocc)] -= mo_e_o[k] Fvv[k][numpy.diag_indices(nvir)] -= mo_e_v[k] eris_ovvo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nocc, nvir, nvir, nocc), dtype=t2.dtype) eris_oovo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nocc, nocc, nvir, nocc), dtype=t2.dtype) eris_vvvo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nvir, nvir, nvir, nocc), dtype=t2.dtype) for km, kb, ke in kpts_helper.loop_kkk(nkpts): kj = kconserv[km, ke, kb] # <mb||je> -> -<mb||ej> eris_ovvo[km, kb, ke] = -eris.ovov[km, kb, kj].transpose(0, 1, 3, 2) # <mn||je> -> -<mn||ej> # let kb = kn as a dummy variable eris_oovo[km, kb, ke] = -eris.ooov[km, kb, kj].transpose(0, 1, 3, 2) # <ma||be> -> - <be||am>* # let kj = ka as a dummy variable kj = kconserv[km, ke, kb] eris_vvvo[ke, kj, kb] = -eris.ovvv[km, kb, ke].transpose(2, 3, 1, 0).conj() # T1 equation t1new = numpy.zeros(shape=t1.shape, dtype=t1.dtype) for ka in range(nkpts): ki = ka t1new[ka] += numpy.array(fov[ka, :, :]).conj() t1new[ka] += einsum('ie,ae->ia', t1[ka], Fvv[ka]) t1new[ka] += -einsum('ma,mi->ia', t1[ka], Foo[ka]) for km in range(nkpts): t1new[ka] += einsum('imae,me->ia', t2[ka, km, ka], Fov[km]) t1new[ka] += -einsum('nf,naif->ia', t1[km], eris.ovov[km, ka, ki]) for kn in range(nkpts): ke = kconserv[km, ki, kn] t1new[ka] += -0.5 * einsum('imef,maef->ia', t2[ki, km, ke], eris.ovvv[km, ka, ke]) t1new[ka] += -0.5 * einsum('mnae,nmei->ia', t2[km, kn, ka], eris_oovo[kn, km, ke]) # T2 equation t2new = numpy.array(eris.oovv).conj() for ki, kj, ka in kpts_helper.loop_kkk(nkpts): # Chemist's notation for momentum conserving t2(ki,kj,ka,kb) kb = kconserv[ki, ka, kj] Ftmp = Fvv[kb] - 0.5 * einsum('mb,me->be', t1[kb], Fov[kb]) tmp = einsum('ijae,be->ijab', t2[ki, kj, ka], Ftmp) t2new[ki, kj, ka] += tmp #t2new[ki,kj,kb] -= tmp.transpose(0,1,3,2) Ftmp = Fvv[ka] - 0.5 * einsum('ma,me->ae', t1[ka], Fov[ka]) tmp = einsum('ijbe,ae->ijab', t2[ki, kj, kb], Ftmp) t2new[ki, kj, ka] -= tmp Ftmp = Foo[kj] + 0.5 * einsum('je,me->mj', t1[kj], Fov[kj]) tmp = einsum('imab,mj->ijab', t2[ki, kj, ka], Ftmp) t2new[ki, kj, ka] -= tmp #t2new[kj,ki,ka] += tmp.transpose(1,0,2,3) Ftmp = Foo[ki] + 0.5 * einsum('ie,me->mi', t1[ki], Fov[ki]) tmp = einsum('jmab,mi->ijab', t2[kj, ki, ka], Ftmp) t2new[ki, kj, ka] += tmp for km in range(nkpts): # Wminj # - km - kn + ka + kb = 0 # => kn = ka - km + kb kn = kconserv[ka, km, kb] t2new[ki, kj, ka] += 0.5 * einsum( 'mnab,mnij->ijab', tau[km, kn, ka], Woooo[km, kn, ki]) ke = km t2new[ki, kj, ka] += 0.5 * einsum( 'ijef,abef->ijab', tau[ki, kj, ke], Wvvvv[ka, kb, ke]) # Wmbej # - km - kb + ke + kj = 0 # => ke = km - kj + kb ke = kconserv[km, kj, kb] tmp = einsum('imae,mbej->ijab', t2[ki, km, ka], Wovvo[km, kb, ke]) # - km - kb + ke + kj = 0 # => ke = km - kj + kb # # t[i,e] => ki = ke # t[m,a] => km = ka if km == ka and ke == ki: tmp -= einsum('ie,ma,mbej->ijab', t1[ki], t1[km], eris_ovvo[km, kb, ke]) t2new[ki, kj, ka] += tmp t2new[ki, kj, kb] -= tmp.transpose(0, 1, 3, 2) t2new[kj, ki, ka] -= tmp.transpose(1, 0, 2, 3) t2new[kj, ki, kb] += tmp.transpose(1, 0, 3, 2) ke = ki tmp = einsum('ie,abej->ijab', t1[ki], eris_vvvo[ka, kb, ke]) t2new[ki, kj, ka] += tmp # P(ij) term ke = kj tmp = einsum('je,abei->ijab', t1[kj], eris_vvvo[ka, kb, ke]) t2new[ki, kj, ka] -= tmp km = ka tmp = einsum('ma,mbij->ijab', t1[ka], eris.ovoo[km, kb, ki]) t2new[ki, kj, ka] -= tmp # P(ab) term km = kb tmp = einsum('mb,maij->ijab', t1[kb], eris.ovoo[km, ka, ki]) t2new[ki, kj, ka] += tmp for ki in range(nkpts): ka = ki # Remove zero/padded elements from denominator eia = LARGE_DENOM * numpy.ones( (nocc, nvir), dtype=eris.mo_energy[0].dtype) n0_ovp_ia = numpy.ix_(nonzero_opadding[ki], nonzero_vpadding[ka]) eia[n0_ovp_ia] = (mo_e_o[ki][:, None] - mo_e_v[ka])[n0_ovp_ia] t1new[ki] /= eia kconserv = kpts_helper.get_kconserv(cc._scf.cell, cc.kpts) for ki, kj, ka in kpts_helper.loop_kkk(nkpts): kb = kconserv[ki, ka, kj] # For LARGE_DENOM, see t1new update above eia = LARGE_DENOM * numpy.ones( (nocc, nvir), dtype=eris.mo_energy[0].dtype) n0_ovp_ia = numpy.ix_(nonzero_opadding[ki], nonzero_vpadding[ka]) eia[n0_ovp_ia] = (mo_e_o[ki][:, None] - mo_e_v[ka])[n0_ovp_ia] ejb = LARGE_DENOM * numpy.ones( (nocc, nvir), dtype=eris.mo_energy[0].dtype) n0_ovp_jb = numpy.ix_(nonzero_opadding[kj], nonzero_vpadding[kb]) ejb[n0_ovp_jb] = (mo_e_o[kj][:, None] - mo_e_v[kb])[n0_ovp_jb] eijab = eia[:, None, :, None] + ejb[:, None, :] t2new[ki, kj, ka] /= eijab time0 = log.timer_debug1('update t1 t2', *time0) return t1new, t2new
def update_amps(cc, t1, t2, eris, max_memory=2000): time0 = time.clock(), time.time() log = logger.Logger(cc.stdout, cc.verbose) nkpts, nocc, nvir = t1.shape #nov = nocc*nvir fock = eris.fock #t1new = numpy.zeros_like(t1) #t2new = numpy.zeros_like(t2) fov = fock[:,:nocc,nocc:].copy() foo = fock[:,:nocc,:nocc].copy() fvv = fock[:,nocc:,nocc:].copy() #mo_e = eris.fock.diagonal() #eia = mo_e[:nocc,None] - mo_e[None,nocc:] #eijab = lib.direct_sum('ia,jb->ijab',eia,eia) tau = imdk.make_tau(cc,t2,t1,t1) ### From eom-cc hackathon code ### Fvv = imdk.cc_Fvv(cc,t1,t2,eris) Foo = imdk.cc_Foo(cc,t1,t2,eris) Fov = imdk.cc_Fov(cc,t1,t2,eris) Woooo = imdk.cc_Woooo(cc,t1,t2,eris) Wvvvv = imdk.cc_Wvvvv(cc,t1,t2,eris) Wovvo = imdk.cc_Wovvo(cc,t1,t2,eris) # Move energy terms to the other side Fvv -= fvv Foo -= foo # Get the momentum conservation array # Note: chemist's notation for momentum conserving t2(ki,kj,ka,kb), even though # integrals are in physics notation kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts) eris_ovvo = numpy.zeros(shape=(nkpts,nkpts,nkpts,nocc,nvir,nvir,nocc), dtype=t2.dtype) eris_oovo = numpy.zeros(shape=(nkpts,nkpts,nkpts,nocc,nocc,nvir,nocc), dtype=t2.dtype) eris_vvvo = numpy.zeros(shape=(nkpts,nkpts,nkpts,nvir,nvir,nvir,nocc), dtype=t2.dtype) for km in range(nkpts): for kb in range(nkpts): for ke in range(nkpts): kj = kconserv[km,ke,kb] # <mb||je> -> -<mb||ej> eris_ovvo[km,kb,ke] = -eris.ovov[km,kb,kj].transpose(0,1,3,2) # <mn||je> -> -<mn||ej> # let kb = kn as a dummy variable eris_oovo[km,kb,ke] = -eris.ooov[km,kb,kj].transpose(0,1,3,2) # <ma||be> -> - <be||am>* # let kj = ka as a dummy variable kj = kconserv[km,ke,kb] eris_vvvo[ke,kj,kb] = -eris.ovvv[km,kb,ke].transpose(2,3,1,0).conj() # T1 equation t1new = numpy.zeros(shape=t1.shape, dtype=t1.dtype) for ka in range(nkpts): ki = ka # TODO: Does this fov need a conj()? Usually zero w/ canonical HF. t1new[ka] += fov[ka,:,:] t1new[ka] += einsum('ie,ae->ia',t1[ka],Fvv[ka]) t1new[ka] += -einsum('ma,mi->ia',t1[ka],Foo[ka]) for km in range(nkpts): t1new[ka] += einsum('imae,me->ia',t2[ka,km,ka],Fov[km]) t1new[ka] += -einsum('nf,naif->ia',t1[km],eris.ovov[km,ka,ki]) for kn in range(nkpts): ke = kconserv[km,ki,kn] t1new[ka] += -0.5*einsum('imef,maef->ia',t2[ki,km,ke],eris.ovvv[km,ka,ke]) t1new[ka] += -0.5*einsum('mnae,nmei->ia',t2[km,kn,ka],eris_oovo[kn,km,ke]) # T2 equation # For conj(), see Hirata and Bartlett, Eq. (36) t2new = eris.oovv.copy().conj() for ki in range(nkpts): for kj in range(nkpts): for ka in range(nkpts): # Chemist's notation for momentum conserving t2(ki,kj,ka,kb) kb = kconserv[ki,ka,kj] Ftmp = Fvv[kb] - 0.5*einsum('mb,me->be',t1[kb],Fov[kb]) tmp = einsum('ijae,be->ijab',t2[ki,kj,ka],Ftmp) t2new[ki,kj,ka] += tmp Ftmp = Fvv[ka] - 0.5*einsum('ma,me->ae',t1[ka],Fov[ka]) tmp = einsum('ijbe,ae->ijab',t2[ki,kj,kb],Ftmp) t2new[ki,kj,ka] -= tmp #t2new[ki,kj,kb] -= tmp.transpose(0,1,3,2) Ftmp = Foo[kj] + 0.5*einsum('je,me->mj',t1[kj],Fov[kj]) tmp = einsum('imab,mj->ijab',t2[ki,kj,ka],Ftmp) t2new[ki,kj,ka] -= tmp Ftmp = Foo[ki] + 0.5*einsum('ie,me->mi',t1[ki],Fov[ki]) tmp = einsum('jmab,mi->ijab',t2[kj,ki,ka],Ftmp) t2new[ki,kj,ka] += tmp #t2new[kj,ki,ka] += tmp.transpose(1,0,2,3) for km in range(nkpts): # Wminj # - km - kn + ka + kb = 0 # => kn = ka - km + kb kn = kconserv[ka,km,kb] t2new[ki,kj,ka] += 0.5*einsum('mnab,mnij->ijab',tau[km,kn,ka],Woooo[km,kn,ki]) ke = km t2new[ki,kj,ka] += 0.5*einsum('ijef,abef->ijab',tau[ki,kj,ke],Wvvvv[ka,kb,ke]) # Wmbej # - km - kb + ke + kj = 0 # => ke = km - kj + kb ke = kconserv[km,kj,kb] tmp = einsum('imae,mbej->ijab',t2[ki,km,ka],Wovvo[km,kb,ke]) # - km - kb + ke + kj = 0 # => ke = km - kj + kb # # t[i,e] => ki = ke # t[m,a] => km = ka if km == ka and ke == ki: tmp -= einsum('ie,ma,mbej->ijab',t1[ki],t1[km],eris_ovvo[km,kb,ke]) t2new[ki,kj,ka] += tmp t2new[ki,kj,kb] -= tmp.transpose(0,1,3,2) t2new[kj,ki,ka] -= tmp.transpose(1,0,2,3) t2new[kj,ki,kb] += tmp.transpose(1,0,3,2) ke = ki tmp = einsum('ie,abej->ijab',t1[ki],eris_vvvo[ka,kb,ke]) t2new[ki,kj,ka] += tmp # P(ij) term ke = kj tmp = einsum('je,abei->ijab',t1[kj],eris_vvvo[ka,kb,ke]) t2new[ki,kj,ka] -= tmp km = ka tmp = einsum('ma,mbij->ijab',t1[ka],eris.ovoo[km,kb,ki]) t2new[ki,kj,ka] -= tmp # P(ab) term km = kb tmp = einsum('mb,maij->ijab',t1[kb],eris.ovoo[km,ka,ki]) t2new[ki,kj,ka] += tmp eia = numpy.zeros(shape=t1new.shape, dtype=t1new.dtype) for ki in range(nkpts): for i in range(nocc): for a in range(nvir): eia[ki,i,a] = foo[ki,i,i] - fvv[ki,a,a] t1new[ki] /= eia[ki] eijab = numpy.zeros(shape=t2new.shape, dtype=t2new.dtype) kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts) for ki in range(nkpts): for kj in range(nkpts): for ka in range(nkpts): kb = kconserv[ki,ka,kj] for i in range(nocc): for a in range(nvir): for j in range(nocc): for b in range(nvir): eijab[ki,kj,ka,i,j,a,b] = ( foo[ki,i,i] + foo[kj,j,j] - fvv[ka,a,a] - fvv[kb,b,b] ) t2new[ki,kj,ka] /= eijab[ki,kj,ka] time0 = log.timer_debug1('update t1 t2', *time0) return t1new, t2new
def update_amps(cc, t1, t2, eris): time0 = time.clock(), time.time() log = logger.Logger(cc.stdout, cc.verbose) nkpts, nocc, nvir = t1.shape fock = eris.fock mo_e_o = [e[:nocc] for e in eris.mo_energy] mo_e_v = [e[nocc:] + cc.level_shift for e in eris.mo_energy] # Get location of padded elements in occupied and virtual space nonzero_opadding, nonzero_vpadding = padding_k_idx(cc, kind="split") fov = fock[:, :nocc, nocc:].copy() foo = fock[:, :nocc, :nocc].copy() fvv = fock[:, nocc:, nocc:].copy() # Get the momentum conservation array # Note: chemist's notation for momentum conserving t2(ki,kj,ka,kb), even though # integrals are in physics notation kconserv = kpts_helper.get_kconserv(cc._scf.cell, cc.kpts) tau = imdk.make_tau(cc, t2, t1, t1, kconserv) Fvv = imdk.cc_Fvv(cc, t1, t2, eris, kconserv) Foo = imdk.cc_Foo(cc, t1, t2, eris, kconserv) Fov = imdk.cc_Fov(cc, t1, t2, eris, kconserv) Woooo = imdk.cc_Woooo(cc, t1, t2, eris, kconserv) Wvvvv = imdk.cc_Wvvvv(cc, t1, t2, eris, kconserv) Wovvo = imdk.cc_Wovvo(cc, t1, t2, eris, kconserv) # Move energy terms to the other side for k in range(nkpts): Foo[k][numpy.diag_indices(nocc)] -= mo_e_o[k] Fvv[k][numpy.diag_indices(nvir)] -= mo_e_v[k] eris_ovvo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nocc, nvir, nvir, nocc), dtype=t2.dtype) eris_oovo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nocc, nocc, nvir, nocc), dtype=t2.dtype) eris_vvvo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nvir, nvir, nvir, nocc), dtype=t2.dtype) for km, kb, ke in kpts_helper.loop_kkk(nkpts): kj = kconserv[km, ke, kb] # <mb||je> -> -<mb||ej> eris_ovvo[km, kb, ke] = -eris.ovov[km, kb, kj].transpose(0, 1, 3, 2) # <mn||je> -> -<mn||ej> # let kb = kn as a dummy variable eris_oovo[km, kb, ke] = -eris.ooov[km, kb, kj].transpose(0, 1, 3, 2) # <ma||be> -> - <be||am>* # let kj = ka as a dummy variable kj = kconserv[km, ke, kb] eris_vvvo[ke, kj, kb] = -eris.ovvv[km, kb, ke].transpose(2, 3, 1, 0).conj() # T1 equation t1new = numpy.zeros(shape=t1.shape, dtype=t1.dtype) for ka in range(nkpts): ki = ka t1new[ka] += numpy.array(fov[ka, :, :]).conj() t1new[ka] += einsum('ie,ae->ia', t1[ka], Fvv[ka]) t1new[ka] += -einsum('ma,mi->ia', t1[ka], Foo[ka]) for km in range(nkpts): t1new[ka] += einsum('imae,me->ia', t2[ka, km, ka], Fov[km]) t1new[ka] += -einsum('nf,naif->ia', t1[km], eris.ovov[km, ka, ki]) for kn in range(nkpts): ke = kconserv[km, ki, kn] t1new[ka] += -0.5 * einsum('imef,maef->ia', t2[ki, km, ke], eris.ovvv[km, ka, ke]) t1new[ka] += -0.5 * einsum('mnae,nmei->ia', t2[km, kn, ka], eris_oovo[kn, km, ke]) # T2 equation t2new = numpy.array(eris.oovv).conj() for ki, kj, ka in kpts_helper.loop_kkk(nkpts): # Chemist's notation for momentum conserving t2(ki,kj,ka,kb) kb = kconserv[ki, ka, kj] Ftmp = Fvv[kb] - 0.5 * einsum('mb,me->be', t1[kb], Fov[kb]) tmp = einsum('ijae,be->ijab', t2[ki, kj, ka], Ftmp) t2new[ki, kj, ka] += tmp #t2new[ki,kj,kb] -= tmp.transpose(0,1,3,2) Ftmp = Fvv[ka] - 0.5 * einsum('ma,me->ae', t1[ka], Fov[ka]) tmp = einsum('ijbe,ae->ijab', t2[ki, kj, kb], Ftmp) t2new[ki, kj, ka] -= tmp Ftmp = Foo[kj] + 0.5 * einsum('je,me->mj', t1[kj], Fov[kj]) tmp = einsum('imab,mj->ijab', t2[ki, kj, ka], Ftmp) t2new[ki, kj, ka] -= tmp #t2new[kj,ki,ka] += tmp.transpose(1,0,2,3) Ftmp = Foo[ki] + 0.5 * einsum('ie,me->mi', t1[ki], Fov[ki]) tmp = einsum('jmab,mi->ijab', t2[kj, ki, ka], Ftmp) t2new[ki, kj, ka] += tmp for km in range(nkpts): # Wminj # - km - kn + ka + kb = 0 # => kn = ka - km + kb kn = kconserv[ka, km, kb] t2new[ki, kj, ka] += 0.5 * einsum('mnab,mnij->ijab', tau[km, kn, ka], Woooo[km, kn, ki]) ke = km t2new[ki, kj, ka] += 0.5 * einsum('ijef,abef->ijab', tau[ki, kj, ke], Wvvvv[ka, kb, ke]) # Wmbej # - km - kb + ke + kj = 0 # => ke = km - kj + kb ke = kconserv[km, kj, kb] tmp = einsum('imae,mbej->ijab', t2[ki, km, ka], Wovvo[km, kb, ke]) # - km - kb + ke + kj = 0 # => ke = km - kj + kb # # t[i,e] => ki = ke # t[m,a] => km = ka if km == ka and ke == ki: tmp -= einsum('ie,ma,mbej->ijab', t1[ki], t1[km], eris_ovvo[km, kb, ke]) t2new[ki, kj, ka] += tmp t2new[ki, kj, kb] -= tmp.transpose(0, 1, 3, 2) t2new[kj, ki, ka] -= tmp.transpose(1, 0, 2, 3) t2new[kj, ki, kb] += tmp.transpose(1, 0, 3, 2) ke = ki tmp = einsum('ie,abej->ijab', t1[ki], eris_vvvo[ka, kb, ke]) t2new[ki, kj, ka] += tmp # P(ij) term ke = kj tmp = einsum('je,abei->ijab', t1[kj], eris_vvvo[ka, kb, ke]) t2new[ki, kj, ka] -= tmp km = ka tmp = einsum('ma,mbij->ijab', t1[ka], eris.ovoo[km, kb, ki]) t2new[ki, kj, ka] -= tmp # P(ab) term km = kb tmp = einsum('mb,maij->ijab', t1[kb], eris.ovoo[km, ka, ki]) t2new[ki, kj, ka] += tmp for ki in range(nkpts): ka = ki # Remove zero/padded elements from denominator eia = LARGE_DENOM * numpy.ones((nocc, nvir), dtype=eris.mo_energy[0].dtype) n0_ovp_ia = numpy.ix_(nonzero_opadding[ki], nonzero_vpadding[ka]) eia[n0_ovp_ia] = (mo_e_o[ki][:,None] - mo_e_v[ka])[n0_ovp_ia] t1new[ki] /= eia kconserv = kpts_helper.get_kconserv(cc._scf.cell, cc.kpts) for ki, kj, ka in kpts_helper.loop_kkk(nkpts): kb = kconserv[ki, ka, kj] # For LARGE_DENOM, see t1new update above eia = LARGE_DENOM * numpy.ones((nocc, nvir), dtype=eris.mo_energy[0].dtype) n0_ovp_ia = numpy.ix_(nonzero_opadding[ki], nonzero_vpadding[ka]) eia[n0_ovp_ia] = (mo_e_o[ki][:,None] - mo_e_v[ka])[n0_ovp_ia] ejb = LARGE_DENOM * numpy.ones((nocc, nvir), dtype=eris.mo_energy[0].dtype) n0_ovp_jb = numpy.ix_(nonzero_opadding[kj], nonzero_vpadding[kb]) ejb[n0_ovp_jb] = (mo_e_o[kj][:,None] - mo_e_v[kb])[n0_ovp_jb] eijab = eia[:, None, :, None] + ejb[:, None, :] t2new[ki, kj, ka] /= eijab time0 = log.timer_debug1('update t1 t2', *time0) return t1new, t2new
def update_amps(cc, t1, t2, eris, max_memory=2000): time0 = time.clock(), time.time() log = logger.Logger(cc.stdout, cc.verbose) nkpts, nocc, nvir = t1.shape fock = eris.fock fov = fock[:, :nocc, nocc:].copy() foo = fock[:, :nocc, :nocc].copy() fvv = fock[:, nocc:, nocc:].copy() #mo_e = eris.fock.diagonal() #eia = mo_e[:nocc,None] - mo_e[None,nocc:] #eijab = lib.direct_sum('ia,jb->ijab',eia,eia) tau = imdk.make_tau(cc, t2, t1, t1) Fvv = imdk.cc_Fvv(cc, t1, t2, eris) Foo = imdk.cc_Foo(cc, t1, t2, eris) Fov = imdk.cc_Fov(cc, t1, t2, eris) Woooo = imdk.cc_Woooo(cc, t1, t2, eris) Wvvvv = imdk.cc_Wvvvv(cc, t1, t2, eris) Wovvo = imdk.cc_Wovvo(cc, t1, t2, eris) # Move energy terms to the other side for k in range(nkpts): Fvv[k] -= numpy.diag(numpy.diag(fvv[k])) Foo[k] -= numpy.diag(numpy.diag(foo[k])) # Get the momentum conservation array # Note: chemist's notation for momentum conserving t2(ki,kj,ka,kb), even though # integrals are in physics notation kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts) eris_ovvo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nocc, nvir, nvir, nocc), dtype=t2.dtype) eris_oovo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nocc, nocc, nvir, nocc), dtype=t2.dtype) eris_vvvo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nvir, nvir, nvir, nocc), dtype=t2.dtype) for km in range(nkpts): for kb in range(nkpts): for ke in range(nkpts): kj = kconserv[km, ke, kb] # <mb||je> -> -<mb||ej> eris_ovvo[km, kb, ke] = -eris.ovov[km, kb, kj].transpose(0, 1, 3, 2) # <mn||je> -> -<mn||ej> # let kb = kn as a dummy variable eris_oovo[km, kb, ke] = -eris.ooov[km, kb, kj].transpose(0, 1, 3, 2) # <ma||be> -> - <be||am>* # let kj = ka as a dummy variable kj = kconserv[km, ke, kb] eris_vvvo[ke, kj, kb] = -eris.ovvv[km, kb, ke].transpose( 2, 3, 1, 0).conj() # T1 equation t1new = numpy.zeros(shape=t1.shape, dtype=t1.dtype) for ka in range(nkpts): ki = ka t1new[ka] += numpy.array(fov[ka, :, :]).conj() t1new[ka] += einsum('ie,ae->ia', t1[ka], Fvv[ka]) t1new[ka] += -einsum('ma,mi->ia', t1[ka], Foo[ka]) for km in range(nkpts): t1new[ka] += einsum('imae,me->ia', t2[ka, km, ka], Fov[km]) t1new[ka] += -einsum('nf,naif->ia', t1[km], eris.ovov[km, ka, ki]) for kn in range(nkpts): ke = kconserv[km, ki, kn] t1new[ka] += -0.5 * einsum('imef,maef->ia', t2[ki, km, ke], eris.ovvv[km, ka, ke]) t1new[ka] += -0.5 * einsum('mnae,nmei->ia', t2[km, kn, ka], eris_oovo[kn, km, ke]) # T2 equation t2new = numpy.array(eris.oovv).conj() for ki in range(nkpts): for kj in range(nkpts): for ka in range(nkpts): # Chemist's notation for momentum conserving t2(ki,kj,ka,kb) kb = kconserv[ki, ka, kj] Ftmp = Fvv[kb] - 0.5 * einsum('mb,me->be', t1[kb], Fov[kb]) tmp = einsum('ijae,be->ijab', t2[ki, kj, ka], Ftmp) t2new[ki, kj, ka] += tmp #t2new[ki,kj,kb] -= tmp.transpose(0,1,3,2) Ftmp = Fvv[ka] - 0.5 * einsum('ma,me->ae', t1[ka], Fov[ka]) tmp = einsum('ijbe,ae->ijab', t2[ki, kj, kb], Ftmp) t2new[ki, kj, ka] -= tmp Ftmp = Foo[kj] + 0.5 * einsum('je,me->mj', t1[kj], Fov[kj]) tmp = einsum('imab,mj->ijab', t2[ki, kj, ka], Ftmp) t2new[ki, kj, ka] -= tmp #t2new[kj,ki,ka] += tmp.transpose(1,0,2,3) Ftmp = Foo[ki] + 0.5 * einsum('ie,me->mi', t1[ki], Fov[ki]) tmp = einsum('jmab,mi->ijab', t2[kj, ki, ka], Ftmp) t2new[ki, kj, ka] += tmp for km in range(nkpts): # Wminj # - km - kn + ka + kb = 0 # => kn = ka - km + kb kn = kconserv[ka, km, kb] t2new[ki, kj, ka] += 0.5 * einsum( 'mnab,mnij->ijab', tau[km, kn, ka], Woooo[km, kn, ki]) ke = km t2new[ki, kj, ka] += 0.5 * einsum( 'ijef,abef->ijab', tau[ki, kj, ke], Wvvvv[ka, kb, ke]) # Wmbej # - km - kb + ke + kj = 0 # => ke = km - kj + kb ke = kconserv[km, kj, kb] tmp = einsum('imae,mbej->ijab', t2[ki, km, ka], Wovvo[km, kb, ke]) # - km - kb + ke + kj = 0 # => ke = km - kj + kb # # t[i,e] => ki = ke # t[m,a] => km = ka if km == ka and ke == ki: tmp -= einsum('ie,ma,mbej->ijab', t1[ki], t1[km], eris_ovvo[km, kb, ke]) t2new[ki, kj, ka] += tmp t2new[ki, kj, kb] -= tmp.transpose(0, 1, 3, 2) t2new[kj, ki, ka] -= tmp.transpose(1, 0, 2, 3) t2new[kj, ki, kb] += tmp.transpose(1, 0, 3, 2) ke = ki tmp = einsum('ie,abej->ijab', t1[ki], eris_vvvo[ka, kb, ke]) t2new[ki, kj, ka] += tmp # P(ij) term ke = kj tmp = einsum('je,abei->ijab', t1[kj], eris_vvvo[ka, kb, ke]) t2new[ki, kj, ka] -= tmp km = ka tmp = einsum('ma,mbij->ijab', t1[ka], eris.ovoo[km, kb, ki]) t2new[ki, kj, ka] -= tmp # P(ab) term km = kb tmp = einsum('mb,maij->ijab', t1[kb], eris.ovoo[km, ka, ki]) t2new[ki, kj, ka] += tmp eia = numpy.zeros(shape=t1new.shape, dtype=t1new.dtype) for ki in range(nkpts): for i in range(nocc): for a in range(nvir): eia[ki, i, a] = foo[ki, i, i] - fvv[ki, a, a] t1new[ki] /= eia[ki] eijab = numpy.zeros(shape=t2new.shape, dtype=t2new.dtype) kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts) for ki in range(nkpts): for kj in range(nkpts): for ka in range(nkpts): kb = kconserv[ki, ka, kj] for i in range(nocc): for a in range(nvir): for j in range(nocc): for b in range(nvir): eijab[ki, kj, ka, i, j, a, b] = (foo[ki, i, i] + foo[kj, j, j] - fvv[ka, a, a] - fvv[kb, b, b]) t2new[ki, kj, ka] /= eijab[ki, kj, ka] time0 = log.timer_debug1('update t1 t2', *time0) return t1new, t2new
def update_amps(cc, t1, t2, eris, max_memory=2000): time0 = time.clock(), time.time() log = logger.Logger(cc.stdout, cc.verbose) nkpts, nocc, nvir = t1.shape fock = eris.fock fov = fock[:, :nocc, nocc:].copy() foo = fock[:, :nocc, :nocc].copy() fvv = fock[:, nocc:, nocc:].copy() tau = imdk.make_tau(cc, t2, t1, t1) Fvv = imdk.cc_Fvv(cc, t1, t2, eris) Foo = imdk.cc_Foo(cc, t1, t2, eris) Fov = imdk.cc_Fov(cc, t1, t2, eris) Woooo = imdk.cc_Woooo(cc, t1, t2, eris) Wvvvv = imdk.cc_Wvvvv(cc, t1, t2, eris) Wovvo = imdk.cc_Wovvo(cc, t1, t2, eris) # Move energy terms to the other side for k in range(nkpts): Fvv[k] -= numpy.diag(numpy.diag(fvv[k])) Foo[k] -= numpy.diag(numpy.diag(foo[k])) # Get the momentum conservation array # Note: chemist's notation for momentum conserving t2(ki,kj,ka,kb), even though # integrals are in physics notation kconserv = kpts_helper.get_kconserv(cc._scf.cell, cc.kpts) eris_ovvo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nocc, nvir, nvir, nocc), dtype=t2.dtype) eris_oovo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nocc, nocc, nvir, nocc), dtype=t2.dtype) eris_vvvo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nvir, nvir, nvir, nocc), dtype=t2.dtype) for km, kb, ke in kpts_helper.loop_kkk(nkpts): kj = kconserv[km, ke, kb] # <mb||je> -> -<mb||ej> eris_ovvo[km, kb, ke] = -eris.ovov[km, kb, kj].transpose(0, 1, 3, 2) # <mn||je> -> -<mn||ej> # let kb = kn as a dummy variable eris_oovo[km, kb, ke] = -eris.ooov[km, kb, kj].transpose(0, 1, 3, 2) # <ma||be> -> - <be||am>* # let kj = ka as a dummy variable kj = kconserv[km, ke, kb] eris_vvvo[ke, kj, kb] = -eris.ovvv[km, kb, ke].transpose(2, 3, 1, 0).conj() # T1 equation t1new = numpy.zeros(shape=t1.shape, dtype=t1.dtype) for ka in range(nkpts): ki = ka t1new[ka] += numpy.array(fov[ka, :, :]).conj() t1new[ka] += einsum('ie,ae->ia', t1[ka], Fvv[ka]) t1new[ka] += -einsum('ma,mi->ia', t1[ka], Foo[ka]) for km in range(nkpts): t1new[ka] += einsum('imae,me->ia', t2[ka, km, ka], Fov[km]) t1new[ka] += -einsum('nf,naif->ia', t1[km], eris.ovov[km, ka, ki]) for kn in range(nkpts): ke = kconserv[km, ki, kn] t1new[ka] += -0.5 * einsum('imef,maef->ia', t2[ki, km, ke], eris.ovvv[km, ka, ke]) t1new[ka] += -0.5 * einsum('mnae,nmei->ia', t2[km, kn, ka], eris_oovo[kn, km, ke]) # T2 equation t2new = numpy.array(eris.oovv).conj() for ki, kj, ka in kpts_helper.loop_kkk(nkpts): # Chemist's notation for momentum conserving t2(ki,kj,ka,kb) kb = kconserv[ki, ka, kj] Ftmp = Fvv[kb] - 0.5 * einsum('mb,me->be', t1[kb], Fov[kb]) tmp = einsum('ijae,be->ijab', t2[ki, kj, ka], Ftmp) t2new[ki, kj, ka] += tmp #t2new[ki,kj,kb] -= tmp.transpose(0,1,3,2) Ftmp = Fvv[ka] - 0.5 * einsum('ma,me->ae', t1[ka], Fov[ka]) tmp = einsum('ijbe,ae->ijab', t2[ki, kj, kb], Ftmp) t2new[ki, kj, ka] -= tmp Ftmp = Foo[kj] + 0.5 * einsum('je,me->mj', t1[kj], Fov[kj]) tmp = einsum('imab,mj->ijab', t2[ki, kj, ka], Ftmp) t2new[ki, kj, ka] -= tmp #t2new[kj,ki,ka] += tmp.transpose(1,0,2,3) Ftmp = Foo[ki] + 0.5 * einsum('ie,me->mi', t1[ki], Fov[ki]) tmp = einsum('jmab,mi->ijab', t2[kj, ki, ka], Ftmp) t2new[ki, kj, ka] += tmp for km in range(nkpts): # Wminj # - km - kn + ka + kb = 0 # => kn = ka - km + kb kn = kconserv[ka, km, kb] t2new[ki, kj, ka] += 0.5 * einsum( 'mnab,mnij->ijab', tau[km, kn, ka], Woooo[km, kn, ki]) ke = km t2new[ki, kj, ka] += 0.5 * einsum( 'ijef,abef->ijab', tau[ki, kj, ke], Wvvvv[ka, kb, ke]) # Wmbej # - km - kb + ke + kj = 0 # => ke = km - kj + kb ke = kconserv[km, kj, kb] tmp = einsum('imae,mbej->ijab', t2[ki, km, ka], Wovvo[km, kb, ke]) # - km - kb + ke + kj = 0 # => ke = km - kj + kb # # t[i,e] => ki = ke # t[m,a] => km = ka if km == ka and ke == ki: tmp -= einsum('ie,ma,mbej->ijab', t1[ki], t1[km], eris_ovvo[km, kb, ke]) t2new[ki, kj, ka] += tmp t2new[ki, kj, kb] -= tmp.transpose(0, 1, 3, 2) t2new[kj, ki, ka] -= tmp.transpose(1, 0, 2, 3) t2new[kj, ki, kb] += tmp.transpose(1, 0, 3, 2) ke = ki tmp = einsum('ie,abej->ijab', t1[ki], eris_vvvo[ka, kb, ke]) t2new[ki, kj, ka] += tmp # P(ij) term ke = kj tmp = einsum('je,abei->ijab', t1[kj], eris_vvvo[ka, kb, ke]) t2new[ki, kj, ka] -= tmp km = ka tmp = einsum('ma,mbij->ijab', t1[ka], eris.ovoo[km, kb, ki]) t2new[ki, kj, ka] -= tmp # P(ab) term km = kb tmp = einsum('mb,maij->ijab', t1[kb], eris.ovoo[km, ka, ki]) t2new[ki, kj, ka] += tmp eia = numpy.zeros(shape=(nocc, nvir), dtype=t1new.dtype) for ki in range(nkpts): eia = foo[ki].diagonal()[:, None] - fvv[ki].diagonal()[None, :] # When padding the occupied/virtual arrays, some fock elements will be zero idx = numpy.where(abs(eia) < LOOSE_ZERO_TOL)[0] eia[idx] = LARGE_DENOM t1new[ki] /= eia eijab = numpy.zeros(shape=(nocc, nocc, nvir, nvir), dtype=t2new.dtype) kconserv = kpts_helper.get_kconserv(cc._scf.cell, cc.kpts) for ki, kj, ka in kpts_helper.loop_kkk(nkpts): kb = kconserv[ki, ka, kj] eijab = (foo[ki].diagonal()[:, None, None, None] + foo[kj].diagonal()[None, :, None, None] - fvv[ka].diagonal()[None, None, :, None] - fvv[kb].diagonal()[None, None, None, :]) # Due to padding; see above discussion concerning t1new in update_amps() idx = numpy.where(abs(eijab) < LOOSE_ZERO_TOL)[0] eijab[idx] = LARGE_DENOM t2new[ki, kj, ka] /= eijab time0 = log.timer_debug1('update t1 t2', *time0) return t1new, t2new