Example #1
0
    def test_ccsd_t_complex(self):
        mol = gto.M()
        numpy.random.seed(12)
        nocc, nvir = 3, 4
        nmo = nocc + nvir
        eris = cc.rccsd._ChemistsERIs()
        eri1 = (numpy.random.random(
            (nmo, nmo, nmo, nmo)) + numpy.random.random(
                (nmo, nmo, nmo, nmo)) * .8j - .5 - .4j)
        eri1 = eri1 + eri1.transpose(1, 0, 2, 3)
        eri1 = eri1 + eri1.transpose(0, 1, 3, 2)
        eri1 = eri1 + eri1.transpose(2, 3, 0, 1)
        eri1 *= .1
        eris.ovvv = eri1[:nocc, nocc:, nocc:, nocc:]
        eris.ovoo = eri1[:nocc, nocc:, :nocc, :nocc]
        eris.ovov = eri1[:nocc, nocc:, :nocc, nocc:]
        t1 = (numpy.random.random((nocc, nvir)) * .1 + numpy.random.random(
            (nocc, nvir)) * .1j)
        t2 = (numpy.random.random(
            (nocc, nocc, nvir, nvir)) * .1 + numpy.random.random(
                (nocc, nocc, nvir, nvir)) * .1j)
        t2 = t2 + t2.transpose(1, 0, 3, 2)
        mf = scf.RHF(mol)
        mcc = cc.CCSD(mf)
        f = (numpy.random.random((nmo, nmo)) * .1 + numpy.random.random(
            (nmo, nmo)) * .1j)
        eris.fock = f + f.T.conj() + numpy.diag(numpy.arange(nmo))
        eris.mo_energy = eris.fock.diagonal().real
        e0 = ccsd_t.kernel(mcc, eris, t1, t2)

        eri2 = numpy.zeros((nmo * 2, nmo * 2, nmo * 2, nmo * 2),
                           dtype=numpy.complex128)
        orbspin = numpy.zeros(nmo * 2, dtype=int)
        orbspin[1::2] = 1
        eri2[0::2, 0::2, 0::2, 0::2] = eri1
        eri2[1::2, 1::2, 0::2, 0::2] = eri1
        eri2[0::2, 0::2, 1::2, 1::2] = eri1
        eri2[1::2, 1::2, 1::2, 1::2] = eri1
        eri2 = eri2.transpose(0, 2, 1, 3) - eri2.transpose(0, 2, 3, 1)
        fock = numpy.zeros((nmo * 2, nmo * 2), dtype=numpy.complex128)
        fock[0::2, 0::2] = eris.fock
        fock[1::2, 1::2] = eris.fock
        eris1 = gccsd._PhysicistsERIs()
        eris1.ovvv = eri2[:nocc * 2, nocc * 2:, nocc * 2:, nocc * 2:]
        eris1.oovv = eri2[:nocc * 2, :nocc * 2, nocc * 2:, nocc * 2:]
        eris1.ooov = eri2[:nocc * 2, :nocc * 2, :nocc * 2, nocc * 2:]
        eris1.fock = fock
        eris1.mo_energy = fock.diagonal().real
        t1 = gccsd.spatial2spin(t1, orbspin)
        t2 = gccsd.spatial2spin(t2, orbspin)
        gcc = gccsd.GCCSD(scf.GHF(gto.M()))
        e1 = gccsd_t.kernel(gcc, eris1, t1, t2)
        self.assertAlmostEqual(e0, e1.real, 9)
        self.assertAlmostEqual(e1,
                               -0.98756910139720788 - 0.0019567929592079489j,
                               9)
Example #2
0
    def test_ccsd_t_complex(self):
        mol = gto.M()
        numpy.random.seed(12)
        nocc, nvir = 3, 4
        nmo = nocc + nvir
        eris = cc.rccsd._ChemistsERIs()
        eri1 = (numpy.random.random((nmo,nmo,nmo,nmo)) +
                numpy.random.random((nmo,nmo,nmo,nmo)) * .8j - .5-.4j)
        eri1 = eri1 + eri1.transpose(1,0,2,3)
        eri1 = eri1 + eri1.transpose(0,1,3,2)
        eri1 = eri1 + eri1.transpose(2,3,0,1)
        eri1 *= .1
        eris.ovvv = eri1[:nocc,nocc:,nocc:,nocc:]
        eris.ovoo = eri1[:nocc,nocc:,:nocc,:nocc]
        eris.ovov = eri1[:nocc,nocc:,:nocc,nocc:]
        t1 = (numpy.random.random((nocc,nvir)) * .1 +
              numpy.random.random((nocc,nvir)) * .1j)
        t2 = (numpy.random.random((nocc,nocc,nvir,nvir)) * .1 +
              numpy.random.random((nocc,nocc,nvir,nvir)) * .1j)
        t2 = t2 + t2.transpose(1,0,3,2)
        mf = scf.RHF(mol)
        mcc = cc.CCSD(mf)
        f = (numpy.random.random((nmo,nmo)) * .1 +
             numpy.random.random((nmo,nmo)) * .1j)
        eris.fock = f+f.T.conj() + numpy.diag(numpy.arange(nmo))
        eris.mo_energy = eris.fock.diagonal().real
        e0 = ccsd_t.kernel(mcc, eris, t1, t2)

        eri2 = numpy.zeros((nmo*2,nmo*2,nmo*2,nmo*2), dtype=numpy.complex)
        orbspin = numpy.zeros(nmo*2,dtype=int)
        orbspin[1::2] = 1
        eri2[0::2,0::2,0::2,0::2] = eri1
        eri2[1::2,1::2,0::2,0::2] = eri1
        eri2[0::2,0::2,1::2,1::2] = eri1
        eri2[1::2,1::2,1::2,1::2] = eri1
        eri2 = eri2.transpose(0,2,1,3) - eri2.transpose(0,2,3,1)
        fock = numpy.zeros((nmo*2,nmo*2), dtype=numpy.complex)
        fock[0::2,0::2] = eris.fock
        fock[1::2,1::2] = eris.fock
        eris1 = gccsd._PhysicistsERIs()
        eris1.ovvv = eri2[:nocc*2,nocc*2:,nocc*2:,nocc*2:]
        eris1.oovv = eri2[:nocc*2,:nocc*2,nocc*2:,nocc*2:]
        eris1.ooov = eri2[:nocc*2,:nocc*2,:nocc*2,nocc*2:]
        eris1.fock = fock
        eris1.mo_energy = fock.diagonal().real
        t1 = gccsd.spatial2spin(t1, orbspin)
        t2 = gccsd.spatial2spin(t2, orbspin)
        gcc = gccsd.GCCSD(scf.GHF(gto.M()))
        e1 = gccsd_t.kernel(gcc, eris1, t1, t2)
        self.assertAlmostEqual(e0, e1.real, 9)
        self.assertAlmostEqual(e1, -0.98756910139720788-0.0019567929592079489j, 9)
Example #3
0
    t2 = np.random.random((nocc, nocc, nvir, nvir)) - .5
    t2 = t2 + np.sin(t2) * .1j
    t2 = t2 + t2.transpose(1, 0, 3, 2)

    mycc = RCCSD(mf)
    t1new_ref, t2new_ref = update_amps(mycc, t1, t2, eris)

    orbspin = np.zeros(nao * 2, dtype=int)
    orbspin[1::2] = 1
    eri1 = np.zeros([nao * 2] * 4, dtype=np.complex)
    eri1[0::2,0::2,0::2,0::2] = \
    eri1[0::2,0::2,1::2,1::2] = \
    eri1[1::2,1::2,0::2,0::2] = \
    eri1[1::2,1::2,1::2,1::2] = eri0
    eri1 = eri1.transpose(0, 2, 1, 3) - eri1.transpose(0, 2, 3, 1)
    erig = gccsd._PhysicistsERIs(mol)
    nocc *= 2
    nvir *= 2
    erig.oooo = eri1[:nocc, :nocc, :nocc, :nocc].copy()
    erig.ooov = eri1[:nocc, :nocc, :nocc, nocc:].copy()
    erig.ovov = eri1[:nocc, nocc:, :nocc, nocc:].copy()
    erig.ovvo = eri1[:nocc, nocc:, nocc:, :nocc].copy()
    erig.oovv = eri1[:nocc, :nocc, nocc:, nocc:].copy()
    erig.ovvv = eri1[:nocc, nocc:, nocc:, nocc:].copy()
    erig.vvvv = eri1[nocc:, nocc:, nocc:, nocc:].copy()
    mo_e = np.array([mf.mo_energy] * 2)
    erig.fock = np.diag(mo_e.T.ravel())

    myccg = gccsd.GCCSD(scf.addons.convert_to_ghf(mf))
    t1, t2 = myccg.amplitudes_from_ccsd(t1, t2)
    t1new, t2new = gccsd.update_amps(myccg, t1, t2, erig)
Example #4
0
    def test_update_amps2(self):  # compare to gccsd.update_amps
        mol = mol_s2
        mf = mf_s2
        myucc = uccsd.UCCSD(mf)
        nocca, noccb = 6, 4
        nmo = mol.nao_nr()
        nvira, nvirb = nmo - nocca, nmo - noccb
        numpy.random.seed(9)
        t1 = [
            numpy.random.random((nocca, nvira)) - .9,
            numpy.random.random((noccb, nvirb)) - .9
        ]
        t2 = [
            numpy.random.random((nocca, nocca, nvira, nvira)) - .9,
            numpy.random.random((nocca, noccb, nvira, nvirb)) - .9,
            numpy.random.random((noccb, noccb, nvirb, nvirb)) - .9
        ]
        t2[0] = t2[0] - t2[0].transpose(1, 0, 2, 3)
        t2[0] = t2[0] - t2[0].transpose(0, 1, 3, 2)
        t2[2] = t2[2] - t2[2].transpose(1, 0, 2, 3)
        t2[2] = t2[2] - t2[2].transpose(0, 1, 3, 2)

        mo_a = mf.mo_coeff[0] + numpy.sin(mf.mo_coeff[0]) * .01j
        mo_b = mf.mo_coeff[1] + numpy.sin(mf.mo_coeff[1]) * .01j
        nao = mo_a.shape[0]
        eri = ao2mo.restore(1, mf._eri, nao)
        eri0aa = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_a.conj(), mo_a,
                            mo_a.conj(), mo_a)
        eri0ab = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_a.conj(), mo_a,
                            mo_b.conj(), mo_b)
        eri0bb = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_b.conj(), mo_b,
                            mo_b.conj(), mo_b)
        eri0ba = eri0ab.transpose(2, 3, 0, 1)

        nvira = nao - nocca
        nvirb = nao - noccb
        eris = uccsd._ChemistsERIs(mol)
        eris.oooo = eri0aa[:nocca, :nocca, :nocca, :nocca].copy()
        eris.ovoo = eri0aa[:nocca, nocca:, :nocca, :nocca].copy()
        eris.oovv = eri0aa[:nocca, :nocca, nocca:, nocca:].copy()
        eris.ovvo = eri0aa[:nocca, nocca:, nocca:, :nocca].copy()
        eris.ovov = eri0aa[:nocca, nocca:, :nocca, nocca:].copy()
        eris.ovvv = eri0aa[:nocca, nocca:, nocca:, nocca:].copy()
        eris.vvvv = eri0aa[nocca:, nocca:, nocca:, nocca:].copy()

        eris.OOOO = eri0bb[:noccb, :noccb, :noccb, :noccb].copy()
        eris.OVOO = eri0bb[:noccb, noccb:, :noccb, :noccb].copy()
        eris.OOVV = eri0bb[:noccb, :noccb, noccb:, noccb:].copy()
        eris.OVVO = eri0bb[:noccb, noccb:, noccb:, :noccb].copy()
        eris.OVOV = eri0bb[:noccb, noccb:, :noccb, noccb:].copy()
        eris.OVVV = eri0bb[:noccb, noccb:, noccb:, noccb:].copy()
        eris.VVVV = eri0bb[noccb:, noccb:, noccb:, noccb:].copy()

        eris.ooOO = eri0ab[:nocca, :nocca, :noccb, :noccb].copy()
        eris.ovOO = eri0ab[:nocca, nocca:, :noccb, :noccb].copy()
        eris.ooVV = eri0ab[:nocca, :nocca, noccb:, noccb:].copy()
        eris.ovVO = eri0ab[:nocca, nocca:, noccb:, :noccb].copy()
        eris.ovOV = eri0ab[:nocca, nocca:, :noccb, noccb:].copy()
        eris.ovVV = eri0ab[:nocca, nocca:, noccb:, noccb:].copy()
        eris.vvVV = eri0ab[nocca:, nocca:, noccb:, noccb:].copy()

        eris.OOoo = eri0ba[:noccb, :noccb, :nocca, :nocca].copy()
        eris.OVoo = eri0ba[:noccb, noccb:, :nocca, :nocca].copy()
        eris.OOvv = eri0ba[:noccb, :noccb, nocca:, nocca:].copy()
        eris.OVvo = eri0ba[:noccb, noccb:, nocca:, :nocca].copy()
        eris.OVov = eri0ba[:noccb, noccb:, :nocca, nocca:].copy()
        eris.OVvv = eri0ba[:noccb, noccb:, nocca:, nocca:].copy()
        eris.VVvv = eri0ba[noccb:, noccb:, nocca:, nocca:].copy()

        eris.focka = numpy.diag(mf.mo_energy[0])
        eris.fockb = numpy.diag(mf.mo_energy[1])
        eris.mo_energy = mf.mo_energy

        t1[0] = t1[0] + numpy.sin(t1[0]) * .05j
        t1[1] = t1[1] + numpy.sin(t1[1]) * .05j
        t2[0] = t2[0] + numpy.sin(t2[0]) * .05j
        t2[1] = t2[1] + numpy.sin(t2[1]) * .05j
        t2[2] = t2[2] + numpy.sin(t2[2]) * .05j
        t1new_ref, t2new_ref = uccsd.update_amps(myucc, t1, t2, eris)

        nocc = nocca + noccb
        orbspin = numpy.zeros(nao * 2, dtype=int)
        orbspin[1::2] = 1
        orbspin[nocc - 1] = 0
        orbspin[nocc] = 1
        eri1 = numpy.zeros([nao * 2] * 4, dtype=numpy.complex)
        idxa = numpy.where(orbspin == 0)[0]
        idxb = numpy.where(orbspin == 1)[0]
        eri1[idxa[:, None, None, None], idxa[:, None, None], idxa[:, None],
             idxa] = eri0aa
        eri1[idxa[:, None, None, None], idxa[:, None, None], idxb[:, None],
             idxb] = eri0ab
        eri1[idxb[:, None, None, None], idxb[:, None, None], idxa[:, None],
             idxa] = eri0ba
        eri1[idxb[:, None, None, None], idxb[:, None, None], idxb[:, None],
             idxb] = eri0bb
        eri1 = eri1.transpose(0, 2, 1, 3) - eri1.transpose(0, 2, 3, 1)
        erig = gccsd._PhysicistsERIs()
        erig.oooo = eri1[:nocc, :nocc, :nocc, :nocc].copy()
        erig.ooov = eri1[:nocc, :nocc, :nocc, nocc:].copy()
        erig.ovov = eri1[:nocc, nocc:, :nocc, nocc:].copy()
        erig.ovvo = eri1[:nocc, nocc:, nocc:, :nocc].copy()
        erig.oovv = eri1[:nocc, :nocc, nocc:, nocc:].copy()
        erig.ovvv = eri1[:nocc, nocc:, nocc:, nocc:].copy()
        erig.vvvv = eri1[nocc:, nocc:, nocc:, nocc:].copy()
        mo_e = numpy.empty(nao * 2)
        mo_e[orbspin == 0] = mf.mo_energy[0]
        mo_e[orbspin == 1] = mf.mo_energy[1]
        erig.fock = numpy.diag(mo_e)
        erig.mo_energy = mo_e.real

        myccg = gccsd.GCCSD(scf.addons.convert_to_ghf(mf))
        t1 = myccg.spatial2spin(t1, orbspin)
        t2 = myccg.spatial2spin(t2, orbspin)
        t1new, t2new = gccsd.update_amps(myccg, t1, t2, erig)
        t1new = myccg.spin2spatial(t1new, orbspin)
        t2new = myccg.spin2spatial(t2new, orbspin)
        self.assertAlmostEqual(abs(t1new[0] - t1new_ref[0]).max(), 0, 12)
        self.assertAlmostEqual(abs(t1new[1] - t1new_ref[1]).max(), 0, 12)
        self.assertAlmostEqual(abs(t2new[0] - t2new_ref[0]).max(), 0, 12)
        self.assertAlmostEqual(abs(t2new[1] - t2new_ref[1]).max(), 0, 12)
        self.assertAlmostEqual(abs(t2new[2] - t2new_ref[2]).max(), 0, 12)
Example #5
0
    def test_update_lambda_complex(self):
        mo_coeff = mf.mo_coeff + np.sin(mf.mo_coeff) * .01j
        nao = mo_coeff.shape[0]
        eri = ao2mo.restore(1, mf._eri, nao)
        eri0 = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_coeff.conj(),
                          mo_coeff, mo_coeff.conj(), mo_coeff)

        nocc, nvir = 5, nao - 5
        eris = rccsd._ChemistsERIs(mol)
        eris.oooo = eri0[:nocc, :nocc, :nocc, :nocc].copy()
        eris.ovoo = eri0[:nocc, nocc:, :nocc, :nocc].copy()
        eris.oovv = eri0[:nocc, :nocc, nocc:, nocc:].copy()
        eris.ovvo = eri0[:nocc, nocc:, nocc:, :nocc].copy()
        eris.ovov = eri0[:nocc, nocc:, :nocc, nocc:].copy()
        eris.ovvv = eri0[:nocc, nocc:, nocc:, nocc:].copy()
        eris.vvvv = eri0[nocc:, nocc:, nocc:, nocc:].copy()
        eris.fock = np.diag(mf.mo_energy)

        np.random.seed(1)
        t1 = np.random.random((nocc, nvir)) + np.random.random(
            (nocc, nvir)) * .1j - .5
        t2 = np.random.random((nocc, nocc, nvir, nvir)) - .5
        t2 = t2 + np.sin(t2) * .1j
        t2 = t2 + t2.transpose(1, 0, 3, 2)

        l1 = np.random.random((nocc, nvir)) + np.random.random(
            (nocc, nvir)) * .1j - .5
        l2 = np.random.random((nocc, nocc, nvir, nvir)) - .5
        l2 = l2 + np.sin(l2) * .1j
        l2 = l2 + l2.transpose(1, 0, 3, 2)
        mycc = rccsd.RCCSD(mf)
        imds = rccsd_lambda.make_intermediates(mycc, t1, t2, eris)
        l1new_ref, l2new_ref = rccsd_lambda.update_lambda(
            mycc, t1, t2, l1, l2, eris, imds)

        orbspin = np.zeros(nao * 2, dtype=int)
        orbspin[1::2] = 1
        eri1 = np.zeros([nao * 2] * 4, dtype=np.complex128)
        eri1[0::2,0::2,0::2,0::2] = \
        eri1[0::2,0::2,1::2,1::2] = \
        eri1[1::2,1::2,0::2,0::2] = \
        eri1[1::2,1::2,1::2,1::2] = eri0
        eri1 = eri1.transpose(0, 2, 1, 3) - eri1.transpose(0, 2, 3, 1)
        erig = gccsd._PhysicistsERIs(mol)
        nocc *= 2
        nvir *= 2
        erig.oooo = eri1[:nocc, :nocc, :nocc, :nocc].copy()
        erig.ooov = eri1[:nocc, :nocc, :nocc, nocc:].copy()
        erig.ovov = eri1[:nocc, nocc:, :nocc, nocc:].copy()
        erig.ovvo = eri1[:nocc, nocc:, nocc:, :nocc].copy()
        erig.oovv = eri1[:nocc, :nocc, nocc:, nocc:].copy()
        erig.ovvv = eri1[:nocc, nocc:, nocc:, nocc:].copy()
        erig.vvvv = eri1[nocc:, nocc:, nocc:, nocc:].copy()
        mo_e = np.array([mf.mo_energy] * 2)
        erig.fock = np.diag(mo_e.T.ravel())
        erig.mo_energy = erig.fock.diagonal()

        myccg = gccsd.GCCSD(scf.addons.convert_to_ghf(mf))
        t1, t2 = myccg.amplitudes_from_ccsd(t1, t2)
        l1, l2 = myccg.amplitudes_from_ccsd(l1, l2)
        imds = gccsd_lambda.make_intermediates(myccg, t1, t2, erig)
        l1new, l2new = gccsd_lambda.update_lambda(myccg, t1, t2, l1, l2, erig,
                                                  imds)
        self.assertAlmostEqual(float(abs(l1new[0::2, 0::2] - l1new_ref).max()),
                               0, 9)
        l2aa = l2new[0::2, 0::2, 0::2, 0::2]
        l2ab = l2new[0::2, 1::2, 0::2, 1::2]
        self.assertAlmostEqual(float(abs(l2ab - l2new_ref).max()), 0, 9)
        self.assertAlmostEqual(
            float(abs(l2ab - l2ab.transpose(1, 0, 2, 3) - l2aa).max()), 0, 9)
Example #6
0
def _make_eris_incore_ghf(mycc, mo_coeff=None, ao2mofn=None):
    """
    Make physist eri with incore ao2mo, for GGHF.
    """
    cput0 = (logger.process_clock(), logger.perf_counter())
    log = logger.Logger(mycc.stdout, mycc.verbose)
    _sync_(mycc)
    eris = gccsd._PhysicistsERIs()
    
    if rank == 0:
        eris._common_init_(mycc, mo_coeff)
        comm.bcast((eris.mo_coeff, eris.fock, eris.nocc, eris.mo_energy))
    else:
        eris.mol = mycc.mol
        eris.mo_coeff, eris.fock, eris.nocc, eris.mo_energy = comm.bcast(None)
    
    nocc = eris.nocc
    nao, nmo = eris.mo_coeff.shape

    nvir = nmo - nocc
    vlocs = [_task_location(nvir, task_id) for task_id in range(mpi.pool.size)]
    vloc0, vloc1 = vlocs[rank]
    vseg = vloc1 - vloc0
    
    if rank == 0:
        if callable(ao2mofn):
            raise NotImplementedError
        else:
            assert eris.mo_coeff.dtype == np.double
            eri = mycc._scf._eri
            if (nao == nmo) and (la.norm(eris.mo_coeff - np.eye(nmo)) < 1e-12):
                # ZHC NOTE special treatment for OO-CCD,
                # where the ao2mo is not needed for identity mo_coeff.
                from libdmet.utils import take_eri as fn
                o = np.arange(0, nocc)
                v = np.arange(nocc, nmo)
                if eri.size == nmo**4:
                    eri = ao2mo.restore(8, eri, nmo)
            else:
                if mycc.save_mem:
                    # ZHC NOTE the following is slower, although may save some memory.
                    def fn(x, mo0, mo1, mo2, mo3):
                        return ao2mo.general(x, (mo0, mo1, mo2, mo3),
                                             compact=False).reshape(mo0.shape[-1], mo1.shape[-1],
                                                                    mo2.shape[-1], mo3.shape[-1])
                    o = eris.mo_coeff[:, :nocc]
                    v = eris.mo_coeff[:, nocc:]
                    if eri.size == nao**4:
                        eri = ao2mo.restore(8, eri, nao)
                else:
                    from libdmet.utils import take_eri as fn
                    o = np.arange(0, nocc)
                    v = np.arange(nocc, nmo)
                    if mycc.remove_h2:
                        mycc._scf._eri = None
                        _release_regs(mycc, remove_h2=True)
                    eri = ao2mo.kernel(eri, eris.mo_coeff)
                    if eri.size == nmo**4:
                        eri = ao2mo.restore(8, eri, nmo)

    comm.Barrier()
    cput2 = log.timer('CCSD ao2mo initialization:     ', *cput0)
    
    # chunck and scatter:
    
    # 1. oooo
    if rank == 0:
        tmp = fn(eri, o, o, o, o)
        eris.oooo = tmp.transpose(0, 2, 1, 3) - tmp.transpose(0, 2, 3, 1)
        tmp = None
        mpi.bcast(eris.oooo)
    else:
        eris.oooo = mpi.bcast(None)
    cput3 = log.timer('CCSD bcast   oooo:              ', *cput2)
    
    # 2. xooo
    if rank == 0:
        tmp = fn(eri, v, o, o, o)
        eri_sliced = [tmp[p0:p1] for (p0, p1) in vlocs]
    else:
        tmp = None
        eri_sliced = None
    tmp = mpi.scatter_new(eri_sliced, root=0, data=tmp)
    eri_sliced = None
    eris.xooo = tmp.transpose(0, 2, 1, 3) - tmp.transpose(0, 2, 3, 1)
    tmp = None
    cput4 = log.timer('CCSD scatter xooo:              ', *cput3)
    
    # 3. xovo
    if rank == 0:
        tmp_vvoo = fn(eri, v, v, o, o)
        tmp_voov = fn(eri, v, o, o, v)
        # ZHC NOTE need to keep tmp_voov for xvoo
        eri_1 = [tmp_vvoo[p0:p1] for (p0, p1) in vlocs]
        eri_2 = [tmp_voov[p0:p1] for (p0, p1) in vlocs]
    else:
        tmp_vvoo = None
        tmp_voov = None
        eri_1 = None
        eri_2 = None

    tmp_1 = mpi.scatter_new(eri_1, root=0, data=tmp_vvoo)
    eri_1 = None
    tmp_vvoo = None
    
    tmp_2 = mpi.scatter_new(eri_2, root=0, data=tmp_voov)
    eri_2 = None
    tmp_voov = None
    
    eris.xovo = tmp_1.transpose(0, 2, 1, 3) - tmp_2.transpose(0, 2, 3, 1)
    tmp_1 = None
    cput5 = log.timer('CCSD scatter xovo:              ', *cput4)
    
    # 4. xvoo
    eris.xvoo = tmp_2.transpose(0, 3, 1, 2) - tmp_2.transpose(0, 3, 2, 1)
    tmp_2 = None
    cput6 = log.timer('CCSD scatter xvoo:              ', *cput5)
    
    # 5. 6. xovv, xvvo
    if rank == 0:
        tmp = fn(eri, v, v, o, v)
        eri_sliced = [tmp[p0:p1] for (p0, p1) in vlocs]
    else:
        tmp = None
        eri_sliced = None
    tmp_1 = mpi.scatter_new(eri_sliced, root=0, data=tmp)
    eri_sliced = None
    eris.xovv = tmp_1.transpose(0, 2, 1, 3) - tmp_1.transpose(0, 2, 3, 1)

    if rank == 0:
        tmp_2 = np.asarray(tmp.transpose(3, 2, 1, 0), order='C') # vovv
        tmp = None
        eri_sliced = [tmp_2[p0:p1] for (p0, p1) in vlocs]
    else:
        tmp_2 = None
        tmp = None
        eri_sliced = None
    tmp_2 = mpi.scatter_new(eri_sliced, root=0, data=tmp_2)
    eri_sliced = None
    
    eris.xvvo = tmp_1.transpose(0, 3, 1, 2) - tmp_2.transpose(0, 2, 3, 1)
    tmp_1 = None
    tmp_2 = None
    cput7 = log.timer('CCSD scatter xovv, xvvo:        ', *cput6)

    # 7. xvvv
    if rank == 0:
        tmp = fn(eri, v, v, v, v)
        if mycc.remove_h2:
            eri = None
            if mycc._scf is not None:
                mycc._scf._eri = None
        eri_sliced = [tmp[p0:p1] for (p0, p1) in vlocs]
    else:
        tmp = None
        eri_sliced = None
    tmp = mpi.scatter_new(eri_sliced, root=0, data=tmp)
    eri_sliced = None
    eris.xvvv = tmp.transpose(0, 2, 1, 3) - tmp.transpose(0, 2, 3, 1)
    tmp = None
    eri = None
    cput8 = log.timer('CCSD scatter xvvv:              ', *cput7)
    
    mycc._eris = eris
    log.timer('CCSD integral transformation   ', *cput0)
    return eris
Example #7
0
def _make_eris_incore(mycc, mo_coeff=None, ao2mofn=None):
    """
    Make physist eri with incore ao2mo.
    """
    cput0 = (logger.process_clock(), logger.perf_counter())
    log = logger.Logger(mycc.stdout, mycc.verbose)
    _sync_(mycc)
    eris = gccsd._PhysicistsERIs()
    
    if rank == 0:
        eris._common_init_(mycc, mo_coeff)
        comm.bcast((eris.mo_coeff, eris.fock, eris.nocc, eris.mo_energy))
    else:
        eris.mol = mycc.mol
        eris.mo_coeff, eris.fock, eris.nocc, eris.mo_energy = comm.bcast(None)
    
    # if workers does not have _eri, bcast from root
    if comm.allreduce(mycc._scf._eri is None, op=mpi.MPI.LOR):
        if rank == 0:
            mpi.bcast(mycc._scf._eri)
        else:
            mycc._scf._eri = mpi.bcast(None)
    cput1 = log.timer('CCSD ao2mo initialization:     ', *cput0)

    nocc = eris.nocc
    nao, nmo = eris.mo_coeff.shape
    nvir = nmo - nocc
    vlocs = [_task_location(nvir, task_id) for task_id in range(mpi.pool.size)]
    vloc0, vloc1 = vlocs[rank]
    vseg = vloc1 - vloc0
    
    plocs = [_task_location(nmo, task_id) for task_id in range(mpi.pool.size)]
    ploc0, ploc1 = plocs[rank]
    pseg = ploc1 - ploc0
    
    mo_a = eris.mo_coeff[:nao//2]
    mo_b = eris.mo_coeff[nao//2:]
    mo_seg_a = mo_a[:, ploc0:ploc1]
    mo_seg_b = mo_b[:, ploc0:ploc1]
    
    fname = "gccsd_eri_tmp_%s.h5"%rank
    f = h5py.File(fname, 'w')
    eri_phys = f.create_dataset('eri_phys', (pseg, nmo, nmo, nmo), 'f8', 
                                chunks=(pseg, 1, nmo, nmo))
    
    eri_a = ao2mo.incore.half_e1(mycc._scf._eri, (mo_seg_a, mo_a), compact=False)
    eri_b = ao2mo.incore.half_e1(mycc._scf._eri, (mo_seg_b, mo_b), compact=False)
    cput1 = log.timer('CCSD ao2mo half_e1:            ', *cput1)

    unit = pseg * nmo * nmo * 2
    mem_now = lib.current_memory()[0]
    max_memory = max(0, mycc.max_memory - mem_now)
    blksize = min(nmo, max(BLKMIN, int((max_memory*0.9e6/8)/unit)))

    for p0, p1 in lib.prange(0, nmo, blksize):
        klmosym_a, nkl_pair_a, mokl_a, klshape_a = \
                ao2mo.incore._conc_mos(mo_a[:, p0:p1], mo_a, compact=False)
        klmosym_b, nkl_pair_b, mokl_b, klshape_b = \
                ao2mo.incore._conc_mos(mo_b[:, p0:p1], mo_b, compact=False)
        
        eri  = _ao2mo.nr_e2(eri_a, mokl_a, klshape_a, aosym='s4', mosym=klmosym_a)
        eri += _ao2mo.nr_e2(eri_a, mokl_b, klshape_b, aosym='s4', mosym=klmosym_b)
        eri += _ao2mo.nr_e2(eri_b, mokl_a, klshape_a, aosym='s4', mosym=klmosym_a)
        eri += _ao2mo.nr_e2(eri_b, mokl_b, klshape_b, aosym='s4', mosym=klmosym_b)
        
        eri = eri.reshape(pseg, nmo, p1-p0, nmo)
        eri_phys[:, p0:p1] = eri.transpose(0, 2, 1, 3) - eri.transpose(0, 2, 3, 1)
        eri = None
    eri_a = None
    eri_b = None
    
    f.close()
    comm.Barrier()
    cput1 = log.timer('CCSD ao2mo nr_e2:              ', *cput1)

    o_idx = -1
    v_idx = mpi.pool.size
    for r, (p0, p1) in enumerate(plocs):
        if p0 <= nocc - 1 < p1:
            o_idx = r
        if p0 <= nocc < p1:
            v_idx = r
            break
    o_files = np.arange(mpi.pool.size)[:(o_idx+1)]
    v_files = np.arange(mpi.pool.size)[v_idx:]

    eris.oooo = np.empty((nocc, nocc, nocc, nocc))
    eris.xooo = np.empty((vseg, nocc, nocc, nocc))
    eris.xovo = np.empty((vseg, nocc, nvir, nocc))
    eris.xovv = np.empty((vseg, nocc, nvir, nvir))
    eris.xvvo = np.empty((vseg, nvir, nvir, nocc))
    eris.xvoo = np.empty((vseg, nvir, nocc, nocc))
    eris.xvvv = np.empty((vseg, nvir, nvir, nvir))
    for r in range(mpi.pool.size):
        f = lib.H5TmpFile(filename="gccsd_eri_tmp_%s.h5"%r, mode='r')
        eri_phys = f["eri_phys"]
        if r in o_files:
            p0, p1 = plocs[r]
            p1 = min(p1, nocc)
            pseg = p1 - p0
            if pseg > 0:
                eris.oooo[p0:p1] = eri_phys[:pseg, :nocc, :nocc, :nocc]
        
        if r in v_files:
            p00, p10 = plocs[r]
            p0 = max(p00, nocc+vloc0)
            p1 = min(p10, nocc+vloc1)
            pseg = p1 - p0
            if pseg > 0:
                eris.xooo[p0-(nocc+vloc0):p1-(nocc+vloc0)] = eri_phys[p0-p00:p1-p00, :nocc, :nocc, :nocc]
                eris.xovo[p0-(nocc+vloc0):p1-(nocc+vloc0)] = eri_phys[p0-p00:p1-p00, :nocc, nocc:, :nocc]
                eris.xvoo[p0-(nocc+vloc0):p1-(nocc+vloc0)] = eri_phys[p0-p00:p1-p00, nocc:, :nocc, :nocc]
                eris.xvvo[p0-(nocc+vloc0):p1-(nocc+vloc0)] = eri_phys[p0-p00:p1-p00, nocc:, nocc:, :nocc]
                eris.xovv[p0-(nocc+vloc0):p1-(nocc+vloc0)] = eri_phys[p0-p00:p1-p00, :nocc, nocc:, nocc:]
                eris.xvvv[p0-(nocc+vloc0):p1-(nocc+vloc0)] = eri_phys[p0-p00:p1-p00, nocc:, nocc:, nocc:]
    cput1 = log.timer('CCSD ao2mo load:               ', *cput1)

    f.close() 
    comm.Barrier()
    os.remove("gccsd_eri_tmp_%s.h5"%rank)
    mycc._eris = eris
    log.timer('CCSD integral transformation   ', *cput0)
    return eris
Example #8
0
    t2 = np.random.random((nocc,nocc,nvir,nvir)) - .5
    t2 = t2 + np.sin(t2) * .1j
    t2 = t2 + t2.transpose(1,0,3,2)

    mycc = RCCSD(mf)
    t1new_ref, t2new_ref = update_amps(mycc, t1, t2, eris)

    orbspin = np.zeros(nao*2, dtype=int)
    orbspin[1::2] = 1
    eri1 = np.zeros([nao*2]*4, dtype=np.complex)
    eri1[0::2,0::2,0::2,0::2] = \
    eri1[0::2,0::2,1::2,1::2] = \
    eri1[1::2,1::2,0::2,0::2] = \
    eri1[1::2,1::2,1::2,1::2] = eri0
    eri1 = eri1.transpose(0,2,1,3) - eri1.transpose(0,2,3,1)
    erig = gccsd._PhysicistsERIs(mol)
    nocc *= 2
    nvir *= 2
    erig.oooo = eri1[:nocc,:nocc,:nocc,:nocc].copy()
    erig.ooov = eri1[:nocc,:nocc,:nocc,nocc:].copy()
    erig.ovov = eri1[:nocc,nocc:,:nocc,nocc:].copy()
    erig.ovvo = eri1[:nocc,nocc:,nocc:,:nocc].copy()
    erig.oovv = eri1[:nocc,:nocc,nocc:,nocc:].copy()
    erig.ovvv = eri1[:nocc,nocc:,nocc:,nocc:].copy()
    erig.vvvv = eri1[nocc:,nocc:,nocc:,nocc:].copy()
    mo_e = np.array([mf.mo_energy]*2)
    erig.fock = np.diag(mo_e.T.ravel())

    myccg = gccsd.GCCSD(scf.addons.convert_to_ghf(mf))
    t1, t2 = myccg.amplitudes_from_ccsd(t1, t2)
    t1new, t2new = gccsd.update_amps(myccg, t1, t2, erig)
Example #9
0
    def test_update_amps2(self):  # compare to gccsd.update_amps
        mol = mol_s2
        mf = mf_s2
        myucc = uccsd.UCCSD(mf)
        nocca, noccb = 6,4
        nmo = mol.nao_nr()
        nvira,nvirb = nmo-nocca, nmo-noccb
        numpy.random.seed(9)
        t1 = [numpy.random.random((nocca,nvira))-.9,
              numpy.random.random((noccb,nvirb))-.9]
        t2 = [numpy.random.random((nocca,nocca,nvira,nvira))-.9,
              numpy.random.random((nocca,noccb,nvira,nvirb))-.9,
              numpy.random.random((noccb,noccb,nvirb,nvirb))-.9]
        t2[0] = t2[0] - t2[0].transpose(1,0,2,3)
        t2[0] = t2[0] - t2[0].transpose(0,1,3,2)
        t2[2] = t2[2] - t2[2].transpose(1,0,2,3)
        t2[2] = t2[2] - t2[2].transpose(0,1,3,2)

        mo_a = mf.mo_coeff[0] + numpy.sin(mf.mo_coeff[0]) * .01j
        mo_b = mf.mo_coeff[1] + numpy.sin(mf.mo_coeff[1]) * .01j
        nao = mo_a.shape[0]
        eri = ao2mo.restore(1, mf._eri, nao)
        eri0aa = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_a.conj(), mo_a, mo_a.conj(), mo_a)
        eri0ab = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_a.conj(), mo_a, mo_b.conj(), mo_b)
        eri0bb = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_b.conj(), mo_b, mo_b.conj(), mo_b)
        eri0ba = eri0ab.transpose(2,3,0,1)

        nvira = nao - nocca
        nvirb = nao - noccb
        eris = uccsd._ChemistsERIs(mol)
        eris.oooo = eri0aa[:nocca,:nocca,:nocca,:nocca].copy()
        eris.ovoo = eri0aa[:nocca,nocca:,:nocca,:nocca].copy()
        eris.oovv = eri0aa[:nocca,:nocca,nocca:,nocca:].copy()
        eris.ovvo = eri0aa[:nocca,nocca:,nocca:,:nocca].copy()
        eris.ovov = eri0aa[:nocca,nocca:,:nocca,nocca:].copy()
        eris.ovvv = eri0aa[:nocca,nocca:,nocca:,nocca:].copy()
        eris.vvvv = eri0aa[nocca:,nocca:,nocca:,nocca:].copy()

        eris.OOOO = eri0bb[:noccb,:noccb,:noccb,:noccb].copy()
        eris.OVOO = eri0bb[:noccb,noccb:,:noccb,:noccb].copy()
        eris.OOVV = eri0bb[:noccb,:noccb,noccb:,noccb:].copy()
        eris.OVVO = eri0bb[:noccb,noccb:,noccb:,:noccb].copy()
        eris.OVOV = eri0bb[:noccb,noccb:,:noccb,noccb:].copy()
        eris.OVVV = eri0bb[:noccb,noccb:,noccb:,noccb:].copy()
        eris.VVVV = eri0bb[noccb:,noccb:,noccb:,noccb:].copy()

        eris.ooOO = eri0ab[:nocca,:nocca,:noccb,:noccb].copy()
        eris.ovOO = eri0ab[:nocca,nocca:,:noccb,:noccb].copy()
        eris.ooVV = eri0ab[:nocca,:nocca,noccb:,noccb:].copy()
        eris.ovVO = eri0ab[:nocca,nocca:,noccb:,:noccb].copy()
        eris.ovOV = eri0ab[:nocca,nocca:,:noccb,noccb:].copy()
        eris.ovVV = eri0ab[:nocca,nocca:,noccb:,noccb:].copy()
        eris.vvVV = eri0ab[nocca:,nocca:,noccb:,noccb:].copy()

        eris.OOoo = eri0ba[:noccb,:noccb,:nocca,:nocca].copy()
        eris.OVoo = eri0ba[:noccb,noccb:,:nocca,:nocca].copy()
        eris.OOvv = eri0ba[:noccb,:noccb,nocca:,nocca:].copy()
        eris.OVvo = eri0ba[:noccb,noccb:,nocca:,:nocca].copy()
        eris.OVov = eri0ba[:noccb,noccb:,:nocca,nocca:].copy()
        eris.OVvv = eri0ba[:noccb,noccb:,nocca:,nocca:].copy()
        eris.VVvv = eri0ba[noccb:,noccb:,nocca:,nocca:].copy()

        eris.focka = numpy.diag(mf.mo_energy[0])
        eris.fockb = numpy.diag(mf.mo_energy[1])
        eris.mo_energy = mf.mo_energy

        t1[0] = t1[0] + numpy.sin(t1[0]) * .05j
        t1[1] = t1[1] + numpy.sin(t1[1]) * .05j
        t2[0] = t2[0] + numpy.sin(t2[0]) * .05j
        t2[1] = t2[1] + numpy.sin(t2[1]) * .05j
        t2[2] = t2[2] + numpy.sin(t2[2]) * .05j
        t1new_ref, t2new_ref = uccsd.update_amps(myucc, t1, t2, eris)

        nocc = nocca + noccb
        orbspin = numpy.zeros(nao*2, dtype=int)
        orbspin[1::2] = 1
        orbspin[nocc-1] = 0
        orbspin[nocc  ] = 1
        eri1 = numpy.zeros([nao*2]*4, dtype=numpy.complex)
        idxa = numpy.where(orbspin == 0)[0]
        idxb = numpy.where(orbspin == 1)[0]
        eri1[idxa[:,None,None,None],idxa[:,None,None],idxa[:,None],idxa] = eri0aa
        eri1[idxa[:,None,None,None],idxa[:,None,None],idxb[:,None],idxb] = eri0ab
        eri1[idxb[:,None,None,None],idxb[:,None,None],idxa[:,None],idxa] = eri0ba
        eri1[idxb[:,None,None,None],idxb[:,None,None],idxb[:,None],idxb] = eri0bb
        eri1 = eri1.transpose(0,2,1,3) - eri1.transpose(0,2,3,1)
        erig = gccsd._PhysicistsERIs()
        erig.oooo = eri1[:nocc,:nocc,:nocc,:nocc].copy()
        erig.ooov = eri1[:nocc,:nocc,:nocc,nocc:].copy()
        erig.ovov = eri1[:nocc,nocc:,:nocc,nocc:].copy()
        erig.ovvo = eri1[:nocc,nocc:,nocc:,:nocc].copy()
        erig.oovv = eri1[:nocc,:nocc,nocc:,nocc:].copy()
        erig.ovvv = eri1[:nocc,nocc:,nocc:,nocc:].copy()
        erig.vvvv = eri1[nocc:,nocc:,nocc:,nocc:].copy()
        mo_e = numpy.empty(nao*2)
        mo_e[orbspin==0] = mf.mo_energy[0]
        mo_e[orbspin==1] = mf.mo_energy[1]
        erig.fock = numpy.diag(mo_e)
        erig.mo_energy = mo_e.real

        myccg = gccsd.GCCSD(scf.addons.convert_to_ghf(mf))
        t1 = myccg.spatial2spin(t1, orbspin)
        t2 = myccg.spatial2spin(t2, orbspin)
        t1new, t2new = gccsd.update_amps(myccg, t1, t2, erig)
        t1new = myccg.spin2spatial(t1new, orbspin)
        t2new = myccg.spin2spatial(t2new, orbspin)
        self.assertAlmostEqual(abs(t1new[0] - t1new_ref[0]).max(), 0, 12)
        self.assertAlmostEqual(abs(t1new[1] - t1new_ref[1]).max(), 0, 12)
        self.assertAlmostEqual(abs(t2new[0] - t2new_ref[0]).max(), 0, 12)
        self.assertAlmostEqual(abs(t2new[1] - t2new_ref[1]).max(), 0, 12)
        self.assertAlmostEqual(abs(t2new[2] - t2new_ref[2]).max(), 0, 12)
Example #10
0
    def test_update_lambda_complex(self):
        nocca, noccb = mol.nelec
        nmo = mol.nao_nr()
        nvira, nvirb = nmo - nocca, nmo - noccb
        numpy.random.seed(9)
        t1 = [
            numpy.random.random((nocca, nvira)) - .9,
            numpy.random.random((noccb, nvirb)) - .9
        ]
        l1 = [
            numpy.random.random((nocca, nvira)) - .9,
            numpy.random.random((noccb, nvirb)) - .9
        ]
        t2 = [
            numpy.random.random((nocca, nocca, nvira, nvira)) - .9,
            numpy.random.random((nocca, noccb, nvira, nvirb)) - .9,
            numpy.random.random((noccb, noccb, nvirb, nvirb)) - .9
        ]
        t2[0] = t2[0] - t2[0].transpose(1, 0, 2, 3)
        t2[0] = t2[0] - t2[0].transpose(0, 1, 3, 2)
        t2[2] = t2[2] - t2[2].transpose(1, 0, 2, 3)
        t2[2] = t2[2] - t2[2].transpose(0, 1, 3, 2)
        l2 = [
            numpy.random.random((nocca, nocca, nvira, nvira)) - .9,
            numpy.random.random((nocca, noccb, nvira, nvirb)) - .9,
            numpy.random.random((noccb, noccb, nvirb, nvirb)) - .9
        ]
        l2[0] = l2[0] - l2[0].transpose(1, 0, 2, 3)
        l2[0] = l2[0] - l2[0].transpose(0, 1, 3, 2)
        l2[2] = l2[2] - l2[2].transpose(1, 0, 2, 3)
        l2[2] = l2[2] - l2[2].transpose(0, 1, 3, 2)

        #        eris = mycc.ao2mo()
        #        imds = make_intermediates(mycc, t1, t2, eris)
        #        l1new, l2new = update_lambda(mycc, t1, t2, l1, l2, eris, imds)
        #        print(lib.finger(l1new[0]) --104.55975252585894)
        #        print(lib.finger(l1new[1]) --241.12677819375281)
        #        print(lib.finger(l2new[0]) --0.4957533529669417)
        #        print(lib.finger(l2new[1]) - 15.46423057451851 )
        #        print(lib.finger(l2new[2]) - 5.8430776663704407)

        nocca, noccb = mol.nelec
        mo_a = mf.mo_coeff[0] + numpy.sin(mf.mo_coeff[0]) * .01j
        mo_b = mf.mo_coeff[1] + numpy.sin(mf.mo_coeff[1]) * .01j
        nao = mo_a.shape[0]
        eri = ao2mo.restore(1, mf._eri, nao)
        eri0aa = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_a.conj(), mo_a,
                            mo_a.conj(), mo_a)
        eri0ab = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_a.conj(), mo_a,
                            mo_b.conj(), mo_b)
        eri0bb = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_b.conj(), mo_b,
                            mo_b.conj(), mo_b)
        eri0ba = eri0ab.transpose(2, 3, 0, 1)

        nvira = nao - nocca
        nvirb = nao - noccb
        eris = uccsd._ChemistsERIs(mol)
        eris.oooo = eri0aa[:nocca, :nocca, :nocca, :nocca].copy()
        eris.ovoo = eri0aa[:nocca, nocca:, :nocca, :nocca].copy()
        eris.oovv = eri0aa[:nocca, :nocca, nocca:, nocca:].copy()
        eris.ovvo = eri0aa[:nocca, nocca:, nocca:, :nocca].copy()
        eris.ovov = eri0aa[:nocca, nocca:, :nocca, nocca:].copy()
        eris.ovvv = eri0aa[:nocca, nocca:, nocca:, nocca:].copy()
        eris.vvvv = eri0aa[nocca:, nocca:, nocca:, nocca:].copy()

        eris.OOOO = eri0bb[:noccb, :noccb, :noccb, :noccb].copy()
        eris.OVOO = eri0bb[:noccb, noccb:, :noccb, :noccb].copy()
        eris.OOVV = eri0bb[:noccb, :noccb, noccb:, noccb:].copy()
        eris.OVVO = eri0bb[:noccb, noccb:, noccb:, :noccb].copy()
        eris.OVOV = eri0bb[:noccb, noccb:, :noccb, noccb:].copy()
        eris.OVVV = eri0bb[:noccb, noccb:, noccb:, noccb:].copy()
        eris.VVVV = eri0bb[noccb:, noccb:, noccb:, noccb:].copy()

        eris.ooOO = eri0ab[:nocca, :nocca, :noccb, :noccb].copy()
        eris.ovOO = eri0ab[:nocca, nocca:, :noccb, :noccb].copy()
        eris.ooVV = eri0ab[:nocca, :nocca, noccb:, noccb:].copy()
        eris.ovVO = eri0ab[:nocca, nocca:, noccb:, :noccb].copy()
        eris.ovOV = eri0ab[:nocca, nocca:, :noccb, noccb:].copy()
        eris.ovVV = eri0ab[:nocca, nocca:, noccb:, noccb:].copy()
        eris.vvVV = eri0ab[nocca:, nocca:, noccb:, noccb:].copy()

        eris.OOoo = eri0ba[:noccb, :noccb, :nocca, :nocca].copy()
        eris.OVoo = eri0ba[:noccb, noccb:, :nocca, :nocca].copy()
        eris.OOvv = eri0ba[:noccb, :noccb, nocca:, nocca:].copy()
        eris.OVvo = eri0ba[:noccb, noccb:, nocca:, :nocca].copy()
        eris.OVov = eri0ba[:noccb, noccb:, :nocca, nocca:].copy()
        eris.OVvv = eri0ba[:noccb, noccb:, nocca:, nocca:].copy()
        eris.VVvv = eri0ba[noccb:, noccb:, nocca:, nocca:].copy()

        eris.focka = numpy.diag(mf.mo_energy[0])
        eris.fockb = numpy.diag(mf.mo_energy[1])

        t1[0] = t1[0] + numpy.sin(t1[0]) * .05j
        t1[1] = t1[1] + numpy.sin(t1[1]) * .05j
        t2[0] = t2[0] + numpy.sin(t2[0]) * .05j
        t2[1] = t2[1] + numpy.sin(t2[1]) * .05j
        t2[2] = t2[2] + numpy.sin(t2[2]) * .05j
        l1[0] = l1[0] + numpy.sin(l1[0]) * .05j
        l1[1] = l1[1] + numpy.sin(l1[1]) * .05j
        l2[0] = l2[0] + numpy.sin(l2[0]) * .05j
        l2[1] = l2[1] + numpy.sin(l2[1]) * .05j
        l2[2] = l2[2] + numpy.sin(l2[2]) * .05j
        imds = uccsd_lambda.make_intermediates(mycc, t1, t2, eris)
        l1new_ref, l2new_ref = uccsd_lambda.update_lambda(
            mycc, t1, t2, l1, l2, eris, imds)

        nocc = nocca + noccb
        orbspin = numpy.zeros(nao * 2, dtype=int)
        orbspin[1::2] = 1
        orbspin[nocc - 1] = 0
        orbspin[nocc] = 1
        eri1 = numpy.zeros([nao * 2] * 4, dtype=numpy.complex)
        idxa = numpy.where(orbspin == 0)[0]
        idxb = numpy.where(orbspin == 1)[0]
        eri1[idxa[:, None, None, None], idxa[:, None, None], idxa[:, None],
             idxa] = eri0aa
        eri1[idxa[:, None, None, None], idxa[:, None, None], idxb[:, None],
             idxb] = eri0ab
        eri1[idxb[:, None, None, None], idxb[:, None, None], idxa[:, None],
             idxa] = eri0ba
        eri1[idxb[:, None, None, None], idxb[:, None, None], idxb[:, None],
             idxb] = eri0bb
        eri1 = eri1.transpose(0, 2, 1, 3) - eri1.transpose(0, 2, 3, 1)
        erig = gccsd._PhysicistsERIs()
        erig.oooo = eri1[:nocc, :nocc, :nocc, :nocc].copy()
        erig.ooov = eri1[:nocc, :nocc, :nocc, nocc:].copy()
        erig.ovov = eri1[:nocc, nocc:, :nocc, nocc:].copy()
        erig.ovvo = eri1[:nocc, nocc:, nocc:, :nocc].copy()
        erig.oovv = eri1[:nocc, :nocc, nocc:, nocc:].copy()
        erig.ovvv = eri1[:nocc, nocc:, nocc:, nocc:].copy()
        erig.vvvv = eri1[nocc:, nocc:, nocc:, nocc:].copy()
        mo_e = numpy.empty(nao * 2)
        mo_e[orbspin == 0] = mf.mo_energy[0]
        mo_e[orbspin == 1] = mf.mo_energy[1]
        erig.fock = numpy.diag(mo_e)

        myccg = gccsd.GCCSD(scf.addons.convert_to_ghf(mf))
        t1 = myccg.spatial2spin(t1, orbspin)
        t2 = myccg.spatial2spin(t2, orbspin)
        l1 = myccg.spatial2spin(l1, orbspin)
        l2 = myccg.spatial2spin(l2, orbspin)
        imds = gccsd_lambda.make_intermediates(myccg, t1, t2, erig)
        l1new, l2new = gccsd_lambda.update_lambda(myccg, t1, t2, l1, l2, erig,
                                                  imds)
        l1new = myccg.spin2spatial(l1new, orbspin)
        l2new = myccg.spin2spatial(l2new, orbspin)
        self.assertAlmostEqual(abs(l1new[0] - l1new_ref[0]).max(), 0, 11)
        self.assertAlmostEqual(abs(l1new[1] - l1new_ref[1]).max(), 0, 11)
        self.assertAlmostEqual(abs(l2new[0] - l2new_ref[0]).max(), 0, 11)
        self.assertAlmostEqual(abs(l2new[1] - l2new_ref[1]).max(), 0, 11)
        self.assertAlmostEqual(abs(l2new[2] - l2new_ref[2]).max(), 0, 11)
Example #11
0
def _make_eris_incore(cc, mo_coeff=None):
    from pyscf.pbc import tools
    from pyscf.pbc.cc.ccsd import _adjust_occ

    log = logger.Logger(cc.stdout, cc.verbose)
    cput0 = (time.clock(), time.time())
    eris = gccsd._PhysicistsERIs()
    cell = cc._scf.cell
    kpts = cc.kpts
    nkpts = cc.nkpts
    nocc = cc.nocc
    nmo = cc.nmo
    nvir = nmo - nocc
    eris.nocc = nocc

    #if any(nocc != numpy.count_nonzero(cc._scf.mo_occ[k] > 0) for k in range(nkpts)):
    #    raise NotImplementedError('Different occupancies found for different k-points')

    if mo_coeff is None:
        mo_coeff = cc.mo_coeff

    nao = mo_coeff[0].shape[0]
    dtype = mo_coeff[0].dtype

    moidx = get_frozen_mask(cc)
    nocc_per_kpt = numpy.asarray(get_nocc(cc, per_kpoint=True))
    nmo_per_kpt  = numpy.asarray(get_nmo(cc, per_kpoint=True))

    padded_moidx = []
    for k in range(nkpts):
        kpt_nocc = nocc_per_kpt[k]
        kpt_nvir = nmo_per_kpt[k] - kpt_nocc
        kpt_padded_moidx = numpy.concatenate((numpy.ones(kpt_nocc, dtype=numpy.bool),
                                              numpy.zeros(nmo - kpt_nocc - kpt_nvir, dtype=numpy.bool),
                                              numpy.ones(kpt_nvir, dtype=numpy.bool)))
        padded_moidx.append(kpt_padded_moidx)

    eris.mo_coeff = []
    eris.orbspin = []
    # Generate the molecular orbital coefficients with the frozen orbitals masked.
    # Each MO is tagged with orbspin, a list of 0's and 1's that give the overall
    # spin of each MO.
    #
    # Here we will work with two index arrays; one is for our original (small) moidx
    # array while the next is for our new (large) padded array.
    for k in range(nkpts):
        kpt_moidx = moidx[k]
        kpt_padded_moidx = padded_moidx[k]

        mo = numpy.zeros((nao, nmo), dtype=dtype)
        mo[:, kpt_padded_moidx] = mo_coeff[k][:, kpt_moidx]
        if getattr(mo_coeff[k], 'orbspin', None) is not None:
            orbspin_dtype = mo_coeff[k].orbspin[kpt_moidx].dtype
            orbspin = numpy.zeros(nmo, dtype=orbspin_dtype)
            orbspin[kpt_padded_moidx] = mo_coeff[k].orbspin[kpt_moidx]
            mo = lib.tag_array(mo, orbspin=orbspin)
            eris.orbspin.append(orbspin)
        # FIXME: What if the user freezes all up spin orbitals in
        # an RHF calculation?  The number of electrons will still be
        # even.
        else:  # guess orbital spin - assumes an RHF calculation
            assert (numpy.count_nonzero(kpt_moidx) % 2 == 0)
            orbspin = numpy.zeros(mo.shape[1], dtype=int)
            orbspin[1::2] = 1
            mo = lib.tag_array(mo, orbspin=orbspin)
            eris.orbspin.append(orbspin)
        eris.mo_coeff.append(mo)

    # Re-make our fock MO matrix elements from density and fock AO
    dm = cc._scf.make_rdm1(cc.mo_coeff, cc.mo_occ)
    with lib.temporary_env(cc._scf, exxdiv=None):
        # _scf.exxdiv affects eris.fock. HF exchange correction should be
        # excluded from the Fock matrix.
        fockao = cc._scf.get_hcore() + cc._scf.get_veff(cell, dm)
    eris.fock = numpy.asarray([reduce(numpy.dot, (mo.T.conj(), fockao[k], mo))
                               for k, mo in enumerate(eris.mo_coeff)])

    eris.mo_energy = [eris.fock[k].diagonal().real for k in range(nkpts)]
    # Add HFX correction in the eris.mo_energy to improve convergence in
    # CCSD iteration. It is useful for the 2D systems since their occupied and
    # the virtual orbital energies may overlap which may lead to numerical
    # issue in the CCSD iterations.
    # FIXME: Whether to add this correction for other exxdiv treatments?
    # Without the correction, MP2 energy may be largely off the correct value.
    madelung = tools.madelung(cell, kpts)
    eris.mo_energy = [_adjust_occ(mo_e, nocc, -madelung)
                      for k, mo_e in enumerate(eris.mo_energy)]

    # Get location of padded elements in occupied and virtual space.
    nocc_per_kpt = get_nocc(cc, per_kpoint=True)
    nonzero_padding = padding_k_idx(cc, kind="joint")

    # Check direct and indirect gaps for possible issues with CCSD convergence.
    mo_e = [eris.mo_energy[kp][nonzero_padding[kp]] for kp in range(nkpts)]
    mo_e = numpy.sort([y for x in mo_e for y in x])  # Sort de-nested array
    gap = mo_e[numpy.sum(nocc_per_kpt)] - mo_e[numpy.sum(nocc_per_kpt)-1]
    if gap < 1e-5:
        logger.warn(cc, 'H**O-LUMO gap %s too small for KCCSD. '
                        'May cause issues in convergence.', gap)

    kconserv = kpts_helper.get_kconserv(cell, kpts)
    if getattr(mo_coeff[0], 'orbspin', None) is None:
        # The bottom nao//2 coefficients are down (up) spin while the top are up (down).
        mo_a_coeff = [mo[:nao // 2] for mo in eris.mo_coeff]
        mo_b_coeff = [mo[nao // 2:] for mo in eris.mo_coeff]

        eri = numpy.empty((nkpts, nkpts, nkpts, nmo, nmo, nmo, nmo), dtype=numpy.complex128)
        fao2mo = cc._scf.with_df.ao2mo
        for kp, kq, kr in kpts_helper.loop_kkk(nkpts):
            ks = kconserv[kp, kq, kr]
            eri_kpt = fao2mo(
                (mo_a_coeff[kp], mo_a_coeff[kq], mo_a_coeff[kr], mo_a_coeff[ks]), (kpts[kp], kpts[kq], kpts[kr], kpts[ks]),
                compact=False)
            eri_kpt += fao2mo(
                (mo_b_coeff[kp], mo_b_coeff[kq], mo_b_coeff[kr], mo_b_coeff[ks]), (kpts[kp], kpts[kq], kpts[kr], kpts[ks]),
                compact=False)
            eri_kpt += fao2mo(
                (mo_a_coeff[kp], mo_a_coeff[kq], mo_b_coeff[kr], mo_b_coeff[ks]), (kpts[kp], kpts[kq], kpts[kr], kpts[ks]),
                compact=False)
            eri_kpt += fao2mo(
                (mo_b_coeff[kp], mo_b_coeff[kq], mo_a_coeff[kr], mo_a_coeff[ks]), (kpts[kp], kpts[kq], kpts[kr], kpts[ks]),
                compact=False)

            eri_kpt = eri_kpt.reshape(nmo, nmo, nmo, nmo)
            eri[kp, kq, kr] = eri_kpt
    else:
        mo_a_coeff = [mo[:nao // 2] + mo[nao // 2:] for mo in eris.mo_coeff]

        eri = numpy.empty((nkpts, nkpts, nkpts, nmo, nmo, nmo, nmo), dtype=numpy.complex128)
        fao2mo = cc._scf.with_df.ao2mo
        for kp, kq, kr in kpts_helper.loop_kkk(nkpts):
            ks = kconserv[kp, kq, kr]
            eri_kpt = fao2mo(
                (mo_a_coeff[kp], mo_a_coeff[kq], mo_a_coeff[kr], mo_a_coeff[ks]), (kpts[kp], kpts[kq], kpts[kr], kpts[ks]),
                compact=False)

            eri_kpt[(eris.orbspin[kp][:, None] != eris.orbspin[kq]).ravel()] = 0
            eri_kpt[:, (eris.orbspin[kr][:, None] != eris.orbspin[ks]).ravel()] = 0
            eri_kpt = eri_kpt.reshape(nmo, nmo, nmo, nmo)
            eri[kp, kq, kr] = eri_kpt

    # Check some antisymmetrized properties of the integrals
    if DEBUG:
        check_antisymm_3412(cc, cc.kpts, eri)

    # Antisymmetrizing (pq|rs)-(ps|rq), where the latter integral is equal to
    # (rq|ps); done since we aren't tracking the kpoint of orbital 's'
    eri = eri - eri.transpose(2, 1, 0, 5, 4, 3, 6)
    # Chemist -> physics notation
    eri = eri.transpose(0, 2, 1, 3, 5, 4, 6)

    # Set the various integrals
    eris.dtype = eri.dtype
    eris.oooo = eri[:, :, :, :nocc, :nocc, :nocc, :nocc].copy() / nkpts
    eris.ooov = eri[:, :, :, :nocc, :nocc, :nocc, nocc:].copy() / nkpts
    eris.ovoo = eri[:, :, :, :nocc, nocc:, :nocc, :nocc].copy() / nkpts
    eris.oovv = eri[:, :, :, :nocc, :nocc, nocc:, nocc:].copy() / nkpts
    eris.ovov = eri[:, :, :, :nocc, nocc:, :nocc, nocc:].copy() / nkpts
    eris.ovvv = eri[:, :, :, :nocc, nocc:, nocc:, nocc:].copy() / nkpts
    eris.vvvv = eri[:, :, :, nocc:, nocc:, nocc:, nocc:].copy() / nkpts

    log.timer('CCSD integral transformation', *cput0)
    return eris
Example #12
0
    def test_update_lambda_complex(self):
        mo_coeff = mf.mo_coeff + np.sin(mf.mo_coeff) * .01j
        nao = mo_coeff.shape[0]
        eri = ao2mo.restore(1, mf._eri, nao)
        eri0 = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_coeff.conj(), mo_coeff,
                          mo_coeff.conj(), mo_coeff)

        nocc, nvir = 5, nao-5
        eris = rccsd._ChemistsERIs(mol)
        eris.oooo = eri0[:nocc,:nocc,:nocc,:nocc].copy()
        eris.ovoo = eri0[:nocc,nocc:,:nocc,:nocc].copy()
        eris.oovv = eri0[:nocc,:nocc,nocc:,nocc:].copy()
        eris.ovvo = eri0[:nocc,nocc:,nocc:,:nocc].copy()
        eris.ovov = eri0[:nocc,nocc:,:nocc,nocc:].copy()
        eris.ovvv = eri0[:nocc,nocc:,nocc:,nocc:].copy()
        eris.vvvv = eri0[nocc:,nocc:,nocc:,nocc:].copy()
        eris.fock = np.diag(mf.mo_energy)

        np.random.seed(1)
        t1 = np.random.random((nocc,nvir)) + np.random.random((nocc,nvir))*.1j - .5
        t2 = np.random.random((nocc,nocc,nvir,nvir)) - .5
        t2 = t2 + np.sin(t2) * .1j
        t2 = t2 + t2.transpose(1,0,3,2)

        l1 = np.random.random((nocc,nvir)) + np.random.random((nocc,nvir))*.1j - .5
        l2 = np.random.random((nocc,nocc,nvir,nvir)) - .5
        l2 = l2 + np.sin(l2) * .1j
        l2 = l2 + l2.transpose(1,0,3,2)
        mycc = rccsd.RCCSD(mf)
        imds = rccsd_lambda.make_intermediates(mycc, t1, t2, eris)
        l1new_ref, l2new_ref = rccsd_lambda.update_lambda(mycc, t1, t2, l1, l2, eris, imds)

        orbspin = np.zeros(nao*2, dtype=int)
        orbspin[1::2] = 1
        eri1 = np.zeros([nao*2]*4, dtype=np.complex)
        eri1[0::2,0::2,0::2,0::2] = \
        eri1[0::2,0::2,1::2,1::2] = \
        eri1[1::2,1::2,0::2,0::2] = \
        eri1[1::2,1::2,1::2,1::2] = eri0
        eri1 = eri1.transpose(0,2,1,3) - eri1.transpose(0,2,3,1)
        erig = gccsd._PhysicistsERIs(mol)
        nocc *= 2
        nvir *= 2
        erig.oooo = eri1[:nocc,:nocc,:nocc,:nocc].copy()
        erig.ooov = eri1[:nocc,:nocc,:nocc,nocc:].copy()
        erig.ovov = eri1[:nocc,nocc:,:nocc,nocc:].copy()
        erig.ovvo = eri1[:nocc,nocc:,nocc:,:nocc].copy()
        erig.oovv = eri1[:nocc,:nocc,nocc:,nocc:].copy()
        erig.ovvv = eri1[:nocc,nocc:,nocc:,nocc:].copy()
        erig.vvvv = eri1[nocc:,nocc:,nocc:,nocc:].copy()
        mo_e = np.array([mf.mo_energy]*2)
        erig.fock = np.diag(mo_e.T.ravel())
        erig.mo_energy = erig.fock.diagonal()

        myccg = gccsd.GCCSD(scf.addons.convert_to_ghf(mf))
        t1, t2 = myccg.amplitudes_from_ccsd(t1, t2)
        l1, l2 = myccg.amplitudes_from_ccsd(l1, l2)
        imds = gccsd_lambda.make_intermediates(myccg, t1, t2, erig)
        l1new, l2new = gccsd_lambda.update_lambda(myccg, t1, t2, l1, l2, erig, imds)
        self.assertAlmostEqual(float(abs(l1new[0::2,0::2]-l1new_ref).max()), 0, 9)
        l2aa = l2new[0::2,0::2,0::2,0::2]
        l2ab = l2new[0::2,1::2,0::2,1::2]
        self.assertAlmostEqual(float(abs(l2ab-l2new_ref).max()), 0, 9)
        self.assertAlmostEqual(float(abs(l2ab-l2ab.transpose(1,0,2,3) - l2aa).max()), 0, 9)
Example #13
0
    def test_uccsd_t_complex(self):
        mol = gto.M()
        numpy.random.seed(12)
        nocca, noccb, nvira, nvirb = 3, 2, 4, 5
        nmo = nocca + nvira
        eris = cc.uccsd._ChemistsERIs()
        eris.nocca = nocca
        eris.noccb = noccb
        eris.nocc = (nocca, noccb)
        eri1 = (numpy.random.random((3,nmo,nmo,nmo,nmo)) +
                numpy.random.random((3,nmo,nmo,nmo,nmo)) * .8j - .5-.4j)
        eri1 = eri1 + eri1.transpose(0,2,1,4,3).conj()
        eri1[0] = eri1[0] + eri1[0].transpose(2,3,0,1)
        eri1[2] = eri1[2] + eri1[2].transpose(2,3,0,1)
        eri1 *= .1
        eris.ovvv = eri1[0,:nocca,nocca:,nocca:,nocca:]
        eris.ovov = eri1[0,:nocca,nocca:,:nocca,nocca:]
        eris.ovoo = eri1[0,:nocca,nocca:,:nocca,:nocca]
        eris.OVVV = eri1[2,:noccb,noccb:,noccb:,noccb:]
        eris.OVOV = eri1[2,:noccb,noccb:,:noccb,noccb:]
        eris.OVOO = eri1[2,:noccb,noccb:,:noccb,:noccb]
        eris.voVP = eri1[1,nocca:,:nocca,noccb:,:     ]
        eris.ovVV = eri1[1,:nocca,nocca:,noccb:,noccb:]
        eris.ovOV = eri1[1,:nocca,nocca:,:noccb,noccb:]
        eris.ovOO = eri1[1,:nocca,nocca:,:noccb,:noccb]
        eris.OVvv = eri1[1,nocca:,nocca:,:noccb,noccb:].transpose(2,3,0,1)
        eris.OVoo = eri1[1,:nocca,:nocca,:noccb,noccb:].transpose(2,3,0,1)
        t1a  = .1 * numpy.random.random((nocca,nvira)) + numpy.random.random((nocca,nvira))*.1j
        t1b  = .1 * numpy.random.random((noccb,nvirb)) + numpy.random.random((noccb,nvirb))*.1j
        t2aa = .1 * numpy.random.random((nocca,nocca,nvira,nvira)) + numpy.random.random((nocca,nocca,nvira,nvira))*.1j
        t2aa = t2aa - t2aa.transpose(0,1,3,2)
        t2aa = t2aa - t2aa.transpose(1,0,2,3)
        t2bb = .1 * numpy.random.random((noccb,noccb,nvirb,nvirb)) + numpy.random.random((noccb,noccb,nvirb,nvirb))*.1j
        t2bb = t2bb - t2bb.transpose(0,1,3,2)
        t2bb = t2bb - t2bb.transpose(1,0,2,3)
        t2ab = .1 * numpy.random.random((nocca,noccb,nvira,nvirb)) + numpy.random.random((nocca,noccb,nvira,nvirb))*.1j
        f = (numpy.random.random((2,nmo,nmo)) * .4 +
             numpy.random.random((2,nmo,nmo)) * .4j)
        eris.focka = f[0]+f[0].T.conj() + numpy.diag(numpy.arange(nmo))
        eris.fockb = f[1]+f[1].T.conj() + numpy.diag(numpy.arange(nmo))
        eris.mo_energy = (eris.focka.diagonal().real,
                          eris.fockb.diagonal().real)
        t1 = t1a, t1b
        t2 = t2aa, t2ab, t2bb
        mcc = cc.UCCSD(scf.UHF(mol))
        mcc.nocc = eris.nocc
        e0 = uccsd_t.kernel(mcc, eris, t1, t2)

        eri2 = numpy.zeros((nmo*2,nmo*2,nmo*2,nmo*2), dtype=eri1.dtype)
        orbspin = numpy.zeros(nmo*2,dtype=int)
        orbspin[1::2] = 1
        eri2[0::2,0::2,0::2,0::2] = eri1[0]
        eri2[1::2,1::2,0::2,0::2] = eri1[1].transpose(2,3,0,1)
        eri2[0::2,0::2,1::2,1::2] = eri1[1]
        eri2[1::2,1::2,1::2,1::2] = eri1[2]
        eri2 = eri2.transpose(0,2,1,3) - eri2.transpose(0,2,3,1)
        fock = numpy.zeros((nmo*2,nmo*2), dtype=eris.focka.dtype)
        fock[0::2,0::2] = eris.focka
        fock[1::2,1::2] = eris.fockb
        eris1 = gccsd._PhysicistsERIs()
        nocc = nocca + noccb
        eris1.ovvv = eri2[:nocc,nocc:,nocc:,nocc:]
        eris1.oovv = eri2[:nocc,:nocc,nocc:,nocc:]
        eris1.ooov = eri2[:nocc,:nocc,:nocc,nocc:]
        eris1.fock = fock
        eris1.mo_energy = fock.diagonal().real
        t1 = gccsd.spatial2spin(t1, orbspin)
        t2 = gccsd.spatial2spin(t2, orbspin)
        gcc = gccsd.GCCSD(scf.GHF(gto.M()))
        e1 = gccsd_t.kernel(gcc, eris1, t1, t2)
        self.assertAlmostEqual(e0, e1.real, 9)
        self.assertAlmostEqual(e1, -0.056092415718338388-0.011390417704868244j, 9)
Example #14
0
def _make_eris_incore(cc, mo_coeff=None):
    log = logger.Logger(cc.stdout, cc.verbose)
    cput0 = (time.clock(), time.time())
    eris = gccsd._PhysicistsERIs()
    kpts = cc.kpts
    nkpts = cc.nkpts
    nocc = cc.nocc
    nmo = cc.nmo
    nvir = nmo - nocc
    eris.nocc = nocc

    #if any(nocc != numpy.count_nonzero(cc._scf.mo_occ[k] > 0) for k in range(nkpts)):
    #    raise NotImplementedError('Different occupancies found for different k-points')

    if mo_coeff is None:
        mo_coeff = cc.mo_coeff
    #else:
    #    # If mo_coeff is not canonical orbital
    #    # TODO does this work for k-points? changed to conjugate.
    #    raise NotImplementedError
    nao = mo_coeff[0].shape[0]
    dtype = mo_coeff[0].dtype

    moidx = get_frozen_mask(cc)
    nocc_per_kpt = numpy.asarray(get_nocc(cc, per_kpoint=True))
    nmo_per_kpt = numpy.asarray(get_nmo(cc, per_kpoint=True))

    padded_moidx = []
    for k in range(nkpts):
        kpt_nocc = nocc_per_kpt[k]
        kpt_nvir = nmo_per_kpt[k] - kpt_nocc
        kpt_padded_moidx = numpy.concatenate(
            (numpy.ones(kpt_nocc, dtype=numpy.bool),
             numpy.zeros(nmo - kpt_nocc - kpt_nvir, dtype=numpy.bool),
             numpy.ones(kpt_nvir, dtype=numpy.bool)))
        padded_moidx.append(kpt_padded_moidx)

    eris.mo_coeff = []
    eris.orbspin = []
    # Generate the molecular orbital coefficients with the frozen orbitals masked.
    # Each MO is tagged with orbspin, a list of 0's and 1's that give the overall
    # spin of each MO.
    #
    # Here we will work with two index arrays; one is for our original (small) moidx
    # array while the next is for our new (large) padded array.
    for k in range(nkpts):
        kpt_moidx = moidx[k]
        kpt_padded_moidx = padded_moidx[k]

        mo = numpy.zeros((nao, nmo), dtype=dtype)
        mo[:, kpt_padded_moidx] = mo_coeff[k][:, kpt_moidx]
        if hasattr(mo_coeff[k], 'orbspin'):
            orbspin_dtype = mo_coeff[k].orbspin[kpt_moidx].dtype
            orbspin = numpy.zeros(nmo, dtype=orbspin_dtype)
            orbspin[kpt_padded_moidx] = mo_coeff[k].orbspin[kpt_moidx]
            mo = lib.tag_array(mo, orbspin=orbspin)
            eris.orbspin.append(orbspin)
        # FIXME: What if the user freezes all up spin orbitals in
        # an RHF calculation?  The number of electrons will still be
        # even.
        else:  # guess orbital spin - assumes an RHF calculation
            assert (numpy.count_nonzero(kpt_moidx) % 2 == 0)
            orbspin = numpy.zeros(mo.shape[1], dtype=int)
            orbspin[1::2] = 1
            mo = lib.tag_array(mo, orbspin=orbspin)
            eris.orbspin.append(orbspin)
        eris.mo_coeff.append(mo)

    # Re-make our fock MO matrix elements from density and fock AO
    dm = cc._scf.make_rdm1(cc.mo_coeff, cc.mo_occ)
    fockao = cc._scf.get_hcore() + cc._scf.get_veff(cc._scf.cell, dm)
    eris.fock = numpy.asarray([
        reduce(numpy.dot, (mo.T.conj(), fockao[k], mo))
        for k, mo in enumerate(eris.mo_coeff)
    ])

    kconserv = kpts_helper.get_kconserv(cc._scf.cell, cc.kpts)
    # The bottom nao//2 coefficients are down (up) spin while the top are up (down).
    # These are 'spin-less' quantities; spin-conservation will be added manually.
    so_coeff = [mo[:nao // 2] + mo[nao // 2:] for mo in eris.mo_coeff]

    eri = numpy.empty((nkpts, nkpts, nkpts, nmo, nmo, nmo, nmo),
                      dtype=numpy.complex128)
    fao2mo = cc._scf.with_df.ao2mo
    for kp, kq, kr in kpts_helper.loop_kkk(nkpts):
        ks = kconserv[kp, kq, kr]
        eri_kpt = fao2mo(
            (so_coeff[kp], so_coeff[kq], so_coeff[kr], so_coeff[ks]),
            (kpts[kp], kpts[kq], kpts[kr], kpts[ks]),
            compact=False)
        eri_kpt[(eris.orbspin[kp][:, None] != eris.orbspin[kq]).ravel()] = 0
        eri_kpt[:, (eris.orbspin[kr][:, None] != eris.orbspin[ks]).ravel()] = 0
        eri_kpt = eri_kpt.reshape(nmo, nmo, nmo, nmo)
        eri[kp, kq, kr] = eri_kpt

    # Check some antisymmetrized properties of the integrals
    if DEBUG:
        check_antisymm_3412(cc, cc.kpts, eri)

    # Antisymmetrizing (pq|rs)-(ps|rq), where the latter integral is equal to
    # (rq|ps); done since we aren't tracking the kpoint of orbital 's'
    eri = eri - eri.transpose(2, 1, 0, 5, 4, 3, 6)
    # Chemist -> physics notation
    eri = eri.transpose(0, 2, 1, 3, 5, 4, 6)

    # Set the various integrals
    eris.dtype = eri.dtype
    eris.oooo = eri[:, :, :, :nocc, :nocc, :nocc, :nocc].copy() / nkpts
    eris.ooov = eri[:, :, :, :nocc, :nocc, :nocc, nocc:].copy() / nkpts
    eris.ovoo = eri[:, :, :, :nocc, nocc:, :nocc, :nocc].copy() / nkpts
    eris.oovv = eri[:, :, :, :nocc, :nocc, nocc:, nocc:].copy() / nkpts
    eris.ovov = eri[:, :, :, :nocc, nocc:, :nocc, nocc:].copy() / nkpts
    eris.ovvv = eri[:, :, :, :nocc, nocc:, nocc:, nocc:].copy() / nkpts
    eris.vvvv = eri[:, :, :, nocc:, nocc:, nocc:, nocc:].copy() / nkpts

    log.timer('CCSD integral transformation', *cput0)
    return eris
Example #15
0
def _make_eris_incore(cc, mo_coeff=None):
    from pyscf.pbc import tools
    from pyscf.pbc.cc.ccsd import _adjust_occ

    log = logger.Logger(cc.stdout, cc.verbose)
    cput0 = (time.clock(), time.time())
    eris = gccsd._PhysicistsERIs()
    cell = cc._scf.cell
    kpts = cc.kpts
    nkpts = cc.nkpts
    nocc = cc.nocc
    nmo = cc.nmo
    nvir = nmo - nocc
    eris.nocc = nocc

    #if any(nocc != numpy.count_nonzero(cc._scf.mo_occ[k] > 0) for k in range(nkpts)):
    #    raise NotImplementedError('Different occupancies found for different k-points')

    if mo_coeff is None:
        mo_coeff = cc.mo_coeff

    nao = mo_coeff[0].shape[0]
    dtype = mo_coeff[0].dtype

    moidx = get_frozen_mask(cc)
    nocc_per_kpt = numpy.asarray(get_nocc(cc, per_kpoint=True))
    nmo_per_kpt = numpy.asarray(get_nmo(cc, per_kpoint=True))

    padded_moidx = []
    for k in range(nkpts):
        kpt_nocc = nocc_per_kpt[k]
        kpt_nvir = nmo_per_kpt[k] - kpt_nocc
        kpt_padded_moidx = numpy.concatenate(
            (numpy.ones(kpt_nocc, dtype=numpy.bool),
             numpy.zeros(nmo - kpt_nocc - kpt_nvir, dtype=numpy.bool),
             numpy.ones(kpt_nvir, dtype=numpy.bool)))
        padded_moidx.append(kpt_padded_moidx)

    eris.mo_coeff = []
    eris.orbspin = []
    # Generate the molecular orbital coefficients with the frozen orbitals masked.
    # Each MO is tagged with orbspin, a list of 0's and 1's that give the overall
    # spin of each MO.
    #
    # Here we will work with two index arrays; one is for our original (small) moidx
    # array while the next is for our new (large) padded array.
    for k in range(nkpts):
        kpt_moidx = moidx[k]
        kpt_padded_moidx = padded_moidx[k]

        mo = numpy.zeros((nao, nmo), dtype=dtype)
        mo[:, kpt_padded_moidx] = mo_coeff[k][:, kpt_moidx]
        if getattr(mo_coeff[k], 'orbspin', None) is not None:
            orbspin_dtype = mo_coeff[k].orbspin[kpt_moidx].dtype
            orbspin = numpy.zeros(nmo, dtype=orbspin_dtype)
            orbspin[kpt_padded_moidx] = mo_coeff[k].orbspin[kpt_moidx]
            mo = lib.tag_array(mo, orbspin=orbspin)
            eris.orbspin.append(orbspin)
        # FIXME: What if the user freezes all up spin orbitals in
        # an RHF calculation?  The number of electrons will still be
        # even.
        else:  # guess orbital spin - assumes an RHF calculation
            assert (numpy.count_nonzero(kpt_moidx) % 2 == 0)
            orbspin = numpy.zeros(mo.shape[1], dtype=int)
            orbspin[1::2] = 1
            mo = lib.tag_array(mo, orbspin=orbspin)
            eris.orbspin.append(orbspin)
        eris.mo_coeff.append(mo)

    # Re-make our fock MO matrix elements from density and fock AO
    dm = cc._scf.make_rdm1(cc.mo_coeff, cc.mo_occ)
    with lib.temporary_env(cc._scf, exxdiv=None):
        # _scf.exxdiv affects eris.fock. HF exchange correction should be
        # excluded from the Fock matrix.
        fockao = cc._scf.get_hcore() + cc._scf.get_veff(cell, dm)
    eris.fock = numpy.asarray([
        reduce(numpy.dot, (mo.T.conj(), fockao[k], mo))
        for k, mo in enumerate(eris.mo_coeff)
    ])

    eris.mo_energy = [eris.fock[k].diagonal().real for k in range(nkpts)]
    # Add HFX correction in the eris.mo_energy to improve convergence in
    # CCSD iteration. It is useful for the 2D systems since their occupied and
    # the virtual orbital energies may overlap which may lead to numerical
    # issue in the CCSD iterations.
    # FIXME: Whether to add this correction for other exxdiv treatments?
    # Without the correction, MP2 energy may be largely off the correct value.
    madelung = tools.madelung(cell, kpts)
    eris.mo_energy = [
        _adjust_occ(mo_e, nocc, -madelung)
        for k, mo_e in enumerate(eris.mo_energy)
    ]

    # Get location of padded elements in occupied and virtual space.
    nocc_per_kpt = get_nocc(cc, per_kpoint=True)
    nonzero_padding = padding_k_idx(cc, kind="joint")

    # Check direct and indirect gaps for possible issues with CCSD convergence.
    mo_e = [eris.mo_energy[kp][nonzero_padding[kp]] for kp in range(nkpts)]
    mo_e = numpy.sort([y for x in mo_e for y in x])  # Sort de-nested array
    gap = mo_e[numpy.sum(nocc_per_kpt)] - mo_e[numpy.sum(nocc_per_kpt) - 1]
    if gap < 1e-5:
        logger.warn(
            cc, 'H**O-LUMO gap %s too small for KCCSD. '
            'May cause issues in convergence.', gap)

    kconserv = kpts_helper.get_kconserv(cell, kpts)
    if getattr(mo_coeff[0], 'orbspin', None) is None:
        # The bottom nao//2 coefficients are down (up) spin while the top are up (down).
        mo_a_coeff = [mo[:nao // 2] for mo in eris.mo_coeff]
        mo_b_coeff = [mo[nao // 2:] for mo in eris.mo_coeff]

        eri = numpy.empty((nkpts, nkpts, nkpts, nmo, nmo, nmo, nmo),
                          dtype=numpy.complex128)
        fao2mo = cc._scf.with_df.ao2mo
        for kp, kq, kr in kpts_helper.loop_kkk(nkpts):
            ks = kconserv[kp, kq, kr]
            eri_kpt = fao2mo((mo_a_coeff[kp], mo_a_coeff[kq], mo_a_coeff[kr],
                              mo_a_coeff[ks]),
                             (kpts[kp], kpts[kq], kpts[kr], kpts[ks]),
                             compact=False)
            eri_kpt += fao2mo((mo_b_coeff[kp], mo_b_coeff[kq], mo_b_coeff[kr],
                               mo_b_coeff[ks]),
                              (kpts[kp], kpts[kq], kpts[kr], kpts[ks]),
                              compact=False)
            eri_kpt += fao2mo((mo_a_coeff[kp], mo_a_coeff[kq], mo_b_coeff[kr],
                               mo_b_coeff[ks]),
                              (kpts[kp], kpts[kq], kpts[kr], kpts[ks]),
                              compact=False)
            eri_kpt += fao2mo((mo_b_coeff[kp], mo_b_coeff[kq], mo_a_coeff[kr],
                               mo_a_coeff[ks]),
                              (kpts[kp], kpts[kq], kpts[kr], kpts[ks]),
                              compact=False)

            eri_kpt = eri_kpt.reshape(nmo, nmo, nmo, nmo)
            eri[kp, kq, kr] = eri_kpt
    else:
        mo_a_coeff = [mo[:nao // 2] + mo[nao // 2:] for mo in eris.mo_coeff]

        eri = numpy.empty((nkpts, nkpts, nkpts, nmo, nmo, nmo, nmo),
                          dtype=numpy.complex128)
        fao2mo = cc._scf.with_df.ao2mo
        for kp, kq, kr in kpts_helper.loop_kkk(nkpts):
            ks = kconserv[kp, kq, kr]
            eri_kpt = fao2mo((mo_a_coeff[kp], mo_a_coeff[kq], mo_a_coeff[kr],
                              mo_a_coeff[ks]),
                             (kpts[kp], kpts[kq], kpts[kr], kpts[ks]),
                             compact=False)

            eri_kpt[(eris.orbspin[kp][:, None] !=
                     eris.orbspin[kq]).ravel()] = 0
            eri_kpt[:,
                    (eris.orbspin[kr][:,
                                      None] != eris.orbspin[ks]).ravel()] = 0
            eri_kpt = eri_kpt.reshape(nmo, nmo, nmo, nmo)
            eri[kp, kq, kr] = eri_kpt

    # Check some antisymmetrized properties of the integrals
    if DEBUG:
        check_antisymm_3412(cc, cc.kpts, eri)

    # Antisymmetrizing (pq|rs)-(ps|rq), where the latter integral is equal to
    # (rq|ps); done since we aren't tracking the kpoint of orbital 's'
    eri = eri - eri.transpose(2, 1, 0, 5, 4, 3, 6)
    # Chemist -> physics notation
    eri = eri.transpose(0, 2, 1, 3, 5, 4, 6)

    # Set the various integrals
    eris.dtype = eri.dtype
    eris.oooo = eri[:, :, :, :nocc, :nocc, :nocc, :nocc].copy() / nkpts
    eris.ooov = eri[:, :, :, :nocc, :nocc, :nocc, nocc:].copy() / nkpts
    eris.ovoo = eri[:, :, :, :nocc, nocc:, :nocc, :nocc].copy() / nkpts
    eris.oovv = eri[:, :, :, :nocc, :nocc, nocc:, nocc:].copy() / nkpts
    eris.ovov = eri[:, :, :, :nocc, nocc:, :nocc, nocc:].copy() / nkpts
    eris.ovvv = eri[:, :, :, :nocc, nocc:, nocc:, nocc:].copy() / nkpts
    eris.vvvv = eri[:, :, :, nocc:, nocc:, nocc:, nocc:].copy() / nkpts

    log.timer('CCSD integral transformation', *cput0)
    return eris
Example #16
0
    def test_uccsd_t_complex(self):
        mol = gto.M()
        numpy.random.seed(12)
        nocca, noccb, nvira, nvirb = 3, 2, 4, 5
        nmo = nocca + nvira
        eris = cc.uccsd._ChemistsERIs()
        eris.nocca = nocca
        eris.noccb = noccb
        eris.nocc = (nocca, noccb)
        eri1 = (numpy.random.random((3,nmo,nmo,nmo,nmo)) +
                numpy.random.random((3,nmo,nmo,nmo,nmo)) * .8j - .5-.4j)
        eri1 = eri1 + eri1.transpose(0,2,1,4,3).conj()
        eri1[0] = eri1[0] + eri1[0].transpose(2,3,0,1)
        eri1[2] = eri1[2] + eri1[2].transpose(2,3,0,1)
        eri1 *= .1
        eris.ovvv = eri1[0,:nocca,nocca:,nocca:,nocca:]
        eris.ovov = eri1[0,:nocca,nocca:,:nocca,nocca:]
        eris.ovoo = eri1[0,:nocca,nocca:,:nocca,:nocca]
        eris.OVVV = eri1[2,:noccb,noccb:,noccb:,noccb:]
        eris.OVOV = eri1[2,:noccb,noccb:,:noccb,noccb:]
        eris.OVOO = eri1[2,:noccb,noccb:,:noccb,:noccb]
        eris.voVP = eri1[1,nocca:,:nocca,noccb:,:     ]
        eris.ovVV = eri1[1,:nocca,nocca:,noccb:,noccb:]
        eris.ovOV = eri1[1,:nocca,nocca:,:noccb,noccb:]
        eris.ovOO = eri1[1,:nocca,nocca:,:noccb,:noccb]
        eris.OVvv = eri1[1,nocca:,nocca:,:noccb,noccb:].transpose(2,3,0,1)
        eris.OVoo = eri1[1,:nocca,:nocca,:noccb,noccb:].transpose(2,3,0,1)
        t1a  = .1 * numpy.random.random((nocca,nvira)) + numpy.random.random((nocca,nvira))*.1j
        t1b  = .1 * numpy.random.random((noccb,nvirb)) + numpy.random.random((noccb,nvirb))*.1j
        t2aa = .1 * numpy.random.random((nocca,nocca,nvira,nvira)) + numpy.random.random((nocca,nocca,nvira,nvira))*.1j
        t2aa = t2aa - t2aa.transpose(0,1,3,2)
        t2aa = t2aa - t2aa.transpose(1,0,2,3)
        t2bb = .1 * numpy.random.random((noccb,noccb,nvirb,nvirb)) + numpy.random.random((noccb,noccb,nvirb,nvirb))*.1j
        t2bb = t2bb - t2bb.transpose(0,1,3,2)
        t2bb = t2bb - t2bb.transpose(1,0,2,3)
        t2ab = .1 * numpy.random.random((nocca,noccb,nvira,nvirb)) + numpy.random.random((nocca,noccb,nvira,nvirb))*.1j
        f = (numpy.random.random((2,nmo,nmo)) * .4 +
             numpy.random.random((2,nmo,nmo)) * .4j)
        eris.focka = f[0]+f[0].T.conj() + numpy.diag(numpy.arange(nmo))
        eris.fockb = f[1]+f[1].T.conj() + numpy.diag(numpy.arange(nmo))
        eris.mo_energy = (eris.focka.diagonal().real,
                          eris.fockb.diagonal().real)
        t1 = t1a, t1b
        t2 = t2aa, t2ab, t2bb
        mcc = cc.UCCSD(scf.UHF(mol))
        mcc.nocc = eris.nocc
        e0 = uccsd_t.kernel(mcc, eris, t1, t2)

        eri2 = numpy.zeros((nmo*2,nmo*2,nmo*2,nmo*2), dtype=eri1.dtype)
        orbspin = numpy.zeros(nmo*2,dtype=int)
        orbspin[1::2] = 1
        eri2[0::2,0::2,0::2,0::2] = eri1[0]
        eri2[1::2,1::2,0::2,0::2] = eri1[1].transpose(2,3,0,1)
        eri2[0::2,0::2,1::2,1::2] = eri1[1]
        eri2[1::2,1::2,1::2,1::2] = eri1[2]
        eri2 = eri2.transpose(0,2,1,3) - eri2.transpose(0,2,3,1)
        fock = numpy.zeros((nmo*2,nmo*2), dtype=eris.focka.dtype)
        fock[0::2,0::2] = eris.focka
        fock[1::2,1::2] = eris.fockb
        eris1 = gccsd._PhysicistsERIs()
        nocc = nocca + noccb
        eris1.ovvv = eri2[:nocc,nocc:,nocc:,nocc:]
        eris1.oovv = eri2[:nocc,:nocc,nocc:,nocc:]
        eris1.ooov = eri2[:nocc,:nocc,:nocc,nocc:]
        eris1.fock = fock
        eris1.mo_energy = fock.diagonal().real
        t1 = gccsd.spatial2spin(t1, orbspin)
        t2 = gccsd.spatial2spin(t2, orbspin)
        gcc = gccsd.GCCSD(scf.GHF(gto.M()))
        e1 = gccsd_t.kernel(gcc, eris1, t1, t2)
        self.assertAlmostEqual(e0, e1.real, 9)
        self.assertAlmostEqual(e1, -0.056092415718338388-0.011390417704868244j, 9)
Example #17
0
    def test_update_lambda_complex(self):
        nocca, noccb = mol.nelec
        nmo = mol.nao_nr()
        nvira,nvirb = nmo-nocca, nmo-noccb
        numpy.random.seed(9)
        t1 = [numpy.random.random((nocca,nvira))-.9,
              numpy.random.random((noccb,nvirb))-.9]
        l1 = [numpy.random.random((nocca,nvira))-.9,
              numpy.random.random((noccb,nvirb))-.9]
        t2 = [numpy.random.random((nocca,nocca,nvira,nvira))-.9,
              numpy.random.random((nocca,noccb,nvira,nvirb))-.9,
              numpy.random.random((noccb,noccb,nvirb,nvirb))-.9]
        t2[0] = t2[0] - t2[0].transpose(1,0,2,3)
        t2[0] = t2[0] - t2[0].transpose(0,1,3,2)
        t2[2] = t2[2] - t2[2].transpose(1,0,2,3)
        t2[2] = t2[2] - t2[2].transpose(0,1,3,2)
        l2 = [numpy.random.random((nocca,nocca,nvira,nvira))-.9,
              numpy.random.random((nocca,noccb,nvira,nvirb))-.9,
              numpy.random.random((noccb,noccb,nvirb,nvirb))-.9]
        l2[0] = l2[0] - l2[0].transpose(1,0,2,3)
        l2[0] = l2[0] - l2[0].transpose(0,1,3,2)
        l2[2] = l2[2] - l2[2].transpose(1,0,2,3)
        l2[2] = l2[2] - l2[2].transpose(0,1,3,2)

#        eris = mycc.ao2mo()
#        imds = make_intermediates(mycc, t1, t2, eris)
#        l1new, l2new = update_lambda(mycc, t1, t2, l1, l2, eris, imds)
#        print(lib.finger(l1new[0]) --104.55975252585894)
#        print(lib.finger(l1new[1]) --241.12677819375281)
#        print(lib.finger(l2new[0]) --0.4957533529669417)
#        print(lib.finger(l2new[1]) - 15.46423057451851 )
#        print(lib.finger(l2new[2]) - 5.8430776663704407)

        nocca, noccb = mol.nelec
        mo_a = mf.mo_coeff[0] + numpy.sin(mf.mo_coeff[0]) * .01j
        mo_b = mf.mo_coeff[1] + numpy.sin(mf.mo_coeff[1]) * .01j
        nao = mo_a.shape[0]
        eri = ao2mo.restore(1, mf._eri, nao)
        eri0aa = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_a.conj(), mo_a, mo_a.conj(), mo_a)
        eri0ab = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_a.conj(), mo_a, mo_b.conj(), mo_b)
        eri0bb = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri, mo_b.conj(), mo_b, mo_b.conj(), mo_b)
        eri0ba = eri0ab.transpose(2,3,0,1)

        nvira = nao - nocca
        nvirb = nao - noccb
        eris = uccsd._ChemistsERIs(mol)
        eris.oooo = eri0aa[:nocca,:nocca,:nocca,:nocca].copy()
        eris.ovoo = eri0aa[:nocca,nocca:,:nocca,:nocca].copy()
        eris.oovv = eri0aa[:nocca,:nocca,nocca:,nocca:].copy()
        eris.ovvo = eri0aa[:nocca,nocca:,nocca:,:nocca].copy()
        eris.ovov = eri0aa[:nocca,nocca:,:nocca,nocca:].copy()
        eris.ovvv = eri0aa[:nocca,nocca:,nocca:,nocca:].copy()
        eris.vvvv = eri0aa[nocca:,nocca:,nocca:,nocca:].copy()

        eris.OOOO = eri0bb[:noccb,:noccb,:noccb,:noccb].copy()
        eris.OVOO = eri0bb[:noccb,noccb:,:noccb,:noccb].copy()
        eris.OOVV = eri0bb[:noccb,:noccb,noccb:,noccb:].copy()
        eris.OVVO = eri0bb[:noccb,noccb:,noccb:,:noccb].copy()
        eris.OVOV = eri0bb[:noccb,noccb:,:noccb,noccb:].copy()
        eris.OVVV = eri0bb[:noccb,noccb:,noccb:,noccb:].copy()
        eris.VVVV = eri0bb[noccb:,noccb:,noccb:,noccb:].copy()

        eris.ooOO = eri0ab[:nocca,:nocca,:noccb,:noccb].copy()
        eris.ovOO = eri0ab[:nocca,nocca:,:noccb,:noccb].copy()
        eris.ooVV = eri0ab[:nocca,:nocca,noccb:,noccb:].copy()
        eris.ovVO = eri0ab[:nocca,nocca:,noccb:,:noccb].copy()
        eris.ovOV = eri0ab[:nocca,nocca:,:noccb,noccb:].copy()
        eris.ovVV = eri0ab[:nocca,nocca:,noccb:,noccb:].copy()
        eris.vvVV = eri0ab[nocca:,nocca:,noccb:,noccb:].copy()

        eris.OOoo = eri0ba[:noccb,:noccb,:nocca,:nocca].copy()
        eris.OVoo = eri0ba[:noccb,noccb:,:nocca,:nocca].copy()
        eris.OOvv = eri0ba[:noccb,:noccb,nocca:,nocca:].copy()
        eris.OVvo = eri0ba[:noccb,noccb:,nocca:,:nocca].copy()
        eris.OVov = eri0ba[:noccb,noccb:,:nocca,nocca:].copy()
        eris.OVvv = eri0ba[:noccb,noccb:,nocca:,nocca:].copy()
        eris.VVvv = eri0ba[noccb:,noccb:,nocca:,nocca:].copy()

        eris.focka = numpy.diag(mf.mo_energy[0])
        eris.fockb = numpy.diag(mf.mo_energy[1])
        eris.mo_energy = mf.mo_energy

        t1[0] = t1[0] + numpy.sin(t1[0]) * .05j
        t1[1] = t1[1] + numpy.sin(t1[1]) * .05j
        t2[0] = t2[0] + numpy.sin(t2[0]) * .05j
        t2[1] = t2[1] + numpy.sin(t2[1]) * .05j
        t2[2] = t2[2] + numpy.sin(t2[2]) * .05j
        l1[0] = l1[0] + numpy.sin(l1[0]) * .05j
        l1[1] = l1[1] + numpy.sin(l1[1]) * .05j
        l2[0] = l2[0] + numpy.sin(l2[0]) * .05j
        l2[1] = l2[1] + numpy.sin(l2[1]) * .05j
        l2[2] = l2[2] + numpy.sin(l2[2]) * .05j
        imds = uccsd_lambda.make_intermediates(mycc, t1, t2, eris)
        l1new_ref, l2new_ref = uccsd_lambda.update_lambda(mycc, t1, t2, l1, l2, eris, imds)

        nocc = nocca + noccb
        orbspin = numpy.zeros(nao*2, dtype=int)
        orbspin[1::2] = 1
        orbspin[nocc-1] = 0
        orbspin[nocc  ] = 1
        eri1 = numpy.zeros([nao*2]*4, dtype=numpy.complex)
        idxa = numpy.where(orbspin == 0)[0]
        idxb = numpy.where(orbspin == 1)[0]
        eri1[idxa[:,None,None,None],idxa[:,None,None],idxa[:,None],idxa] = eri0aa
        eri1[idxa[:,None,None,None],idxa[:,None,None],idxb[:,None],idxb] = eri0ab
        eri1[idxb[:,None,None,None],idxb[:,None,None],idxa[:,None],idxa] = eri0ba
        eri1[idxb[:,None,None,None],idxb[:,None,None],idxb[:,None],idxb] = eri0bb
        eri1 = eri1.transpose(0,2,1,3) - eri1.transpose(0,2,3,1)
        erig = gccsd._PhysicistsERIs()
        erig.oooo = eri1[:nocc,:nocc,:nocc,:nocc].copy()
        erig.ooov = eri1[:nocc,:nocc,:nocc,nocc:].copy()
        erig.ovov = eri1[:nocc,nocc:,:nocc,nocc:].copy()
        erig.ovvo = eri1[:nocc,nocc:,nocc:,:nocc].copy()
        erig.oovv = eri1[:nocc,:nocc,nocc:,nocc:].copy()
        erig.ovvv = eri1[:nocc,nocc:,nocc:,nocc:].copy()
        erig.vvvv = eri1[nocc:,nocc:,nocc:,nocc:].copy()
        mo_e = numpy.empty(nao*2)
        mo_e[orbspin==0] = mf.mo_energy[0]
        mo_e[orbspin==1] = mf.mo_energy[1]
        erig.fock = numpy.diag(mo_e)
        erig.mo_energy = mo_e.real

        myccg = gccsd.GCCSD(scf.addons.convert_to_ghf(mf))
        t1 = myccg.spatial2spin(t1, orbspin)
        t2 = myccg.spatial2spin(t2, orbspin)
        l1 = myccg.spatial2spin(l1, orbspin)
        l2 = myccg.spatial2spin(l2, orbspin)
        imds = gccsd_lambda.make_intermediates(myccg, t1, t2, erig)
        l1new, l2new = gccsd_lambda.update_lambda(myccg, t1, t2, l1, l2, erig, imds)
        l1new = myccg.spin2spatial(l1new, orbspin)
        l2new = myccg.spin2spatial(l2new, orbspin)
        self.assertAlmostEqual(abs(l1new[0] - l1new_ref[0]).max(), 0, 11)
        self.assertAlmostEqual(abs(l1new[1] - l1new_ref[1]).max(), 0, 11)
        self.assertAlmostEqual(abs(l2new[0] - l2new_ref[0]).max(), 0, 11)
        self.assertAlmostEqual(abs(l2new[1] - l2new_ref[1]).max(), 0, 11)
        self.assertAlmostEqual(abs(l2new[2] - l2new_ref[2]).max(), 0, 11)