23#include <triqs/mc_tools.hpp>
25#include "./O_tau_ins.hpp"
27namespace triqs_cthyb {
29 using namespace triqs::gfs;
30 using namespace triqs::mesh;
32 measure_O_tau_ins::measure_O_tau_ins(std::optional<gf<imtime, scalar_valued>> &O_tau_opt, qmc_data
const &data,
int n_tau,
33 many_body_op_t
const &op1, many_body_op_t
const &op2,
int min_ins, mc_tools::random_generator &rng)
34 : data(data), average_sign(0), op1(op1), op2(op2), min_ins(min_ins), rng(rng) {
35 O_tau_opt = gf<imtime, scalar_valued>{{data.config.beta(), Boson, n_tau}};
36 O_tau.rebind(*O_tau_opt);
39 op1_d = data.imp_trace.attach_aux_operator(op1);
40 op2_d = data.imp_trace.attach_aux_operator(op2);
43 void measure_O_tau_ins::accumulate(mc_weight_t s) {
44 s *= data.atomic_reweighting;
48 for (
const auto &det : data.dets) pto += det.size();
49 int nsamples = pto * pto;
50 if( nsamples < min_ins ) nsamples = min_ins;
52 mc_weight_t atomic_weight, atomic_reweighting;
53 auto [bare_atomic_weight, bare_atomic_reweighting] = data.imp_trace.compute();
54 const auto prefactor = s / bare_atomic_weight / bare_atomic_reweighting / double(nsamples);
56 for ([[maybe_unused]]
int i : range(nsamples)) {
57 auto tau1 = data.tau_seg.get_random_pt(rng);
58 auto tau2 = data.tau_seg.get_random_pt(rng);
59 double dtau = double(tau2 - tau1);
62 data.imp_trace.try_insert(tau1, op1_d);
63 data.imp_trace.try_insert(tau2, op2_d);
64 std::tie(atomic_weight, atomic_reweighting) = data.imp_trace.compute();
65 }
catch (rbt_insert_error
const &) { atomic_weight = 0.; }
67 data.imp_trace.cancel_insert();
68 O_tau[closest_mesh_pt(dtau)] += prefactor * atomic_weight * atomic_reweighting;
72 void measure_O_tau_ins::collect_results(mpi::communicator
const &c) {
73 O_tau = mpi::all_reduce(O_tau, c);
74 average_sign = mpi::all_reduce(average_sign, c);
76 O_tau *= double(O_tau.mesh().size() - 1) / real(average_sign);
82 int last = O_tau.mesh().size() - 1;
83 auto average = O_tau[0] + O_tau[last];
86 O_tau[last] = average;