コード例 #1
0
def build_dfmp2(e, qpx, qyz, chempot=0.0, **kwargs):
    ''' Builds a set of auxiliaries representing all (i,j,a) and (a,b,i)
        diagrams. Output is controlled by input dimensions:

        If e is (n,) and qpx (q,n,m):
            restricted, return single `Aux`
        If e is (2,n) and qpx (2,q,n,m):
            unrestricted, return both `Aux`

    Parameters
    ----------
    See either auxgf.aux.build_rmp2.build_rmp2 or 
    auxgf.aux.build_ump2.build_ump2

    Returns
    -------
    poles : Aux
        auxiliaries
    '''

    ndim = util.iter_depth(e)

    if ndim == 1:
        return build_dfrmp2(e, qpx, qyz, chempot=chempot, **kwargs)
    elif ndim == 2:
        a = build_dfump2(e, qpx, qyz, chempot=chempot, **kwargs)
        b = build_dfump2(e[::-1],
                         qpx[::-1],
                         qyz[::-1],
                         chempot=chempot[::-1],
                         **kwargs)
        return a, b
    else:
        raise ValueError
コード例 #2
0
def build_mp2_iter(se, h_phys, eri_mo, **kwargs):
    ''' Builds a set of auxiliaries representing all (i,j,a) and (a,b,i)
        diagrams by iterating the current set of auxiliaries according
        to the eigenvalue form of the Dyson equation.

    Parameters
    ----------
    se : Aux
        auxiliaries of previous iteration
    eri_mo : (n,n,n,n) ndarray
        two-electron repulsion integrals in MO basis
    wtol : float, optional
        threshold for an eigenvalue to be considered zero
    ss_factor : float, optional
        same spin factor, default 1.0
    os_factor : float, optional
        opposite spin factor, default 1.0

    Returns
    -------
    poles : Aux
        auxiliaries
    '''

    ndim = util.iter_depth(se)

    if ndim == 0:
        return build_rmp2_iter(se, h_phys, eri_mo, **kwargs)
    elif ndim == 1:
        return build_ump2_iter(se, h_phys, eri_mo, **kwargs)
    else:
        raise ValueError
コード例 #3
0
def build_mp2_part(eo, ev, xija, **kwargs):
    ''' Builds a set of auxiliaries representing all (i,j,a) or (a,b,i)
        diagrams.

    Parameters
    ----------
    See either auxgf.aux.build_rmp2.build_rmp2_part or
    auxgf.aux.build_ump2.build_ump2_part

    Returns
    -------
    e : (m) ndarray
        auxiliary energies
    v : (n,m) ndarray
        auxiliary couplings
    '''

    ndim = util.iter_depth(eo)

    if ndim == 1:
        return build_rmp2_part(eo, ev, xija, **kwargs)
    elif ndim == 2:
        return build_ump2_part(eo, ev, xija, **kwargs)
    else:
        raise ValueError
コード例 #4
0
def energy_mp2_aux(mo, se, both_sides=False):
    ''' Calculates the two-body contribution to the electronic energy
        using the MOs and the auxiliary representation of the
        self-energy according the the MP2 form of the Galitskii-Migdal
        formula.

    Parameters
    ----------
    mo : (n) ndarray
        MO energies
    se : Aux
        auxiliary representation of self-energy
    both_sides : bool, optional
        if True, calculate both halves of the functional and return
        the mean, default False

    Returns
    -------
    e2b : float
        two-body contribution to electronic energy
    '''

    if isinstance(se, (tuple, list)):
        n = len(se)
        if util.iter_depth(mo) == 2:
            return sum([
                energy_mp2_aux(mo[i], se[i], both_sides=both_sides)
                for i in range(n)
            ]) / n
        else:
            return sum([
                energy_mp2_aux(mo, se[i], both_sides=both_sides)
                for i in range(n)
            ]) / n

    nphys = se.nphys

    occ = mo < se.chempot
    vir = mo >= se.chempot

    vxk = se.v_vir[occ]
    dxk = 1.0 / util.outer_sum([mo[occ], -se.e_vir])

    e2b = util.einsum('xk,xk,xk->', vxk, vxk.conj(), dxk)

    if both_sides:
        vxk = se.v_occ[vir]
        dxk = -1.0 / util.outer_sum([mo[vir], -se.e_occ])

        e2b += util.einsum('xk,xk,xk->', vxk, vxk.conj(), dxk)
        e2b *= 0.5

    return np.ravel(e2b.real)[0]