Beispiel #1
0
Datei: bse.py Projekt: TRIQS/tprf
def fixed_fermionic_window_python_wnk(chi_wnk, nwf):
    r""" Helper routine to reduce the number of fermionic Matsubara 
    frequencies :math:`\nu` in a two frequency and one momenta dependent
    generalized susceptibility :math:`\chi_{abcd}(\omega, \nu, \mathbf{k})`.

    Parameters
    ----------

    chi_wnk : two frequency and one momenta dependent generalized 
              susceptibility :math:`\chi_{abcd}(\omega, \nu, \mathbf{k})`.
    nwf : number of fermionic frequencies to keep.

    Returns
    -------

    chi_wnk_out : Susceptibility with reduced number of fermionic Matsubara
                  frequencies.
    """

    g2 = chi_wnk
    wmesh, nmesh, kmesh = g2.mesh.components

    beta = g2.mesh.components[0].beta
    nmesh_small = MeshImFreq(beta=beta, S='Fermion', n_max=nwf)

    chi_wnk_out = Gf(mesh=MeshProduct(wmesh, nmesh_small, kmesh),
                     target_shape=g2.target_shape)

    n = g2.data.shape[1]
    s = n // 2 - nwf
    e = n // 2 + nwf

    chi_wnk_out.data[:] = g2.data[:, s:e, :]

    return chi_wnk_out
Beispiel #2
0
    def compute_chi0_k(self):

        from triqs.gf import Gf

        chi0_k = Gf(mesh=self.e_k.mesh, target_shape=self.shape_abcd)
        chi0_k.data[:] = self.chi0_kabcd

        return chi0_k
Beispiel #3
0
def Gf_from_struct(mesh, struct):
    # Without block structure
    if not isinstance(struct[0], list):
        return Gf(mesh=mesh, indices=struct)

    # With block structure
    G_lst = []
    for bl, idx_lst in struct:
        G_lst.append(Gf(mesh=mesh, indices=idx_lst))
    return BlockGf(name_list=[bl[0] for bl in struct], block_list=G_lst)
Beispiel #4
0
def ek_tb_dispersion_on_bzmesh(tb_lattice, bzmesh, bz):
    """ Evaluate dispersion on bzmesh from tight binding model. """

    n_orb = tb_lattice.NOrbitalsInUnitCell
    ek = Gf(mesh=bzmesh, target_shape=[n_orb] * 2)

    k_vec = np.array([k.value for k in bzmesh])
    k_vec_rel = get_relative_k_from_absolute(k_vec, bz.units)

    ek.data[:] = tb_lattice.hopping(k_vec_rel.T).transpose(2, 0, 1)

    return ek
Beispiel #5
0
def create_random_gamma_wnn(p):
    wmesh_gamma = MeshImFreq(beta=p.beta, S="Boson", n_max=p.nw_gamma)
    nmesh_gamma = MeshImFreq(beta=p.beta, S="Fermion", n_max=p.nwf)

    gamma_wnn = Gf(
        mesh=MeshProduct(wmesh_gamma, nmesh_gamma, nmesh_gamma),
        target_shape=2 * g0_wk.target_shape,
    )

    np.random.seed(p.seed)
    gamma_wnn.data[:] = np.random.rand(*gamma_wnn.data.shape)

    return gamma_wnn
Beispiel #6
0
def delta_inv(beta, nw, nk=100):

    mesh = MeshImFreq(beta, 'Fermion', n_max=nw)

    Sigma0, Sigma1 = 1.337, 3.5235
    ek = 2.*np.random.random(nk) - 1.

    G = Gf(mesh=mesh, target_shape=[1, 1])
    Sig = G.copy()
    for w in Sig.mesh:
        Sig[w][:] = Sigma0 + Sigma1 /w
 
    for e in ek: G << G + inverse(iOmega_n - e - Sig)

    G /= nk

    Delta = G.copy()
    Delta << inverse(G) - iOmega_n + Sig

    sum_ek = - np.sum(ek) / nk

    Roo = np.abs(Sigma0) + 1.

    w = [ w for w in mesh ]
    wmax = np.abs(w[-1].value)

    tail, err = Delta.fit_tail()

    order = len(tail)

    trunc_err_anal = (Roo / (0.8 * wmax))**order

    ratio = tail[0] / sum_ek
    diff = np.abs(1 - ratio)

    print('-' * 72)
    print('beta =', beta)
    print('nw =', nw)
    print('wmax =', wmax)
    print('tail_fit order =', len(tail))
    print('tail_fit err =', err)
    print(tail[:3])
    #print sum_ek
    print('trunc_err_anal =', trunc_err_anal)
    print('ratio =', ratio)
    print('diff =', diff)

    return diff[0, 0]
Beispiel #7
0
def setup_dmft_calculation(p):

    p = copy.deepcopy(p)
    p.iter = 0

    # -- Local Hubbard interaction
    from triqs.operators import n
    p.solve.h_int = p.U * n('up', 0) * n(
        'do', 0) - 0.5 * p.U * (n('up', 0) + n('do', 0))

    # -- 2D square lattice w. nearest neighbour hopping t
    from triqs_tprf.tight_binding import TBLattice
    T = -p.t * np.eye(2)
    H = TBLattice(units=[(1, 0, 0), (0, 1, 0)],
                  orbital_positions=[(0, 0, 0)] * 2,
                  orbital_names=['up', 'do'],
                  hopping={
                      (0, +1): T,
                      (0, -1): T,
                      (+1, 0): T,
                      (-1, 0): T
                  })

    kmesh = H.get_kmesh(n_k=(p.n_k, p.n_k, 1))
    p.e_k = H.fourier(kmesh)

    # -- Initial zero guess for the self-energy
    p.sigma_w = Gf(mesh=MeshImFreq(p.init.beta, 'Fermion', p.init.n_iw),
                   target_shape=[2, 2])
    p.sigma_w.zero()

    return p
Beispiel #8
0
def convert_from_ndarray_to_triqs(U_Q, Q, cell, kpts):

    from triqs.gf import Gf, MeshBrZone
    from triqs.lattice.lattice_tools import BrillouinZone
    from triqs.lattice.lattice_tools import BravaisLattice

    bl = BravaisLattice(cell, [(0, 0, 0)])
    bz = BrillouinZone(bl)
    bzmesh = MeshBrZone(bz, np.diag(np.array(kpts, dtype=np.int32)))

    u_q = Gf(mesh=bzmesh, target_shape=U_Q.shape[1:])

    tmp = np.array(Q * kpts[None, :], dtype=np.int)
    I = [tuple(tmp[i]) for i in range(Q.shape[0])]

    for qidx, i in enumerate(I):
        for k in bzmesh:

            # -- Generalize this transform absolute to relative k-points
            a = cell[0, 0]
            q = k * 0.5 * a / np.pi

            j = tuple(np.array(kpts * q, dtype=np.int))
            if i == j: u_q[k].data[:] = U_Q[qidx]

    return u_q
Beispiel #9
0
def test_add_fake_bosonic_mesh_with_gf_k_without_beta(bzmesh):
    gf_k = Gf(mesh=bzmesh, target_shape=(2, 2))

    try:
        gf_wk = add_fake_bosonic_mesh(gf_k)
    except ValueError:
        pass
Beispiel #10
0
def test_add_fake_bosonic_mesh_with_gf_k_with_beta(bzmesh):
    gf_k = Gf(mesh=bzmesh, target_shape=(2, 2))
    beta = 10
    gf_wk = add_fake_bosonic_mesh(gf_k, beta=beta)

    np.testing.assert_allclose(gf_k.data, gf_wk[Idx(0), :].data)
    assert gf_wk.mesh[0].beta == beta
Beispiel #11
0
def test_add_fake_bosonic_mesh_with_gf_nk(bzmesh):
    nmesh = MeshImFreq(beta=1, S="Fermion", n_max=1)

    gf_nk = Gf(mesh=MeshProduct(nmesh, bzmesh), target_shape=(2, 2))
    gf_wnk = add_fake_bosonic_mesh(gf_nk)

    np.testing.assert_allclose(gf_nk.data, gf_wnk[Idx(0), :, :].data)
Beispiel #12
0
def solve_lattice_bse(parm, momsus=False):

    print('--> solve_lattice_bse')

    print('nw =', parm.nw)
    print('nwf =', parm.nwf)
    
    # ------------------------------------------------------------------
    # -- Setup lattice

    bl = BravaisLattice([(1,0,0), (0,1,0)])

    bz = BrillouinZone(bl)    
    bzmesh = MeshBrZone(bz, n_k=1) # only one k-point
    
    e_k = Gf(mesh=bzmesh, target_shape=[1, 1])
    e_k *= 0.
          
    # ------------------------------------------------------------------
    # -- Lattice single-particle Green's function

    mesh = MeshImFreq(beta=parm.beta, S='Fermion', n_max=parm.nwf_gf)

    parm.Sigma_iw = parm.G_iw.copy()
    G0_iw = parm.G_iw.copy()

    G0_iw << inverse(iOmega_n + 0.5*parm.U)
    parm.Sigma_iw << inverse(G0_iw) - inverse(parm.G_iw)
    
    parm.mu = 0.5*parm.U
    g_wk = lattice_dyson_g_wk(mu=parm.mu, e_k=e_k, sigma_w=parm.Sigma_iw)
    g_wr = fourier_wk_to_wr(g_wk)

    # ------------------------------------------------------------------
    # -- Non-interacting generalized lattice susceptibility

    chi0_wr = chi0r_from_gr_PH(nw=parm.nw, nnu=parm.nwf, gr=g_wr) 
    chi0_wk = chi0q_from_chi0r(chi0_wr)

    # ------------------------------------------------------------------
    # -- Solve lattice BSE

    parm.chi_wk = chiq_from_chi0q_and_gamma_PH(chi0_wk, parm.gamma_m)

    # ------------------------------------------------------------------
    # -- Store results and static results
    
    num = np.squeeze(parm.chi_wk.data.real)
    ref = np.squeeze(parm.chi_m.data.real)
    
    diff = np.max(np.abs(num - ref))
    print('diff =', diff)
    
    parm.chi_w = chiq_sum_nu_q(parm.chi_wk) # static suscept
    
    return parm
Beispiel #13
0
def put_gf_on_mesh(g_in, wmesh):

    assert (len(wmesh) <= len(g_in.mesh))

    g_out = Gf(mesh=wmesh, target_shape=g_in.target_shape)

    for w in wmesh:
        index = w.linear_index + wmesh.first_index()  # absolute index
        g_out[w] = g_in[Idx(index)]

    return g_out
Beispiel #14
0
def G2_loc_fixed_fermionic_window_python(g2, nwf):
    """ Limit the last two fermionic freqiencies of a three
    frequency Green's function object :math:`G(\omega, \nu, \nu')`
    to ``nwf``. """

    nw = (g2.data.shape[0] + 1) // 2
    n = g2.data.shape[1]
    beta = g2.mesh.components[0].beta

    assert (n // 2 >= nwf)

    mesh_iw = MeshImFreq(beta=beta, S='Boson', n_max=nw)
    mesh_inu = MeshImFreq(beta=beta, S='Fermion', n_max=nwf)
    mesh_prod = MeshProduct(mesh_iw, mesh_inu, mesh_inu)

    g2_out = Gf(mesh=mesh_prod, target_shape=g2.target_shape)

    s = n // 2 - nwf
    e = n // 2 + nwf

    g2_out.data[:] = g2.data[:, s:e, s:e]
    return g2_out
Beispiel #15
0
def general_susceptibility_from_charge_and_spin(chi_c, chi_s, spin_fast=True):
    """Construct a general susceptibility (spin dependent) from chi spin and charge

    Parameters:

    chi_c: Greens function, the charge susceptibility
    chi_s: Greens function, the spin susceptibility
    spin_fast: bool, True if spin is the fast index, e.g.
                        xz up, xz down, xy up, xy down, yz up, yz down,
                    or False if spin is the slow index, e.g.
                        xz up, xy up, yz up, xz down, xy down, yz down.
    """

    norb = chi_c.target_shape[-1]
    rank = chi_c.rank
    target_rank = chi_c.target_rank

    chi_general = Gf(mesh=chi_c.mesh, target_shape=target_rank * (2 * norb, ))

    chi_uu = 0.5 * (chi_c + chi_s)
    chi_ud = 0.5 * (chi_c - chi_s)
    chi_xud = chi_s

    idx_rank = rank * (slice(None), )

    if spin_fast:
        up = slice(None, None, 2)
        down = slice(1, None, 2)

    else:
        up = slice(norb)
        down = slice(norb, None)

    chi_general.data[idx_rank + (up, up, up, up)] = chi_uu.data
    chi_general.data[idx_rank + (down, down, down, down)] = chi_uu.data
    chi_general.data[idx_rank + (up, up, down, down)] = chi_ud.data
    chi_general.data[idx_rank + (down, down, up, up)] = chi_ud.data
    chi_general.data[idx_rank + (up, down, down, up)] = chi_xud.data
    chi_general.data[idx_rank + (down, up, up, down)] = chi_xud.data

    return chi_general
Beispiel #16
0
def strip_sigma(nw, beta, sigma_in, debug=False):

    np.testing.assert_almost_equal(beta, sigma_in.mesh.beta)

    wmesh = MeshImFreq(beta, 'Fermion', n_max=nw)
    sigma = Gf(mesh=wmesh, target_shape=sigma_in.target_shape)

    for w in wmesh:
        index = w.linear_index + wmesh.first_index()  # absolute index
        sigma[w] = sigma_in[Idx(index)]

    if debug:
        from triqs.plot.mpl_interface import oplot, plt
        oplot(p.Sigmalatt_iw)
        oplot(sigma, 'x')
        plt.show()
        exit()

    return sigma
Beispiel #17
0
def add_fake_bosonic_mesh(gf, beta=None):
    """ Put a one value bosonic mesh as the first mesh argument of a 
    Green's function object.

    Parameters
    ----------
    gf : Gf,
         Green's function on some arbitrary mesh. If 'beta' is not given
         one mesh needs to be a 'MeshImFreq' to obtain a beta'
    beta : float, optional
           The inverse temperature used for the fake bosonic mesh.

    Returns
    -------
    gf_w : Gf,
           Green's function with an additional one value bosonic mesh
           on its first position.
    """
    mesh = gf.mesh
    if isinstance(mesh, MeshProduct):
        meshes = mesh.components
    else:
        meshes = (mesh, )

    # If beta is not given access it from a 'MeshImFreq' of the 'Gf'
    if not beta:
        betas = [mesh.beta for mesh in meshes if hasattr(mesh, "beta")]
        if len(betas) == 0:
            raise ValueError(
                "No 'beta' was given and the Green's function does not contain"
                " a 'MeshImFreq'")
        beta = betas[0]

    wmesh = MeshImFreq(beta, 'Boson', 1)
    mesh = (wmesh, ) + meshes
    mesh = MeshProduct(*mesh)

    gf_w = Gf(mesh=mesh, target_shape=gf.target_shape)
    gf_w.data[0, ...] = gf.data

    return gf_w
Beispiel #18
0
beta = 20.0
n_k = 20
nw_g = 512
mu = 0.0
nw = 10
nnu = 100

# -- BZ-sampling

bz = BrillouinZone(BravaisLattice([[1, 0], [0, 1]]))
bzmesh = MeshBrZone(bz, n_k=n_k)
q_list = [q for q in bzmesh]

# -- Dispersion

ek = Gf(mesh=bzmesh, target_shape=[1, 1])
for idx, k in enumerate(bzmesh):
    #ek[k] = -2*t*(np.cos(k[0]) + np.cos(k[1])) # does not work...
    ek.data[idx] = -2 * (np.cos(k[0]) + np.cos(k[1]))

mesh = MeshImFreq(beta=beta, S='Fermion', n_max=nw_g)
bmesh = MeshImFreq(beta=beta, S='Boson', n_max=nw)

iw_list = np.array([iw for iw in bmesh])
iw_zero_idx = np.where(iw_list == 0)[0][0]

# -- Lattice single-particle Green's function

g0k = g0k_from_ek(mu=mu, ek=ek, mesh=mesh)
g0r = gr_from_gk(g0k)
Beispiel #19
0
    g_iwn = GfImFreq(name='$g$', beta=beta,
                     statistic='Fermion', n_points=10,
                     target_shape=(1,1))

    ed.set_g2_tau(g_tau[0,0], c(up,0), c_dag(up,0))
    ed.set_g2_iwn(g_iwn[0,0], c(up,0), c_dag(up,0))

    # ------------------------------------------------------------------
    # -- Two particle Green's functions

    ntau = 20
    imtime = MeshImTime(beta, 'Fermion', ntau)
    prodmesh = MeshProduct(imtime, imtime, imtime)

    g40_tau = Gf(name='g40_tau', mesh=prodmesh, target_shape=[1, 1, 1, 1])
    g4_tau = Gf(name='g4_tau', mesh=prodmesh, target_shape=[1, 1, 1, 1])

    ed.set_g40_tau(g40_tau, g_tau[0,0])
    ed.set_g4_tau(g4_tau[0,0,0,0], c(up,0), c_dag(up,0), c(up,0), c_dag(up,0))

    # ------------------------------------------------------------------
    # -- Two particle Green's functions (equal times)

    prodmesh = MeshProduct(imtime, imtime)
    g3pp_tau = Gf(name='g4_tau', mesh=prodmesh, target_shape=[1, 1, 1, 1])
    ed.set_g3_tau(g3pp_tau[0,0,0,0], c(up,0), c_dag(up,0), c(up,0)*c_dag(up,0))

    # ------------------------------------------------------------------
    # -- Store to hdf5
Beispiel #20
0
from triqs.lattice import BravaisLattice, BrillouinZone
from triqs.gf import Gf, MeshProduct, MeshBrillouinZone, MeshImFreq

n_k = 32
n_w = 20
t=1
beta = 10.

BL = BravaisLattice([(1, 0, 0), (0, 1, 0)]) # Two unit vectors in R3
BZ = BrillouinZone(BL)

kmesh = MeshBrillouinZone(BZ, n_k=n_k)
wmesh = MeshImFreq(beta=beta, S='Fermion', n_max=n_w)

g0 = Gf(mesh=MeshProduct(wmesh, kmesh), target_shape=[])  # g0(k,omega), scalar valued

def eps(k):
    return -2 * t* (np.cos(k.value[0]) + np.cos(k.value[1]))

# NB : loop is a bit slow in python ...
for k in g0.mesh[1]:
    for w in g0.mesh[0]:
        g0[w,k] = 1/(w - eps(k))

#name = "gd_k"
#G_k = HDFArchive(name+".h5",'r')[name]


spin = 'up'
Beispiel #21
0
def make_calc():

    # ------------------------------------------------------------------
    # -- Hubbard atom with two bath sites, Hamiltonian

    p = ParameterCollection(
        beta=1.0,
        U=5.0,
        nw=1,
        nwf=20,
    )

    p.nwf_gf = 4 * p.nwf
    p.mu = 0.5 * p.U

    # ------------------------------------------------------------------

    ca_up, cc_up = c('0', 0), c_dag('0', 0)
    ca_do, cc_do = c('0', 1), c_dag('0', 1)

    docc = cc_up * ca_up * cc_do * ca_do
    nA = cc_up * ca_up + cc_do * ca_do
    p.H = -p.mu * nA + p.U * docc

    # ------------------------------------------------------------------
    # -- Exact diagonalization

    # Conversion from TRIQS to Pomerol notation for operator indices
    # TRIQS:   block_name, inner_index
    # Pomerol: site_label, orbital_index, spin_name
    index_converter = {
        ('0', 0): ('loc', 0, 'up'),
        ('0', 1): ('loc', 0, 'down'),
    }

    # -- Create Exact Diagonalization instance
    ed = PomerolED(index_converter, verbose=True)
    ed.diagonalize(p.H)  # -- Diagonalize H

    gf_struct = [['0', [0, 1]]]

    # -- Single-particle Green's functions
    p.G_iw = ed.G_iw(gf_struct, p.beta, n_iw=p.nwf_gf)['0']

    # -- Particle-particle two-particle Matsubara frequency Green's function
    opt = dict(beta=p.beta,
               gf_struct=gf_struct,
               blocks=set([("0", "0")]),
               n_iw=p.nw,
               n_inu=p.nwf)

    p.G2_iw_ph = ed.G2_iw_inu_inup(channel='PH', **opt)[('0', '0')]

    # ------------------------------------------------------------------
    # -- Generalized susceptibility in magnetic PH channel

    p.chi_m = Gf(mesh=p.G2_iw_ph.mesh, target_shape=[1, 1, 1, 1])
    p.chi_m[0, 0, 0, 0] = p.G2_iw_ph[0, 0, 0, 0] - p.G2_iw_ph[0, 0, 1, 1]

    p.chi0_m = chi0_from_gg2_PH(p.G_iw, p.chi_m)
    p.label = r'Pomerol'

    # ------------------------------------------------------------------
    # -- Generalized susceptibility in PH channel

    p.chi = chi_from_gg2_PH(p.G_iw, p.G2_iw_ph)
    p.chi0 = chi0_from_gg2_PH(p.G_iw, p.G2_iw_ph)
    p.gamma = inverse_PH(p.chi0) - inverse_PH(p.chi)

    # ------------------------------------------------------------------
    # -- Store to hdf5

    filename = 'data_pomerol.h5'
    with HDFArchive(filename, 'w') as res:
        res['p'] = p
Beispiel #22
0
Datei: bse.py Projekt: TRIQS/tprf
def solve_lattice_bse_at_specific_w(g_wk, gamma_wnn, nw_index):
    r""" Compute the generalized lattice susceptibility 
    :math:`\chi_{\bar{a}b\bar{c}d}(i\omega_{n=\mathrm{nw\_index}}, \mathbf{k})` using the Bethe-Salpeter 
    equation (BSE) for a specific :math:`i\omega_{n=\mathrm{nw\_index}}`.


    Parameters
    ----------

    g_wk : Gf,
           Single-particle Green's function :math:`G_{a\bar{b}}(i\nu_n, \mathbf{k})`.
    gamma_wnn : Gf,
                Local particle-hole vertex function 
                :math:`\Gamma_{a\bar{b}c\bar{d}}(i\omega_n, i\nu_n, i\nu_n')`.
    nw_index : int,
               The bosonic Matsubara frequency index :math:`i\omega_{n=\mathrm{nw\_index}}`
               at which the BSE is solved.

    Returns
    -------
    chi_k : Gf,
            Generalized lattice susceptibility 
            :math:`\chi_{\bar{a}b\bar{c}d}(i\omega_{n=\mathrm{nw\_index}}, \mathbf{k})`.

    chi0_k : Gf,
             Generalized bare lattice susceptibility 
             :math:`\chi^0_{\bar{a}b\bar{c}d}(i\omega_{n=\mathrm{nw\_index}}, \mathbf{k})`.
    """

    # Only use \Gamma at the specific \omega
    gamma_nn = gamma_wnn[Idx(nw_index), :, :]
    # Keep fake bosonic mesh for usability with other functions
    gamma_wnn = add_fake_bosonic_mesh(gamma_nn)

    fmesh_g = g_wk.mesh.components[0]
    kmesh = g_wk.mesh.components[1]

    bmesh = gamma_wnn.mesh.components[0]
    fmesh = gamma_wnn.mesh.components[1]

    nk = len(kmesh)
    nwf = len(fmesh) // 2
    nwf_g = len(fmesh_g) // 2

    if mpi.is_master_node():
        print(tprf_banner(), "\n")
        print(
            'Lattcie BSE with local vertex approximation at specific \omega.\n'
        )
        print('nk    =', nk)
        print('nw_index    =', nw_index)
        print('nwf   =', nwf)
        print('nwf_g =', nwf_g)
        print()

    mpi.report('--> chi0_wk_tail_corr')
    # Calculate chi0_wk up to the specific \omega
    chi0_wk_tail_corr = imtime_bubble_chi0_wk(g_wk,
                                              nw=np.abs(nw_index) + 1,
                                              save_memory=True)
    # Only use specific \omega, but put back on fake bosonic mesh
    chi0_k_tail_corr = chi0_wk_tail_corr[Idx(nw_index), :]
    chi0_wk_tail_corr = add_fake_bosonic_mesh(chi0_k_tail_corr,
                                              beta=bmesh.beta)

    chi0_nk = get_chi0_nk_at_specific_w(g_wk, nw_index=nw_index, nwf=nwf)
    # Keep fake bosonic mesh for usability with other functions
    chi0_wnk = add_fake_bosonic_mesh(chi0_nk)

    mpi.report('--> trace chi0_wnk')
    chi0_wk = chi0q_sum_nu(chi0_wnk)

    dchi_wk = chi0_wk_tail_corr - chi0_wk

    chi0_kw = Gf(mesh=MeshProduct(kmesh, bmesh),
                 target_shape=chi0_wk_tail_corr.target_shape)
    chi0_kw.data[:] = chi0_wk_tail_corr.data.swapaxes(0, 1)

    del chi0_wk
    del chi0_wk_tail_corr

    assert (chi0_wnk.mesh.components[0] == bmesh)
    assert (chi0_wnk.mesh.components[1] == fmesh)
    assert (chi0_wnk.mesh.components[2] == kmesh)

    # -- Lattice BSE calc with built in trace
    mpi.report('--> chi_kw from BSE')
    #mpi.report('DEBUG BSE INACTIVE'*72)
    chi_kw = chiq_sum_nu_from_chi0q_and_gamma_PH(chi0_wnk, gamma_wnn)
    #chi_kw = chi0_kw.copy()

    mpi.barrier()
    mpi.report('--> chi_kw from BSE (done)')

    del chi0_wnk

    mpi.report('--> chi_kw tail corrected (using chi0_wnk)')
    for k in kmesh:
        chi_kw[
            k, :] += dchi_wk[:,
                             k]  # -- account for high freq of chi_0 (better than nothing)

    del dchi_wk

    mpi.report('--> solve_lattice_bse, done.')

    chi_k = chi_kw[:, Idx(0)]
    del chi_kw

    chi0_k = chi0_kw[:, Idx(0)]
    del chi0_kw

    return chi_k, chi0_k
Beispiel #23
0
Datei: bse.py Projekt: TRIQS/tprf
def solve_lattice_bse(g_wk, gamma_wnn):
    r""" Compute the generalized lattice susceptibility 
    :math:`\chi_{\bar{a}b\bar{c}d}(\mathbf{k}, \omega_n)` using the Bethe-Salpeter 
    equation (BSE).

    Parameters
    ----------

    g_wk : Gf,
           Single-particle Green's function :math:`G_{a\bar{b}}(i\nu_n, \mathbf{k})`.
    gamma_wnn : Gf,
                Local particle-hole vertex function 
                :math:`\Gamma_{a\bar{b}c\bar{d}}(i\omega_n, i\nu_n, i\nu_n')`.

    Returns
    -------
    chi_kw : Gf,
             Generalized lattice susceptibility 
             :math:`\chi_{\bar{a}b\bar{c}d}(\mathbf{k}, i\omega_n)`.

    chi0_kw : Gf,
              Generalized bare lattice susceptibility 
              :math:`\chi^0_{\bar{a}b\bar{c}d}(\mathbf{k}, i\omega_n)`.
    """

    fmesh_g = g_wk.mesh.components[0]
    kmesh = g_wk.mesh.components[1]

    bmesh = gamma_wnn.mesh.components[0]
    fmesh = gamma_wnn.mesh.components[1]

    nk = len(kmesh)
    nw = (len(bmesh) + 1) // 2
    nwf = len(fmesh) // 2
    nwf_g = len(fmesh_g) // 2

    if mpi.is_master_node():
        print(tprf_banner(), "\n")
        print('Lattcie BSE with local vertex approximation.\n')
        print('nk    =', nk)
        print('nw    =', nw)
        print('nwf   =', nwf)
        print('nwf_g =', nwf_g)
        print()

    mpi.report('--> chi0_wk_tail_corr')
    chi0_wk_tail_corr = imtime_bubble_chi0_wk(g_wk, nw=nw)

    mpi.barrier()
    mpi.report('B1 ' +
               str(chi0_wk_tail_corr[Idx(0), Idx(0, 0, 0)][0, 0, 0, 0]))
    mpi.barrier()

    chi0_wnk = get_chi0_wnk(g_wk, nw=nw, nwf=nwf)

    mpi.barrier()
    mpi.report('C ' + str(chi0_wnk[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0]))
    mpi.barrier()

    mpi.report('--> trace chi0_wnk')
    chi0_wk = chi0q_sum_nu(chi0_wnk)

    mpi.barrier()
    mpi.report('D ' + str(chi0_wk[Idx(0), Idx(0, 0, 0)][0, 0, 0, 0]))
    mpi.barrier()

    dchi_wk = chi0_wk_tail_corr - chi0_wk

    chi0_kw = Gf(mesh=MeshProduct(kmesh, bmesh),
                 target_shape=chi0_wk_tail_corr.target_shape)
    chi0_kw.data[:] = chi0_wk_tail_corr.data.swapaxes(0, 1)

    del chi0_wk
    del chi0_wk_tail_corr

    assert (chi0_wnk.mesh.components[0] == bmesh)
    assert (chi0_wnk.mesh.components[1] == fmesh)
    assert (chi0_wnk.mesh.components[2] == kmesh)

    # -- Lattice BSE calc with built in trace
    mpi.report('--> chi_kw from BSE')
    #mpi.report('DEBUG BSE INACTIVE'*72)
    chi_kw = chiq_sum_nu_from_chi0q_and_gamma_PH(chi0_wnk, gamma_wnn)
    #chi_kw = chi0_kw.copy()

    mpi.barrier()
    mpi.report('--> chi_kw from BSE (done)')

    del chi0_wnk

    mpi.report('--> chi_kw tail corrected (using chi0_wnk)')
    for k in kmesh:
        chi_kw[
            k, :] += dchi_wk[:,
                             k]  # -- account for high freq of chi_0 (better than nothing)

    del dchi_wk

    mpi.report('--> solve_lattice_bse, done.')

    return chi_kw, chi0_kw
Beispiel #24
0
# ----------------------------------------------------------------------

p = ParameterCollection(beta = 10,
                        nw = 10,
                        nk = 4,
                        norb = 2,)

wmesh = MeshImFreq(beta=p.beta, S='Fermion', n_max=p.nw)

cell = np.eye(3)
bl = BravaisLattice(cell)
bz = BrillouinZone(bl)
kmesh = MeshBrZone(bz, p.nk * np.eye(3, dtype=int))

gf = Gf(mesh=MeshProduct(wmesh, kmesh), target_shape=2*(p.norb,))
gf.data[:] = np.random.rand(*gf.data.shape)

# -- Eexception handling
try:
    enforce_symmetry(gf, "something", "odd")
except ValueError as error:
    if not str(error) == "No symmetrize function for this variable exists.":
        raise Exception("Wrong exception was raised: \n %s"%error)
else:
    raise Exception("Function call should have failed.")

try:
    enforce_symmetry(gf, "frequency", "weird")
except ValueError as error:
    if not str(error) == "Symmetry can only be 'even' or 'odd'.":
Beispiel #25
0
def test_two_particle_greens_function():

    # ------------------------------------------------------------------
    # -- Hubbard atom with two bath sites, Hamiltonian

    beta = 2.0
    V1 = 2.0
    V2 = 5.0
    epsilon1 = 0.00
    epsilon2 = 4.00
    mu = 2.0
    U = 0.0

    up, do = 0, 1
    docc = c_dag(up, 0) * c(up, 0) * c_dag(do, 0) * c(do, 0)
    nA = c_dag(up, 0) * c(up, 0) + c_dag(do, 0) * c(do, 0)
    nB = c_dag(up, 1) * c(up, 1) + c_dag(do, 1) * c(do, 1)
    nC = c_dag(up, 2) * c(up, 2) + c_dag(do, 2) * c(do, 2)

    H = -mu * nA + epsilon1 * nB + epsilon2 * nC + U * docc + \
        V1 * (c_dag(up, 0) * c(up, 1) + c_dag(up, 1) * c(up, 0) +
              c_dag(do, 0) * c(do, 1) + c_dag(do, 1) * c(do, 0)) + \
        V2 * (c_dag(up, 0) * c(up, 2) + c_dag(up, 2) * c(up, 0) +
              c_dag(do, 0) * c(do, 2) + c_dag(do, 2) * c(do, 0))

    # ------------------------------------------------------------------
    # -- Exact diagonalization

    fundamental_operators = [
        c(up, 0), c(do, 0),
        c(up, 1), c(do, 1),
        c(up, 2), c(do, 2)
    ]

    ed = TriqsExactDiagonalization(H, fundamental_operators, beta)

    # ------------------------------------------------------------------
    # -- single particle Green's functions

    g_tau = GfImTime(name=r'$g$',
                     beta=beta,
                     statistic='Fermion',
                     n_points=100,
                     target_shape=(1, 1))

    ed.set_g2_tau(g_tau[0, 0], c(up, 0), c_dag(up, 0))

    # ------------------------------------------------------------------
    # -- Two particle Green's functions

    ntau = 10
    imtime = MeshImTime(beta, 'Fermion', ntau)
    prodmesh = MeshProduct(imtime, imtime, imtime)

    g40_tau = Gf(name='g40_tau', mesh=prodmesh, target_shape=(1, 1, 1, 1))
    g4_tau = Gf(name='g4_tau', mesh=prodmesh, target_shape=(1, 1, 1, 1))

    ed.set_g40_tau_matrix(g40_tau, g_tau)
    ed.set_g4_tau(g4_tau[0, 0, 0, 0], c(up, 0), c_dag(up, 0), c(up, 0),
                  c_dag(up, 0))

    # ------------------------------------------------------------------
    # -- compare

    zero_outer_planes_and_equal_times(g4_tau)
    zero_outer_planes_and_equal_times(g40_tau)
    np.testing.assert_array_almost_equal(g4_tau.data, g40_tau.data)
def trace_nn(G2_wnn):
    bmesh = G2_wnn.mesh.components[0]
    G2_w = Gf(mesh=bmesh, target_shape=G2_wnn.target_shape)
    G2_w.data[:] = np.sum(G2_wnn.data, axis=(1, 2)) / bmesh.beta**2
    return G2_w
Beispiel #27
0
for tau in g_tau.mesh:
    g_tau[tau] = np.exp(-beta * tau)

for idx, tau in enumerate(g_tau.mesh):

    # comparison does not work at beta since the evaluation g_tau() wraps..
    if idx == len(g_tau.mesh) - 1: break

    #diff_interp = g_tau(tau)[0,0] - g_ref[idx] # FIXME: tau is complex

    diff_interp = g_tau(tau.real)[0, 0] - g_ref[idx]
    diff_dbrack = g_tau[tau][0, 0] - g_ref[idx]

    np.testing.assert_almost_equal(diff_interp, 0.0)
    np.testing.assert_almost_equal(diff_dbrack, 0.0)

# -- three imaginary time gf

imtime = MeshImTime(beta=beta, S='Fermion', n_max=ntau)
g4_tau = Gf(name='g4_tau',
            mesh=MeshProduct(imtime, imtime, imtime),
            indices=[1])

for t1, t2, t3 in g4_tau.mesh:
    g4_tau[t1, t2, t3] = g_tau(t1) * g_tau(t3) - g_tau(t1) * g_tau(t3)

for t1, t2, t3 in g4_tau.mesh:
    val = g4_tau[t1, t2, t3]
    val_ref = g_tau(t1) * g_tau(t3) - g_tau(t1) * g_tau(t3)
    np.testing.assert_array_almost_equal(val, val_ref)
def make_calc():

    # ------------------------------------------------------------------
    # -- Read precomputed ED data

    filename = "data_pomerol.tar.gz"
    p = read_TarGZ_HDFArchive(filename)

    # ------------------------------------------------------------------
    # -- RPA tensor

    from triqs_tprf.rpa_tensor import get_rpa_tensor
    from triqs_tprf.rpa_tensor import fundamental_operators_from_gf_struct

    fundamental_operators = fundamental_operators_from_gf_struct(p.gf_struct)
    p.U_abcd = get_rpa_tensor(p.H_int, fundamental_operators)

    # ------------------------------------------------------------------
    # -- Generalized PH susceptibility

    loc_bse = ParameterCollection()

    loc_bse.chi_wnn = chi_from_gg2_PH(p.G_iw, p.G2_iw_ph)
    loc_bse.chi0_wnn = chi0_from_gg2_PH(p.G_iw, p.G2_iw_ph)

    loc_bse.gamma_wnn = inverse_PH(loc_bse.chi0_wnn) - inverse_PH(
        loc_bse.chi_wnn)
    loc_bse.chi_wnn_ref = inverse_PH(
        inverse_PH(loc_bse.chi0_wnn) - loc_bse.gamma_wnn)

    np.testing.assert_array_almost_equal(loc_bse.chi_wnn.data,
                                         loc_bse.chi_wnn_ref.data)

    loc_bse.chi0_w = trace_nn(loc_bse.chi0_wnn)
    loc_bse.chi_w = trace_nn(loc_bse.chi_wnn)

    # ------------------------------------------------------------------
    # -- RPA, using BSE inverses and constant Gamma

    loc_rpa = ParameterCollection()
    loc_rpa.U_abcd = p.U_abcd

    # -- Build constant gamma
    loc_rpa.gamma_wnn = loc_bse.gamma_wnn.copy()
    loc_rpa.gamma_wnn.data[:] = loc_rpa.U_abcd[None, None, None, ...]
    # Nb! In the three frequency form $\Gamma \propto U/\beta^2$
    loc_rpa.gamma_wnn.data[:] /= p.beta**2

    loc_rpa.chi0_wnn = loc_bse.chi0_wnn
    loc_rpa.chi0_w = loc_bse.chi0_w

    # -- Solve RPA
    loc_rpa.chi_wnn = inverse_PH(
        inverse_PH(loc_rpa.chi0_wnn) - loc_rpa.gamma_wnn)
    loc_rpa.chi_w = trace_nn(loc_rpa.chi_wnn)

    # ------------------------------------------------------------------
    # -- Bubble RPA on lattice

    lat_rpa = ParameterCollection()

    # -- Setup dummy lattice Green's function equal to local Green's function

    bz = BrillouinZone(
        BravaisLattice(units=np.eye(3), orbital_positions=[(0, 0, 0)]))
    periodization_matrix = np.diag(np.array(list([1] * 3), dtype=np.int32))
    kmesh = MeshBrZone(bz, periodization_matrix)
    wmesh = MeshImFreq(beta=p.beta, S='Fermion', n_max=p.nwf_gf)

    lat_rpa.g_wk = Gf(mesh=MeshProduct(wmesh, kmesh),
                      target_shape=p.G_iw.target_shape)
    lat_rpa.g_wk[:, Idx(0, 0, 0)] = p.G_iw

    # -- chi0_wk bubble and chi_wk_rpa bubble RPA

    from triqs_tprf.lattice_utils import imtime_bubble_chi0_wk
    lat_rpa.chi0_wk = imtime_bubble_chi0_wk(lat_rpa.g_wk, nw=1)

    from triqs_tprf.lattice import solve_rpa_PH
    lat_rpa.chi_wk = solve_rpa_PH(lat_rpa.chi0_wk, p.U_abcd)

    lat_rpa.chi0_w = lat_rpa.chi0_wk[:, Idx(0, 0, 0)]
    lat_rpa.chi_w = lat_rpa.chi_wk[:, Idx(0, 0, 0)]

    print('--> cf Tr[chi0] and chi0_wk')
    print(loc_rpa.chi0_w.data.reshape((4, 4)).real)
    print(lat_rpa.chi0_w.data.reshape((4, 4)).real)

    np.testing.assert_array_almost_equal(loc_rpa.chi0_w.data,
                                         lat_rpa.chi0_w.data,
                                         decimal=2)

    print('ok!')

    print('--> cf Tr[chi_rpa] and chi_wk_rpa')
    print(loc_rpa.chi_w.data.reshape((4, 4)).real)
    print(lat_rpa.chi_w.data.reshape((4, 4)).real)

    np.testing.assert_array_almost_equal(loc_rpa.chi_w.data,
                                         lat_rpa.chi_w.data,
                                         decimal=2)

    print('ok!')

    # ------------------------------------------------------------------
    # -- Lattice BSE

    lat_bse = ParameterCollection()

    lat_bse.g_wk = lat_rpa.g_wk

    from triqs_tprf.lattice import fourier_wk_to_wr
    lat_bse.g_wr = fourier_wk_to_wr(lat_bse.g_wk)

    from triqs_tprf.lattice import chi0r_from_gr_PH
    lat_bse.chi0_wnr = chi0r_from_gr_PH(nw=1, nnu=p.nwf, gr=lat_bse.g_wr)

    from triqs_tprf.lattice import chi0q_from_chi0r
    lat_bse.chi0_wnk = chi0q_from_chi0r(lat_bse.chi0_wnr)

    # -- Lattice BSE calc
    from triqs_tprf.lattice import chiq_from_chi0q_and_gamma_PH
    lat_bse.chi_kwnn = chiq_from_chi0q_and_gamma_PH(lat_bse.chi0_wnk,
                                                    loc_bse.gamma_wnn)

    # -- Trace results
    from triqs_tprf.lattice import chi0q_sum_nu_tail_corr_PH
    from triqs_tprf.lattice import chi0q_sum_nu
    lat_bse.chi0_wk_tail_corr = chi0q_sum_nu_tail_corr_PH(lat_bse.chi0_wnk)
    lat_bse.chi0_wk = chi0q_sum_nu(lat_bse.chi0_wnk)

    from triqs_tprf.lattice import chiq_sum_nu, chiq_sum_nu_q
    lat_bse.chi_kw = chiq_sum_nu(lat_bse.chi_kwnn)

    lat_bse.chi0_w_tail_corr = lat_bse.chi0_wk_tail_corr[:, Idx(0, 0, 0)]
    lat_bse.chi0_w = lat_bse.chi0_wk[:, Idx(0, 0, 0)]
    lat_bse.chi_w = lat_bse.chi_kw[Idx(0, 0, 0), :]

    print('--> cf Tr[chi0_wnk] and chi0_wk')
    print(lat_bse.chi0_w_tail_corr.data.reshape((4, 4)).real)
    print(lat_bse.chi0_w.data.reshape((4, 4)).real)
    print(lat_rpa.chi0_w.data.reshape((4, 4)).real)

    np.testing.assert_array_almost_equal(lat_bse.chi0_w_tail_corr.data,
                                         lat_rpa.chi0_w.data)

    np.testing.assert_array_almost_equal(lat_bse.chi0_w.data,
                                         lat_rpa.chi0_w.data,
                                         decimal=2)

    print('ok!')

    print('--> cf Tr[chi_kwnn] and chi_wk')
    print(lat_bse.chi_w.data.reshape((4, 4)).real)
    print(loc_bse.chi_w.data.reshape((4, 4)).real)

    np.testing.assert_array_almost_equal(lat_bse.chi_w.data,
                                         loc_bse.chi_w.data)

    print('ok!')

    # ------------------------------------------------------------------
    # -- Store to hdf5

    filename = 'data_bse_rpa.h5'
    with HDFArchive(filename, 'w') as res:
        res['p'] = p
Beispiel #29
0
Datei: gw.py Projekt: TRIQS/tprf
        (+1, ): t,
        (-1, ): t,
    },
    orbital_positions=[(0, 0, 0)] * norb,
)

kmesh = t_r.get_kmesh(n_k=(8, 1, 1))
e_k = t_r.fourier(kmesh)

print(e_k.data)

kmesh = e_k.mesh
wmesh = MeshImFreq(beta, 'Fermion', nw)
g_wk = lattice_dyson_g0_wk(mu=mu, e_k=e_k, mesh=wmesh)

V_k = Gf(mesh=kmesh, target_shape=[norb] * 4)
V_k.data[:] = V

print('--> pi_bubble')
PI_wk = bubble_PI_wk(g_wk)

print('--> screened_interaction_W')
Wr_wk = retarded_screened_interaction_Wr_wk(PI_wk, V_k)

print('--> gw_self_energy')
sigma_wk = gw_sigma_wk(Wr_wk, g_wk, fft_flag=True)
sigma_wk_ref = gw_sigma_wk(Wr_wk, g_wk, fft_flag=False)
np.testing.assert_array_almost_equal(sigma_wk.data, sigma_wk_ref.data)

print('--> lattice_dyson_g_wk')
g_wk = lattice_dyson_g_wk(mu, e_k, sigma_wk)
Beispiel #30
0
def make_calc():
            
    # ------------------------------------------------------------------
    # -- Read precomputed ED data

    filename = "bse_and_rpa_loc_vs_latt.tar.gz"
    p = read_TarGZ_HDFArchive(filename)['p']
    
    # ------------------------------------------------------------------
    # -- RPA tensor
    
    from triqs_tprf.rpa_tensor import get_rpa_tensor
    from triqs_tprf.rpa_tensor import fundamental_operators_from_gf_struct
    
    fundamental_operators = fundamental_operators_from_gf_struct(p.gf_struct)
    p.U_abcd = get_rpa_tensor(p.H_int, fundamental_operators)

    # ------------------------------------------------------------------
    # -- Generalized PH susceptibility
            
    loc_bse = ParameterCollection()
         
    loc_bse.chi_wnn = chi_from_gg2_PH(p.G_iw, p.G2_iw_ph)
    loc_bse.chi0_wnn = chi0_from_gg2_PH(p.G_iw, p.G2_iw_ph)
    
    loc_bse.gamma_wnn = inverse_PH(loc_bse.chi0_wnn) - inverse_PH(loc_bse.chi_wnn)
    loc_bse.chi_wnn_ref = inverse_PH( inverse_PH(loc_bse.chi0_wnn) - loc_bse.gamma_wnn )

    np.testing.assert_array_almost_equal(
        loc_bse.chi_wnn.data, loc_bse.chi_wnn_ref.data)

    from triqs_tprf.bse import solve_local_bse
    loc_bse.gamma_wnn_ref = solve_local_bse(loc_bse.chi0_wnn, loc_bse.chi_wnn)

    np.testing.assert_array_almost_equal(
        loc_bse.gamma_wnn.data, loc_bse.gamma_wnn_ref.data)
    
    loc_bse.chi0_w = trace_nn(loc_bse.chi0_wnn)
    loc_bse.chi_w = trace_nn(loc_bse.chi_wnn)

    # ------------------------------------------------------------------
    # -- RPA, using BSE inverses and constant Gamma

    loc_rpa = ParameterCollection()

    loc_rpa.chi0_wnn = loc_bse.chi0_wnn
    loc_rpa.chi0_w = loc_bse.chi0_w

    loc_rpa.U_abcd = p.U_abcd
    
    # -- Build constant gamma
    from triqs_tprf.rpa_tensor import get_gamma_rpa
    loc_rpa.gamma_wnn = get_gamma_rpa(loc_rpa.chi0_wnn, loc_rpa.U_abcd)
    
    # -- Solve RPA
    loc_rpa.chi_wnn = inverse_PH( inverse_PH(loc_rpa.chi0_wnn) - loc_rpa.gamma_wnn )
    loc_rpa.chi_w = trace_nn(loc_rpa.chi_wnn)
    
    # ------------------------------------------------------------------
    # -- Bubble RPA on lattice

    lat_rpa = ParameterCollection()
    
    # -- Setup dummy lattice Green's function equal to local Green's function
    
    bz = BrillouinZone(BravaisLattice(units=np.eye(3), orbital_positions=[(0,0,0)]))
    periodization_matrix = np.diag(np.array(list([1]*3), dtype=int))
    kmesh = MeshBrZone(bz, periodization_matrix)    
    wmesh = MeshImFreq(beta=p.beta, S='Fermion', n_max=p.nwf_gf)

    lat_rpa.g_wk = Gf(mesh=MeshProduct(wmesh, kmesh), target_shape=p.G_iw.target_shape)
    lat_rpa.g_wk[:, Idx(0, 0, 0)] = p.G_iw

    # -- chi0_wk bubble and chi_wk_rpa bubble RPA

    from triqs_tprf.lattice_utils import imtime_bubble_chi0_wk
    lat_rpa.chi0_wk = imtime_bubble_chi0_wk(lat_rpa.g_wk, nw=1)

    from triqs_tprf.lattice import solve_rpa_PH
    lat_rpa.chi_wk = solve_rpa_PH(lat_rpa.chi0_wk, p.U_abcd)

    lat_rpa.chi0_w = lat_rpa.chi0_wk[:, Idx(0,0,0)]
    lat_rpa.chi_w = lat_rpa.chi_wk[:, Idx(0,0,0)]

    print('--> cf Tr[chi0] and chi0_wk')
    print(loc_rpa.chi0_w.data.reshape((4, 4)).real)
    print(lat_rpa.chi0_w.data.reshape((4, 4)).real)

    np.testing.assert_array_almost_equal(
        loc_rpa.chi0_w.data, lat_rpa.chi0_w.data, decimal=2)

    print('ok!')

    print('--> cf Tr[chi_rpa] and chi_wk_rpa')
    print(loc_rpa.chi_w.data.reshape((4, 4)).real)
    print(lat_rpa.chi_w.data.reshape((4, 4)).real)

    np.testing.assert_array_almost_equal(
        loc_rpa.chi_w.data, lat_rpa.chi_w.data, decimal=2)

    print('ok!')
    
    # ------------------------------------------------------------------
    # -- Lattice BSE

    lat_bse = ParameterCollection()

    lat_bse.g_wk = lat_rpa.g_wk
    
    lat_bse.mu = p.mu

    lat_bse.e_k = Gf(mesh=kmesh, target_shape=p.G_iw.target_shape)
    lat_bse.e_k[Idx(0,0,0)] = np.eye(2)

    lat_bse.sigma_w = p.G_iw.copy()
    lat_bse.sigma_w << iOmega_n + lat_bse.mu * np.eye(2) - lat_bse.e_k[Idx(0,0,0)] - inverse(p.G_iw)

    lat_bse.g_wk_ref = lat_bse.g_wk.copy()
    lat_bse.g_wk_ref[:,Idx(0,0,0)] << inverse(
        iOmega_n + lat_bse.mu * np.eye(2) - lat_bse.e_k[Idx(0,0,0)] - lat_bse.sigma_w)

    np.testing.assert_array_almost_equal(lat_bse.g_wk.data, lat_bse.g_wk_ref.data)

    #for w in lat_bse.g_wk.mesh.components[0]:
    #    print w, lat_bse.g_wk[w, Idx(0,0,0)][0, 0]

    from triqs_tprf.lattice import fourier_wk_to_wr
    lat_bse.g_wr = fourier_wk_to_wr(lat_bse.g_wk)

    from triqs_tprf.lattice import chi0r_from_gr_PH
    lat_bse.chi0_wnr = chi0r_from_gr_PH(nw=1, nn=p.nwf, g_nr=lat_bse.g_wr)

    from triqs_tprf.lattice import chi0q_from_chi0r
    lat_bse.chi0_wnk = chi0q_from_chi0r(lat_bse.chi0_wnr)

    #for n in lat_bse.chi0_wnk.mesh.components[1]:
    #    print n.value, lat_bse.chi0_wnk[Idx(0), n, Idx(0,0,0)][0,0,0,0]

    # -- Lattice BSE calc
    from triqs_tprf.lattice import chiq_from_chi0q_and_gamma_PH
    lat_bse.chi_kwnn = chiq_from_chi0q_and_gamma_PH(lat_bse.chi0_wnk, loc_bse.gamma_wnn)

    # -- Lattice BSE calc with built in trace
    from triqs_tprf.lattice import chiq_sum_nu_from_chi0q_and_gamma_PH
    lat_bse.chi_kw_ref = chiq_sum_nu_from_chi0q_and_gamma_PH(lat_bse.chi0_wnk, loc_bse.gamma_wnn)

    # -- Lattice BSE calc with built in trace using g_wk
    from triqs_tprf.lattice import chiq_sum_nu_from_g_wk_and_gamma_PH
    lat_bse.chi_kw_tail_corr_ref = chiq_sum_nu_from_g_wk_and_gamma_PH(lat_bse.g_wk, loc_bse.gamma_wnn)
    
    # -- Trace results
    from triqs_tprf.lattice import chi0q_sum_nu_tail_corr_PH
    from triqs_tprf.lattice import chi0q_sum_nu
    lat_bse.chi0_wk_tail_corr = chi0q_sum_nu_tail_corr_PH(lat_bse.chi0_wnk)
    lat_bse.chi0_wk = chi0q_sum_nu(lat_bse.chi0_wnk)

    from triqs_tprf.lattice import chiq_sum_nu, chiq_sum_nu_q
    lat_bse.chi_kw = chiq_sum_nu(lat_bse.chi_kwnn)
    
    np.testing.assert_array_almost_equal(lat_bse.chi_kw.data, lat_bse.chi_kw_ref.data)

    from triqs_tprf.bse import solve_lattice_bse
    lat_bse.chi_kw_tail_corr, tmp = solve_lattice_bse(lat_bse.g_wk, loc_bse.gamma_wnn)

    from triqs_tprf.bse import solve_lattice_bse_e_k_sigma_w
    lat_bse.chi_kw_tail_corr_new = solve_lattice_bse_e_k_sigma_w(lat_bse.mu, lat_bse.e_k, lat_bse.sigma_w, loc_bse.gamma_wnn)

    np.testing.assert_array_almost_equal(lat_bse.chi_kw_tail_corr.data, lat_bse.chi_kw_tail_corr_ref.data)
    np.testing.assert_array_almost_equal(lat_bse.chi_kw_tail_corr.data, lat_bse.chi_kw_tail_corr_new.data)
    np.testing.assert_array_almost_equal(lat_bse.chi_kw_tail_corr_ref.data, lat_bse.chi_kw_tail_corr_new.data)
    
    lat_bse.chi0_w_tail_corr = lat_bse.chi0_wk_tail_corr[:, Idx(0, 0, 0)]
    lat_bse.chi0_w = lat_bse.chi0_wk[:, Idx(0, 0, 0)]
    lat_bse.chi_w_tail_corr = lat_bse.chi_kw_tail_corr[Idx(0, 0, 0), :]
    lat_bse.chi_w = lat_bse.chi_kw[Idx(0, 0, 0), :]

    print('--> cf Tr[chi0_wnk] and chi0_wk')
    print(lat_bse.chi0_w_tail_corr.data.reshape((4, 4)).real)
    print(lat_bse.chi0_w.data.reshape((4, 4)).real)
    print(lat_rpa.chi0_w.data.reshape((4, 4)).real)

    np.testing.assert_array_almost_equal(
        lat_bse.chi0_w_tail_corr.data, lat_rpa.chi0_w.data)

    np.testing.assert_array_almost_equal(
        lat_bse.chi0_w.data, lat_rpa.chi0_w.data, decimal=2)
    
    print('ok!')
    
    print('--> cf Tr[chi_kwnn] and chi_wk (without chi0 tail corr)')
    print(lat_bse.chi_w.data.reshape((4, 4)).real)
    print(loc_bse.chi_w.data.reshape((4, 4)).real)

    np.testing.assert_array_almost_equal(
        lat_bse.chi_w.data, loc_bse.chi_w.data)

    print('ok!')

    # ------------------------------------------------------------------
    # -- Use chi0 tail corrected trace to correct chi_rpa cf bubble

    dchi_wk = lat_bse.chi0_wk_tail_corr - lat_bse.chi0_wk
    dchi_w = dchi_wk[:, Idx(0, 0, 0)]
    
    loc_rpa.chi_w_tail_corr = loc_rpa.chi_w + dchi_w

    # -- this will be the same, but it will be close to the real physical value
    lat_bse.chi_w_tail_corr_ref = lat_bse.chi_w + dchi_w
    loc_bse.chi_w_tail_corr_ref = loc_bse.chi_w + dchi_w
    
    print('--> cf Tr[chi_rpa] and chi_wk_rpa')
    print(loc_rpa.chi_w.data.reshape((4, 4)).real)
    print(loc_rpa.chi_w_tail_corr.data.reshape((4, 4)).real)
    print(lat_rpa.chi_w.data.reshape((4, 4)).real)

    np.testing.assert_array_almost_equal(
        loc_rpa.chi_w_tail_corr.data, lat_rpa.chi_w.data, decimal=3)

    print('--> cf Tr[chi_kwnn] with tail corr (from chi0_wnk)')
    print(lat_bse.chi_w_tail_corr.data.reshape((4, 4)).real)
    print(lat_bse.chi_w_tail_corr_ref.data.reshape((4, 4)).real)

    np.testing.assert_array_almost_equal(
        lat_bse.chi_w_tail_corr.data, lat_bse.chi_w_tail_corr_ref.data)
    
    print('ok!')

    # ------------------------------------------------------------------
    # -- Store to hdf5
    
    filename = 'data_bse_rpa.h5'
    with HDFArchive(filename,'w') as res:
        res['p'] = p