6#include "./M3ph_iw.hpp"
8namespace triqs_ctint::measures {
10 M3ph_iw::M3ph_iw(params_t
const ¶ms_, qmc_config_t
const &qmc_config_, container_set *results, g_tau_cv_t G0_tau_)
12 qmc_config(qmc_config_),
13 buf_arrarr(params_.n_blocks()),
14 buf_arrarr_GM(params_.n_blocks()),
15 buf_arrarr_MG(params_.n_blocks()),
16 G0_tau(std::move(G0_tau_)) {
19 mesh::imfreq iW_mesh{params.beta, Boson, params.n_iW_M3};
20 mesh::imfreq iw_mesh{params.beta, Fermion, params.n_iw_M3};
21 mesh::prod<imfreq, imfreq> M3ph_iw_mesh{iW_mesh, iw_mesh};
24 results->M3ph_iw_nfft = make_block2_gf(M3ph_iw_mesh, params.gf_struct);
25 M3ph_iw_.rebind(results->M3ph_iw_nfft.value());
29 mesh::imfreq iw_mesh_large{params.beta, Fermion, params.n_iw_M3 + params.n_iW_M3};
30 M = block_gf{mesh::prod<imfreq, imfreq>{iw_mesh_large, iw_mesh}, params.gf_struct};
31 GM = block_gf{iw_mesh, params.gf_struct};
32 MG = block_gf{iw_mesh_large, params.gf_struct};
34 auto init_target_func = [&](
int bl) {
35 int bl_size = GM[bl].target_shape()[0];
36 return array<dcomplex, 2>(bl_size, bl_size);
38 GMG = array_adapter{make_shape(params.n_blocks()), init_target_func};
41 for (
int bl : range(params.n_blocks())) {
43 auto init_func_M = [&](
int i,
int j) {
return nfft_buf_t<2>{slice_target_to_scalar(M[bl], i, j).data(), params.nfft_buf_size, params.beta}; };
44 buf_arrarr(bl) = array_adapter{M[bl].target_shape(), init_func_M};
47 auto init_func_GM = [&](
int i,
int j) {
return nfft_buf_t<1>{slice_target_to_scalar(GM[bl], i, j).data(), params.nfft_buf_size, params.beta}; };
48 buf_arrarr_GM(bl) = array_adapter{GM[bl].target_shape(), init_func_GM};
51 auto init_func_MG = [&](
int i,
int j) {
return nfft_buf_t<1>{slice_target_to_scalar(MG[bl], i, j).data(), params.nfft_buf_size, params.beta}; };
52 buf_arrarr_MG(bl) = array_adapter{MG[bl].target_shape(), init_func_MG};
61 for (
auto &i : GMG) { i() = 0; }
66 double beta = params.beta;
69 for (
int bl : range(params.n_blocks())) {
70 int bl_size = GM[bl].target_shape()[0];
73 foreach (qmc_config.dets[bl], [&](c_t
const &c_i, cdag_t
const &cdag_j,
auto const &Ginv_ji) {
74 auto tau_i = double(c_i.tau);
75 auto tau_j = double(cdag_j.tau);
78 buf_arrarr(bl)(cdag_j.u, c_i.u).push_back({tau_j, beta - tau_i}, -Ginv_ji);
81 for (
int abar_u : range(bl_size)) {
82 auto G0_ia = G0_tau[bl][closest_mesh_pt(tau_i)](c_i.
u, abar_u);
83 for (
int b_u : range(bl_size)) {
85 auto G0_bj = -G0_tau[bl][closest_mesh_pt(beta - tau_j)](b_u, cdag_j.
u);
86 GMG(bl)(abar_u, b_u) += G0_bj * Ginv_ji * G0_ia;
88 buf_arrarr_GM(bl)(b_u, c_i.
u).push_back({beta - tau_i}, -G0_bj * Ginv_ji);
89 buf_arrarr_MG(bl)(b_u, c_i.
u).push_back({tau_j}, Ginv_ji * G0_ia);
96 for (
auto &buf_arr : buf_arrarr)
97 for (auto &buf : buf_arr) buf.flush();
98 for (
auto &buf_arr : buf_arrarr_GM)
99 for (
auto &buf : buf_arr) buf.flush();
100 for (
auto &buf_arr : buf_arrarr_MG)
101 for (
auto &buf : buf_arr) buf.flush();
103 auto [iW_mesh, iw_mesh] = M3ph_iw_(0, 0).mesh();
105 for (
int bl1 : range(params.n_blocks()))
106 for (
int bl2 : range(params.n_blocks())) {
108 int bl1_size = M[bl1].target_shape()[0];
109 int bl2_size = M[bl2].target_shape()[0];
110 auto const &M1 = M[bl1];
111 auto const &GMG2 = GMG(bl2);
112 auto const &GM1 = GM[bl1];
113 auto const &MG2 = MG(bl2);
114 auto &M3ph_iw = M3ph_iw_(bl1, bl2);
116 for (auto iW : iW_mesh)
117 for (auto iw : iw_mesh)
118 for (int i : range(bl1_size))
119 for (int j : range(bl1_size))
120 for (int k : range(bl2_size))
121 for (int l : range(bl2_size)) {
122 M3ph_iw[iW, iw](i, j, k, l) += sign * M1[iW + iw, iw.value()](j, i) * GMG2(l, k);
123 if (bl1 == bl2) { M3ph_iw[iW, iw](i, j, k, l) -= sign * GM1[iw.value()](l, i) * MG2[iW + iw](j, k); }
130 Z = mpi::all_reduce(Z, comm);
131 M3ph_iw_ = mpi::all_reduce(M3ph_iw_, comm);
132 M3ph_iw_ = M3ph_iw_ / Z;
int u
The orbital (or non-block) index.
void collect_results(mpi::communicator const &comm)
Collect results and normalize.
void accumulate(mc_weight_t sign)
Accumulate M_tau using binning.