TRIQS/triqs_ctint 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
types.hpp
1// Copyright (c) 2017--present, The Simons Foundation
2// This file is part of TRIQS/ctint and is licensed under the terms of GPLv3 or later.
3// SPDX-License-Identifier: GPL-3.0-or-later
4// See LICENSE in the root of this distribution for details.
5
6
7#pragma once
8
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>
15
16#include <itertools/itertools.hpp>
17#include <mpi/mpi.hpp>
18
19#include <iostream>
20#include <string>
21#include <utility>
22#include <variant>
23
24namespace triqs_ctint {
25
26 using namespace std::complex_literals; // Complex Unity 1i
27 using namespace triqs;
28 using namespace triqs::gfs;
29 using namespace nda;
30 using namespace triqs::operators;
31 using namespace triqs::operators::utils;
32 using namespace triqs::hilbert_space;
33 using namespace triqs::utility;
34 using namespace h5;
35
36 using namespace itertools;
37
39 enum class Chan_t { PP, PH, XPH };
40
42 using alpha_t = array<double, 4>;
43
45 using triqs::gfs::gf_struct_t;
46
48#ifdef GTAU_IS_COMPLEX
49 using g_tau_t = block_gf<imtime, matrix_valued>;
50#else
51 using g_tau_t = block_gf<imtime, matrix_real_valued>;
52#endif
53
55 using g_tau_cv_t = g_tau_t::const_view_type;
56
58 using g_tau_v_t = g_tau_t::view_type;
59
61 using g_tau_scalar_t = g_tau_t::g_t::scalar_t;
62
64 using g_iw_t = block_gf<mesh::dlr_imfreq, matrix_valued>;
65 using g_dlr_iw_t = g_iw_t; // explicit alias used by M_iw measurement
66
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;
70
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;
74
76#if defined GTAU_IS_COMPLEX || defined INTERACTION_IS_COMPLEX
77 using M_tau_target_t = matrix_valued;
78#else
79 using M_tau_target_t = matrix_real_valued;
80#endif
81 using M_tau_scalar_t = M_tau_target_t::scalar_t;
82
84#ifdef INTERACTION_IS_COMPLEX
85 using U_scalar_t = dcomplex;
86#else
87 using U_scalar_t = double;
88#endif
89
91 using mc_weight_t = decltype(U_scalar_t{} * g_tau_scalar_t{});
92
94 using block_matrix_t = std::vector<matrix<M_tau_scalar_t>>;
95
97 using block_matrix_v_t = std::vector<matrix_view<M_tau_scalar_t>>;
98
100 using chi2_iw_t = block2_gf<imfreq, tensor_valued<4>>;
101
103 using chi2_tau_t = block2_gf<imtime, tensor_valued<4>>;
104
106 using chi2_tau_v_t = chi2_tau_t::view_type;
107
109 using chi2_tau_cv_t = chi2_tau_t::const_view_type;
110
112 using chi3_iw_t = block2_gf<prod<imfreq, imfreq>, tensor_valued<4>>;
113
115 using chi3_iw_v_t = chi3_iw_t::view_type;
116
118 using chi3_iw_cv_t = chi3_iw_t::const_view_type;
119
121 using chi3_tau_t = block2_gf<prod<imtime, imtime>, tensor_valued<4>>;
122
124 using chi3_tau_v_t = chi3_tau_t::view_type;
125
127 using chi3_tau_cv_t = chi3_tau_t::const_view_type;
128
130 using chi4_iw_t = block2_gf<prod<imfreq, imfreq, imfreq>, tensor_valued<4>>;
131
133 using chi4_tau_t = block2_gf<prod<imtime, imtime, imtime>, tensor_valued<4>>;
134
135 // Declare some placeholders for the rest of the code. Use anonymous namespace for proper linkage
136 // in this code, all variables with trailing _ are placeholders by convention.
137 namespace {
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_;
157 } // anonymous namespace
158
159} // namespace triqs_ctint
160
161namespace triqs::gfs {
162
164 //FIXME Implement with is_array trait
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);
168 }
169 //FIXME array_const_view should be constructable from array_view
170 template <typename Value_t, int Rank> double max_norm(array_view<Value_t, Rank> const &arr) { return max_norm(make_const_view(arr)); }
171
173 template <typename Gf> std::enable_if_t<is_gf_v<Gf>, double> max_norm(Gf const &G) { return max_norm(G.data()); }
174
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) {
176
177 std::vector<std::vector<gf<M, Target>>> gf_vecvec;
178 std::vector<std::string> block_names;
179
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));
186 else
187 gf_vec.emplace_back(m, make_shape(bl1_size, bl2_size));
188 }
189 gf_vecvec.emplace_back(std::move(gf_vec));
190 }
191
192 return make_block2_gf(block_names, block_names, std::move(gf_vecvec));
193 }
194
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) {
197
198 std::vector<std::vector<gf<M1, Target>>> gf_vecvec;
199
200 int n_blocks0 = g_in.block_names()[0].size();
201 int n_blocks1 = g_in.block_names()[1].size();
202
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));
207 }
208
209 return make_block2_gf(g_in.block_names()[0], g_in.block_names()[1], std::move(gf_vecvec));
210 }
211
212 template <typename Scalar_t> std::vector<matrix<Scalar_t>> make_block_vector(gf_struct_t const &gf_struct) {
213
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)); }
216 return res;
217 }
218} // namespace triqs::gfs
219
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; }
223
225 inline std::pair<int, int> get_int_indices(canonical_ops_t const &op, hilbert_space::gf_struct_t const &gf_struct) {
226
227 // The Fundamental operator-set allows for easy check of index validity
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 ";
230
231 // Get block-name with apply visitor, lambda(0) is called to determine return type ...
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]);
234
235 // Capture positions in block and nonblock list
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); }
239 }
240 TRIQS_RUNTIME_ERROR << "Error: Failed to retrieve integer indices for operator";
241 }
242
243 // Function that takes a bosonic operator Op = Sum_i a_i c^+(bi, ui) c(bi, vi)
244 // and returns a vector<tuple> with v[i] = (b_i, a_i, (c^+(bi, ui), c(bi, vi)))
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);
256 }
257 return terms;
258 }
259
260} // namespace triqs::operators
261
262// Useful macros
263
264#define STR(x) #x
265#define STRINGIZE(x) STR(x)
266
267#ifdef DEBUG_CTINT
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
271#define BREAK(X) \
272 std::cerr << X << " ... " << std::endl; \
273 getchar()
274#else
275#define DEBUG(X)
276#define BREAK(X)
277#endif