23#include "./G2_iw_acc.hpp"
25namespace triqs_cthyb {
29 template <G2_channel Channel>
30 measure_G2_iw_base<Channel>::measure_G2_iw_base(std::optional<G2_iw_t> &G2_iw_opt,
32 G2_measures_t
const &G2_measures)
33 : data(data), average_sign(0), G2_measures(G2_measures) {
35 const double beta = data.config.beta();
37 order = G2_measures.params.measure_G2_block_order;
38 int n_bosonic = G2_measures.params.measure_G2_n_bosonic;
39 int n_fermionic = G2_measures.params.measure_G2_n_fermionic;
43 mesh::imfreq mesh_f{beta, Fermion, n_fermionic};
44 mesh::imfreq mesh_b{beta, Boson, n_bosonic};
46 mesh::prod<imfreq, imfreq, imfreq> mesh_fff{mesh_f, mesh_f, mesh_f};
47 mesh::prod<imfreq, imfreq, imfreq> mesh_bff{mesh_b, mesh_f, mesh_f};
49 if (Channel == G2_channel::AllFermionic)
50 G2_iw_opt = make_block2_gf(mesh_fff, G2_measures.gf_struct, order);
52 G2_iw_opt = make_block2_gf(mesh_bff, G2_measures.gf_struct, order);
54 G2_iw.rebind(*G2_iw_opt);
60 if (Channel == G2_channel::AllFermionic) {
61 mesh::imfreq iw_mesh_large{beta, Fermion, 3 * n_fermionic};
62 mesh::imfreq iw_mesh_small{beta, Fermion, n_fermionic};
63 M_mesh = mesh::prod<imfreq, imfreq>{iw_mesh_large, iw_mesh_small};
65 int nfreq = n_bosonic + n_fermionic;
66 mesh::imfreq iw_mesh{beta, Fermion, nfreq};
67 M_mesh = mesh::prod<imfreq, imfreq>{iw_mesh, iw_mesh};
71 M = block_gf{M_mesh, G2_measures.gf_struct};
75 template <G2_channel Channel>
76 void accumulate_impl_AABB(G2_iw_t::g_t::view_type G2, mc_weight_t s, M_t
const &M_ij,
78 template <G2_channel Channel>
79 void accumulate_impl_ABBA(G2_iw_t::g_t::view_type G2, mc_weight_t s, M_t
const &M_ij,
82 template <G2_channel Channel>
void measure_G2_iw_base<Channel>::accumulate_G2(mc_weight_t s) {
84 s *= data.atomic_reweighting;
88 for (
auto &m : G2_measures()) {
89 auto G2_iw_block = G2_iw(m.b1.idx, m.b2.idx);
90 bool diag_block = (m.b1.idx == m.b2.idx);
91 if (order == block_order::AABB || diag_block)
92 accumulate_impl_AABB<Channel>(G2_iw_block, s, M(m.b1.idx), M(m.b2.idx));
93 if (order == block_order::ABBA || diag_block)
94 accumulate_impl_ABBA<Channel>(G2_iw_block, s, M(m.b1.idx), M(m.b2.idx));
99 template <G2_channel Channel>
100 void measure_G2_iw_base<Channel>::collect_results(mpi::communicator
const &com) {
102 average_sign = mpi::all_reduce(average_sign, com);
103 G2_iw = mpi::all_reduce(G2_iw, com);
105 G2_iw = G2_iw / (real(average_sign) * data.config.beta());
107 if (com.rank() == 0) {
108 std::cout <<
"measure/G2_iw: timer_M = " << double(timer_M) <<
"\n";
109 std::cout <<
"measure/G2_iw: timer_G2 = " << double(timer_G2) <<
"\n";
116 void accumulate_impl_AABB<G2_channel::PH>(G2_iw_t::g_t::view_type G2, mc_weight_t s,
117 M_t
const &M_ij, M_t
const &M_kl) {
120 for (
const auto &[w, n1, n2] : G2.mesh())
121 for (
const auto [i, j, k, l] : G2.target_indices())
122 G2[w, n1, n2](i, j, k, l) += s * M_ij[n1.value(), n1 + w](i, j) * M_kl[n2 + w, n2.value()](k, l);
126 void accumulate_impl_ABBA<G2_channel::PH>(G2_iw_t::g_t::view_type G2, mc_weight_t s,
127 M_t
const &M_il, M_t
const &M_kj) {
130 for (
const auto &[w, n1, n2] : G2.mesh())
131 for (
const auto [i, j, k, l] : G2.target_indices())
132 G2[w, n1, n2](i, j, k, l) -= s * M_il[n1.value(), n2.value()](i, l) * M_kj[n2 + w, n1 + w](k, j);
138 void accumulate_impl_AABB<G2_channel::PP>(G2_iw_t::g_t::view_type G2, mc_weight_t s,
139 M_t
const &M_ij, M_t
const &M_kl) {
142 for (
const auto &[w, n1, n2] : G2.mesh())
143 for (
const auto [i, j, k, l] : G2.target_indices())
144 G2[w, n1, n2](i, j, k, l) += s * M_ij[n1.value(), w - n2](i, j) * M_kl[w - n1, n2.value()](k, l);
148 void accumulate_impl_ABBA<G2_channel::PP>(G2_iw_t::g_t::view_type G2, mc_weight_t s,
149 M_t
const &M_il, M_t
const &M_kj) {
153 for (
const auto &[w, n1, n2] : G2.mesh())
154 for (
const auto [i, j, k, l] : G2.target_indices())
155 G2[w, n1, n2](i, j, k, l) -= s * M_il[n1.value(), n2.value()](i, l) * M_kj[w - n1, w - n2](k, j);
161 void accumulate_impl_AABB<G2_channel::AllFermionic>(G2_iw_t::g_t::view_type G2, mc_weight_t s,
162 M_t
const &M_ij, M_t
const &M_kl) {
165 for (
const auto &[n1, n2, n3] : G2.mesh()) {
166 auto n4 = n1 + n3 - n2;
167 for (
const auto [i, j, k, l] : G2.target_indices())
168 G2[n1, n2, n3](i, j, k, l) += s * M_ij[n2.value(), n1.value()](j, i) * M_kl[n4, n3.value()](l, k);
173 void accumulate_impl_ABBA<G2_channel::AllFermionic>(G2_iw_t::g_t::view_type G2, mc_weight_t s,
174 M_t
const &M_il, M_t
const &M_kj) {
177 for (
const auto &[n1, n2, n3] : G2.mesh()) {
178 auto n4 = n1 + n3 - n2;
179 for (
const auto [i, j, k, l] : G2.target_indices())
180 G2[n1, n2, n3](i, j, k, l) -= s * M_il[n4, n1.value()](l, i) * M_kj[n2.value(), n3.value()](j, k);
184 template class measure_G2_iw_base<G2_channel::AllFermionic>;
185 template class measure_G2_iw_base<G2_channel::PP>;
186 template class measure_G2_iw_base<G2_channel::PH>;