Exemple #1
0
def make_rdm2(mp, t2=None, ao_repr=False):
    r'''
    Two-particle density matrix in the molecular spin-orbital representation

    dm2[p,q,r,s] = <p^\dagger r^\dagger s q>

    where p,q,r,s are spin-orbitals. p,q correspond to one particle and r,s
    correspond to another particle.  The contraction between ERIs (in
    Chemist's notation) and rdm2 is
    E = einsum('pqrs,pqrs', eri, rdm2)
    '''
    if t2 is None: t2 = mp.t2
    nmo0 = mp.nmo
    nocc = nocc0 = mp.nocc

    if mp.frozen is None:
        dm2 = numpy.zeros((nmo0,nmo0,nmo0,nmo0), dtype=t2.dtype) # Chemist's notation
        #dm2[:nocc,nocc:,:nocc,nocc:] = t2.transpose(0,2,1,3) * .5 - t2.transpose(0,3,1,2) * .5
        # using t2.transpose(0,2,1,3) == -t2.transpose(0,3,1,2)
        dm2[:nocc,nocc:,:nocc,nocc:] = t2.transpose(0,2,1,3)
        dm2[nocc:,:nocc,nocc:,:nocc] = dm2[:nocc,nocc:,:nocc,nocc:].transpose(1,0,3,2).conj()
    else:
        nmo0 = mp.mo_occ.size
        nocc0 = numpy.count_nonzero(mp.mo_occ > 0)
        moidx = mp.get_frozen_mask()
        oidx = numpy.where(moidx & (mp.mo_occ > 0))[0]
        vidx = numpy.where(moidx & (mp.mo_occ ==0))[0]

        dm2 = numpy.zeros((nmo0,nmo0,nmo0,nmo0), dtype=t2.dtype) # Chemist's notation
        dm2[oidx[:,None,None,None],vidx[:,None,None],oidx[:,None],vidx] = \
                t2.transpose(0,2,1,3)
        dm2[nocc0:,:nocc0,nocc0:,:nocc0] = \
                dm2[:nocc0,nocc0:,:nocc0,nocc0:].transpose(1,0,3,2).conj()

    dm1 = make_rdm1(mp, t2)
    dm1[numpy.diag_indices(nocc0)] -= 1

    # Be careful with convention of dm1 and dm2
    #   dm1[q,p] = <p^\dagger q>
    #   dm2[p,q,r,s] = < p^\dagger r^\dagger s q >
    #   E = einsum('pq,qp', h1, dm1) + .5 * einsum('pqrs,pqrs', eri, dm2)
    # When adding dm1 contribution, dm1 subscripts need to be flipped
    for i in range(nocc0):
        dm2[i,i,:,:] += dm1.T
        dm2[:,:,i,i] += dm1.T
        dm2[:,i,i,:] -= dm1.T
        dm2[i,:,:,i] -= dm1

    for i in range(nocc0):
        for j in range(nocc0):
            dm2[i,i,j,j] += 1
            dm2[i,j,j,i] -= 1

    if ao_repr:
        from pyscf.cc import ccsd_rdm
        dm2 = ccsd_rdm._rdm2_mo2ao(dm2, mp.mo_coeff)
    return dm2
Exemple #2
0
def make_rdm2(mp, t2=None, ao_repr=False):
    r'''
    Two-particle spin density matrices dm2aa, dm2ab, dm2bb in MO basis

    dm2aa[p,q,r,s] = <q_alpha^\dagger s_alpha^\dagger r_alpha p_alpha>
    dm2ab[p,q,r,s] = <q_alpha^\dagger s_beta^\dagger r_beta p_alpha>
    dm2bb[p,q,r,s] = <q_beta^\dagger s_beta^\dagger r_beta p_beta>

    (p,q correspond to one particle and r,s correspond to another particle)
    Two-particle density matrix should be contracted to integrals with the
    pattern below to compute energy

    E = numpy.einsum('pqrs,pqrs', eri_aa, dm2_aa)
    E+= numpy.einsum('pqrs,pqrs', eri_ab, dm2_ab)
    E+= numpy.einsum('pqrs,rspq', eri_ba, dm2_ab)
    E+= numpy.einsum('pqrs,pqrs', eri_bb, dm2_bb)

    where eri_aa[p,q,r,s] = (p_alpha q_alpha | r_alpha s_alpha )
    eri_ab[p,q,r,s] = ( p_alpha q_alpha | r_beta s_beta )
    eri_ba[p,q,r,s] = ( p_beta q_beta | r_alpha s_alpha )
    eri_bb[p,q,r,s] = ( p_beta q_beta | r_beta s_beta )
    '''
    if t2 is None: t2 = mp.t2
    nmoa, nmob = nmoa0, nmob0 = mp.nmo
    nocca, noccb = nocca0, noccb0 = mp.nocc
    t2aa, t2ab, t2bb = t2

    if not (mp.frozen is 0 or mp.frozen is None):
        nmoa0 = mp.mo_occ[0].size
        nmob0 = mp.mo_occ[1].size
        nocca0 = numpy.count_nonzero(mp.mo_occ[0] > 0)
        noccb0 = numpy.count_nonzero(mp.mo_occ[1] > 0)
        moidxa, moidxb = mp.get_frozen_mask()
        oidxa = numpy.where(moidxa & (mp.mo_occ[0] > 0))[0]
        vidxa = numpy.where(moidxa & (mp.mo_occ[0] == 0))[0]
        oidxb = numpy.where(moidxb & (mp.mo_occ[1] > 0))[0]
        vidxb = numpy.where(moidxb & (mp.mo_occ[1] == 0))[0]

        dm2aa = numpy.zeros((nmoa0, nmoa0, nmoa0, nmoa0), dtype=t2aa.dtype)
        dm2ab = numpy.zeros((nmoa0, nmoa0, nmob0, nmob0), dtype=t2aa.dtype)
        dm2bb = numpy.zeros((nmob0, nmob0, nmob0, nmob0), dtype=t2aa.dtype)

        tmp = t2aa.transpose(0, 2, 1, 3)
        dm2aa[oidxa[:, None, None, None], vidxa[:, None, None], oidxa[:, None],
              vidxa] = tmp
        dm2aa[vidxa[:, None, None, None], oidxa[:, None, None], vidxa[:, None],
              oidxa] = tmp.conj().transpose(1, 0, 3, 2)

        tmp = t2bb.transpose(0, 2, 1, 3)
        dm2bb[oidxb[:, None, None, None], vidxb[:, None, None], oidxb[:, None],
              vidxb] = tmp
        dm2bb[vidxb[:, None, None, None], oidxb[:, None, None], vidxb[:, None],
              oidxb] = tmp.conj().transpose(1, 0, 3, 2)

        dm2ab[oidxa[:, None, None, None], vidxa[:, None, None], oidxb[:, None],
              vidxb] = t2ab.transpose(0, 2, 1, 3)
        dm2ab[vidxa[:, None, None, None], oidxa[:, None, None], vidxb[:, None],
              oidxb] = t2ab.conj().transpose(2, 0, 3, 1)

    else:
        dm2aa = numpy.zeros((nmoa0, nmoa0, nmoa0, nmoa0), dtype=t2aa.dtype)
        dm2ab = numpy.zeros((nmoa0, nmoa0, nmob0, nmob0), dtype=t2aa.dtype)
        dm2bb = numpy.zeros((nmob0, nmob0, nmob0, nmob0), dtype=t2aa.dtype)

        #:tmp = (t2aa.transpose(0,2,1,3) - t2aa.transpose(0,3,1,2)) * .5
        #: t2aa.transpose(0,2,1,3) == -t2aa.transpose(0,3,1,2)
        tmp = t2aa.transpose(0, 2, 1, 3)
        dm2aa[:nocca0, nocca0:, :nocca0, nocca0:] = tmp
        dm2aa[nocca0:, :nocca0,
              nocca0:, :nocca0] = tmp.conj().transpose(1, 0, 3, 2)

        tmp = t2bb.transpose(0, 2, 1, 3)
        dm2bb[:noccb0, noccb0:, :noccb0, noccb0:] = tmp
        dm2bb[noccb0:, :noccb0,
              noccb0:, :noccb0] = tmp.conj().transpose(1, 0, 3, 2)

        dm2ab[:nocca0, nocca0:, :noccb0, noccb0:] = t2ab.transpose(0, 2, 1, 3)
        dm2ab[nocca0:, :nocca0, noccb0:, :noccb0] = t2ab.transpose(2, 0, 3,
                                                                   1).conj()

    dm1a, dm1b = make_rdm1(mp, t2)
    dm1a[numpy.diag_indices(nocca0)] -= 1
    dm1b[numpy.diag_indices(noccb0)] -= 1

    for i in range(nocca0):
        dm2aa[i, i, :, :] += dm1a.T
        dm2aa[:, :, i, i] += dm1a.T
        dm2aa[:, i, i, :] -= dm1a.T
        dm2aa[i, :, :, i] -= dm1a
        dm2ab[i, i, :, :] += dm1b.T
    for i in range(noccb0):
        dm2bb[i, i, :, :] += dm1b.T
        dm2bb[:, :, i, i] += dm1b.T
        dm2bb[:, i, i, :] -= dm1b.T
        dm2bb[i, :, :, i] -= dm1b
        dm2ab[:, :, i, i] += dm1a.T

    for i in range(nocca0):
        for j in range(nocca0):
            dm2aa[i, i, j, j] += 1
            dm2aa[i, j, j, i] -= 1
    for i in range(noccb0):
        for j in range(noccb0):
            dm2bb[i, i, j, j] += 1
            dm2bb[i, j, j, i] -= 1
    for i in range(nocca0):
        for j in range(noccb0):
            dm2ab[i, i, j, j] += 1

    if ao_repr:
        from pyscf.cc import ccsd_rdm
        from pyscf.cc import uccsd_rdm
        dm2aa = ccsd_rdm._rdm2_mo2ao(dm2aa, mp.mo_coeff[0])
        dm2bb = ccsd_rdm._rdm2_mo2ao(dm2bb, mp.mo_coeff[1])
        dm2ab = uccsd_rdm._dm2ab_mo2ao(dm2ab, mp.mo_coeff[0], mp.mo_coeff[1])
    return dm2aa, dm2ab, dm2bb
Exemple #3
0
def make_rdm2(mp, t2=None, eris=None, ao_repr=False):
    r'''
    Spin-traced two-particle density matrix in MO basis

    dm2[p,q,r,s] = \sum_{sigma,tau} <p_sigma^\dagger r_tau^\dagger s_tau q_sigma>

    Note the contraction between ERIs (in Chemist's notation) and rdm2 is
    E = einsum('pqrs,pqrs', eri, rdm2)
    '''
    if t2 is None: t2 = mp.t2
    nmo = nmo0 = mp.nmo
    nocc = nocc0 = mp.nocc
    nvir = nmo - nocc
    if t2 is None:
        if eris is None:
            eris = mp.ao2mo()
        mo_energy = eris.mo_energy
        eia = mo_energy[:nocc,None] - mo_energy[None,nocc:]

    if mp.frozen is not None:
        nmo0 = mp.mo_occ.size
        nocc0 = numpy.count_nonzero(mp.mo_occ > 0)
        moidx = get_frozen_mask(mp)
        oidx = numpy.where(moidx & (mp.mo_occ > 0))[0]
        vidx = numpy.where(moidx & (mp.mo_occ ==0))[0]
    else:
        moidx = oidx = vidx = None

    dm1 = make_rdm1(mp, t2, eris)
    dm1[numpy.diag_indices(nocc0)] -= 2

    dm2 = numpy.zeros((nmo0,nmo0,nmo0,nmo0), dtype=dm1.dtype) # Chemist notation
    #dm2[:nocc,nocc:,:nocc,nocc:] = t2.transpose(0,3,1,2)*2 - t2.transpose(0,2,1,3)
    #dm2[nocc:,:nocc,nocc:,:nocc] = t2.transpose(3,0,2,1)*2 - t2.transpose(2,0,3,1)
    for i in range(nocc):
        if t2 is None:
            gi = numpy.asarray(eris.ovov[i*nvir:(i+1)*nvir])
            gi = gi.reshape(nvir,nocc,nvir).transpose(1,0,2)
            t2i = gi.conj()/lib.direct_sum('jb+a->jba', eia, eia[i])
        else:
            t2i = t2[i]
        # dm2 was computed as dm2[p,q,r,s] = < p^\dagger r^\dagger s q > in the
        # above. Transposing it so that it be contracted with ERIs (in Chemist's
        # notation):
        #   E = einsum('pqrs,pqrs', eri, rdm2)
        dovov = t2i.transpose(1,0,2)*2 - t2i.transpose(2,0,1)
        dovov *= 2
        if moidx is None:
            dm2[i,nocc:,:nocc,nocc:] = dovov
            dm2[nocc:,i,nocc:,:nocc] = dovov.conj().transpose(0,2,1)
        else:
            dm2[oidx[i],vidx[:,None,None],oidx[:,None],vidx] = dovov
            dm2[vidx[:,None,None],oidx[i],vidx[:,None],oidx] = dovov.conj().transpose(0,2,1)

    # Be careful with convention of dm1 and dm2
    #   dm1[q,p] = <p^\dagger q>
    #   dm2[p,q,r,s] = < p^\dagger r^\dagger s q >
    #   E = einsum('pq,qp', h1, dm1) + .5 * einsum('pqrs,pqrs', eri, dm2)
    # When adding dm1 contribution, dm1 subscripts need to be flipped
    for i in range(nocc0):
        dm2[i,i,:,:] += dm1.T * 2
        dm2[:,:,i,i] += dm1.T * 2
        dm2[:,i,i,:] -= dm1.T
        dm2[i,:,:,i] -= dm1

    for i in range(nocc0):
        for j in range(nocc0):
            dm2[i,i,j,j] += 4
            dm2[i,j,j,i] -= 2

    if ao_repr:
        from pyscf.cc import ccsd_rdm
        dm2 = ccsd_rdm._rdm2_mo2ao(dm2, mp.mo_coeff)
    return dm2
Exemple #4
0
def _make_rdm2(mycc, d1, d2, with_dm1=True, with_frozen=True, ao_repr=False):
    r'''
    dm2[p,q,r,s] = <p^\dagger r^\dagger s q>

    Note the contraction between ERIs (in Chemist's notation) and rdm2 is
    E = einsum('pqrs,pqrs', eri, rdm2)
    '''
    dovov, dvvvv, doooo, doovv, dovvo, dvvov, dovvv, dooov = d2
    nocc, nvir = dovov.shape[:2]
    nmo = nocc + nvir

    dm2 = numpy.empty((nmo, nmo, nmo, nmo), dtype=doooo.dtype)

    dovov = numpy.asarray(dovov)
    dm2[:nocc, nocc:, :nocc, nocc:] = dovov
    dm2[nocc:, :nocc, nocc:, :nocc] = dm2[:nocc, nocc:, :nocc,
                                          nocc:].transpose(1, 0, 3, 2).conj()
    dovov = None

    dovvo = numpy.asarray(dovvo)
    dm2[:nocc, :nocc, nocc:, nocc:] = -dovvo.transpose(0, 3, 2, 1)
    dm2[nocc:, nocc:, :nocc, :nocc] = -dovvo.transpose(2, 1, 0, 3)
    dm2[:nocc, nocc:, nocc:, :nocc] = dovvo
    dm2[nocc:, :nocc, :nocc, nocc:] = dovvo.transpose(1, 0, 3, 2).conj()
    dovvo = None

    dm2[nocc:, nocc:, nocc:, nocc:] = dvvvv
    dm2[:nocc, :nocc, :nocc, :nocc] = doooo

    dovvv = numpy.asarray(dovvv)
    dm2[:nocc, nocc:, nocc:, nocc:] = dovvv
    dm2[nocc:, nocc:, :nocc, nocc:] = dovvv.transpose(2, 3, 0, 1)
    dm2[nocc:, nocc:, nocc:, :nocc] = dovvv.transpose(3, 2, 1, 0).conj()
    dm2[nocc:, :nocc, nocc:, nocc:] = dovvv.transpose(1, 0, 3, 2).conj()
    dovvv = None

    dooov = numpy.asarray(dooov)
    dm2[:nocc, :nocc, :nocc, nocc:] = dooov
    dm2[:nocc, nocc:, :nocc, :nocc] = dooov.transpose(2, 3, 0, 1)
    dm2[:nocc, :nocc, nocc:, :nocc] = dooov.transpose(1, 0, 3, 2).conj()
    dm2[nocc:, :nocc, :nocc, :nocc] = dooov.transpose(3, 2, 1, 0).conj()

    if with_frozen and not (mycc.frozen is 0 or mycc.frozen is None):
        nmo, nmo0 = mycc.mo_occ.size, nmo
        nocc = numpy.count_nonzero(mycc.mo_occ > 0)
        rdm2 = numpy.zeros((nmo, nmo, nmo, nmo), dtype=dm2.dtype)
        moidx = numpy.where(mycc.get_frozen_mask())[0]
        idx = (moidx.reshape(-1, 1) * nmo + moidx).ravel()
        lib.takebak_2d(rdm2.reshape(nmo**2, nmo**2),
                       dm2.reshape(nmo0**2, nmo0**2), idx, idx)
        dm2 = rdm2

    if with_dm1:
        dm1 = _make_rdm1(mycc, d1, with_frozen)
        dm1[numpy.diag_indices(nocc)] -= 1

        for i in range(nocc):
            # Be careful with the convention of dm1 and the transpose of dm2 at the end
            dm2[i, i, :, :] += dm1
            dm2[:, :, i, i] += dm1
            dm2[:, i, i, :] -= dm1
            dm2[i, :, :, i] -= dm1.T

        for i in range(nocc):
            for j in range(nocc):
                dm2[i, i, j, j] += 1
                dm2[i, j, j, i] -= 1

    # dm2 was computed as dm2[p,q,r,s] = < p^\dagger r^\dagger s q > in the
    # above. Transposing it so that it be contracted with ERIs (in Chemist's
    # notation):
    #   E = einsum('pqrs,pqrs', eri, rdm2)
    dm2 = dm2.transpose(1, 0, 3, 2)
    if ao_repr:
        from pyscf.cc import ccsd_rdm
        dm2 = ccsd_rdm._rdm2_mo2ao(dm2, mycc.mo_coeff)
    return dm2
Exemple #5
0
def _make_rdm2(mycc, d1, d2, with_dm1=True, with_frozen=True, ao_repr=False):
    dovov, dovOV, dOVov, dOVOV = d2[0]
    dvvvv, dvvVV, dVVvv, dVVVV = d2[1]
    doooo, dooOO, dOOoo, dOOOO = d2[2]
    doovv, dooVV, dOOvv, dOOVV = d2[3]
    dovvo, dovVO, dOVvo, dOVVO = d2[4]
    dvvov, dvvOV, dVVov, dVVOV = d2[5]
    dovvv, dovVV, dOVvv, dOVVV = d2[6]
    dooov, dooOV, dOOov, dOOOV = d2[7]
    nocca, nvira, noccb, nvirb = dovOV.shape
    nmoa = nocca + nvira
    nmob = noccb + nvirb

    dm2aa = numpy.empty((nmoa, nmoa, nmoa, nmoa), dtype=doovv.dtype)
    dm2ab = numpy.empty((nmoa, nmoa, nmob, nmob), dtype=doovv.dtype)
    dm2bb = numpy.empty((nmob, nmob, nmob, nmob), dtype=doovv.dtype)

    # dm2aa
    dovov = numpy.asarray(dovov)
    dm2aa[:nocca, nocca:, :nocca, nocca:] = dovov
    dm2aa[nocca:, :nocca,
          nocca:, :nocca] = dm2aa[:nocca, nocca:, :nocca,
                                  nocca:].transpose(1, 0, 3, 2).conj()
    dovov = None

    #assert(abs(doovv+dovvo.transpose(0,3,2,1)).max() == 0)
    dovvo = numpy.asarray(dovvo)
    dm2aa[:nocca, :nocca, nocca:, nocca:] = -dovvo.transpose(0, 3, 2, 1)
    dm2aa[nocca:,
          nocca:, :nocca, :nocca] = dm2aa[:nocca, :nocca, nocca:,
                                          nocca:].transpose(2, 3, 0, 1)
    dm2aa[:nocca, nocca:, nocca:, :nocca] = dovvo
    dm2aa[nocca:, :nocca, :nocca,
          nocca:] = dm2aa[:nocca, nocca:,
                          nocca:, :nocca].transpose(1, 0, 3, 2).conj()
    dovvo = None

    if len(dvvvv.shape) == 2:
        dvvvv = ao2mo.restore(1, dvvvv, nvira)
    dm2aa[nocca:, nocca:, nocca:, nocca:] = dvvvv
    dm2aa[:nocca, :nocca, :nocca, :nocca] = doooo

    dovvv = numpy.asarray(dovvv)
    dm2aa[:nocca, nocca:, nocca:, nocca:] = dovvv
    dm2aa[nocca:, nocca:, :nocca, nocca:] = dovvv.transpose(2, 3, 0, 1)
    dm2aa[nocca:, nocca:, nocca:, :nocca] = dovvv.transpose(3, 2, 1, 0).conj()
    dm2aa[nocca:, :nocca, nocca:, nocca:] = dovvv.transpose(1, 0, 3, 2).conj()
    dovvv = None

    dooov = numpy.asarray(dooov)
    dm2aa[:nocca, :nocca, :nocca, nocca:] = dooov
    dm2aa[:nocca, nocca:, :nocca, :nocca] = dooov.transpose(2, 3, 0, 1)
    dm2aa[:nocca, :nocca, nocca:, :nocca] = dooov.transpose(1, 0, 3, 2).conj()
    dm2aa[nocca:, :nocca, :nocca, :nocca] = dooov.transpose(3, 2, 1, 0).conj()
    dooov = None

    # dm2bb
    dOVOV = numpy.asarray(dOVOV)
    dm2bb[:noccb, noccb:, :noccb, noccb:] = dOVOV
    dm2bb[noccb:, :noccb,
          noccb:, :noccb] = dm2bb[:noccb, noccb:, :noccb,
                                  noccb:].transpose(1, 0, 3, 2).conj()
    dOVOV = None

    dOVVO = numpy.asarray(dOVVO)
    dm2bb[:noccb, :noccb, noccb:, noccb:] = -dOVVO.transpose(0, 3, 2, 1)
    dm2bb[noccb:,
          noccb:, :noccb, :noccb] = dm2bb[:noccb, :noccb, noccb:,
                                          noccb:].transpose(2, 3, 0, 1)
    dm2bb[:noccb, noccb:, noccb:, :noccb] = dOVVO
    dm2bb[noccb:, :noccb, :noccb,
          noccb:] = dm2bb[:noccb, noccb:,
                          noccb:, :noccb].transpose(1, 0, 3, 2).conj()
    dOVVO = None

    if len(dVVVV.shape) == 2:
        dVVVV = ao2mo.restore(1, dVVVV, nvirb)
    dm2bb[noccb:, noccb:, noccb:, noccb:] = dVVVV
    dm2bb[:noccb, :noccb, :noccb, :noccb] = dOOOO

    dOVVV = numpy.asarray(dOVVV)
    dm2bb[:noccb, noccb:, noccb:, noccb:] = dOVVV
    dm2bb[noccb:, noccb:, :noccb, noccb:] = dOVVV.transpose(2, 3, 0, 1)
    dm2bb[noccb:, noccb:, noccb:, :noccb] = dOVVV.transpose(3, 2, 1, 0).conj()
    dm2bb[noccb:, :noccb, noccb:, noccb:] = dOVVV.transpose(1, 0, 3, 2).conj()
    dOVVV = None

    dOOOV = numpy.asarray(dOOOV)
    dm2bb[:noccb, :noccb, :noccb, noccb:] = dOOOV
    dm2bb[:noccb, noccb:, :noccb, :noccb] = dOOOV.transpose(2, 3, 0, 1)
    dm2bb[:noccb, :noccb, noccb:, :noccb] = dOOOV.transpose(1, 0, 3, 2).conj()
    dm2bb[noccb:, :noccb, :noccb, :noccb] = dOOOV.transpose(3, 2, 1, 0).conj()
    dOOOV = None

    # dm2ab
    dovOV = numpy.asarray(dovOV)
    dm2ab[:nocca, nocca:, :noccb, noccb:] = dovOV
    dm2ab[nocca:, :nocca,
          noccb:, :noccb] = dm2ab[:nocca, nocca:, :noccb,
                                  noccb:].transpose(1, 0, 3, 2).conj()
    dovOV = None

    dovVO = numpy.asarray(dovVO)
    dm2ab[:nocca, :nocca, noccb:, noccb:] = dooVV
    dm2ab[nocca:, nocca:, :noccb, :noccb] = dOOvv.transpose(2, 3, 0, 1)
    dm2ab[:nocca, nocca:, noccb:, :noccb] = dovVO
    dm2ab[nocca:, :nocca, :noccb, noccb:] = dovVO.transpose(1, 0, 3, 2).conj()
    dovVO = None

    if len(dvvVV.shape) == 2:
        idxa = numpy.tril_indices(nvira)
        dvvVV1 = lib.unpack_tril(dvvVV)
        dvvVV = numpy.empty((nvira, nvira, nvirb, nvirb))
        dvvVV[idxa] = dvvVV1
        dvvVV[idxa[1], idxa[0]] = dvvVV1
        dvvVV1 = None
    dm2ab[nocca:, nocca:, noccb:, noccb:] = dvvVV
    dm2ab[:nocca, :nocca, :noccb, :noccb] = dooOO

    dovVV = numpy.asarray(dovVV)
    dm2ab[:nocca, nocca:, noccb:, noccb:] = dovVV
    dm2ab[nocca:, nocca:, :noccb, noccb:] = dOVvv.transpose(2, 3, 0, 1)
    dm2ab[nocca:, nocca:, noccb:, :noccb] = dOVvv.transpose(3, 2, 1, 0).conj()
    dm2ab[nocca:, :nocca, noccb:, noccb:] = dovVV.transpose(1, 0, 3, 2).conj()
    dovVV = None

    dooOV = numpy.asarray(dooOV)
    dm2ab[:nocca, :nocca, :noccb, noccb:] = dooOV
    dm2ab[:nocca, nocca:, :noccb, :noccb] = dOOov.transpose(2, 3, 0, 1)
    dm2ab[:nocca, :nocca, noccb:, :noccb] = dooOV.transpose(1, 0, 3, 2).conj()
    dm2ab[nocca:, :nocca, :noccb, :noccb] = dOOov.transpose(3, 2, 1, 0).conj()
    dooOV = None

    if with_frozen and not (mycc.frozen is 0 or mycc.frozen is None):
        nmoa0 = dm2aa.shape[0]
        nmob0 = dm2bb.shape[0]
        nmoa = mycc.mo_occ[0].size
        nmob = mycc.mo_occ[1].size
        nocca = numpy.count_nonzero(mycc.mo_occ[0] > 0)
        noccb = numpy.count_nonzero(mycc.mo_occ[1] > 0)

        rdm2aa = numpy.zeros((nmoa, nmoa, nmoa, nmoa), dtype=dm2aa.dtype)
        rdm2ab = numpy.zeros((nmoa, nmoa, nmob, nmob), dtype=dm2ab.dtype)
        rdm2bb = numpy.zeros((nmob, nmob, nmob, nmob), dtype=dm2bb.dtype)
        moidxa, moidxb = mycc.get_frozen_mask()
        moidxa = numpy.where(moidxa)[0]
        moidxb = numpy.where(moidxb)[0]
        idxa = (moidxa.reshape(-1, 1) * nmoa + moidxa).ravel()
        idxb = (moidxb.reshape(-1, 1) * nmob + moidxb).ravel()
        lib.takebak_2d(rdm2aa.reshape(nmoa**2, nmoa**2),
                       dm2aa.reshape(nmoa0**2, nmoa0**2), idxa, idxa)
        lib.takebak_2d(rdm2bb.reshape(nmob**2, nmob**2),
                       dm2bb.reshape(nmob0**2, nmob0**2), idxb, idxb)
        lib.takebak_2d(rdm2ab.reshape(nmoa**2, nmob**2),
                       dm2ab.reshape(nmoa0**2, nmob0**2), idxa, idxb)
        dm2aa, dm2ab, dm2bb = rdm2aa, rdm2ab, rdm2bb

    if with_dm1:
        dm1a, dm1b = _make_rdm1(mycc, d1, with_frozen=True)
        dm1a[numpy.diag_indices(nocca)] -= 1
        dm1b[numpy.diag_indices(noccb)] -= 1

        for i in range(nocca):
            dm2aa[i, i, :, :] += dm1a
            dm2aa[:, :, i, i] += dm1a
            dm2aa[:, i, i, :] -= dm1a
            dm2aa[i, :, :, i] -= dm1a.T
            dm2ab[i, i, :, :] += dm1b
        for i in range(noccb):
            dm2bb[i, i, :, :] += dm1b
            dm2bb[:, :, i, i] += dm1b
            dm2bb[:, i, i, :] -= dm1b
            dm2bb[i, :, :, i] -= dm1b.T
            dm2ab[:, :, i, i] += dm1a

        for i in range(nocca):
            for j in range(nocca):
                dm2aa[i, i, j, j] += 1
                dm2aa[i, j, j, i] -= 1
        for i in range(noccb):
            for j in range(noccb):
                dm2bb[i, i, j, j] += 1
                dm2bb[i, j, j, i] -= 1
        for i in range(nocca):
            for j in range(noccb):
                dm2ab[i, i, j, j] += 1

    dm2aa = dm2aa.transpose(1, 0, 3, 2)
    dm2ab = dm2ab.transpose(1, 0, 3, 2)
    dm2bb = dm2bb.transpose(1, 0, 3, 2)

    if ao_repr:
        from pyscf.cc import ccsd_rdm
        dm2aa = ccsd_rdm._rdm2_mo2ao(dm2aa, mycc.mo_coeff[0])
        dm2bb = ccsd_rdm._rdm2_mo2ao(dm2bb, mycc.mo_coeff[1])
        dm2ab = _dm2ab_mo2ao(dm2ab, mycc.mo_coeff[0], mycc.mo_coeff[1])
    return dm2aa, dm2ab, dm2bb