7#include "./qmc_config.hpp"
10namespace triqs_ctint {
24 chi4_iw_t G2_conn_from_M4(chi4_iw_t::const_view_type M4_iw, g_reg_iw_cv_t M_iw, g_reg_iw_cv_t G0_iw);
38 chi4_iw_t G2pp_conn_from_M4pp(chi4_iw_t::const_view_type M4pp_iw, g_reg_iw_cv_t M_iw, g_reg_iw_cv_t G0_iw);
52 chi4_iw_t G2ph_conn_from_M4ph(chi4_iw_t::const_view_type M4ph_iw, g_reg_iw_cv_t M_iw, g_reg_iw_cv_t G0_iw);
64 chi4_iw_t F_from_G2c(chi4_iw_t::const_view_type G2_conn_iw, g_reg_iw_cv_t G_iw);
76 chi4_iw_t Fpp_from_G2pp_conn(chi4_iw_t::const_view_type G2pp_conn_iw, g_reg_iw_cv_t G_iw);
88 chi4_iw_t Fph_from_G2ph_conn(chi4_iw_t::const_view_type G2ph_conn_iw, g_reg_iw_cv_t G_iw);
100 chi4_iw_t G2_from_G2c(chi4_iw_t::const_view_type G2_conn_iw, g_reg_iw_cv_t G_iw);
112 chi4_iw_t G2pp_from_G2pp_conn(chi4_iw_t::const_view_type G2pp_conn_iw, g_reg_iw_cv_t G_iw);
124 chi4_iw_t G2ph_from_G2ph_conn(chi4_iw_t::const_view_type G2ph_conn_iw, g_reg_iw_cv_t G_iw);
137 chi4_iw_t chi_tilde_ph_from_G2ph_conn(chi4_iw_t::const_view_type G2ph_conn_iw, g_reg_iw_cv_t G_iw);
140 template <Chan_t Chan>
141 chi3_iw_t chi3_from_M3(chi3_iw_cv_t M3_iw, g_reg_iw_cv_t M_iw, g_reg_iw_cv_t G0_iw, block_matrix_t
const &dens_G, block_matrix_t
const &M_hartree) {
143 double beta = M_iw[0].mesh().beta();
144 int n_blocks = M_iw.size();
147 chi3_iw_t M3_iw_conn = M3_iw;
150 chi3_iw_t chi3_iw = M3_iw;
154 g_reg_iw_t GM = G0_iw * M_iw;
155 g_reg_iw_t MG = M_iw * G0_iw;
156 g_reg_iw_t GMG = G0_iw * M_iw * G0_iw;
157 g_reg_iw_t G_iw = G0_iw + G0_iw * M_iw * G0_iw;
159 for (
int bl1 : range(n_blocks))
160 for (
int bl2 : range(n_blocks)) {
163 int bl1_size = M3_iw(bl1, bl2).target_shape()[0];
164 int bl2_size = M3_iw(bl1, bl2).target_shape()[2];
166 if constexpr (Chan == Chan_t::PP) {
168 M3_iw_conn(bl1, bl2)(iW_, iw_)(i_, j_, k_, l_) << M3_iw(bl1, bl2)[iW_, iw_](i_, j_, k_, l_)
169 - GM[bl1](iw_)(j_, i_) * GM[bl2](iW_ - iw_)(l_, k_) + kronecker(bl1, bl2) * GM[bl1](iw_)(l_, i_) * GM[bl2](iW_ - iw_)(j_, k_);
171 for (
int m : range(bl1_size))
172 for (
int n : range(bl2_size))
173 chi3_iw(bl1, bl2)(iW_, iw_)(i_, j_, k_, l_) << chi3_iw(bl1, bl2)[iW_, iw_](i_, j_, k_, l_)
174 + G0_iw[bl1](iw_)(m, i_) * G0_iw[bl2](iW_ - iw_)(n, k_) * M3_iw_conn(bl1, bl2)(iW_, iw_)(m, j_, n, l_);
177 chi3_iw(bl1, bl2)(iW_, iw_)(i_, j_, k_, l_) << chi3_iw(bl1, bl2)[iW_, iw_](i_, j_, k_, l_)
178 + G_iw[bl1](iw_)(j_, i_) * G_iw[bl2](iW_ - iw_)(l_, k_) - kronecker(bl1, bl2) * G_iw[bl1](iw_)(l_, i_) * G_iw[bl2](iW_ - iw_)(j_, k_);
180 }
else if constexpr (Chan == Chan_t::PH) {
182 auto km_GMG = make_zero_tail(GMG, 3);
183 for (
auto [km_bl, M_hartree_bl] : zip(km_GMG, M_hartree)) km_bl(2, ellipsis()) = M_hartree_bl;
184 auto tail_GMG = fit_hermitian_tail(GMG, km_GMG).first;
185 auto dens_GMG = density(GMG, tail_GMG);
187 M3_iw_conn(bl1, bl2)(iW_, iw_)(i_, j_, k_, l_) << M3_iw(bl1, bl2)[iW_, iw_](i_, j_, k_, l_)
188 - beta * kronecker(iW_) * M_iw[bl1](iw_)(j_, i_) * dens_GMG[bl2](l_, k_)
189 + kronecker(bl1, bl2) * GM[bl1](iw_)(l_, i_) * MG[bl2](iW_ + iw_)(j_, k_);
191 for (
int m : range(bl1_size))
192 for (
int n : range(bl1_size))
193 chi3_iw(bl1, bl2)(iW_, iw_)(i_, j_, k_, l_) << chi3_iw(bl1, bl2)[iW_, iw_](i_, j_, k_, l_)
194 + G0_iw[bl1](iw_)(m, i_) * G0_iw[bl1](iW_ + iw_)(j_, n) * M3_iw_conn(bl1, bl2)(iW_, iw_)(m, n, k_, l_);
197 chi3_iw(bl1, bl2)(iW_, iw_)(i_, j_, k_, l_) << chi3_iw(bl1, bl2)[iW_, iw_](i_, j_, k_, l_)
198 + beta * kronecker(iW_) * G_iw[bl1](iw_)(j_, i_) * dens_G[bl2](l_, k_)
199 - kronecker(bl1, bl2) * G_iw[bl1](iw_)(l_, i_) * G_iw[bl2](iW_ + iw_)(j_, k_);
200 }
else if constexpr (Chan == Chan_t::XPH) {
202 auto km_GMG = make_zero_tail(GMG, 3);
203 for (
auto [km_bl, M_hartree_bl] : zip(km_GMG, M_hartree)) km_bl(2, ellipsis()) = M_hartree_bl;
204 auto tail_GMG = fit_hermitian_tail(GMG, km_GMG).first;
205 auto dens_GMG = density(GMG, tail_GMG);
207 M3_iw_conn(bl1, bl2)(iW_, iw_)(i_, j_, k_, l_) << M3_iw(bl1, bl2)[iW_, iw_](i_, j_, k_, l_)
208 - GM[bl1](iw_)(j_, i_) * MG[bl2](iW_ + iw_)(l_, k_)
209 + kronecker(bl1, bl2) * beta * kronecker(iW_) * M_iw[bl1](iw_)(l_, i_) * dens_GMG[bl2](j_, k_);
211 for (
int m : range(bl1_size))
212 for (
int n : range(bl1_size))
213 chi3_iw(bl1, bl2)(iW_, iw_)(i_, j_, k_, l_) << chi3_iw(bl1, bl2)[iW_, iw_](i_, j_, k_, l_)
214 + G0_iw[bl1](iw_)(m, i_) * G0_iw[bl2](iW_ + iw_)(l_, n) * M3_iw_conn(bl1, bl2)(iW_, iw_)(m, j_, k_, n);
217 chi3_iw(bl1, bl2)(iW_, iw_)(i_, j_, k_, l_) << chi3_iw(bl1, bl2)[iW_, iw_](i_, j_, k_, l_)
218 + G_iw[bl1](iw_)(j_, i_) * G_iw[bl2](iW_ + iw_)(l_, k_)
219 - kronecker(bl1, bl2) * beta * kronecker(iW_) * G_iw[bl1](iw_)(l_, i_) * dens_GMG[bl2](j_, k_);
227 template <Chan_t Chan> chi2_tau_t chi2_from_chi2_conn(chi2_tau_cv_t chi2_tau_conn, g_reg_iw_cv_t G_iw, block_matrix_t
const &dens_G) {
229 double beta = G_iw[0].mesh().beta();
230 int n_blocks = G_iw.size();
233 chi2_tau_t chi2_tau = chi2_tau_conn;
235 auto tau_mesh = make_adjoint_mesh(G_iw[0].mesh());
237 auto km_G = make_zero_tail(G_iw, 2);
238 for (
auto &km_bl : km_G) matrix_view<dcomplex>{km_bl(1, ellipsis())} = 1.0;
239 auto tail_G = fit_hermitian_tail(G_iw, km_G).first;
241#ifdef GTAU_IS_COMPLEX
242 g_tau_t G_tau = make_gf_from_fourier(G_iw, tau_mesh, tail_G);
244 g_tau_t G_tau = real(make_gf_from_fourier(G_iw, tau_mesh, tail_G));
245 if (!is_gf_real_in_tau(G_iw, 1e-8)) std::cerr <<
"WARNING: Assuming real G_tau, but found Imag(G(tau)) > 1e-8. Casting to Real.\n";
248 for (
int bl1 : range(n_blocks))
249 for (
int bl2 : range(n_blocks)) {
251 if constexpr (Chan == Chan_t::PP) {
254 chi2_tau(bl1, bl2)(t_)(i_, j_, k_, l_) << chi2_tau_conn(bl1, bl2)[t_](i_, j_, k_, l_) + G_tau[bl1](t_)(j_, i_) * G_tau[bl2](t_)(l_, k_)
255 - kronecker(bl1, bl2) * G_tau[bl1](t_)(l_, i_) * G_tau[bl2](t_)(j_, k_);
257 }
else if constexpr (Chan == Chan_t::PH) {
259 chi2_tau(bl1, bl2)(t_)(i_, j_, k_, l_) << chi2_tau_conn(bl1, bl2)[t_](i_, j_, k_, l_) + dens_G[bl1](j_, i_) * dens_G[bl2](l_, k_)
260 + kronecker(bl1, bl2) * G_tau[bl1](beta - t_)(l_, i_) * G_tau[bl2](t_)(j_, k_);
262 }
else if constexpr (Chan == Chan_t::XPH) {
264 chi2_tau(bl1, bl2)(t_)(i_, j_, k_, l_) << chi2_tau_conn(bl1, bl2)[t_](i_, j_, k_, l_)
265 - G_tau[bl1](beta - t_)(j_, i_) * G_tau[bl2](t_)(l_, k_)
266 - kronecker(bl1, bl2) * dens_G[bl1](l_, i_) * dens_G[bl2](j_, k_);
274 template <Chan_t Chan>
275 gf<imtime, matrix_valued> chiAB_from_chi2(chi2_tau_cv_t chi2_tau, gf_struct_t
const &gf_struct, std::vector<many_body_operator>
const &A_op_vec,
276 std::vector<many_body_operator>
const &B_op_vec) {
278 using op_term_t = std::tuple<dcomplex, std::pair<int, int>, std::pair<int, int>>;
279 std::vector<std::vector<op_term_t>> A_vec;
280 std::vector<std::vector<op_term_t>> B_vec;
282 for (
auto A : A_op_vec) A_vec.emplace_back(get_terms(A, gf_struct));
283 for (
auto B : B_op_vec) B_vec.emplace_back(get_terms(B, gf_struct));
285 auto chiAB_tau = gf<imtime, matrix_valued>{chi2_tau(0, 0).mesh(), make_shape(A_vec.size(), B_vec.size())};
287 for (
auto [j, B] : enumerate(B_vec))
288 for (
auto &[coef_B, bl_pair_B, idx_pair_B] : B) {
290 auto [idx_cdag_B, idx_c_B] = idx_pair_B;
291 auto [bl_cdag_B, bl_c_B] = bl_pair_B;
293 for (
auto [i, A] : enumerate(A_vec))
294 for (
auto &[coef_A, bl_pair_A, idx_pair_A] : A) {
296 auto [idx_cdag_A, idx_c_A] = idx_pair_A;
297 auto [bl_cdag_A, bl_c_A] = bl_pair_A;
299 if ((bl_cdag_A != bl_c_A) || (bl_cdag_B != bl_c_B)) {
300 TRIQS_RUNTIME_ERROR <<
"Monomials with unequal blocks not implemented for chiAB_from_chi2";
303 auto chiAB_tau_ij = slice_target_to_scalar(chiAB_tau, i, j);
304 auto chi2_tau_AABB_ijkl = slice_target_to_scalar(chi2_tau(bl_c_A, bl_c_B), idx_cdag_A, idx_c_A, idx_cdag_B, idx_c_B);
305 chiAB_tau_ij() += coef_A * coef_B * chi2_tau_AABB_ijkl;
313 template <Chan_t Chan>
314 chi3_tau_t M3_conn_from_M3(chi3_tau_t M3_tau, g_reg_iw_cv_t M_iw, g_reg_iw_cv_t G0_iw, g_tau_cv_t M_tau, block_matrix_t
const &M_hartree) {
316 double beta = M_tau[0].mesh().beta();
317 int n_blocks = M_tau.size();
320 g_reg_iw_t GM_iw = G0_iw * M_iw;
321 g_reg_iw_t MG_iw = M_iw * G0_iw;
322 g_reg_iw_t GMG_iw = G0_iw * M_iw * G0_iw;
324 auto km_GM = make_zero_tail(GM_iw, 2);
325 for (
auto [km_bl, M_hartree_bl] : zip(km_GM, M_hartree)) km_bl(1, ellipsis()) = M_hartree_bl;
326 auto tail_GM = fit_hermitian_tail(GM_iw, km_GM).first;
327 auto tail_MG = fit_hermitian_tail(MG_iw, km_GM).first;
328 auto tau_mesh = make_adjoint_mesh(M_iw[0].mesh());
329 auto GM = make_gf_from_fourier(GM_iw, tau_mesh, tail_GM);
330 auto MG = make_gf_from_fourier(MG_iw, tau_mesh, tail_MG);
332 auto km_GMG = make_zero_tail(GMG_iw, 3);
333 for (
auto [km_bl, M_hartree_bl] : zip(km_GMG, M_hartree)) km_bl(2, ellipsis()) = M_hartree_bl;
334 auto tail_GMG = fit_hermitian_tail(GMG_iw, km_GMG).first;
335 auto dens_GMG = density(GMG_iw, tail_GMG);
338 chi3_tau_t M3_tau_conn = M3_tau;
339 for (
int bl1 : range(n_blocks))
340 for (
int bl2 : range(n_blocks)) {
342 if constexpr (Chan == Chan_t::PP) {
344 M3_tau_conn(bl1, bl2)(t1_, t2_)(i_, j_, k_, l_) << M3_tau(bl1, bl2)[t1_, t2_](i_, j_, k_, l_) - GM[bl1](t1_)(j_, i_) * GM[bl2](t2_)(l_, k_)
345 + kronecker(bl1, bl2) * GM[bl1](t1_)(l_, i_) * GM[bl2](t2_)(j_, k_);
347 }
else if constexpr (Chan == Chan_t::PH) {
349 for (
auto [t1, t2] : M3_tau(0, 0).mesh()) {
353 M3_tau_conn(bl1, bl2)[t1, t2](i_, j_, k_, l_) << M3_tau(bl1, bl2)[t1, t2](i_, j_, k_, l_)
354 - (0.5 * M_tau[bl1](0.0)(j_, i_) - 0.5 * M_tau[bl1](beta)(j_, i_)) * dens_GMG[bl2](l_, k_)
355 - kronecker(bl1, bl2) * GM[bl1](beta - t1)(l_, i_) * MG[bl2](t2)(j_, k_);
365 d_t2_t1 = t2 - t1 + beta;
368 M3_tau_conn(bl1, bl2)[t1, t2](i_, j_, k_, l_) << M3_tau(bl1, bl2)[t1, t2](i_, j_, k_, l_)
369 - s * M_tau[bl1](d_t2_t1)(j_, i_) * dens_GMG[bl2](l_, k_)
370 - kronecker(bl1, bl2) * GM[bl1](beta - t1)(l_, i_) * MG[bl2](t2)(j_, k_);
372 }
else if constexpr (Chan == Chan_t::XPH) {
374 for (
auto [t1, t2] : M3_tau(0, 0).mesh()) {
378 M3_tau_conn(bl1, bl2)[t1, t2](i_, j_, k_, l_) << M3_tau(bl1, bl2)[t1, t2](i_, j_, k_, l_)
379 + kronecker(bl1, bl2) * (0.5 * M_tau[bl1](0.0)(l_, i_) - 0.5 * M_tau[bl1](beta)(l_, i_)) * dens_GMG[bl2](j_, k_)
380 + GM[bl1](beta - t1)(j_, i_) * MG[bl2](t2)(l_, k_);
390 d_t2_t1 = t2 - t1 + beta;
393 M3_tau_conn(bl1, bl2)[t1, t2](i_, j_, k_, l_) << M3_tau(bl1, bl2)[t1, t2](i_, j_, k_, l_)
394 + kronecker(bl1, bl2) * s * M_tau[bl1](d_t2_t1)(l_, i_) * dens_GMG[bl2](j_, k_)
395 + GM[bl1](beta - t1)(j_, i_) * MG[bl2](t2)(l_, k_);
404 template <Chan_t Chan>
405 chi2_tau_t chi2_conn_from_M3(chi3_tau_cv_t M3, chi2_tau_t M3_delta, g_reg_iw_cv_t M_iw, g_reg_iw_cv_t G0_iw, g_tau_cv_t M_tau,
406 block_matrix_t
const &M_hartree, g_tau_cv_t G0_tau) {
408 double beta = G0_tau[0].mesh().beta();
409 int n_blocks = G0_tau.size();
411 auto const &tau_mesh_M3 = M3(0, 0).mesh();
412 double dtau_M3 = std::get<0>(tau_mesh_M3).delta();
413 int n_tau_M3 = std::get<0>(tau_mesh_M3).size();
415 auto const &tau_mesh_M3_del = M3_delta(0, 0).mesh();
416 double dtau_M3_del = tau_mesh_M3_del.delta();
417 int n_tau_M3_del = tau_mesh_M3_del.size();
421 int n_tau_chi2 = n_tau_M3 * 2 - 1;
422 auto tau_mesh_chi2 = mesh::imtime{beta, Boson, n_tau_chi2};
423 auto chi2_conn = make_block2_gf(tau_mesh_chi2, M3);
426 chi3_tau_t M3_conn = M3_conn_from_M3<Chan>(M3, M_iw, G0_iw, M_tau, M_hartree);
427 M3_conn() = M3_conn() * dtau_M3 * dtau_M3;
430 g_reg_iw_t GMG_iw = G0_iw * M_iw * G0_iw;
431 auto km = make_zero_tail(GMG_iw, 3);
432 for (
auto [km_bl, M_hartree_bl] : zip(km, M_hartree)) km_bl(2, ellipsis()) = M_hartree_bl;
433 auto tail = fit_hermitian_tail(GMG_iw, km).first;
434 auto dens_GMG = density(GMG_iw, tail);
437 if constexpr (Chan == Chan_t::PH) {
438 for (
auto [bl1, bl2] : product_range(n_blocks, n_blocks)) {
439 M3_delta(bl1, bl2)(t_)(i_, j_, k_, l_) << M3_delta(bl1, bl2)[t_](i_, j_, k_, l_) - M_hartree[bl1](j_, i_) * dens_GMG[bl2](l_, k_);
441 }
else if constexpr (Chan == Chan_t::XPH) {
442 for (
auto [bl1, bl2] : product_range(n_blocks, n_blocks)) {
443 M3_delta(bl1, bl2)(t_)(i_, j_, k_, l_) << M3_delta(bl1, bl2)[t_](i_, j_, k_, l_)
444 + kronecker(bl1, bl2) * M_hartree[bl1](l_, i_) * dens_GMG[bl2](j_, k_);
447 M3_delta() = M3_delta() * dtau_M3_del;
451 for (
auto [M, M_del] : zip(M3_conn, M3_delta)) {
454 M[n_tau_M3 - 1, _] *= 0.5;
455 M[_, n_tau_M3 - 1] *= 0.5;
457 M_del[n_tau_M3_del - 1] *= 0.5;
460 for (
auto t : tau_mesh_chi2) {
463 if (t.data_index() % 2 == 0 and t.data_index() != 0 and t.data_index() != n_tau_chi2 - 1)
continue;
468 auto get_G0_vecs = [&](mesh::imtime
const &tau_mesh) {
469 auto G0_d_ti_t_vec = std::vector<array<dcomplex, 3>>{};
470 auto G0_d_t_ti_vec = std::vector<array<dcomplex, 3>>{};
472 for (
int bl : range(n_blocks)) {
473 int n_tau = tau_mesh.size();
474 auto sh = G0_tau[bl].target_shape();
475 G0_d_ti_t_vec.emplace_back(sh[0], sh[1], n_tau);
476 G0_d_t_ti_vec.emplace_back(sh[0], sh[1], n_tau);
478 for (
auto ti : tau_mesh) {
480 auto [s1, d_ti_t] = cyclic_difference(ti, t);
481 auto [s2, d_t_ti] = cyclic_difference(t, ti);
484 if (t.data_index() == 0) {
491 if (t.data_index() == n_tau_chi2 - 1) {
499 G0_d_ti_t_vec[bl](range::all, range::all, ti.data_index()) = s1 * G0_tau[bl](d_ti_t);
500 G0_d_t_ti_vec[bl](range::all, range::all, ti.data_index()) = s2 * G0_tau[bl](d_t_ti);
504 return std::make_pair(G0_d_ti_t_vec, G0_d_t_ti_vec);
507 auto [G0_d_ti_t, G0_d_t_ti] = get_G0_vecs(std::get<0>(tau_mesh_M3));
508 auto [G0_d_ti_t_del, G0_d_t_ti_del] = get_G0_vecs(tau_mesh_M3_del);
512 for (
auto [bl1, bl2] : product_range(n_blocks, n_blocks)) {
515 int bl1_size = M3(bl1, bl2).target_shape()[0];
516 int bl2_size = M3(bl1, bl2).target_shape()[2];
518 auto chi2c = chi2_conn(bl1, bl2)[t];
520 if constexpr (Chan == Chan_t::PP) {
522 auto arr_GG = array<dcomplex, 5>(bl1_size, bl1_size, bl2_size, bl2_size, n_tau_M3_del);
523 for (
auto [m, i, n, k] : product_range(bl1_size, bl1_size, bl2_size, bl2_size)) {
524 arr_GG(m, i, n, k, range::all) = G0_d_t_ti_del[bl1](m, i, range::all) * G0_d_t_ti_del[bl2](n, k, range::all);
527 auto M3_perm = nda::array<dcomplex, 6>{permuted_indices_view<encode(std::array{4, 5, 0, 1, 2, 3})>(M3_conn(bl1, bl2).data())};
528 auto M3_del = nda::array<dcomplex, 5>{permuted_indices_view<encode(std::array{4, 0, 1, 2, 3})>(M3_delta(bl1, bl2).data())};
530 for (
auto [m, j, n, l] : product_range(bl1_size, bl1_size, bl2_size, bl2_size)) {
532 auto M3_mjnl = matrix_view<dcomplex>{M3_perm(m, j, n, l, _, _)};
533 for (
auto [i, k] : product_range(bl1_size, bl2_size)) {
534 auto G1_mi = vector_view<dcomplex>(G0_d_t_ti[bl1](m, i, range::all));
535 auto G2_nk = vector_view<dcomplex>(G0_d_t_ti[bl2](n, k, range::all));
536 chi2c(i, j, k, l) += nda::blas::dot(G1_mi, M3_mjnl * G2_nk);
540 auto M3_del_mjnl = vector_view<dcomplex>{M3_del(m, j, n, l, _)};
541 for (
auto [i, k] : product_range(bl1_size, bl2_size)) {
542 chi2c(i, j, k, l) += nda::blas::dot(M3_del_mjnl, vector_view<dcomplex>(arr_GG(m, i, n, k, range::all)));
546 }
else if constexpr (Chan == Chan_t::PH) {
548 auto arr_GG = array<dcomplex, 5>(bl1_size, bl1_size, bl1_size, bl1_size, n_tau_M3_del);
549 for (
auto [m, i, j, n] : product_range(bl1_size, bl1_size, bl1_size, bl1_size)) {
550 arr_GG(m, i, j, n, range::all) = G0_d_ti_t_del[bl1](m, i, range::all) * G0_d_t_ti_del[bl1](j, n, range::all);
553 auto M3_perm = nda::array<dcomplex, 6>{permuted_indices_view<encode(std::array{4, 5, 0, 1, 2, 3})>(M3_conn(bl1, bl2).data())};
554 auto M3_del = nda::array<dcomplex, 5>{permuted_indices_view<encode(std::array{4, 0, 1, 2, 3})>(M3_delta(bl1, bl2).data())};
556 for (
auto [m, n, k, l] : product_range(bl1_size, bl1_size, bl2_size, bl2_size)) {
558 auto M3_mnkl = matrix_view<dcomplex>{M3_perm(m, n, k, l, _, _)};
559 for (
auto [i, j] : product_range(bl1_size, bl1_size)) {
560 auto G1_mi = vector_view<dcomplex>(G0_d_ti_t[bl1](m, i, range::all));
561 auto G2_jn = vector_view<dcomplex>(G0_d_t_ti[bl1](j, n, range::all));
562 chi2c(i, j, k, l) += nda::blas::dot(G1_mi, M3_mnkl * G2_jn);
566 auto M3_del_mnkl = vector_view<dcomplex>{M3_del(m, n, k, l, _)};
567 for (
auto [i, j] : product_range(bl1_size, bl1_size)) {
568 chi2c(i, j, k, l) += nda::blas::dot(M3_del_mnkl, vector_view<dcomplex>(arr_GG(m, i, j, n, range::all)));
572 }
else if constexpr (Chan == Chan_t::XPH) {
574 auto arr_GG = array<dcomplex, 5>(bl1_size, bl1_size, bl2_size, bl2_size, n_tau_M3_del);
575 for (
auto [m, i, l, n] : product_range(bl1_size, bl1_size, bl2_size, bl2_size)) {
576 arr_GG(m, i, l, n, range::all) = G0_d_ti_t_del[bl1](m, i, range::all) * G0_d_t_ti_del[bl2](l, n, range::all);
579 auto M3_perm = nda::array<dcomplex, 6>{permuted_indices_view<encode(std::array{4, 5, 0, 1, 2, 3})>(M3_conn(bl1, bl2).data())};
580 auto M3_del = nda::array<dcomplex, 5>{permuted_indices_view<encode(std::array{4, 0, 1, 2, 3})>(M3_delta(bl1, bl2).data())};
582 for (
auto [m, j, k, n] : product_range(bl1_size, bl1_size, bl2_size, bl2_size)) {
584 auto M3_mjkn = matrix_view<dcomplex>{M3_perm(m, j, k, n, _, _)};
585 for (
auto [i, l] : product_range(bl1_size, bl2_size)) {
586 auto G1_mi = vector_view<dcomplex>(G0_d_ti_t[bl1](m, i, range::all));
587 auto G2_ln = vector_view<dcomplex>(G0_d_t_ti[bl2](l, n, range::all));
588 chi2c(i, j, k, l) += nda::blas::dot(G1_mi, M3_mjkn * G2_ln);
592 auto M3_del_mjkn = vector_view<dcomplex>{M3_del(m, j, k, n, _)};
593 for (
auto [i, l] : product_range(bl1_size, bl2_size)) {
594 chi2c(i, j, k, l) += nda::blas::dot(M3_del_mjkn, vector_view<dcomplex>(arr_GG(m, i, l, n, range::all)));
601 for (
auto t : tau_mesh_chi2) {
603 if (t.data_index() % 2 == 0 and t.data_index() != 0 and t.data_index() != n_tau_chi2 - 1) {
604 for (
auto [bl1, bl2] : product_range(n_blocks, n_blocks)) {
605 chi2_conn(bl1, bl2)[t] = 0.5 * (chi2_conn(bl1, bl2)[t.data_index() - 1] + chi2_conn(bl1, bl2)[t.data_index() + 1]);
629 inline chi3_iw_t chi3_from_M3_PP(chi3_iw_cv_t M3_iw, g_reg_iw_cv_t M_iw, g_reg_iw_cv_t G0_iw, block_matrix_t
const &dens_G,
630 block_matrix_t
const &M_hartree) {
631 return chi3_from_M3<Chan_t::PP>(M3_iw, M_iw, G0_iw, dens_G, M_hartree);
648 inline chi3_iw_t chi3_from_M3_PH(chi3_iw_cv_t M3_iw, g_reg_iw_cv_t M_iw, g_reg_iw_cv_t G0_iw, block_matrix_t
const &dens_G,
649 block_matrix_t
const &M_hartree) {
650 return chi3_from_M3<Chan_t::PH>(M3_iw, M_iw, G0_iw, dens_G, M_hartree);
664 inline chi2_tau_t chi2_from_chi2_conn_PP(chi2_tau_cv_t chi2_conn_tau, g_reg_iw_cv_t G_iw, block_matrix_t
const &dens_G) {
665 return chi2_from_chi2_conn<Chan_t::PP>(chi2_conn_tau, G_iw, dens_G);
679 inline chi2_tau_t chi2_from_chi2_conn_PH(chi2_tau_cv_t chi2_conn_tau, g_reg_iw_cv_t G_iw, block_matrix_t
const &dens_G) {
680 return chi2_from_chi2_conn<Chan_t::PH>(chi2_conn_tau, G_iw, dens_G);
695 inline gf<imtime, matrix_valued> chiAB_from_chi2_PP(chi2_tau_cv_t chi2pp_tau, gf_struct_t
const &gf_struct,
696 std::vector<many_body_operator>
const &A_op_vec,
697 std::vector<many_body_operator>
const &B_op_vec) {
698 return chiAB_from_chi2<Chan_t::PP>(chi2pp_tau, gf_struct, A_op_vec, B_op_vec);
713 inline gf<imtime, matrix_valued> chiAB_from_chi2_PH(chi2_tau_cv_t chi2ph_tau, gf_struct_t
const &gf_struct,
714 std::vector<many_body_operator>
const &A_op_vec,
715 std::vector<many_body_operator>
const &B_op_vec) {
716 return chiAB_from_chi2<Chan_t::PH>(chi2ph_tau, gf_struct, A_op_vec, B_op_vec);
735 inline chi2_tau_t chi2_conn_from_M3_PP(chi3_tau_t M3pp_tau, chi2_tau_t M3pp_delta, g_reg_iw_cv_t M_iw, g_reg_iw_cv_t G0_iw, g_tau_cv_t M_tau,
736 block_matrix_t
const &M_hartree, g_tau_cv_t G0_tau) {
737 return chi2_conn_from_M3<Chan_t::PP>(M3pp_tau, M3pp_delta, M_iw, G0_iw, M_tau, M_hartree, G0_tau);
756 inline chi2_tau_t chi2_conn_from_M3_PH(chi3_tau_t M3ph_tau, chi2_tau_t M3ph_delta, g_reg_iw_cv_t M_iw, g_reg_iw_cv_t G0_iw, g_tau_cv_t M_tau,
757 block_matrix_t
const &M_hartree, g_tau_cv_t G0_tau) {
758 return chi2_conn_from_M3<Chan_t::PH>(M3ph_tau, M3ph_delta, M_iw, G0_iw, M_tau, M_hartree, G0_tau);