示例#1
0
def Srs(mc, dms, eris=None, verbose=None):
    #Subspace S_rs^{(-2)}
    mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff)
    dm1 = dms['1']
    dm2 = dms['2']
    dm3 = dms['3']
    ncore = mo_core.shape[1]
    ncas = mo_cas.shape[1]
    nocc = ncore + ncas
    if mo_virt.shape[1] == 0:
        return 0, 0
    if eris is None:
        h1e = mc.h1e_for_cas()[0]
        h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0, 2, 1, 3)
        h2e_v = ao2mo.incore.general(mc._scf._eri,
                                     [mo_virt, mo_cas, mo_virt, mo_cas],
                                     compact=False)
        h2e_v = h2e_v.reshape(mo_virt.shape[1], ncas, mo_virt.shape[1],
                              ncas).transpose(0, 2, 1, 3)
    else:
        h1e = eris['h1eff'][ncore:nocc, ncore:nocc]
        h2e = eris['ppaa'][ncore:nocc, ncore:nocc].transpose(0, 2, 1, 3)
        h2e_v = eris['papa'][nocc:, :, nocc:].transpose(0, 2, 1, 3)


# a7 is very sensitive to the accuracy of HF orbital and CI wfn
    rm2, a7 = make_a7(h1e, h2e, dm1, dm2, dm3)
    norm = 0.5 * einsum('rsqp,rsba,pqba->rs', h2e_v, h2e_v, rm2)
    h = 0.5 * einsum('rsqp,rsba,pqab->rs', h2e_v, h2e_v, a7)
    diff = mc.mo_energy[nocc:, None] + mc.mo_energy[None, nocc:]
    return _norm_to_energy(norm, h, diff)
示例#2
0
def make_a23(h1e, h2e, dm1, dm2, dm3):
    a23 = -einsum('ip,caib->abcp',h1e,dm2)\
          -einsum('pijk,cajbik->abcp',h2e,dm3)\
          +2.0*einsum('bp,ca->abcp',h1e,dm1)\
          +2.0*einsum('pibk,caik->abcp',h2e,dm2)

    return a23
示例#3
0
def Sijr(mc, dms, eris, verbose=None):
    #Subspace S_ijr^{(1)}
    mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff)
    dm1 = dms['1']
    dm2 = dms['2']
    ncore = mo_core.shape[1]
    ncas = mo_cas.shape[1]
    nocc = ncore + ncas
    if eris is None:
        h1e = mc.h1e_for_cas()[0]
        h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0, 2, 1, 3)
        h2e_v = ao2mo.incore.general(mc._scf._eri,
                                     [mo_virt, mo_core, mo_cas, mo_core],
                                     compact=False)
        h2e_v = h2e_v.reshape(mo_virt.shape[1], ncore, ncas,
                              ncore).transpose(0, 2, 1, 3)
    else:
        h1e = eris['h1eff'][ncore:nocc, ncore:nocc]
        h2e = eris['ppaa'][ncore:nocc, ncore:nocc].transpose(0, 2, 1, 3)
        h2e_v = eris['pacv'][:ncore].transpose(3, 1, 2, 0)
    if 'h1' in dms:
        hdm1 = dms['h1']
    else:
        hdm1 = make_hdm1(dm1)

    a3 = make_a3(h1e, h2e, dm1, dm2, hdm1)
    norm = 2.0*einsum('rpji,raji,pa->rji',h2e_v,h2e_v,hdm1)\
         - 1.0*einsum('rpji,raij,pa->rji',h2e_v,h2e_v,hdm1)
    h = 2.0*einsum('rpji,raji,pa->rji',h2e_v,h2e_v,a3)\
         - 1.0*einsum('rpji,raij,pa->rji',h2e_v,h2e_v,a3)

    diff = mc.mo_energy[nocc:, None, None] - mc.mo_energy[
        None, :ncore, None] - mc.mo_energy[None, None, :ncore]

    return _norm_to_energy(norm, h, diff)
示例#4
0
def Sijrs(mc, eris, verbose=None):
    mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff)
    ncore = mo_core.shape[1]
    nvirt = mo_virt.shape[1]
    ncas = mo_cas.shape[1]
    nocc = ncore + ncas
    if eris is None:
        erifile = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR)
        feri = ao2mo.outcore.general(mc.mol,
                                     (mo_core, mo_virt, mo_core, mo_virt),
                                     erifile.name,
                                     verbose=mc.verbose)
    else:
        feri = eris['cvcv']

    eia = mc.mo_energy[:ncore, None] - mc.mo_energy[None, nocc:]
    norm = 0
    e = 0
    with ao2mo.load(feri) as cvcv:
        for i in range(ncore):
            djba = (eia.reshape(-1, 1) + eia[i].reshape(1, -1)).ravel()
            gi = numpy.asarray(cvcv[i * nvirt:(i + 1) * nvirt])
            gi = gi.reshape(nvirt, ncore, nvirt).transpose(1, 2, 0)
            t2i = (gi.ravel() / djba).reshape(ncore, nvirt, nvirt)
            # 2*ijab-ijba
            theta = gi * 2 - gi.transpose(0, 2, 1)
            norm += einsum('jab,jab', gi, theta)
            e += einsum('jab,jab', t2i, theta)
    return norm, e
示例#5
0
def Srsi(mc, dms, eris, verbose=None):
    #Subspace S_ijr^{(1)}
    mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff)
    dm1 = dms['1']
    dm2 = dms['2']
    ncore = mo_core.shape[1]
    ncas = mo_cas.shape[1]
    nocc = ncore + ncas
    if eris is None:
        h1e = mc.h1e_for_cas()[0]
        h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0, 2, 1, 3)
        h2e_v = ao2mo.incore.general(mc._scf._eri,
                                     [mo_virt, mo_core, mo_virt, mo_cas],
                                     compact=False)
        h2e_v = h2e_v.reshape(mo_virt.shape[1], ncore, mo_virt.shape[1],
                              ncas).transpose(0, 2, 1, 3)
    else:
        h1e = eris['h1eff'][ncore:nocc, ncore:nocc]
        h2e = eris['ppaa'][ncore:nocc, ncore:nocc].transpose(0, 2, 1, 3)
        h2e_v = eris['pacv'][nocc:].transpose(3, 0, 2, 1)

    k27 = make_k27(h1e, h2e, dm1, dm2)
    norm = 2.0*einsum('rsip,rsia,pa->rsi',h2e_v,h2e_v,dm1)\
         - 1.0*einsum('rsip,sria,pa->rsi',h2e_v,h2e_v,dm1)
    h = 2.0*einsum('rsip,rsia,pa->rsi',h2e_v,h2e_v,k27)\
         - 1.0*einsum('rsip,sria,pa->rsi',h2e_v,h2e_v,k27)
    diff = mc.mo_energy[nocc:, None, None] + mc.mo_energy[
        None, nocc:, None] - mc.mo_energy[None, None, :ncore]
    return _norm_to_energy(norm, h, diff)
示例#6
0
def make_a25(h1e, h2e, dm1, dm2):

    a25 = -einsum('pi,ai->ap',h1e,dm1)\
          -einsum('pijk,jaik->ap',h2e,dm2)\
          +2.0*einsum('ap->pa',h1e)\
          +2.0*einsum('piaj,ij->ap',h2e,dm1)

    return a25
示例#7
0
 def Hx(x):
     x_reshape = np.reshape(x, guessShape)
     tmp1 = einsum('ijk,nqks->ijnqs', HBlock[0],
                   x_reshape)  # Could be 'ijk,mpir->jkmpr'
     tmp2 = einsum('jlmn,ijnqs->ilmqs', mpo, tmp1)
     tmp3 = einsum('lopq,ilmqs->imops', mpo, tmp2)
     finalVec = einsum('ros,imops->mpir', HBlock[1], tmp3)
     return -finalVec.ravel()
示例#8
0
def makeNextGuess(A, S, B, a, maxBondDim=10):
    a0 = a[1]
    a1 = min(maxBondDim, a0 * 2)
    (n1, n2, n3) = A.shape
    Aguess = np.pad(einsum('ijk,k->ijk', A, S),
                    ((0, 0), (0, a0 - n2), (0, a1 - n3)), 'constant')
    Bguess = np.pad(B, ((0, 0), (0, a1 - n3), (0, a0 - n2)), 'constant')
    initGuess = einsum('ijk,lkm->iljm', Aguess, Bguess)
    return initGuess
示例#9
0
 def Hx(x):
     print(x.shape)
     x_reshape = np.reshape(x,guessShape)
     tmp1 = einsum('ijk,nqks->ijnqs',LHBlock,x_reshape) # Could be 'ijk,mpir->jkmpr'
     tmp2 = einsum('jlmn,ijnqs->ilmqs',W[2],tmp1)
     tmp3 = einsum('lopq,ilmqs->imops',W[2],tmp2)
     finalVec = einsum('ros,imops->mpir',RHBlock,tmp3)
     print(finalVec.ravel().shape)
     return -finalVec.ravel()
示例#10
0
def make_a9(h1e, h2e, hdm1, hdm2, hdm3):
    a9 = einsum('ib,pqai->pqab', h1e, hdm2)
    a9 += einsum('ijib,pqaj->pqab', h2e, hdm2) * 2.0
    a9 -= einsum('ijjb,pqai->pqab', h2e, hdm2)
    a9 -= einsum('ijkb,pkqaij->pqab', h2e, hdm3)
    a9 += einsum('ia,pqib->pqab', h1e, hdm2)
    a9 -= einsum('ijja,pqib->pqab', h2e, hdm2)
    a9 -= einsum('ijba,pqji->pqab', h2e, hdm2)
    a9 += einsum('ijia,pqjb->pqab', h2e, hdm2) * 2.0
    a9 -= einsum('ijka,pqkjbi->pqab', h2e, hdm3)
    return a9
示例#11
0
def make_hdm3(dm1, dm2, dm3, hdm1, hdm2):
    delta = numpy.eye(dm3.shape[0])
    hdm3 = - einsum('pb,qrac->pqrabc',delta,hdm2)\
          - einsum('br,pqac->pqrabc',delta,hdm2)\
          + einsum('bq,prac->pqrabc',delta,hdm2)*2.0\
          + einsum('ap,bqcr->pqrabc',delta,dm2)*2.0\
          - einsum('ap,cr,bq->pqrabc',delta,delta,dm1)*4.0\
          + einsum('cr,bqap->pqrabc',delta,dm2)*2.0\
          - einsum('bqapcr->pqrabc',dm3)\
          + einsum('ar,pc,bq->pqrabc',delta,delta,dm1)*2.0\
          - einsum('ar,bqcp->pqrabc',delta,dm2)
    return hdm3
示例#12
0
def make_hdm2(dm1, dm2):
    delta = numpy.eye(dm2.shape[0])
    dm2 = einsum('ikjl->ijkl', dm2) - einsum('jk,il->ijkl', delta, dm1)
    hdm2 = einsum('klij->ijkl',dm2)\
            + einsum('il,kj->ijkl',delta,dm1)\
            + einsum('jk,li->ijkl',delta,dm1)\
            - 2.0*einsum('ik,lj->ijkl',delta,dm1)\
            - 2.0*einsum('jl,ki->ijkl',delta,dm1)\
            - 2.0*einsum('il,jk->ijkl',delta,delta)\
            + 4.0*einsum('ik,jl->ijkl',delta,delta)

    return hdm2
示例#13
0
def make_a16(h1e, h2e, dms, civec, norb, nelec, link_index=None):
    dm3 = dms['3']
    #dm4 = dms['4']
    if 'f3ca' in dms and 'f3ac' in dms:
        f3ca = dms['f3ca']
        f3ac = dms['f3ac']
    else:
        if isinstance(nelec, (int, numpy.integer)):
            neleca = nelecb = nelec // 2
        else:
            neleca, nelecb = nelec
        if link_index is None:
            link_indexa = fci.cistring.gen_linkstr_index(range(norb), neleca)
            link_indexb = fci.cistring.gen_linkstr_index(range(norb), nelecb)
        else:
            link_indexa, link_indexb = link_index
        eri = h2e.transpose(0, 2, 1, 3)
        f3ca = _contract4pdm('NEVPTkern_cedf_aedf', eri, civec, norb, nelec,
                             (link_indexa, link_indexb))
        f3ac = _contract4pdm('NEVPTkern_aedf_ecdf', eri, civec, norb, nelec,
                             (link_indexa, link_indexb))

    a16 = -einsum('ib,rpqiac->pqrabc', h1e, dm3)
    a16 += einsum('ia,rpqbic->pqrabc', h1e, dm3)
    a16 -= einsum('ci,rpqbai->pqrabc', h1e, dm3)

    # qjkiac = acqjki + delta(ja)qcki + delta(ia)qjkc - delta(qc)ajki - delta(kc)qjai
    #:a16 -= einsum('kbij,rpqjkiac->pqrabc', h2e, dm4)
    a16 -= f3ca.transpose(1, 4, 0, 2, 5, 3)  # c'a'acb'b -> a'b'c'abc
    a16 -= einsum('kbia,rpqcki->pqrabc', h2e, dm3)
    a16 -= einsum('kbaj,rpqjkc->pqrabc', h2e, dm3)
    a16 += einsum('cbij,rpqjai->pqrabc', h2e, dm3)
    fdm2 = einsum('kbij,rpajki->prab', h2e, dm3)
    for i in range(norb):
        a16[:, i, :, :, :, i] += fdm2

    #:a16 += einsum('ijka,rpqbjcik->pqrabc', h2e, dm4)
    a16 += f3ac.transpose(1, 2, 0, 4, 3, 5)  # c'a'b'bac -> a'b'c'abc

    #:a16 -= einsum('kcij,rpqbajki->pqrabc', h2e, dm4)
    a16 -= f3ca.transpose(1, 2, 0, 4, 3, 5)  # c'a'b'bac -> a'b'c'abc

    a16 += einsum('jbij,rpqiac->pqrabc', h2e, dm3)
    a16 -= einsum('cjka,rpqbjk->pqrabc', h2e, dm3)
    a16 += einsum('jcij,rpqbai->pqrabc', h2e, dm3)
    return a16
示例#14
0
def Sij(mc, dms, eris, verbose=None):
    #Subspace S_ij^{(-2)}
    mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff)
    dm1 = dms['1']
    dm2 = dms['2']
    dm3 = dms['3']
    ncore = mo_core.shape[1]
    ncas = mo_cas.shape[1]
    nocc = ncore + ncas
    if mo_core.size == 0:
        return 0.0, 0
    if eris is None:
        h1e = mc.h1e_for_cas()[0]
        h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0, 2, 1, 3)
        h2e_v = ao2mo.incore.general(mc._scf._eri,
                                     [mo_cas, mo_core, mo_cas, mo_core],
                                     compact=False)
        h2e_v = h2e_v.reshape(ncas, ncore, ncas, ncore).transpose(0, 2, 1, 3)
    else:
        h1e = eris['h1eff'][ncore:nocc, ncore:nocc]
        h2e = eris['ppaa'][ncore:nocc, ncore:nocc].transpose(0, 2, 1, 3)
        h2e_v = eris['papa'][:ncore, :, :ncore].transpose(1, 3, 0, 2)

    if 'h1' in dms:
        hdm1 = dms['h1']
    else:
        hdm1 = make_hdm1(dm1)
    if 'h2' in dms:
        hdm2 = dms['h2']
    else:
        hdm2 = make_hdm2(dm1, dm2)
    if 'h3' in dms:
        hdm3 = dms['h3']
    else:
        hdm3 = make_hdm3(dm1, dm2, dm3, hdm1, hdm2)


# a9 is very sensitive to the accuracy of HF orbital and CI wfn
    a9 = make_a9(h1e, h2e, hdm1, hdm2, hdm3)
    norm = 0.5 * einsum('qpij,baij,pqab->ij', h2e_v, h2e_v, hdm2)
    h = 0.5 * einsum('qpij,baij,pqab->ij', h2e_v, h2e_v, a9)
    diff = mc.mo_energy[:ncore, None] + mc.mo_energy[None, :ncore]
    return _norm_to_energy(norm, h, -diff)
示例#15
0
def Si(mc, ci, dms, eris=None, verbose=None):
    #Subspace S_i^{(1)}
    mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff)
    dm1 = dms['1']
    dm2 = dms['2']
    dm3 = dms['3']
    #dm4 = dms['4']
    ncore = mo_core.shape[1]
    ncas = mo_cas.shape[1]
    nocc = ncore + ncas

    if eris is None:
        h1e = mc.h1e_for_cas()[0]
        h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0, 2, 1, 3)
        h2e_v = ao2mo.incore.general(mc._scf._eri,
                                     [mo_cas, mo_core, mo_cas, mo_cas],
                                     compact=False)
        h2e_v = h2e_v.reshape(ncas, ncore, ncas, ncas).transpose(0, 2, 1, 3)
        core_dm = numpy.dot(mo_core, mo_core.T) * 2
        core_vhf = mc.get_veff(mc.mol, core_dm)
        h1e_v = reduce(numpy.dot,
                       (mo_cas.T, mc.get_hcore() + core_vhf, mo_core))
    else:
        h1e = eris['h1eff'][ncore:nocc, ncore:nocc]
        h2e = eris['ppaa'][ncore:nocc, ncore:nocc].transpose(0, 2, 1, 3)
        h2e_v = eris['ppaa'][ncore:nocc, :ncore].transpose(0, 2, 1, 3)
        h1e_v = eris['h1eff'][ncore:nocc, :ncore]

    if getattr(mc.fcisolver, 'nevpt_intermediate', None):
        #mc.fcisolver.make_a22(ncas, state)
        a22 = mc.fcisolver.nevpt_intermediate('A22', ncas, mc.nelecas, ci)
    else:
        a22 = make_a22(h1e, h2e, dms, ci, ncas, mc.nelecas)
    a23 = make_a23(h1e, h2e, dm1, dm2, dm3)
    a25 = make_a25(h1e, h2e, dm1, dm2)
    delta = numpy.eye(ncas)
    dm3_h = einsum('abef,cd->abcdef',dm2,delta)*2\
            - dm3.transpose(0,1,3,2,4,5)
    dm2_h = einsum('ab,cd->abcd',dm1,delta)*2\
            - dm2.transpose(0,1,3,2)
    dm1_h = 2 * delta - dm1.transpose(1, 0)

    ener = einsum('qpir,pqrabc,baic->i',h2e_v,a22,h2e_v)\
        +  einsum('qpir,pqra,ai->i',h2e_v,a23,h1e_v)*2.0\
        +  einsum('pi,pa,ai->i',h1e_v,a25,h1e_v)

    norm = einsum('qpir,rpqbac,baic->i',h2e_v,dm3_h,h2e_v)\
        +  einsum('qpir,rpqa,ai->i',h2e_v,dm2_h,h1e_v)*2.0\
        +  einsum('pi,pa,ai->i',h1e_v,dm1_h,h1e_v)

    return _norm_to_energy(norm, ener, -mc.mo_energy[:ncore])
示例#16
0
def makeBlocks(mps, mpo=None, block=None, lmps=None):
    if block is None:
        if mpo is None:
            block = [np.array([[1.]]), np.array([[1.]])]
        else:
            block = [np.array([[[1.]]]), np.array([[[1.]]])]
    if lmps is None:
        lmps = mps
    if mpo is None:
        tmp1 = einsum('jl,ijk->ilk', block[0], lmps[0].conj())
        block[0] = einsum('ilk,ilm->km', tmp1, mps[0])
        tmp1 = einsum('op,nko->nkp', block[1], lmps[1].conj())
        block[1] = einsum('nkp,nmp->km', tmp1, mps[1])
    else:
        tmp1 = einsum('ijk,lim->jklm', block[0], lmps[0].conj())
        tmp2 = einsum('jklm,jnlo->kmno', tmp1, mpo[0])
        block[0] = einsum('kmno,okp->mnp', tmp2, mps[0])
        tmp1 = einsum('nop,kmp->kmno', mps[1], block[1])
        tmp2 = einsum('kmno,lmin->iklo', tmp1, mpo[1])
        block[1] = einsum('iklo,ijk->jlo', tmp2, lmps[1].conj())
    return block
示例#17
0
def make_a12(h1e, h2e, dm1, dm2, dm3):
    a12 = einsum('ia,qpib->pqab',h1e,dm2)\
        - einsum('bi,qpai->pqab',h1e,dm2)\
        + einsum('ijka,qpjbik->pqab',h2e,dm3)\
        - einsum('kbij,qpajki->pqab',h2e,dm3)\
        - einsum('bjka,qpjk->pqab',h2e,dm2)\
        + einsum('jbij,qpai->pqab',h2e,dm2)
    return a12
示例#18
0
def Sr(mc, ci, dms, eris=None, verbose=None):
    #The subspace S_r^{(-1)}
    mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff)
    dm1 = dms['1']
    dm2 = dms['2']
    dm3 = dms['3']
    #dm4 = dms['4']
    ncore = mo_core.shape[1]
    nvirt = mo_virt.shape[1]
    ncas = mo_cas.shape[1]
    nocc = ncore + ncas

    if eris is None:
        h1e = mc.h1e_for_cas()[0]
        h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0, 2, 1, 3)
        h2e_v = ao2mo.incore.general(mc._scf._eri,
                                     [mo_virt, mo_cas, mo_cas, mo_cas],
                                     compact=False)
        h2e_v = h2e_v.reshape(mo_virt.shape[1], ncas, ncas,
                              ncas).transpose(0, 2, 1, 3)
        core_dm = numpy.dot(mo_core, mo_core.T) * 2
        core_vhf = mc.get_veff(mc.mol, core_dm)
        h1e_v = reduce(numpy.dot,
                       (mo_virt.T, mc.get_hcore() + core_vhf, mo_cas))
        h1e_v -= einsum('mbbn->mn', h2e_v)
    else:
        h1e = eris['h1eff'][ncore:nocc, ncore:nocc]
        h2e = eris['ppaa'][ncore:nocc, ncore:nocc].transpose(0, 2, 1, 3)
        h2e_v = eris['ppaa'][nocc:, ncore:nocc].transpose(0, 2, 1, 3)
        h1e_v = eris['h1eff'][nocc:, ncore:nocc] - einsum('mbbn->mn', h2e_v)

    if getattr(mc.fcisolver, 'nevpt_intermediate', None):
        a16 = mc.fcisolver.nevpt_intermediate('A16', ncas, mc.nelecas, ci)
    else:
        a16 = make_a16(h1e, h2e, dms, ci, ncas, mc.nelecas)
    a17 = make_a17(h1e, h2e, dm2, dm3)
    a19 = make_a19(h1e, h2e, dm1, dm2)

    ener = einsum('ipqr,pqrabc,iabc->i',h2e_v,a16,h2e_v)\
        +  einsum('ipqr,pqra,ia->i',h2e_v,a17,h1e_v)*2.0\
        +  einsum('ip,pa,ia->i',h1e_v,a19,h1e_v)

    norm = einsum('ipqr,rpqbac,iabc->i',h2e_v,dm3,h2e_v)\
        +  einsum('ipqr,rpqa,ia->i',h2e_v,dm2,h1e_v)*2.0\
        +  einsum('ip,pa,ia->i',h1e_v,dm1,h1e_v)

    return _norm_to_energy(norm, ener, mc.mo_energy[nocc:])
示例#19
0
def mpo2mat(mpo):
    N = len(mpo)
    (_,_,d,_) = mpo[0].shape
    mat = np.zeros((d**N,d**N))
    occ = np.zeros((d**N,N),dtype=int)
    for i in range(d**N):
        occ[i,:] = np.asarray(list(map(lambda x: int(x),'0'*(N-len(bin(i)[N:]))+bin(i)[N:])))
    for i in range(d**N):
        i_occ = occ[i,:]
        for j in range(d**N):
            j_occ = occ[j,:]
            tmp_mat = np.array([[1]])
            for k in range(N):
                tmp_mat = einsum('ij,jk->ik',tmp_mat,mpo[k][:,:,i_occ[k],j_occ[k]])
            mat[i,j] += tmp_mat[[0]]
    return mat
示例#20
0
def createInitMPS(W, Wl=None, maxBondDim=10, d=2, obsvs=None):
    left = True
    if Wl is None: left = False
    H = mpo2mat([W[0], W[1]])
    # Diagonalize Hamiltonian
    (e0, lwf, rwf) = sortEig(H)
    # Ensure Proper Normalization
    # <-|R> = 1
    # <L|R> = 1
    rwf = rwf / np.sum(rwf)
    lwf = lwf / np.sum(lwf * rwf)
    ############################################
    # Reshape wavefunction for SVD
    rpsi = np.reshape(rwf, (2, 2))
    lpsi = np.reshape(lwf, (2, 2))
    ############################################
    # Do SVD of initial unit cell
    a = [1, min(maxBondDim, d)]
    (A, S, B) = decompose(rpsi, a)
    if left: (Al, Sl, Bl) = decompose(lpsi, a)
    ############################################
    # Evaluate Observables
    if left:
        obVals = evaluateObservables([A, S, B], [Al, Sl, Bl], obsvs, init=True)
    else:
        obVals = evaluateObservables([A, S, B], [A, S, B], obsvs, init=True)
    ############################################
    # Store left and right environments
    block = makeBlocks([A, B])
    hBlock = makeBlocks([A, B], mpo=[W[0], W[1]])
    nextGuess = makeNextGuess(A, S, B, a, maxBondDim)
    E = einsum('ijk,i,k,ijk->', hBlock[0], S, S, hBlock[1]) / einsum(
        'ko,k,o,ko->', block[0], S, S, block[1])
    if left:
        blockL = makeBlocks([Al, Bl])
        hBlockL = makeBlocks([Al, Bl], mpo=[Wl[0], Wl[1]])
        blockLR = makeBlocks([A, B], lmps=[Al, Bl])
        hBlockLR = makeBlocks([A, B], lmps=[Al, Bl], mpo=[W[0], W[1]])
        nextGuessL = makeNextGuess(Al, Sl, Bl, a, maxBondDim)
        block = [block, blockL, blockLR]
        hBlock = [hBlock, hBlockL, hBlockLR]
        nextGuess = [nextGuess, nextGuessL]
        El = einsum('ijk,i,k,ijk->', hBlockL[0], Sl, Sl, hBlockL[1]) / einsum(
            'ko,k,o,ko->', blockL[0], Sl, Sl, blockL[1])
        Elr = einsum('ijk,i,k,ijk->',
                     hBlockLR[0], Sl, S, hBlockLR[1]) / einsum(
                         'ko,k,o,ko->', blockLR[0], Sl, S, blockLR[1])
    return (E, [A, B], block, hBlock, nextGuess)
示例#21
0
# Make Initial Unit Cell
H = np.zeros((2**2,2**2))
occ = np.zeros((2**2,2),dtype=int)
sum_occ = np.zeros(2**2,dtype=int)
for i in range(2**2):
    occ[i,:] = np.asarray(list(map(lambda x: int(x),'0'*(2-len(bin(i)[2:]))+bin(i)[2:])))
    #print(occ[i,:])
    sum_occ[i] = np.sum(occ[i,:])
# Calculate Hamiltonian
for i in range(2**2):
    i_occ = occ[i,:]
    for j in range(2**2):
        j_occ = occ[j,:]
        tmp_mat0 = np.array([[1]])
        for k in range(2):
            tmp_mat0 = einsum('ij,jk->ik',tmp_mat0,W[k][:,:,i_occ[k],j_occ[k]])
        H[i,j] += tmp_mat0[[0]]
# Diagonalize Hamiltonian
e0,lwf,rwf = la.eig(H,left=True)
inds = np.argsort(e0)
e0 = e0[inds[-1]]
rwf = rwf[:,inds[-1]]
lwf = lwf[:,inds[-1]]
# Ensure Proper Normalization
# <-|R> = 1
# <L|R> = 1
rwf = rwf/np.sum(rwf)
lwf = lwf/np.sum(lwf*rwf)
print('\nExact Diagonalization Energy: {}'.format(e0))
print('Energy Check {}'.format(einsum('i,ij,j->',lwf.conj(),H,rwf)/einsum('i,i->',lwf.conj(),rwf)))
############################################
示例#22
0
def evaluateObservables(state,
                        lstate,
                        obsvs,
                        block=[np.array([[1.]]),
                               np.array([[1.]])],
                        init=False,
                        norm=1.):
    for ob in obsvs:
        if ob["useBlock"] == False:
            if len(ob["mpo"]) == 2:
                tmp1 = einsum('ik  , lim, m->klm ', block[0], lstate[0].conj(),
                              lstate[1].conj())
                tmp2 = einsum('klm , jnlo  ->kmno', tmp1, ob["mpo"][0])
                tmp3 = einsum('kmno, okp, p->mnp ', tmp2, state[0], state[1])
                tmp4 = einsum('mnp , qmr   ->npqr', tmp3, lstate[2].conj())
                tmp5 = einsum('npqr, nsqt  ->prt ', tmp4, ob["mpo"][1])
                tmp6 = einsum('prt , tpu   ->ru  ', tmp5, state[2])
                ob["val"] = einsum('ru  , ru    ->    ', tmp6, block[1]) / norm
            else:
                ob["val"] = [None] * 2
                tmp1 = einsum('ik  , lim, m->klm ', block[0], lstate[0].conj(),
                              lstate[1].conj())
                tmp2 = einsum('klm , jnlo  ->kmo ', tmp1, ob["mpo"])
                tmp3 = einsum('kmo , okp, p->mp  ', tmp2, state[0], state[1])
                tmp4 = einsum('mp  , qmr   ->pqr ', tmp3, lstate[2].conj())
                tmp5 = einsum('pqr , qpu   ->ru  ', tmp4, state[2])
                ob["val"][0] = einsum('ru  , ru    ->    ', tmp5,
                                      block[1]) / norm
                tmp1 = einsum('ik  , lim, m->klm ', block[0], lstate[0].conj(),
                              lstate[1].conj())
                tmp2 = einsum('klm , lkn, n->mn  ', tmp1, state[0], state[1])
                tmp3 = einsum('mn  , omp   ->nop ', tmp2, lstate[2].conj())
                tmp4 = einsum('nop , qros  ->psn ', tmp3, ob["mpo"])
                tmp5 = einsum('psn , snt   ->pt  ', tmp4, state[2])
                ob["val"][1] = einsum('pt,pt->', tmp5, block[1]) / norm
        else:
            # Select correct site operators
            if init:
                mpo = [ob["mpo"][0], ob["mpo"][1]]
                newBlock = makeBlocks([state[0], state[2]],
                                      mpo,
                                      block=None,
                                      lmps=[lstate[0], lstate[2]])
            else:
                mpo = [ob["mpo"][2], ob["mpo"][2]]
                newBlock = makeBlocks([state[0], state[2]],
                                      mpo,
                                      block=ob["block"],
                                      lmps=[lstate[0], lstate[2]])
            ob["block"][0] = newBlock[0]
            ob["block"][1] = newBlock[1]
            # Evaluate Operator
            ob["val"] = einsum('ijk,ijk,i,k', ob["block"][0], ob["block"][1],
                               state[1], lstate[1]) / norm
示例#23
0
def runOptLR(mps,
             mpo,
             block,
             hBlock,
             nextGuess,
             E_init=0,
             maxBondDim=10,
             minIter=10,
             maxIter=10000,
             tol=1e-10,
             plotConv=True,
             d=2,
             obsvs=None,
             updateFunc=None):
    if VERBOSE > 3:
        print('Running LR Optimization Scheme')
    # Extract Inputs
    mps, mpsl = mps[0], mps[1]
    mpo, mpol = mpo[0], mpo[1]
    blockL = block[1]
    blockLR = block[2]
    block = block[0]
    hBlockL = hBlock[1]
    hBlockLR = hBlock[2]
    hBlock = hBlock[0]
    nextGuessL = nextGuess[1]
    nextGuess = nextGuess[0]
    # Make a function that can update stuff
    if updateFunc is not None:
        passVars = (mps, mpsl, mpo, mpol, blockL, blockLR, block, hBlockL,
                    hBlockLR, hBlock, nextGuessL, nextGuess, obsvs)
        returnVars = updateFunc(passVars)
        mps = returnVars[0]
        mpsl = returnVars[1]
        mpo = returnVars[2]
        mpol = returnVars[3]
        blockL = returnVars[4]
        blockLR = returnVars[5]
        block = returnVars[6]
        hBlockL = returnVars[7]
        hBlockLR = returnVars[8]
        hBlock = returnVars[9]
        nextGuessL = returnVars[10]
        nextGuess = returnVars[11]
        obsvs = returnVars[12]
    # Set up Iterative Loop Parameters
    fig = initializePlot(plotConv)
    converged = False
    iterCnt = 0
    nBond = 1
    E_prev = E_init
    a = [1, min(maxBondDim, d)]  # Keep Track of bond dimensions
    Evec = [E_init]
    EEvec = [0.]
    nBondVec = [1]
    while not converged:
        nBond += 2
        a[0] = a[1]
        a[1] = min(maxBondDim, a[0] * 2)
        # ------------------------------------------------------------------------------
        # Run Eigensolver
        H = setupEigenProb(mpo, hBlock, nextGuess)
        E, v = runEigenSolver(H)
        E /= nBond
        Hl = setupEigenProb(mpol, hBlockL, nextGuessL)
        El, vl = runEigenSolver(Hl)
        El /= nBond
        v, vl = normEigVecs(v, vl)
        # ------------------------------------------------------------------------------
        # Reshape result into state
        (_, _, n1, _) = mpo.shape
        (_, _, n2, _) = mpo.shape
        (n3, _, _) = hBlock[0].shape
        (n4, _, _) = hBlock[1].shape
        psi = np.reshape(v, (n1, n2, n3, n4))  # s_l s_(l+1) a_(l-1) a_(l+1)
        psi = np.transpose(psi, (2, 0, 1, 3))  # a_(l-1) s_l a_(l+1) s_(l+1)
        psi = np.reshape(psi, (n3 * n1, n4 * n2))
        lpsi = np.reshape(vl, (n1, n2, n3, n4))
        lpsi = np.transpose(lpsi, (2, 0, 1, 3))
        lpsi = np.reshape(lpsi, (n3 * n1, n4 * n2))
        # ------------------------------------------------------------------------------
        # Perform USV Decomposition
        (A, S, B) = decompose(psi, a)
        mps = [A, B]
        EE, _ = calcEntanglement(S)
        (Al, Sl, Bl) = decompose(lpsi, a)
        mpsl = [Al, Bl]
        ############################################
        # Evaluate Observables
        obVals = evaluateObservables([A, S, B], [Al, Sl, Bl],
                                     block=blockLR,
                                     obsvs=obsvs)
        # -----------------------------------------------------------------------------
        # Store left and right environments
        block = makeBlocks(mps, block=block)
        hBlock = makeBlocks(mps, mpo=[mpo, mpo], block=hBlock)
        blockL = makeBlocks(mpsl, block=blockL)
        hBlockL = makeBlocks(mpsl, mpo=[mpol, mpol], block=hBlockL)
        blockLR = makeBlocks(mps, lmps=mpsl, block=blockLR)
        hBlockLR = makeBlocks(mps, lmps=mpsl, mpo=[mpo, mpo], block=hBlockLR)
        E = einsum('ijk,i,k,ijk->', hBlock[0], S, S, hBlock[1]) / einsum(
            'ko,k,o,ko->', block[0], S, S, block[1]) / nBond
        El = einsum('ijk,i,k,ijk->', hBlockL[0], Sl, Sl, hBlockL[1]) / einsum(
            'ko,k,o,ko->', blockL[0], Sl, Sl, blockL[1]) / nBond
        Elr = einsum('ijk,i,k,ijk->',
                     hBlockLR[0], S, Sl, hBlockLR[1]) / einsum(
                         'ko,k,o,ko->', blockLR[0], S, Sl, blockLR[1]) / nBond
        obsvs = normalizeObservables(
            obsvs, einsum('ko,k,o,ko->', blockLR[0], S, Sl, blockLR[1]))
        # -----------------------------------------------------------------------------
        # Make next Initial Guess
        nextGuess = makeNextGuess(A, S, B, a, maxBondDim)
        nextGuessL = makeNextGuess(Al, Sl, Bl, a, maxBondDim)
        # ------------------------------------------------------------------------------
        # Check for convergence
        if VERBOSE > 2:
            print(
                '\tEnergy from Optimization = {},{},{}\tvonNeumann Entropy = {}'
                .format(E, El, Elr, EE))
        if (np.abs(E - E_prev) < tol) and (iterCnt > minIter):
            converged = True
            if VERBOSE > 1:
                print('System Converged {} {}'.format(E, E_prev))
        elif iterCnt == maxIter:
            converged = True
            if VERBOSE > 1:
                print('Convergence not acheived')
        else:
            E_prev = E
            iterCnt += 1
            Evec.append(E)
            EEvec.append(EE)
            nBondVec.append(nBond)
            updatePlot(plotConv, fig, Evec, nBondVec)
            if updateFunc is not None:
                passVars = (mps, mpsl, mpo, mpol, blockL, blockLR, block,
                            hBlockL, hBlockLR, hBlock, nextGuessL, nextGuess,
                            obsvs)
                returnVars = updateFunc(passVars)
                mps = returnVars[0]
                mpsl = returnVars[1]
                mpo = returnVars[2]
                mpol = returnVars[3]
                blockL = returnVars[4]
                blockLR = returnVars[5]
                block = returnVars[6]
                hBlockL = returnVars[7]
                hBlockLR = returnVars[8]
                hBlock = returnVars[9]
                nextGuessL = returnVars[10]
                nextGuess = returnVars[11]
                obsvs = returnVars[12]
    return Evec, EEvec, obsvs
示例#24
0
def make_k27(h1e, h2e, dm1, dm2):
    k27 = -einsum('ai,pi->pa',h1e,dm1)\
         -einsum('iajk,pkij->pa',h2e,dm2)\
         +einsum('iaji,pj->pa',h2e,dm1)
    return k27
示例#25
0
def setupEigenProbSlow(HBlock, mpo):
    # PH - Do for left Eigenvec
    H = einsum('ijk,jlmn,lopq,ros->mpirnqks', HBlock[0], mpo, mpo, HBlock[1])
    (n1, n2, n3, n4, n5, n6, n7, n8) = H.shape
    H = np.reshape(H, (n1 * n2 * n3 * n4, n5 * n6 * n7 * n8))
    return H
示例#26
0
def make_a7(h1e, h2e, dm1, dm2, dm3):
    #This dm2 and dm3 need to be in the form of norm order
    delta = numpy.eye(dm2.shape[0])
    # a^+_ia^+_ja_ka^l =  E^i_lE^j_k -\delta_{j,l} E^i_k
    rm2 = einsum('iljk->ijkl', dm2) - einsum('ik,jl->ijkl', dm1, delta)
    # E^{i,j,k}_{l,m,n} = E^{i,j}_{m,n}E^k_l -\delta_{k,m}E^{i,j}_{l,n}- \delta_{k,n}E^{i,j}_{m,l}
    # = E^i_nE^j_mE^k_l -\delta_{j,n}E^i_mE^k_l -\delta_{k,m}E^{i,j}_{l,n} -\delta_{k,n}E^{i,j}_{m,l}
    rm3 = einsum('injmkl->ijklmn',dm3)\
        - einsum('jn,imkl->ijklmn',delta,dm2)\
        - einsum('km,ijln->ijklmn',delta,rm2)\
        - einsum('kn,ijml->ijklmn',delta,rm2)

    a7 = -einsum('bi,pqia->pqab',h1e,rm2)\
         -einsum('ai,pqbi->pqab',h1e,rm2)\
         -einsum('kbij,pqkija->pqab',h2e,rm3) \
         -einsum('kaij,pqkibj->pqab',h2e,rm3) \
         -einsum('baij,pqij->pqab',h2e,rm2)
    return rm2, a7
示例#27
0
def make_a22(h1e, h2e, dms, civec, norb, nelec, link_index=None):
    dm2 = dms['2']
    dm3 = dms['3']
    #dm4 = dms['4']
    if 'f3ca' in dms and 'f3ac' in dms:
        f3ca = dms['f3ca']
        f3ac = dms['f3ac']
    else:
        if isinstance(nelec, (int, numpy.integer)):
            neleca = nelecb = nelec // 2
        else:
            neleca, nelecb = nelec
        if link_index is None:
            link_indexa = fci.cistring.gen_linkstr_index(range(norb), neleca)
            link_indexb = fci.cistring.gen_linkstr_index(range(norb), nelecb)
        else:
            link_indexa, link_indexb = link_index
        eri = h2e.transpose(0, 2, 1, 3)
        f3ca = _contract4pdm('NEVPTkern_cedf_aedf', eri, civec, norb, nelec,
                             (link_indexa, link_indexb))
        f3ac = _contract4pdm('NEVPTkern_aedf_ecdf', eri, civec, norb, nelec,
                             (link_indexa, link_indexb))

    a22 = -einsum('pb,kipjac->ijkabc', h1e, dm3)
    a22 -= einsum('pa,kibjpc->ijkabc', h1e, dm3)
    a22 += einsum('cp,kibjap->ijkabc', h1e, dm3)
    a22 += einsum('cqra,kibjqr->ijkabc', h2e, dm3)
    a22 -= einsum('qcpq,kibjap->ijkabc', h2e, dm3)

    # qjprac = acqjpr + delta(ja)qcpr + delta(ra)qjpc - delta(qc)ajpr - delta(pc)qjar
    #a22 -= einsum('pqrb,kiqjprac->ijkabc', h2e, dm4)
    a22 -= f3ac.transpose(1, 5, 0, 2, 4, 3)  # c'a'acbb'
    fdm2 = einsum('pqrb,kiqcpr->ikbc', h2e, dm3)
    for i in range(norb):
        a22[:, i, :, i, :, :] -= fdm2
    a22 -= einsum('pqab,kiqjpc->ijkabc', h2e, dm3)
    a22 += einsum('pcrb,kiajpr->ijkabc', h2e, dm3)
    a22 += einsum('cqrb,kiqjar->ijkabc', h2e, dm3)

    #a22 -= einsum('pqra,kibjqcpr->ijkabc', h2e, dm4)
    a22 -= f3ac.transpose(1, 3, 0, 4, 2, 5)  # c'a'bb'ac -> a'b'c'abc

    #a22 += einsum('rcpq,kibjaqrp->ijkabc', h2e, dm4)
    a22 += f3ca.transpose(1, 3, 0, 4, 2, 5)  # c'a'bb'ac -> a'b'c'abc

    a22 += 2.0 * einsum('jb,kiac->ijkabc', h1e, dm2)
    a22 += 2.0 * einsum('pjrb,kiprac->ijkabc', h2e, dm3)
    fdm2 = einsum('pa,kipc->ikac', h1e, dm2)
    fdm2 -= einsum('cp,kiap->ikac', h1e, dm2)
    fdm2 -= einsum('cqra,kiqr->ikac', h2e, dm2)
    fdm2 += einsum('qcpq,kiap->ikac', h2e, dm2)
    fdm2 += einsum('pqra,kiqcpr->ikac', h2e, dm3)
    fdm2 -= einsum('rcpq,kiaqrp->ikac', h2e, dm3)
    for i in range(norb):
        a22[:, i, :, :, i, :] += fdm2 * 2

    return a22
示例#28
0
    def fciqmc(self, dirname='.'):
        if isinstance(self.verbose, logger.Logger):
            log = self.verbose
        else:
            log = logger.Logger(self.stdout, self.verbose)
        time0 = (time.clock(), time.time())

        print('Reading FCIQMC 1, 2, 3 RDMs...')
        dm1, dm2, dm3 = fciqmcscf.stochastic_mrpt.read_rdms_fciqmc(
            self.ncas, self.nelecas, dirname=dirname)
        dms = {'1': dm1, '2': dm2, '3': dm3}
        print('FCIQMC 1, 2, 3 RDMs read successfully.')
        if (not self.canonicalized):
            self.mo_coeff, _, self.mo_energy = self.canonicalize(
                self.mo_coeff, ci=None, verbose=self.verbose, casdm1=dm1)

        ncore = self.ncore
        ncas = self.ncas
        nocc = ncore + ncas
        assert dm1.shape[0] == ncas

        time1 = log.timer('3pdm, 4pdm', *time0)
        eris = _ERIS(self, self.mo_coeff)
        time1 = log.timer('integral transformation', *time1)

        aaaa = eris['ppaa'][ncore:nocc, ncore:nocc].copy()

        try:
            print('Reading FCIQMC NEVPT2 intermediate...')
            f3ac, f3ca = fciqmcscf.stochastic_mrpt.full_nevpt2_intermediates_fciqmc(
                dm1,
                dm2,
                dm3,
                self.ncas,
                aaaa.transpose(0, 2, 1, 3),
                dirname=dirname)
            print('FCIQMC NEVPT2 intermediates read successfully.')
        except IOError:
            print('FCIQMC NEVPT2 intermediate not found, reading 4RDM')
            dm4 = fciqmcscf.stochastic_mrpt.read_neci_pdm_mrpt(
                'spinfree_FourRDM.1', self.ncas)
            print('Computing low-rank part of FCIQMC NEVPT2 intermediate...')
            f3ac, f3ca = fciqmcscf.stochastic_mrpt.calc_lower_rank_part_of_intermediates(
                dms['1'], dms['2'], dms['3'], aaaa.transpose(0, 2, 1, 3))
            print('Adding rank-4 part of the NEVPT2 intermediate...')
            f3ac += einsum('pqra,kibjqcpr->ijkabc', aaaa.transpose(0, 2, 1, 3),
                           dm4).transpose(2, 0, 4, 1, 3, 5)
            f3ca += einsum('rcpq,kibjaqrp->ijkabc', aaaa.transpose(0, 2, 1, 3),
                           dm4).transpose(2, 0, 4, 1, 3, 5)
            print('complete')
            # the dms are all normal ordered, so switch to product-of-single-excitation ordering
        print('Reordering FCIQMC RDMs from NORD to POSE...')
        fciqmcscf.stochastic_mrpt.unreorder_dm123(dms['1'],
                                                  dms['2'],
                                                  dms['3'],
                                                  inplace=True)
        print('complete')
        dms['f3ca'] = f3ca
        dms['f3ac'] = f3ac

        time1 = log.timer('eri-4pdm contraction', *time1)

        norm_Sr, e_Sr = Sr(self, None, dms, eris)
        logger.note(self, "Sr    (-1)',   E = %.14f", e_Sr)
        time1 = log.timer("space Sr (-1)'", *time1)
        norm_Si, e_Si = Si(self, None, dms, eris)
        logger.note(self, "Si    (+1)',   E = %.14f", e_Si)

        time1 = log.timer("space Si (+1)'", *time1)
        norm_Sijrs, e_Sijrs = Sijrs(self, eris)
        logger.note(self, "Sijrs (0)  ,   E = %.14f", e_Sijrs)
        time1 = log.timer('space Sijrs (0)', *time1)
        norm_Sijr, e_Sijr = Sijr(self, dms, eris)
        logger.note(self, "Sijr  (+1) ,   E = %.14f", e_Sijr)
        time1 = log.timer('space Sijr (+1)', *time1)
        norm_Srsi, e_Srsi = Srsi(self, dms, eris)
        logger.note(self, "Srsi  (-1) ,   E = %.14f", e_Srsi)
        time1 = log.timer('space Srsi (-1)', *time1)
        norm_Srs, e_Srs = Srs(self, dms, eris)
        logger.note(self, "Srs   (-2) ,   E = %.14f", e_Srs)
        time1 = log.timer('space Srs (-2)', *time1)
        norm_Sij, e_Sij = Sij(self, dms, eris)
        logger.note(self, "Sij   (+2) ,   E = %.14f", e_Sij)
        time1 = log.timer('space Sij (+2)', *time1)
        norm_Sir, e_Sir = Sir(self, dms, eris)
        logger.note(self, "Sir   (0)' ,   E = %.14f", e_Sir)
        time1 = log.timer("space Sir (0)'", *time1)

        nevpt_e = e_Sr + e_Si + e_Sijrs + e_Sijr + e_Srsi + e_Srs + e_Sij + e_Sir
        logger.note(self, "Nevpt2 Energy = %.15f", nevpt_e)
        log.timer('SC-NEVPT2', *time0)

        self.e_corr = nevpt_e
        return nevpt_e
示例#29
0
def Sir(mc, dms, eris, verbose=None):
    #Subspace S_il^{(0)}
    mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff)
    dm1 = dms['1']
    dm2 = dms['2']
    dm3 = dms['3']
    ncore = mo_core.shape[1]
    ncas = mo_cas.shape[1]
    nocc = ncore + ncas
    if eris is None:
        h1e = mc.h1e_for_cas()[0]
        h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0, 2, 1, 3)
        h2e_v1 = ao2mo.incore.general(mc._scf._eri,
                                      [mo_virt, mo_core, mo_cas, mo_cas],
                                      compact=False)
        h2e_v1 = h2e_v1.reshape(mo_virt.shape[1], ncore, ncas,
                                ncas).transpose(0, 2, 1, 3)
        h2e_v2 = ao2mo.incore.general(mc._scf._eri,
                                      [mo_virt, mo_cas, mo_cas, mo_core],
                                      compact=False)
        h2e_v2 = h2e_v2.reshape(mo_virt.shape[1], ncas, ncas,
                                ncore).transpose(0, 2, 1, 3)
        core_dm = numpy.dot(mo_core, mo_core.T) * 2
    else:
        h1e = eris['h1eff'][ncore:nocc, ncore:nocc]
        h2e = eris['ppaa'][ncore:nocc, ncore:nocc].transpose(0, 2, 1, 3)
        h2e_v1 = eris['ppaa'][nocc:, :ncore].transpose(0, 2, 1, 3)
        h2e_v2 = eris['papa'][nocc:, :, :ncore].transpose(0, 3, 1, 2)
        h1e_v = eris['h1eff'][nocc:, :ncore]

    norm = einsum('rpiq,raib,qpab->ir',h2e_v1,h2e_v1,dm2)*2.0\
         - einsum('rpiq,rabi,qpab->ir',h2e_v1,h2e_v2,dm2)\
         - einsum('rpqi,raib,qpab->ir',h2e_v2,h2e_v1,dm2)\
         + einsum('raqi,rabi,qb->ir',h2e_v2,h2e_v2,dm1)*2.0\
         - einsum('rpqi,rabi,qbap->ir',h2e_v2,h2e_v2,dm2)\
         + einsum('rpqi,raai,qp->ir',h2e_v2,h2e_v2,dm1)\
         + einsum('rpiq,ri,qp->ir',h2e_v1,h1e_v,dm1)*4.0\
         - einsum('rpqi,ri,qp->ir',h2e_v2,h1e_v,dm1)*2.0\
         + einsum('ri,ri->ir',h1e_v,h1e_v)*2.0

    a12 = make_a12(h1e, h2e, dm1, dm2, dm3)
    a13 = make_a13(h1e, h2e, dm1, dm2, dm3)

    h = einsum('rpiq,raib,pqab->ir',h2e_v1,h2e_v1,a12)*2.0\
         - einsum('rpiq,rabi,pqab->ir',h2e_v1,h2e_v2,a12)\
         - einsum('rpqi,raib,pqab->ir',h2e_v2,h2e_v1,a12)\
         + einsum('rpqi,rabi,pqab->ir',h2e_v2,h2e_v2,a13)
    diff = mc.mo_energy[:ncore, None] - mc.mo_energy[None, nocc:]
    return _norm_to_energy(norm, h, -diff)
示例#30
0
def make_a13(h1e, h2e, dm1, dm2, dm3):
    delta = numpy.eye(dm3.shape[0])
    a13 = -einsum('ia,qbip->pqab', h1e, dm2)
    a13 += einsum('pa,qb->pqab', h1e, dm1) * 2.0
    a13 += einsum('bi,qiap->pqab', h1e, dm2)
    a13 -= einsum('pa,bi,qi->pqab', delta, h1e, dm1) * 2.0
    a13 -= einsum('ijka,qbjpik->pqab', h2e, dm3)
    a13 += einsum('kbij,qjapki->pqab', h2e, dm3)
    a13 += einsum('blma,qmlp->pqab', h2e, dm2)
    a13 += einsum('kpma,qbkm->pqab', h2e, dm2) * 2.0
    a13 -= einsum('bpma,qm->pqab', h2e, dm1) * 2.0
    a13 -= einsum('lbkl,qkap->pqab', h2e, dm2)
    a13 -= einsum('ap,mbkl,qlmk->pqab', delta, h2e, dm2) * 2.0
    a13 += einsum('ap,lbkl,qk->pqab', delta, h2e, dm1) * 2.0
    return a13