22#include "impurity_trace.hpp"
23#include <triqs/gfs.hpp>
24#include <triqs/mesh.hpp>
25#include <triqs/det_manip.hpp>
27namespace triqs_cthyb {
28 using namespace triqs::gfs;
29 using namespace triqs::mesh;
39 std::map<std::pair<int, int>,
int> linindex;
40 atom_diag
const &h_diag;
41 mutable impurity_trace imp_trace;
42 std::vector<int> n_inner;
43 block_gf<imtime, delta_target_t> delta;
46 struct delta_block_adaptor {
47 gf<imtime, delta_target_t> delta_block;
49 delta_block_adaptor(gf_const_view<imtime, delta_target_t> delta_block) : delta_block(std::move(delta_block)) {}
50 delta_block_adaptor(delta_block_adaptor
const &) =
default;
51 delta_block_adaptor(delta_block_adaptor &&) =
default;
52 delta_block_adaptor &operator=(delta_block_adaptor
const &) =
delete;
53 delta_block_adaptor &operator=(delta_block_adaptor &&) =
default;
55 det_scalar_t operator()(std::pair<time_pt, int>
const &x, std::pair<time_pt, int>
const &y)
const {
56 det_scalar_t res = delta_block[closest_mesh_pt(
double(x.first - y.first))](x.second, y.second);
57 return (x.first >= y.first ? res : -res);
61 friend void swap(delta_block_adaptor &dba1, delta_block_adaptor &dba2)
noexcept { std::swap(dba1.delta_block, dba2.delta_block); }
64 std::vector<det_manip::det_manip<delta_block_adaptor>> dets;
65 int current_sign, old_sign;
66 h_scalar_t atomic_weight;
67 h_scalar_t atomic_reweighting;
70 qmc_data(
double beta,
solve_parameters_t const &p, atom_diag
const &h_diag, std::map<std::pair<int, int>,
int> linindex,
71 block_gf_const_view<imtime> delta, std::vector<int> n_inner, histo_map_t *histo_map)
76 imp_trace(beta, h_diag, histo_map, p.use_norm_as_weight, p.measure_density_matrix, p.performance_analysis),
78 delta(map([](gf_const_view<imtime> d) {
return real(d); }, delta)),
82 std::vector<std::vector<std::pair<time_pt, int>>> X(delta.size()), Y(delta.size());
85 if (p.initial_configuration) {
88 if (p.initial_configuration->beta() != beta) {
89 TRIQS_RUNTIME_ERROR <<
"Beta of initial configuration not equal current beta: " << p.initial_configuration->beta() <<
" != " << beta;
92 for (
auto const &[tau, op] : p.initial_configuration.value()) {
94 if (op.block_index >= delta.size() || op.inner_index >= n_inner[op.block_index]
95 || op.linear_index != linindex.at({op.block_index, op.inner_index})) {
96 TRIQS_RUNTIME_ERROR <<
"Inconsistency in the block structure of the initial configuration";
100 imp_trace.try_insert(tau, op);
101 imp_trace.confirm_insert();
105 X[op.block_index].emplace_back(tau, op.inner_index);
107 Y[op.block_index].emplace_back(tau, op.inner_index);
110 config.insert(tau, op);
113 for (
auto bl : range(delta.size())) {
114 if (X[bl].size() != Y[bl].size())
115 TRIQS_RUNTIME_ERROR <<
"Unequal number of c_dag and c operators in bl " << bl <<
" of the initial configuration";
120 std::tie(atomic_weight, atomic_reweighting) = imp_trace.compute();
124 dets.reserve(delta.size());
125 for (
auto const &bl : range(delta.size())) {
126#ifdef HYBRIDISATION_IS_COMPLEX
129 if (!is_gf_real(delta[bl], 1e-10)) {
130 if (p.verbosity >= 2) {
131 std::cerr <<
"WARNING: The Delta(tau) block number " << bl <<
" is not real in tau space\n";
132 std::cerr <<
"WARNING: max(Im[Delta(tau)]) = " << max_element(abs(imag(delta[bl].data()))) <<
"\n";
133 std::cerr <<
"WARNING: Dissregarding the imaginary component in the calculation.\n";
139 dets.emplace_back(delta_functor, p.det_init_size);
141 dets.emplace_back(delta_functor, X[bl], Y[bl]);
143 dets.back().set_singular_threshold(p.det_singular_threshold);
144 dets.back().set_n_operations_before_check(p.det_n_operations_before_check);
145 dets.back().set_precision_warning(p.det_precision_warning);
146 dets.back().set_precision_error(p.det_precision_error);
151 qmc_data(qmc_data
const &) =
delete;
152 qmc_data &operator=(qmc_data
const &) =
delete;
157 size_t num_blocks = dets.size();
158 std::vector<int> n_op_with_a_equal_to(num_blocks, 0), n_ndag_op_with_a_equal_to(num_blocks, 0);
164 for (
auto const &op : config) {
167 for (
int a = op.second.block_index + 1; a < num_blocks; ++a) s += n_op_with_a_equal_to[a];
168 n_op_with_a_equal_to[op.second.block_index]++;
171 if (op.second.dagger)
172 s += n_ndag_op_with_a_equal_to[op.second.block_index];
174 n_ndag_op_with_a_equal_to[op.second.block_index]++;
179 for (
int block_index = 0; block_index < num_blocks; block_index++) {
180 int n = dets[block_index].size();
181 s += n * (n + 1) / 2;
184 old_sign = current_sign;
185 current_sign = (s % 2 == 0 ? 1 : -1);
191 using det_type = det_manip::det_manip<qmc_data::delta_block_adaptor>;
194 inline void print_det_sequence(qmc_data
const &data) {
197 for (block_index = 0; block_index < data.dets.size(); ++block_index) {
198 auto det = data.dets[block_index];
199 if (det.size() == 0)
return;
200 std::cout <<
"BLOCK = " << block_index << std::endl;
201 for (i = 0; i < det.size(); ++i) {
202 std::cout <<
" ic_dag = " << i <<
": tau = " << det.get_x(i).first << std::endl;
204 for (i = 0; i < det.size(); ++i) {
205 std::cout <<
" ic = " << i <<
": tau = " << det.get_y(i).first << std::endl;
210 inline void print_det_sequence(det_type
const &det) {
212 for (i = 0; i < det.size(); ++i) {
213 std::cout <<
" ic_dag = " << i <<
": tau = " << det.get_x(i).first << std::endl;
215 for (i = 0; i < det.size(); ++i) {
216 std::cout <<
" ic = " << i <<
": tau = " << det.get_y(i).first << std::endl;
221 inline void check_det_sequence(det_type
const &det,
int config_id) {
222 if (det.size() == 0)
return;
223 auto tau = det.get_x(0).first;
224 for (
auto ic_dag = 0; ic_dag < det.size(); ++ic_dag) {
225 if (tau < det.get_x(ic_dag).first) {
226 std::cout <<
"ERROR in det order in config " << config_id << std::endl;
227 print_det_sequence(det);
228 TRIQS_RUNTIME_ERROR <<
"Det ordering wrong: tau(ic_dag = " << ic_dag <<
") = " << double(det.get_x(ic_dag).first);
230 tau = det.get_x(ic_dag).first;
232 tau = det.get_y(0).first;
233 for (
auto ic = 0; ic < det.size(); ++ic) {
234 if (tau < det.get_y(ic).first) {
235 std::cout <<
"ERROR in det order in config " << config_id << std::endl;
236 print_det_sequence(det);
237 TRIQS_RUNTIME_ERROR <<
"Det ordering wrong: tau(ic = " << ic <<
") = " << double(det.get_y(ic).first);
239 tau = det.get_y(ic).first;
This callable object adapts the Delta function for the call of the det.
Parameters passed to the solve method of the solver class.