9#include <triqs/gfs.hpp>
10#include <triqs/mesh.hpp>
11#include <triqs/arrays/block_matrix.hpp>
12#include <triqs/operators/many_body_operator.hpp>
13#include <triqs/hilbert_space/fundamental_operator_set.hpp>
14#include <triqs/operators/util/extractors.hpp>
16#include <itertools/itertools.hpp>
24namespace triqs_ctint {
26 using namespace std::complex_literals;
27 using namespace triqs;
28 using namespace triqs::gfs;
30 using namespace triqs::operators;
31 using namespace triqs::operators::utils;
32 using namespace triqs::hilbert_space;
33 using namespace triqs::utility;
36 using namespace itertools;
39 enum class Chan_t { PP, PH, XPH };
42 using alpha_t = array<double, 4>;
45 using triqs::gfs::gf_struct_t;
49 using g_tau_t = block_gf<imtime, matrix_valued>;
51 using g_tau_t = block_gf<imtime, matrix_real_valued>;
55 using g_tau_cv_t = g_tau_t::const_view_type;
58 using g_tau_v_t = g_tau_t::view_type;
61 using g_tau_scalar_t = g_tau_t::g_t::scalar_t;
64 using g_iw_t = block_gf<mesh::dlr_imfreq, matrix_valued>;
65 using g_dlr_iw_t = g_iw_t;
68 using g_dlr_iw_cv_t = g_iw_t::const_view_type;
69 using g_dlr_iw_v_t = g_iw_t::view_type;
72 using g_reg_iw_t = block_gf<imfreq, matrix_valued>;
73 using g_reg_iw_cv_t = g_reg_iw_t::const_view_type;
76#if defined GTAU_IS_COMPLEX || defined INTERACTION_IS_COMPLEX
77 using M_tau_target_t = matrix_valued;
79 using M_tau_target_t = matrix_real_valued;
81 using M_tau_scalar_t = M_tau_target_t::scalar_t;
84#ifdef INTERACTION_IS_COMPLEX
85 using U_scalar_t = dcomplex;
87 using U_scalar_t = double;
91 using mc_weight_t =
decltype(U_scalar_t{} * g_tau_scalar_t{});
94 using block_matrix_t = std::vector<matrix<M_tau_scalar_t>>;
97 using block_matrix_v_t = std::vector<matrix_view<M_tau_scalar_t>>;
100 using chi2_iw_t = block2_gf<imfreq, tensor_valued<4>>;
103 using chi2_tau_t = block2_gf<imtime, tensor_valued<4>>;
106 using chi2_tau_v_t = chi2_tau_t::view_type;
109 using chi2_tau_cv_t = chi2_tau_t::const_view_type;
112 using chi3_iw_t = block2_gf<prod<imfreq, imfreq>, tensor_valued<4>>;
115 using chi3_iw_v_t = chi3_iw_t::view_type;
118 using chi3_iw_cv_t = chi3_iw_t::const_view_type;
121 using chi3_tau_t = block2_gf<prod<imtime, imtime>, tensor_valued<4>>;
124 using chi3_tau_v_t = chi3_tau_t::view_type;
127 using chi3_tau_cv_t = chi3_tau_t::const_view_type;
130 using chi4_iw_t = block2_gf<prod<imfreq, imfreq, imfreq>, tensor_valued<4>>;
133 using chi4_tau_t = block2_gf<prod<imtime, imtime, imtime>, tensor_valued<4>>;
138 using nda::clef::placeholder;
139 const placeholder<0> i_;
140 const placeholder<1> j_;
141 const placeholder<2> k_;
142 const placeholder<3> l_;
143 const placeholder<4> iw_;
144 const placeholder<5> iw1_;
145 const placeholder<6> iw2_;
146 const placeholder<7> iw3_;
147 const placeholder<8> iw4_;
148 const placeholder<9> t_;
149 const placeholder<10> t1_;
150 const placeholder<11> t2_;
151 const placeholder<12> t3_;
152 const placeholder<13> bl_;
153 const placeholder<14> bl1_;
154 const placeholder<15> bl2_;
155 const placeholder<16> iW_;
156 const placeholder<17> iwp_;
161namespace triqs::gfs {
165 template <
typename Value_t,
int Rank>
double max_norm(array_const_view<Value_t, Rank>
const &arr) {
166 auto max_itr = std::max_element(arr.begin(), arr.end(), [](
auto a,
auto b) { return std::abs(a) < std::abs(b); });
167 return std::abs(*max_itr);
170 template <
typename Value_t,
int Rank>
double max_norm(array_view<Value_t, Rank>
const &arr) {
return max_norm(make_const_view(arr)); }
173 template <
typename Gf> std::enable_if_t<is_gf_v<Gf>,
double> max_norm(Gf
const &G) {
return max_norm(G.data()); }
175 template <
typename M,
typename Target = tensor_valued<4>> block2_gf<M, Target> make_block2_gf(M
const &m, gf_struct_t
const &gf_struct) {
177 std::vector<std::vector<gf<M, Target>>> gf_vecvec;
178 std::vector<std::string> block_names;
180 for (
auto const &[bl1, bl1_size] : gf_struct) {
181 block_names.push_back(bl1);
182 std::vector<gf<M, Target>> gf_vec;
183 for (
auto const &[bl2, bl2_size] : gf_struct) {
184 if constexpr (Target::rank == 4)
185 gf_vec.emplace_back(m, make_shape(bl1_size, bl1_size, bl2_size, bl2_size));
187 gf_vec.emplace_back(m, make_shape(bl1_size, bl2_size));
189 gf_vecvec.emplace_back(std::move(gf_vec));
192 return make_block2_gf(block_names, block_names, std::move(gf_vecvec));
195 template <
typename M1,
typename M2,
typename Target = tensor_valued<4>>
196 block2_gf<M1, Target> make_block2_gf(M1
const &m, block2_gf_const_view<M2, Target> g_in) {
198 std::vector<std::vector<gf<M1, Target>>> gf_vecvec;
200 int n_blocks0 = g_in.block_names()[0].size();
201 int n_blocks1 = g_in.block_names()[1].size();
203 for (
int i : range(n_blocks0)) {
204 std::vector<gf<M1, Target>> gf_vec;
205 for (
int j : range(n_blocks1)) { gf_vec.emplace_back(m, g_in(i, j).target_shape()); }
206 gf_vecvec.emplace_back(std::move(gf_vec));
209 return make_block2_gf(g_in.block_names()[0], g_in.block_names()[1], std::move(gf_vecvec));
212 template <
typename Scalar_t> std::vector<matrix<Scalar_t>> make_block_vector(gf_struct_t
const &gf_struct) {
214 std::vector<matrix<Scalar_t>> res;
215 for (
auto const &[bl, bl_size] : gf_struct) { res.emplace_back(nda::zeros<Scalar_t>(bl_size, bl_size)); }
220namespace triqs::operators {
222 inline bool is_densdens_interact(monomial_t m) {
return m.size() == 4 and m[0].indices == m[3].indices and m[1].indices == m[2].indices; }
225 inline std::pair<int, int> get_int_indices(canonical_ops_t
const &op, hilbert_space::gf_struct_t
const &gf_struct) {
228 hilbert_space::fundamental_operator_set fs(gf_struct);
229 if (!fs.has_indices(op.indices)) TRIQS_RUNTIME_ERROR <<
" Index of c/c^+ operator not compatible with Green Function structure ";
232 std::string op_bl_name = visit([](
auto idx) {
return std::to_string(idx); }, op.indices[0]);
233 long nonbl_int_idx = std::get<long>(op.indices[1]);
236 for (
auto [bl_int_idx, bl] : itertools::enumerate(gf_struct)) {
237 auto const &[bl_name, bl_size] = bl;
238 if (bl_name == op_bl_name and 0 <= nonbl_int_idx and nonbl_int_idx < bl_size) {
return std::make_pair(bl_int_idx, nonbl_int_idx); }
240 TRIQS_RUNTIME_ERROR <<
"Error: Failed to retrieve integer indices for operator";
245 inline auto get_terms(many_body_operator
const &A, hilbert_space::gf_struct_t
const &gf_struct) {
246 std::vector<std::tuple<std::complex<double>, std::pair<int, int>, std::pair<int, int>>> terms;
247 for (
auto const &term : A) {
248 auto const &m = term.monomial;
249 if (m.size() != 2 or !m[0].dagger or m[1].dagger)
250 TRIQS_RUNTIME_ERROR <<
" Monomial in bosonic operator of chiAB measurement not of the proper form c^+ c \n";
251 auto [bl1, i] = get_int_indices(m[0], gf_struct);
252 auto [bl2, j] = get_int_indices(m[1], gf_struct);
253 auto bl_pair = std::make_pair(bl1, bl2);
254 auto idx_pair = std::make_pair(i, j);
255 terms.emplace_back(term.coef, bl_pair, idx_pair);
265#define STRINGIZE(x) STR(x)
268#define TRIQS_EXCEPTION_SHOW_CPP_TRACE
269#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
270#define DEBUG(X) std::cerr << AS_STRING(X) << " = " << X << " at " << __FILENAME__ << ':' << __LINE__ << std::endl
272 std::cerr << X << " ... " << std::endl; \