def bubble_PI_wk(g_wk): r""" Compute the particle-hole bubble from the single particle lattice Green's function .. math:: \Pi_{abcd}(i\omega_n, k) = - \mathcal{F}_{\tau, \mathbf{r} \rightarrow i\omega_n, \mathbf{k}} \left\{ G_{d\bar{a}}(\tau, \mathbf{r}) G_{b\bar{c}}(-\tau, -\mathbf{r}) \right\} Parameters ---------- g_wk : TRIQS Green's function (rank 2) on Matsubara and Brillouinzone meshes Single particle lattice Green's function. Returns ------- PI_wk : TRIQS Green's function (rank 4) on Matsubara and Brillouinzone meshes Particle hole bubble. """ nw = len(g_wk.mesh.components[0]) // 2 g_wr = fourier_wk_to_wr(g_wk) g_tr = fourier_wr_to_tr(g_wr) del g_wr PI_tr = chi0_tr_from_grt_PH(g_tr) del g_tr PI_wr = chi_wr_from_chi_tr(PI_tr, nw=nw) del PI_tr PI_wk = chi_wk_from_chi_wr(PI_wr) del PI_wr return PI_wk
def get_chi0_nk_at_specific_w(g_wk, nw_index=1, nwf=None): r""" Compute the generalized bare lattice susceptibility :math:`\chi^{0}_{\bar{a}b\bar{c}d}(i\omega_{n=\mathrm{nw\_index}}, i\nu_n, \mathbf{k})` from the single-particle Green's function :math:`G_{a\bar{b}}(i\nu_n, \mathbf{k})` 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})`. nw_index : int, The bosonic Matsubara frequency index :math:`i\omega_{n=\mathrm{nw\_index}}` at which :math:`\chi^0` is calculated. nwf : int, Number of fermionic frequencies in :math:`\chi^0`. Returns ------- chi0_nk : Gf, Generalized bare lattice susceptibility :math:`\chi^{0}_{\bar{a}b\bar{c}d}(i\omega_{n=\mathrm{nw\_index}}, i\nu_n, \mathbf{k})`. """ fmesh = g_wk.mesh.components[0] kmesh = g_wk.mesh.components[1] if nwf is None: nwf = len(fmesh) // 2 mpi.barrier() mpi.report('g_wk ' + str(g_wk[Idx(2), Idx(0, 1, 2)][0, 0])) n = np.sum(g_wk.data) // len(kmesh) mpi.report('n ' + str(n)) mpi.barrier() mpi.report('--> g_wr from g_wk') g_wr = fourier_wk_to_wr(g_wk) mpi.report('--> chi0_wnr from g_wr') chi0_nr = chi0_nr_from_gr_PH_at_specific_w(nw_index=nw_index, nn=nwf, g_nr=g_wr) del g_wr mpi.report('--> chi0_wnk from chi0_wnr') # Create a 'fake' bosonic mesh to be able to use 'chi0q_from_chi0r' chi0_wnr = add_fake_bosonic_mesh(chi0_nr) del chi0_nr chi0_wnk = chi0q_from_chi0r(chi0_wnr) del chi0_wnr chi0_nk = chi0_wnk[Idx(0), :, :] del chi0_wnk return chi0_nk
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 = MeshBrillouinZone(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
def bubble_setup(beta, mu, tb_lattice, nk, nw, sigma_w=None): print tprf_banner(), "\n" print 'beta =', beta print 'mu =', mu print 'sigma =', (not (sigma == None)) norb = tb_lattice.NOrbitalsInUnitCell print 'nk =', nk print 'nw =', nw print 'norb =', norb print ntau = 4 * nw ntot = np.prod(nk) * norb**4 + np.prod(nk) * (nw + ntau) * norb**2 nbytes = ntot * np.complex128().nbytes ngb = nbytes / 1024.**3 print 'Approx. Memory Utilization: %2.2f GB\n' % ngb periodization_matrix = np.diag(np.array(list(nk), dtype=np.int32)) #print 'periodization_matrix =\n', periodization_matrix bz = BrillouinZone(tb_lattice.bl) bzmesh = MeshBrillouinZone(bz, periodization_matrix) print '--> ek' e_k = ek_tb_dispersion_on_bzmesh(tb_lattice, bzmesh, bz) if sigma is None: print '--> g0k' wmesh = MeshImFreq(beta=beta, S='Fermion', n_max=nw) g_wk = lattice_dyson_g0_wk(mu=mu, e_k=e_k, mesh=wmesh) else: print '--> gk' sigma_w = strip_sigma(nw, beta, sigma) g_wk = lattice_dyson_g_wk(mu=mu, e_k=e_k, sigma_w=sigma_w) print '--> gr_from_gk (k->r)' g_wr = fourier_wk_to_wr(g_wk) del g_wk print '--> grt_from_grw (w->tau)' g_tr = fourier_wr_to_tr(g_wr) del g_wr if sigma is None: return g_tr else: return g_tr, sigma_w
def imtime_bubble_chi0_wk(g_wk, nw=1): wmesh, kmesh = g_wk.mesh.components norb = g_wk.target_shape[0] beta = wmesh.beta nw_g = len(wmesh) nk = len(kmesh) ntau = 4 * nw_g ntot = np.prod(nk) * norb**4 + np.prod(nk) * (nw_g + ntau) * norb**2 nbytes = ntot * np.complex128().nbytes ngb = nbytes / 1024.**3 if mpi.is_master_node(): print tprf_banner(), "\n" print 'beta =', beta print 'nk =', nk print 'nw =', nw_g print 'norb =', norb print print 'Approx. Memory Utilization: %2.2f GB\n' % ngb mpi.report('--> fourier_wk_to_wr') g_wr = fourier_wk_to_wr(g_wk) del g_wk mpi.report('--> fourier_wr_to_tr') g_tr = fourier_wr_to_tr(g_wr) del g_wr if nw == 1: mpi.report('--> chi0_w0r_from_grt_PH (bubble in tau & r)') chi0_wr = chi0_w0r_from_grt_PH(g_tr) del g_tr else: mpi.report('--> chi0_tr_from_grt_PH (bubble in tau & r)') chi0_tr = chi0_tr_from_grt_PH(g_tr) del g_tr mpi.report('--> chi_wr_from_chi_tr') chi0_wr = chi_wr_from_chi_tr(chi0_tr, nw=nw) del chi_tr mpi.report('--> chi_wk_from_chi_wr (r->k)') chi0_wk = chi_wk_from_chi_wr(chi0_wr) del chi0_wr return chi0_wk
def test_square_lattice_chi00(): # ------------------------------------------------------------------ # -- Discretizations n_k = (2, 2, 1) nw_g = 500 nnu = 400 nw = 1 # ------------------------------------------------------------------ # -- tight binding parameters beta = 20.0 mu = 0.0 t = 1.0 h_loc = np.array([ [-0.3, -0.5], [-0.5, .4], ]) T = -t * np.array([ [1., 0.23], [0.23, 0.5], ]) # ------------------------------------------------------------------ # -- tight binding print '--> tight binding model' t_r = TBLattice( units=[(1, 0, 0), (0, 1, 0)], hopping={ # nearest neighbour hopping -t (0, 0): h_loc, (0, +1): T, (0, -1): T, (+1, 0): T, (-1, 0): T, }, orbital_positions=[(0, 0, 0)] * 2, orbital_names=['up_0', 'do_0'], ) e_k = t_r.on_mesh_brillouin_zone(n_k) kmesh = e_k.mesh wmesh = MeshImFreq(beta=beta, S='Fermion', n_max=nw_g) print '--> g0_wk' g0_wk = lattice_dyson_g0_wk(mu=mu, e_k=e_k, mesh=wmesh) print '--> g0_wr' g0_wr = fourier_wk_to_wr(g0_wk) print '--> g0_tr' g0_tr = fourier_wr_to_tr(g0_wr) # ------------------------------------------------------------------ # -- anaytic chi00 print '--> chi00_wk analytic' chi00_wk_analytic = lindhard_chi00_wk(e_k=e_k, nw=nw, beta=beta, mu=mu) print '--> chi00_wr analytic' chi00_wr_analytic = chi_wr_from_chi_wk(chi00_wk_analytic) # ------------------------------------------------------------------ # -- imtime chi00 print '--> chi0_tr_from_grt_PH' chi00_tr = chi0_tr_from_grt_PH(g0_tr) print '--> chi_wr_from_chi_tr' chi00_wr = chi_wr_from_chi_tr(chi00_tr, nw=1) print '--> chi_w0r_from_chi_tr' chi00_wr_ref = chi_w0r_from_chi_tr(chi00_tr) print '--> chi0_w0r_from_grt_PH' chi00_wr_opt = chi0_w0r_from_grt_PH(g0_tr) print 'dchi00_wr =', np.max( np.abs(chi00_wr_analytic.data - chi00_wr.data)) print 'dchi00_wr_ref =', np.max( np.abs(chi00_wr_analytic.data - chi00_wr_ref.data)) print 'dchi00_wr_opt =', np.max( np.abs(chi00_wr_analytic.data - chi00_wr_opt.data)) np.testing.assert_array_almost_equal(chi00_wr_analytic.data, chi00_wr.data, decimal=8) np.testing.assert_array_almost_equal(chi00_wr_analytic.data, chi00_wr_ref.data, decimal=4) np.testing.assert_array_almost_equal(chi00_wr_analytic.data, chi00_wr_opt.data, decimal=4) print '--> chi_wk_from_chi_wr' chi00_wk_imtime = chi_wk_from_chi_wr(chi00_wr) # ------------------------------------------------------------------ # -- imtime chi00 helper function chi00_wk_imtime_2 = imtime_bubble_chi0_wk(g0_wk, nw=1) # ------------------------------------------------------------------ # -- imfreq chi00 print '--> chi00_wnr' chi00_wnr = chi0r_from_gr_PH(nw=1, nnu=nnu, gr=g0_wr) print '--> chi00_wnk' chi00_wnk = chi0q_from_chi0r(chi00_wnr) # -- Test per k and w calculator for chi0_wnk print '--> chi00_wnk_ref' from triqs_tprf.lattice import chi0q_from_g_wk_PH chi00_wnk_ref = chi0q_from_g_wk_PH(nw=1, nnu=nnu, g_wk=g0_wk) diff = np.max(np.abs(chi00_wnk.data - chi00_wnk_ref.data)) print 'chi00_wnk diff =', diff np.testing.assert_array_almost_equal(chi00_wnk.data, chi00_wnk_ref.data) print '--> chi00_wk_imfreq' chi00_wk_imfreq = chi0q_sum_nu(chi00_wnk) print '--> chi00_wk_imfreq_tail_corr' chi00_wk_imfreq_tail_corr = chi0q_sum_nu_tail_corr_PH(chi00_wnk) # ------------------------------------------------------------------ # -- Compare results def cf_chi_w0(chi1, chi2, decimal=9): chi1, chi2 = chi1[Idx(0), :].data, chi2[Idx(0), :].data diff = np.linalg.norm(chi1 - chi2) print '|dchi| =', diff np.testing.assert_array_almost_equal(chi1, chi2, decimal=decimal) print '--> Cf analytic with imtime' cf_chi_w0(chi00_wk_analytic, chi00_wk_imtime, decimal=7) print '--> Cf analytic with imtime 2' cf_chi_w0(chi00_wk_analytic, chi00_wk_imtime_2, decimal=4) print '--> Cf analytic with imfreq' cf_chi_w0(chi00_wk_analytic, chi00_wk_imfreq, decimal=2) print '--> Cf analytic with imfreq (tail corr)' cf_chi_w0(chi00_wk_analytic, chi00_wk_imfreq_tail_corr, decimal=5)
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 = MeshBrillouinZone(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
def get_chi0_wnk(g_wk, nw=1, nwf=None): fmesh = g_wk.mesh.components[0] kmesh = g_wk.mesh.components[1] if nwf is None: nwf = len(fmesh) / 2 mpi.barrier() mpi.report('g_wk ' + str(g_wk[Idx(2), Idx(0, 1, 2)][0, 0])) n = np.sum(g_wk.data) / len(kmesh) mpi.report('n ' + str(n)) mpi.barrier() mpi.report('--> g_wr from g_wk') g_wr = fourier_wk_to_wr(g_wk) mpi.barrier() mpi.report('g_wr ' + str(g_wr[Idx(2), Idx(0, 1, 2)][0, 0])) n_r = np.sum(g_wr.data, axis=0)[0] mpi.report('n_r=0 ' + str(n_r[0, 0])) mpi.barrier() mpi.report('--> chi0_wnr from g_wr') chi0_wnr = chi0r_from_gr_PH(nw=nw, nnu=nwf, gr=g_wr) #mpi.report('--> chi0_wnr from g_wr (nompi)') #chi0_wnr_nompi = chi0r_from_gr_PH_nompi(nw=nw, nnu=nwf, gr=g_wr) del g_wr #abs_diff = np.abs(chi0_wnr.data - chi0_wnr_nompi.data) #mpi.report('shape = ' + str(abs_diff.shape)) #idx = np.argmax(abs_diff) #mpi.report('argmax = ' + str(idx)) #diff = np.max(abs_diff) #mpi.report('diff = %6.6f' % diff) #del chi0_wnr #chi0_wnr = chi0_wnr_nompi #exit() mpi.barrier() mpi.report('chi0_wnr ' + str(chi0_wnr[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) chi0_r0 = np.sum(chi0_wnr[:, :, Idx(0, 0, 0)].data) mpi.report('chi0_r0 ' + str(chi0_r0)) mpi.barrier() mpi.report('--> chi0_wnk from chi0_wnr') chi0_wnk = chi0q_from_chi0r(chi0_wnr) del chi0_wnr mpi.barrier() mpi.report('chi0_wnk ' + str(chi0_wnk[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) chi0 = np.sum(chi0_wnk.data) / len(kmesh) mpi.report('chi0 = ' + str(chi0)) mpi.barrier() #if mpi.is_master_node(): if False: from triqs_tprf.ParameterCollection import ParameterCollection p = ParameterCollection() p.g_wk = g_wk p.g_wr = g_wr p.chi0_wnr = chi0_wnr p.chi0_wnk = chi0_wnk print '--> Writing debug info for BSE' with HDFArchive('data_debug_bse.h5', 'w') as arch: arch['p'] = p mpi.barrier() return chi0_wnk
def get_chi0_wnk(g_wk, nw=1, nwf=None): r""" Compute the generalized lattice bubble susceptibility :math:`\chi^{(0)}_{abcd}(\omega, \nu, \mathbf{k})` from the single-particle Green's function :math:`G_{ab}(\omega, \mathbf{k})`. Parameters ---------- g_wk : Single-particle Green's function :math:`G_{ab}(\omega, \mathbf{k})`. nw : Number of bosonic freqiencies in :math:`\chi`. nwf : Number of fermionic freqiencies in :math:`\chi`. Returns ------- chi0_wnk : Generalized lattice bubble susceptibility :math:`\chi^{(0)}_{abcd}(\omega, \nu, \mathbf{k})` """ fmesh = g_wk.mesh.components[0] kmesh = g_wk.mesh.components[1] if nwf is None: nwf = len(fmesh) / 2 mpi.barrier() mpi.report('g_wk ' + str(g_wk[Idx(2), Idx(0, 0, 0)][0, 0])) n = np.sum(g_wk.data) / len(kmesh) mpi.report('n ' + str(n)) mpi.barrier() mpi.report('--> g_wr from g_wk') g_wr = fourier_wk_to_wr(g_wk) mpi.barrier() mpi.report('g_wr ' + str(g_wr[Idx(2), Idx(0, 0, 0)][0, 0])) n_r = np.sum(g_wr.data, axis=0)[0] mpi.report('n_r=0 ' + str(n_r[0, 0])) mpi.barrier() mpi.report('--> chi0_wnr from g_wr') chi0_wnr = chi0r_from_gr_PH(nw=nw, nn=nwf, g_nr=g_wr) #mpi.report('--> chi0_wnr from g_wr (nompi)') #chi0_wnr_nompi = chi0r_from_gr_PH_nompi(nw=nw, nn=nwf, g_wr=g_wr) del g_wr #abs_diff = np.abs(chi0_wnr.data - chi0_wnr_nompi.data) #mpi.report('shape = ' + str(abs_diff.shape)) #idx = np.argmax(abs_diff) #mpi.report('argmax = ' + str(idx)) #diff = np.max(abs_diff) #mpi.report('diff = %6.6f' % diff) #del chi0_wnr #chi0_wnr = chi0_wnr_nompi #exit() mpi.barrier() mpi.report('chi0_wnr ' + str(chi0_wnr[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) chi0_r0 = np.sum(chi0_wnr[:, :, Idx(0, 0, 0)].data) mpi.report('chi0_r0 ' + str(chi0_r0)) mpi.barrier() mpi.report('--> chi0_wnk from chi0_wnr') chi0_wnk = chi0q_from_chi0r(chi0_wnr) del chi0_wnr mpi.barrier() mpi.report('chi0_wnk ' + str(chi0_wnk[Idx(0), Idx(0), Idx(0, 0, 0)][0, 0, 0, 0])) chi0 = np.sum(chi0_wnk.data) / len(kmesh) mpi.report('chi0 = ' + str(chi0)) mpi.barrier() #if mpi.is_master_node(): if False: from triqs_tprf.ParameterCollection import ParameterCollection p = ParameterCollection() p.g_wk = g_wk p.g_wr = g_wr p.chi0_wnr = chi0_wnr p.chi0_wnk = chi0_wnk print '--> Writing debug info for BSE' with HDFArchive('data_debug_bse.h5', 'w') as arch: arch['p'] = p mpi.barrier() return chi0_wnk
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=np.int32)) kmesh = MeshBrillouinZone(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
import pytriqs.utility.mpi as mpi from pytriqs.gf import Gf, MeshImFreq, MeshProduct from pytriqs.gf import MeshBrillouinZone, MeshCyclicLattice from pytriqs.lattice import BrillouinZone, BravaisLattice from triqs_tprf.lattice import lattice_dyson_g0_wk from triqs_tprf.lattice import fourier_wk_to_wr from triqs_tprf.lattice import fourier_wr_to_wk bz = BrillouinZone(BravaisLattice([[1, 0], [0, 1]])) periodization_matrix = np.diag(np.array([10, 10, 1], dtype=np.int32)) bzmesh = MeshBrillouinZone(bz, periodization_matrix) lmesh = MeshCyclicLattice(bz.lattice, periodization_matrix) e_k = Gf(mesh=bzmesh, target_shape=[1, 1]) for k in bzmesh: e_k[k] = -2 * (np.cos(k[0]) + np.cos(k[1])) # does not work... mesh = MeshImFreq(beta=1.0, S='Fermion', n_max=1024) g0_wk = lattice_dyson_g0_wk(mu=1.0, e_k=e_k, mesh=mesh) g0_wr = fourier_wk_to_wr(g0_wk) g0_wk_ref = fourier_wr_to_wk(g0_wr) np.testing.assert_array_almost_equal(g0_wk.data, g0_wk_ref.data)
def imtime_bubble_chi0_wk(g_wk, nw=1): ncores = multiprocessing.cpu_count() wmesh, kmesh = g_wk.mesh.components norb = g_wk.target_shape[0] beta = wmesh.beta nw_g = len(wmesh) nk = len(kmesh) ntau = 2 * nw_g # -- Memory Approximation ng_tr = ntau * np.prod(nk) * norb**2 # storing G(tau, r) ng_wr = nw_g * np.prod(nk) * norb**2 # storing G(w, r) ng_t = ntau * norb**2 # storing G(tau) nchi_tr = ntau * np.prod(nk) * norb**4 # storing \chi(tau, r) nchi_wr = nw * np.prod(nk) * norb**4 # storing \chi(w, r) nchi_t = ntau * norb**4 # storing \chi(tau) nchi_w = nw * norb**4 # storing \chi(w) nchi_r = np.prod(nk) * norb**4 # storing \chi(r) if nw == 1: ntot_case_1 = ng_tr + ng_wr ntot_case_2 = ng_tr + nchi_wr + ncores * (nchi_t + 2 * ng_t) ntot_case_3 = 4 * nchi_wr ntot = max(ntot_case_1, ntot_case_2, ntot_case_3) else: ntot_case_1 = ng_tr + nchi_tr + ncores * (nchi_t + 2 * ng_t) ntot_case_2 = nchi_tr + nchi_wr + ncores * (nchi_w + nchi_t) ntot = max(ntot_case_1, ntot_case_2) nbytes = ntot * np.complex128().nbytes ngb = nbytes / 1024.**3 if mpi.is_master_node(): print tprf_banner(), "\n" print 'beta =', beta print 'nk =', nk print 'nw =', nw_g print 'norb =', norb print print 'Approx. Memory Utilization: %2.2f GB\n' % ngb mpi.report('--> fourier_wk_to_wr') g_wr = fourier_wk_to_wr(g_wk) del g_wk mpi.report('--> fourier_wr_to_tr') g_tr = fourier_wr_to_tr(g_wr) del g_wr if nw == 1: mpi.report('--> chi0_w0r_from_grt_PH (bubble in tau & r)') chi0_wr = chi0_w0r_from_grt_PH(g_tr) del g_tr else: mpi.report('--> chi0_tr_from_grt_PH (bubble in tau & r)') chi0_tr = chi0_tr_from_grt_PH(g_tr) del g_tr mpi.report('--> chi_wr_from_chi_tr') chi0_wr = chi_wr_from_chi_tr(chi0_tr, nw=nw) del chi0_tr mpi.report('--> chi_wk_from_chi_wr (r->k)') chi0_wk = chi_wk_from_chi_wr(chi0_wr) del chi0_wr return chi0_wk
def gw_sigma_wk(Wr_wk, g_wk, fft_flag=False): r""" GW self energy :math:`\Sigma(i\omega_n, \mathbf{k})` calculator Fourier transforms the screened interaction and the single-particle Green's function to imagiary time and real space. .. math:: G_{ab}(\tau, \mathbf{r}) = \mathcal{F}^{-1} \left\{ G_{ab}(i\omega_n, \mathbf{k}) \right\} .. math:: W^{(r)}_{abcd}(\tau, \mathbf{r}) = \mathcal{F}^{-1} \left\{ W^{(r)}_{abcd}(i\omega_n, \mathbf{k}) \right\} computes the GW self-energy as the product .. math:: \Sigma_{ab}(\tau, \mathbf{r}) = \sum_{cd} W^{(r)}_{abcd}(\tau, \mathbf{r}) G_{cd}(\tau, \mathbf{r}) and transforms back to frequency and momentum .. math:: \Sigma_{ab}(i\omega_n, \mathbf{k}) = \mathcal{F} \left\{ \Sigma_{ab}(\tau, \mathbf{r}) \right\} Parameters ---------- V_k : TRIQS Green's function (rank 4) on a Brillouinzone mesh static bare interaction :math:`V_{abcd}(\mathbf{k})` Wr_wk : TRIQS Green's function (rank 4) on Matsubara and Brillouinzone meshes retarded screened interaction :math:`W^{(r)}_{abcd}(i\omega_n, \mathbf{k})` g_wk : TRIQS Green's function (rank 2) on Matsubara and Brillouinzone meshes single particle Green's function :math:`G_{ab}(i\omega_n, \mathbf{k})` Returns ------- sigma_wk : TRIQS Green's function (rank 2) on Matsubara and Brillouinzone meshes GW self-energy :math:`\Sigma_{ab}(i\omega_n, \mathbf{k})` """ if fft_flag: nw = len(g_wk.mesh.components[0]) // 2 ntau = nw * 6 + 1 mpi.report('g wk -> wr') g_wr = fourier_wk_to_wr(g_wk) mpi.report('g wr -> tr') g_tr = fourier_wr_to_tr(g_wr, nt=ntau) del g_wr mpi.report('W wk -> wr') Wr_wr = chi_wr_from_chi_wk(Wr_wk) mpi.report('W wr -> tr') Wr_tr = chi_tr_from_chi_wr(Wr_wr, ntau=ntau) del Wr_wr mpi.report('sigma tr') sigma_tr = cpp_gw_sigma_tr(Wr_tr, g_tr) del Wr_tr del g_tr mpi.report('sigma tr -> wr') sigma_wr = fourier_tr_to_wr(sigma_tr, nw=nw) del sigma_tr mpi.report('sigma wr -> wk') sigma_wk = fourier_wr_to_wk(sigma_wr) del sigma_wr else: sigma_wk = cpp_gw_sigma_wk_serial_fft(Wr_wk, g_wk) return sigma_wk