Exemple #1
0
    def run_diis(self, se, diis=None):
        ''' Runs the direct inversion of the iterative subspace for the
            self-energy.

        Args:
            se : SelfEnergy
                Auxiliaries of the self-energy
            diis : lib.diis.DIIS
                DIIS object

        Returns:
            :class:`SelfEnergy`
        '''

        if diis is None:
            return se

        se_occ = se.get_occupied()
        se_vir = se.get_virtual()

        vv_occ = np.dot(se_occ.coupling, se_occ.coupling.T)
        vv_vir = np.dot(se_vir.coupling, se_vir.coupling.T)

        vev_occ = np.dot(se_occ.coupling * se_occ.energy[None], se_occ.coupling.T)
        vev_vir = np.dot(se_vir.coupling * se_vir.energy[None], se_vir.coupling.T)

        dat = np.array([vv_occ, vv_vir, vev_occ, vev_vir])
        dat = diis.update(dat)
        vv_occ, vv_vir, vev_occ, vev_vir = dat

        se_occ = aux.SelfEnergy(*_agf2.cholesky_build(vv_occ, vev_occ), chempot=se.chempot)
        se_vir = aux.SelfEnergy(*_agf2.cholesky_build(vv_vir, vev_vir), chempot=se.chempot)
        se = aux.combine(se_occ, se_vir)

        return se
Exemple #2
0
    def run_diis(self, se, diis=None):
        ''' Runs the direct inversion of the iterative subspace for the
            self-energy.

        Args:
            se : SelfEnergy
                Auxiliaries of the self-energy
            diis : lib.diis.DIIS
                DIIS object

        Returns:
            tuple of :class:`SelfEnergy`
        '''

        if diis is None:
            return se

        se_occ_a, se_occ_b = (se[0].get_occupied(), se[1].get_occupied())
        se_vir_a, se_vir_b = (se[0].get_virtual(), se[1].get_virtual())

        vv_occ_a = np.dot(se_occ_a.coupling, se_occ_a.coupling.T)
        vv_occ_b = np.dot(se_occ_b.coupling, se_occ_b.coupling.T)
        vv_vir_a = np.dot(se_vir_a.coupling, se_vir_a.coupling.T)
        vv_vir_b = np.dot(se_vir_b.coupling, se_vir_b.coupling.T)

        vev_occ_a = np.dot(se_occ_a.coupling * se_occ_a.energy[None],
                           se_occ_a.coupling.T)
        vev_occ_b = np.dot(se_occ_b.coupling * se_occ_b.energy[None],
                           se_occ_b.coupling.T)
        vev_vir_a = np.dot(se_vir_a.coupling * se_vir_a.energy[None],
                           se_vir_a.coupling.T)
        vev_vir_b = np.dot(se_vir_b.coupling * se_vir_b.energy[None],
                           se_vir_b.coupling.T)

        dat = np.array([
            vv_occ_a, vv_vir_a, vev_occ_a, vev_vir_a, vv_occ_b, vv_vir_b,
            vev_occ_b, vev_vir_b
        ])
        dat = diis.update(dat)
        vv_occ_a, vv_vir_a, vev_occ_a, vev_vir_a, \
                vv_occ_b, vv_vir_b, vev_occ_b, vev_vir_b = dat

        se_occ_a = aux.SelfEnergy(*_agf2.cholesky_build(vv_occ_a, vev_occ_a),
                                  chempot=se[0].chempot)
        se_vir_a = aux.SelfEnergy(*_agf2.cholesky_build(vv_vir_a, vev_vir_a),
                                  chempot=se[0].chempot)
        se_occ_b = aux.SelfEnergy(*_agf2.cholesky_build(vv_occ_b, vev_occ_b),
                                  chempot=se[1].chempot)
        se_vir_b = aux.SelfEnergy(*_agf2.cholesky_build(vv_vir_b, vev_vir_b),
                                  chempot=se[1].chempot)
        se = (aux.combine(se_occ_a, se_vir_a), aux.combine(se_occ_b, se_vir_b))

        return se
Exemple #3
0
    def build_se(self,
                 eri=None,
                 gf=None,
                 os_factor=None,
                 ss_factor=None,
                 se_prev=None):
        ''' Builds the auxiliaries of the self-energy.

        Args:
            eri : _ChemistsERIs
                Electronic repulsion integrals
            gf : GreensFunction
                Auxiliaries of the Green's function

        Kwargs:
            os_factor : float
                Opposite-spin factor for spin-component-scaled (SCS)
                calculations. Default 1.0
            ss_factor : float
                Same-spin factor for spin-component-scaled (SCS)
                calculations. Default 1.0
            se_prev : SelfEnergy
                Previous self-energy for damping. Default value is None

        Returns:
            :class:`SelfEnergy`
        '''

        if eri is None: eri = self.ao2mo()
        if gf is None: gf = self.gf
        if gf is None: gf = self.init_gf()

        if os_factor is None: os_factor = self.os_factor
        if ss_factor is None: ss_factor = self.ss_factor

        facs = dict(os_factor=os_factor, ss_factor=ss_factor)
        gf_occ = gf.get_occupied()
        gf_vir = gf.get_virtual()

        if gf_occ.naux == 0 or gf_vir.naux == 0:
            logger.warn(
                self, 'Attempting to build a self-energy with '
                'no (i,j,a) or (a,b,i) configurations.')
            se = aux.SelfEnergy([], [
                [],
            ] * self.nmo, chempot=gf.chempot)
        else:
            se_occ = self.build_se_part(eri, gf_occ, gf_vir, **facs)
            se_vir = self.build_se_part(eri, gf_vir, gf_occ, **facs)
            se = aux.combine(se_occ, se_vir)

        if se_prev is not None and self.damping != 0.0:
            se.coupling *= np.sqrt(1.0 - self.damping)
            se_prev.coupling *= np.sqrt(self.damping)
            se = aux.combine(se, se_prev)
            se = se.compress(n=(None, 0))

        return se
Exemple #4
0
def build_se_part(agf2, eri, gf_occ, gf_vir, os_factor=1.0, ss_factor=1.0):
    ''' Builds either the auxiliaries of the occupied self-energy,
        or virtual if :attr:`gf_occ` and :attr:`gf_vir` are swapped.

    Args:
        eri : _ChemistsERIs
            Electronic repulsion integrals
        gf_occ : GreensFunction
            Occupied Green's function
        gf_vir : GreensFunction
            Virtual Green's function

    Kwargs:
        os_factor : float
            Opposite-spin factor for spin-component-scaled (SCS)
            calculations. Default 1.0
        ss_factor : float
            Same-spin factor for spin-component-scaled (SCS)
            calculations. Default 1.0

    Returns:
        :class:`SelfEnergy`
    '''

    cput0 = (logger.process_clock(), logger.perf_counter())
    log = logger.Logger(agf2.stdout, agf2.verbose)

    assert type(gf_occ) is aux.GreensFunction
    assert type(gf_vir) is aux.GreensFunction

    nmo = eri.nmo
    tol = agf2.weight_tol
    facs = dict(os_factor=os_factor, ss_factor=ss_factor)

    ci, ei = gf_occ.coupling, gf_occ.energy
    ca, ea = gf_vir.coupling, gf_vir.energy

    mem_incore = (gf_occ.nphys * gf_occ.naux**2 * gf_vir.naux) * 8 / 1e6
    mem_now = lib.current_memory()[0]
    if (mem_incore + mem_now < agf2.max_memory) or agf2.incore_complete:
        qeri = _make_qmo_eris_incore(agf2, eri, (ci, ci, ca))
    else:
        qeri = _make_qmo_eris_outcore(agf2, eri, (ci, ci, ca))

    if isinstance(qeri, np.ndarray):
        vv, vev = _agf2.build_mats_ragf2_incore(qeri, ei, ea, **facs)
    else:
        vv, vev = _agf2.build_mats_ragf2_outcore(qeri, ei, ea, **facs)

    e, c = _agf2.cholesky_build(vv, vev)
    se = aux.SelfEnergy(e, c, chempot=gf_occ.chempot)
    se.remove_uncoupled(tol=tol)

    if not (agf2.frozen is None or agf2.frozen == 0):
        mask = get_frozen_mask(agf2)
        coupling = np.zeros((nmo, se.naux))
        coupling[mask] = se.coupling
        se = aux.SelfEnergy(se.energy, coupling, chempot=se.chempot)

    log.timer('se part', *cput0)

    return se
Exemple #5
0
def build_se_part(agf2, eri, gf_occ, gf_vir, os_factor=1.0, ss_factor=1.0):
    ''' Builds either the auxiliaries of the occupied self-energy,
        or virtual if :attr:`gf_occ` and :attr:`gf_vir` are swapped.

    Args:
        eri : _ChemistsERIs
            Electronic repulsion integrals
        gf_occ : GreensFunction
            Occupied Green's function
        gf_vir : GreensFunction
            Virtual Green's function

    Kwargs:
        os_factor : float
            Opposite-spin factor for spin-component-scaled (SCS)
            calculations. Default 1.0
        ss_factor : float
            Same-spin factor for spin-component-scaled (SCS)
            calculations. Default 1.0

    Returns:
        :class:`SelfEnergy`
    '''

    cput0 = (logger.process_clock(), logger.perf_counter())
    log = logger.Logger(agf2.stdout, agf2.verbose)

    assert type(gf_occ) is aux.GreensFunction
    assert type(gf_vir) is aux.GreensFunction

    nmo = agf2.nmo
    nocc = gf_occ.naux
    nvir = gf_vir.naux
    naux = nocc * nocc * nvir
    tol = agf2.weight_tol

    if not (agf2.frozen is None or agf2.frozen == 0):
        mask = ragf2.get_frozen_mask(agf2)
        nmo -= np.sum(~mask)

    e = np.zeros((naux))
    v = np.zeros((nmo, naux))

    fpos = np.sqrt(0.5 * os_factor)
    fneg = np.sqrt(0.5 * os_factor + ss_factor)
    fdia = np.sqrt(os_factor)

    eja = lib.direct_sum('j,a->ja', gf_occ.energy, -gf_vir.energy)

    coeffs = (gf_occ.coupling, gf_occ.coupling, gf_vir.coupling)
    qeri = _make_qmo_eris_incore(agf2, eri, coeffs)

    p1 = 0
    for i in range(nocc):
        xija = qeri[:, i, :i].reshape(nmo, -1)
        xjia = qeri[:, :i, i].reshape(nmo, -1)
        xiia = qeri[:, i, i].reshape(nmo, -1)
        eija = gf_occ.energy[i] + eja[:i + 1]

        p0, p1 = p1, p1 + i * nvir
        e[p0:p1] = eija[:i].ravel()
        v[:, p0:p1] = fneg * (xija - xjia)

        p0, p1 = p1, p1 + i * nvir
        e[p0:p1] = eija[:i].ravel()
        v[:, p0:p1] = fpos * (xija + xjia)

        p0, p1 = p1, p1 + nvir
        e[p0:p1] = eija[i].ravel()
        v[:, p0:p1] = fdia * xiia

    se = aux.SelfEnergy(e, v, chempot=gf_occ.chempot)
    se.remove_uncoupled(tol=tol)

    if not (agf2.frozen is None or agf2.frozen == 0):
        coupling = np.zeros((agf2.nmo, se.naux))
        coupling[mask] = se.coupling
        se = aux.SelfEnergy(se.energy, coupling, chempot=se.chempot)

    log.timer('se part', *cput0)

    return se
Exemple #6
0
def build_se_part(agf2, eri, gf_occ, gf_vir, os_factor=1.0, ss_factor=1.0):
    ''' Builds either the auxiliaries of the occupied self-energy,
        or virtual if :attr:`gf_occ` and :attr:`gf_vir` are swapped.

    Args:
        eri : _ChemistsERIs
            Electronic repulsion integrals
        gf_occ : GreensFunction
            Occupied Green's function
        gf_vir : GreensFunction
            Virtual Green's function

    Kwargs:
        os_factor : float
            Opposite-spin factor for spin-component-scaled (SCS)
            calculations. Default 1.0
        ss_factor : float
            Same-spin factor for spin-component-scaled (SCS)
            calculations. Default 1.0

    Returns:
        :class:`SelfEnergy`
    '''

    cput0 = (logger.process_clock(), logger.perf_counter())
    log = logger.Logger(agf2.stdout, agf2.verbose)

    assert type(gf_occ) is aux.GreensFunction
    assert type(gf_vir) is aux.GreensFunction

    nmo = eri.nmo
    nocc, nvir = gf_occ.naux, gf_vir.naux
    naux = agf2.with_df.get_naoaux()
    tol = agf2.weight_tol
    facs = dict(os_factor=os_factor, ss_factor=ss_factor)

    ei, ci = gf_occ.energy, gf_occ.coupling
    ea, ca = gf_vir.energy, gf_vir.coupling

    qxi, qja = _make_qmo_eris_incore(agf2, eri, (ci, ci, ca))

    himem_required = naux * (nvir + nmo) + (nocc * nvir) * (2 * nmo + 1) + (
        2 * nmo**2)
    himem_required *= 8e-6
    himem_required *= lib.num_threads()

    if ((himem_required * 1.05 + lib.current_memory()[0]) > agf2.max_memory
            and agf2.allow_lowmem_build) or agf2.allow_lowmem_build == 'force':
        log.debug(
            'Thread-private memory overhead %.3f exceeds max_memory, using '
            'low-memory version.', himem_required)
        vv, vev = _agf2.build_mats_dfragf2_lowmem(qxi, qja, ei, ea, **facs)
    else:
        vv, vev = _agf2.build_mats_dfragf2_incore(qxi, qja, ei, ea, **facs)

    e, c = _agf2.cholesky_build(vv, vev)
    se = aux.SelfEnergy(e, c, chempot=gf_occ.chempot)
    se.remove_uncoupled(tol=tol)

    if not (agf2.frozen is None or agf2.frozen == 0):
        mask = ragf2.get_frozen_mask(agf2)
        coupling = np.zeros((nmo, se.naux))
        coupling[mask] = se.coupling
        se = aux.SelfEnergy(se.energy, coupling, chempot=se.chempot)

    log.timer('se part', *cput0)

    return se
Exemple #7
0
def build_se_part(agf2, eri, gf_occ, gf_vir, os_factor=1.0, ss_factor=1.0):
    ''' Builds either the auxiliaries of the occupied self-energy,
        or virtual if :attr:`gf_occ` and :attr:`gf_vir` are swapped,
        for a single spin.

    Args:
        eri : _ChemistsERIs
            Electronic repulsion integrals
        gf_occ : tuple of GreensFunction
            Occupied Green's function for each spin
        gf_vir : tuple of GreensFunction
            Virtual Green's function for each spin

    Kwargs:
        os_factor : float
            Opposite-spin factor for spin-component-scaled (SCS)
            calculations. Default 1.0
        ss_factor : float
            Same-spin factor for spin-component-scaled (SCS)
            calculations. Default 1.0

    Returns:
        :class:`SelfEnergy`
    '''

    cput0 = (logger.process_clock(), logger.perf_counter())
    log = logger.Logger(agf2.stdout, agf2.verbose)

    assert type(gf_occ[0]) is aux.GreensFunction
    assert type(gf_occ[1]) is aux.GreensFunction
    assert type(gf_vir[0]) is aux.GreensFunction
    assert type(gf_vir[1]) is aux.GreensFunction

    nmo = eri.nmo
    noa, nob = gf_occ[0].naux, gf_occ[1].naux
    nva, nvb = gf_vir[0].naux, gf_vir[1].naux
    tol = agf2.weight_tol
    facs = dict(os_factor=os_factor, ss_factor=ss_factor)

    ci_a, ei_a = gf_occ[0].coupling, gf_occ[0].energy
    ci_b, ei_b = gf_occ[1].coupling, gf_occ[1].energy
    ca_a, ea_a = gf_vir[0].coupling, gf_vir[0].energy
    ca_b, ea_b = gf_vir[1].coupling, gf_vir[1].energy

    mem_incore = (nmo[0] * noa * (noa * nva + nob * nvb)) * 8 / 1e6
    mem_now = lib.current_memory()[0]
    if (mem_incore + mem_now < agf2.max_memory) or agf2.incore_complete:
        qeri = _make_qmo_eris_incore(agf2,
                                     eri, (ci_a, ci_a, ca_a),
                                     (ci_b, ci_b, ca_b),
                                     spin=0)
    else:
        qeri = _make_qmo_eris_outcore(agf2,
                                      eri, (ci_a, ci_a, ca_a),
                                      (ci_b, ci_b, ca_b),
                                      spin=0)

    if isinstance(qeri[0], np.ndarray):
        vv, vev = _agf2.build_mats_uagf2_incore(qeri, (ei_a, ei_b),
                                                (ea_a, ea_b), **facs)
    else:
        vv, vev = _agf2.build_mats_uagf2_outcore(qeri, (ei_a, ei_b),
                                                 (ea_a, ea_b), **facs)

    e, c = _agf2.cholesky_build(vv, vev)
    se_a = aux.SelfEnergy(e, c, chempot=gf_occ[0].chempot)
    se_a.remove_uncoupled(tol=tol)

    if not (agf2.frozen is None or agf2.frozen == 0):
        mask = get_frozen_mask(agf2)
        coupling = np.zeros((nmo[0], se_a.naux))
        coupling[mask[0]] = se_a.coupling
        se_a = aux.SelfEnergy(se_a.energy, coupling, chempot=se_a.chempot)

    cput0 = log.timer('se part (alpha)', *cput0)

    mem_incore = (nmo[1] * nob * (nob * nvb + noa * nva)) * 8 / 1e6
    mem_now = lib.current_memory()[0]
    if (mem_incore + mem_now < agf2.max_memory) or agf2.incore_complete:
        qeri = _make_qmo_eris_incore(agf2,
                                     eri, (ci_a, ci_a, ca_a),
                                     (ci_b, ci_b, ca_b),
                                     spin=1)
    else:
        qeri = _make_qmo_eris_outcore(agf2,
                                      eri, (ci_a, ci_a, ca_a),
                                      (ci_b, ci_b, ca_b),
                                      spin=1)

    if isinstance(qeri[0], np.ndarray):
        vv, vev = _agf2.build_mats_uagf2_incore(qeri, (ei_b, ei_a),
                                                (ea_b, ea_a), **facs)
    else:
        vv, vev = _agf2.build_mats_uagf2_outcore(qeri, (ei_b, ei_a),
                                                 (ea_b, ea_a), **facs)

    e, c = _agf2.cholesky_build(vv, vev)
    se_b = aux.SelfEnergy(e, c, chempot=gf_occ[1].chempot)
    se_b.remove_uncoupled(tol=tol)

    if not (agf2.frozen is None or agf2.frozen == 0):
        mask = get_frozen_mask(agf2)
        coupling = np.zeros((nmo[1], se_b.naux))
        coupling[mask[1]] = se_b.coupling
        se_b = aux.SelfEnergy(se_b.energy, coupling, chempot=se_b.chempot)

    cput0 = log.timer('se part (beta)', *cput0)

    return (se_a, se_b)
Exemple #8
0
def build_se_part(agf2, eri, gf_occ, gf_vir, os_factor=1.0, ss_factor=1.0):
    ''' Builds either the auxiliaries of the occupied self-energy,
        or virtual if :attr:`gf_occ` and :attr:`gf_vir` are swapped.

    Args:
        eri : _ChemistsERIs
            Electronic repulsion integrals
        gf_occ : GreensFunction
            Occupied Green's function
        gf_vir : GreensFunction
            Virtual Green's function

    Kwargs:
        os_factor : float
            Opposite-spin factor for spin-component-scaled (SCS)
            calculations. Default 1.0
        ss_factor : float
            Same-spin factor for spin-component-scaled (SCS)
            calculations. Default 1.0

    Returns:
        :class:`SelfEnergy`
    '''

    cput0 = (logger.process_clock(), logger.perf_counter())
    log = logger.Logger(agf2.stdout, agf2.verbose)

    assert type(gf_occ[0]) is aux.GreensFunction
    assert type(gf_occ[1]) is aux.GreensFunction
    assert type(gf_vir[0]) is aux.GreensFunction
    assert type(gf_vir[1]) is aux.GreensFunction

    nmoa, nmob = eri.nmo
    nocca, nvira = gf_occ[0].naux, gf_vir[0].naux
    noccb, nvirb = gf_occ[1].naux, gf_vir[1].naux
    naux = agf2.with_df.get_naoaux()
    tol = agf2.weight_tol
    facs = dict(os_factor=os_factor, ss_factor=ss_factor)

    ci_a, ei_a = gf_occ[0].coupling, gf_occ[0].energy
    ci_b, ei_b = gf_occ[1].coupling, gf_occ[1].energy
    ca_a, ea_a = gf_vir[0].coupling, gf_vir[0].energy
    ca_b, ea_b = gf_vir[1].coupling, gf_vir[1].energy

    qeri = _make_qmo_eris_incore(agf2, eri, (ci_a, ci_a, ca_a),
                                 (ci_b, ci_b, ca_b))
    (qxi_a, qja_a), (qxi_b, qja_b) = qeri
    qxi = (qxi_a, qxi_b)
    qja = (qja_a, qja_b)

    himem_required = naux * (nvira + nmoa) + (
        nocca * nvira + noccb * nvirb) * (1 + 2 * nmoa) + (2 * nmoa**2)
    himem_required *= 8e-6
    himem_required *= lib.num_threads()

    if ((himem_required * 1.05 + lib.current_memory()[0]) > agf2.max_memory
            and agf2.allow_lowmem_build) or agf2.allow_lowmem_build == 'force':
        log.debug(
            'Thread-private memory overhead %.3f exceeds max_memory, using '
            'low-memory version.', himem_required)
        build_mats_dfuagf2 = _agf2.build_mats_dfuagf2_lowmem
    else:
        build_mats_dfuagf2 = _agf2.build_mats_dfuagf2_incore

    vv, vev = build_mats_dfuagf2(qxi, qja, (ei_a, ei_b), (ea_a, ea_b), **facs)
    e, c = _agf2.cholesky_build(vv, vev)
    se_a = aux.SelfEnergy(e, c, chempot=gf_occ[0].chempot)
    se_a.remove_uncoupled(tol=tol)

    if not (agf2.frozen is None or agf2.frozen == 0):
        mask = uagf2.get_frozen_mask(agf2)
        coupling = np.zeros((nmoa, se_a.naux))
        coupling[mask[0]] = se_a.coupling
        se_a = aux.SelfEnergy(se_a.energy, coupling, chempot=se_a.chempot)

    cput0 = log.timer('se part (alpha)', *cput0)

    himem_required = naux * (nvirb + nmob) + (
        noccb * nvirb + nocca * nvira) * (1 + 2 * nmob) + (2 * nmob**2)
    himem_required *= 8e-6
    himem_required *= lib.num_threads()

    if ((himem_required * 1.05 + lib.current_memory()[0]) > agf2.max_memory
            and agf2.allow_lowmem_build) or agf2.allow_lowmem_build == 'force':
        log.debug(
            'Thread-private memory overhead %.3f exceeds max_memory, using '
            'low-memory version.', himem_required)
        build_mats_dfuagf2 = _agf2.build_mats_dfuagf2_lowmem
    else:
        build_mats_dfuagf2 = _agf2.build_mats_dfuagf2_incore

    rv = np.s_[::-1]
    vv, vev = build_mats_dfuagf2(qxi[rv], qja[rv], (ei_b, ei_a), (ea_b, ea_a),
                                 **facs)
    e, c = _agf2.cholesky_build(vv, vev)
    se_b = aux.SelfEnergy(e, c, chempot=gf_occ[1].chempot)
    se_b.remove_uncoupled(tol=tol)

    if not (agf2.frozen is None or agf2.frozen == 0):
        mask = uagf2.get_frozen_mask(agf2)
        coupling = np.zeros((nmoa, se_b.naux))
        coupling[mask[1]] = se_b.coupling
        se_b = aux.SelfEnergy(se_b.energy, coupling, chempot=se_b.chempot)

    cput0 = log.timer('se part (beta)', *cput0)

    return (se_a, se_b)
Exemple #9
0
    def _build_se_part_spin(spin=0):
        ''' Perform the build for a single spin

        spin = 0: alpha
        spin = 1: beta
        '''

        if spin == 0:
            ab = slice(None)
        else:
            ab = slice(None, None, -1)

        nmoa, nmob = agf2.nmo[ab]
        gfo_a, gfo_b = gf_occ[ab]
        gfv_a, gfv_b = gf_vir[ab]
        noa, nob = gfo_a.naux, gfo_b.naux
        nva, nvb = gfv_a.naux, gfv_b.naux
        naux = nva*noa*(noa-1)//2 + nvb*noa*nob

        if not (agf2.frozen is None or agf2.frozen == 0):
            mask = uagf2.get_frozen_mask(agf2)
            nmoa -= np.sum(~mask[ab][0])
            nmob -= np.sum(~mask[ab][1])

        e = np.zeros((naux))
        v = np.zeros((nmoa, naux))

        falph = np.sqrt(ss_factor)
        fbeta = np.sqrt(os_factor)

        eja_a = lib.direct_sum('j,a->ja', gfo_a.energy, -gfv_a.energy)
        eja_b = lib.direct_sum('j,a->ja', gfo_b.energy, -gfv_b.energy)

        ca = (gf_occ[0].coupling, gf_occ[0].coupling, gf_vir[0].coupling)
        cb = (gf_occ[1].coupling, gf_occ[1].coupling, gf_vir[1].coupling)
        qeri = _make_qmo_eris_incore(agf2, eri, ca, cb, spin=spin)
        qeri_aa, qeri_ab = qeri

        p1 = 0
        for i in range(noa):
            xija_aa = qeri_aa[:,i,:i].reshape(nmoa, -1)
            xjia_aa = qeri_aa[:,:i,i].reshape(nmoa, -1)
            xija_ab = qeri_ab[:,i].reshape(nmoa, -1)

            eija_aa = gfo_a.energy[i] + eja_a[:i]
            eija_ab = gfo_a.energy[i] + eja_b

            p0, p1 = p1, p1 + i*nva
            e[p0:p1] = eija_aa.ravel()
            v[:,p0:p1] = falph * (xija_aa - xjia_aa)

            p0, p1 = p1, p1 + nob*nvb
            e[p0:p1] = eija_ab.ravel()
            v[:,p0:p1] = fbeta * xija_ab

        se = aux.SelfEnergy(e, v, chempot=gfo_a.chempot)
        se.remove_uncoupled(tol=tol)

        if not (agf2.frozen is None or agf2.frozen == 0):
            coupling = np.zeros((agf2.nmo[ab][0], se.naux))
            coupling[mask[ab][0]] = se.coupling
            se = aux.SelfEnergy(se.energy, coupling, chempot=gfo_a.chempot)

        return se