TRIQS/triqs_ctint unstable
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/operators/many_body_operator.hpp>
12#include <triqs/hilbert_space/fundamental_operator_set.hpp>
13#include <triqs/operators/util/extractors.hpp>
14
15#include <itertools/itertools.hpp>
16#include <mpi/mpi.hpp>
17
18#include <iostream>
19#include <string>
20#include <utility>
21#include <variant>
22
23namespace triqs_ctint {
24
25 using namespace std::complex_literals; // Complex Unity 1i
26 using namespace triqs;
27 using namespace triqs::gfs;
28 using namespace nda;
29 using namespace triqs::operators;
30 using namespace triqs::operators::utils;
31 using namespace triqs::hilbert_space;
32 using namespace triqs::utility;
33 using namespace h5;
34
35 using namespace itertools;
36
38 enum class Chan_t { PP, PH, XPH };
39
41 using alpha_t = array<double, 4>;
42
44 using triqs::gfs::gf_struct_t;
45
47#ifdef GTAU_IS_COMPLEX
48 using g_tau_t = block_gf<imtime, matrix_valued>;
49#else
50 using g_tau_t = block_gf<imtime, matrix_real_valued>;
51#endif
52
54 using g_tau_cv_t = g_tau_t::const_view_type;
55
57 using g_tau_v_t = g_tau_t::view_type;
58
60 using g_tau_scalar_t = g_tau_t::g_t::scalar_t;
61
63 using g_iw_t = block_gf<mesh::dlr_imfreq, matrix_valued>;
64 using g_dlr_iw_t = g_iw_t; // explicit alias used by M_iw measurement
65
67 using g_dlr_iw_cv_t = g_iw_t::const_view_type;
68 using g_dlr_iw_v_t = g_iw_t::view_type;
69
71 using g_reg_iw_t = block_gf<imfreq, matrix_valued>;
72 using g_reg_iw_cv_t = g_reg_iw_t::const_view_type;
73
75#if defined GTAU_IS_COMPLEX || defined INTERACTION_IS_COMPLEX
76 using M_tau_target_t = matrix_valued;
77#else
78 using M_tau_target_t = matrix_real_valued;
79#endif
80 using M_tau_scalar_t = M_tau_target_t::scalar_t;
81
83#ifdef INTERACTION_IS_COMPLEX
84 using U_scalar_t = dcomplex;
85#else
86 using U_scalar_t = double;
87#endif
88
90 using mc_weight_t = decltype(U_scalar_t{} * g_tau_scalar_t{});
91
93 using block_matrix_t = std::vector<matrix<M_tau_scalar_t>>;
94
96 using block_matrix_v_t = std::vector<matrix_view<M_tau_scalar_t>>;
97
99 using chi2_iw_t = block2_gf<imfreq, tensor_valued<4>>;
100
102 using chi2_tau_t = block2_gf<imtime, tensor_valued<4>>;
103
105 using chi2_tau_v_t = chi2_tau_t::view_type;
106
108 using chi2_tau_cv_t = chi2_tau_t::const_view_type;
109
111 using chi3_iw_t = block2_gf<prod<imfreq, imfreq>, tensor_valued<4>>;
112
114 using chi3_iw_v_t = chi3_iw_t::view_type;
115
117 using chi3_iw_cv_t = chi3_iw_t::const_view_type;
118
120 using chi3_tau_t = block2_gf<prod<imtime, imtime>, tensor_valued<4>>;
121
123 using chi3_tau_v_t = chi3_tau_t::view_type;
124
126 using chi3_tau_cv_t = chi3_tau_t::const_view_type;
127
129 using chi4_iw_t = block2_gf<prod<imfreq, imfreq, imfreq>, tensor_valued<4>>;
130
132 using chi4_tau_t = block2_gf<prod<imtime, imtime, imtime>, tensor_valued<4>>;
133
134 // Declare some placeholders for the rest of the code. Use anonymous namespace for proper linkage
135 // in this code, all variables with trailing _ are placeholders by convention.
136 namespace {
137 using nda::clef::placeholder;
138 const placeholder<0> i_;
139 const placeholder<1> j_;
140 const placeholder<2> k_;
141 const placeholder<3> l_;
142 const placeholder<4> iw_;
143 const placeholder<5> iw1_;
144 const placeholder<6> iw2_;
145 const placeholder<7> iw3_;
146 const placeholder<8> iw4_;
147 const placeholder<9> t_;
148 const placeholder<10> t1_;
149 const placeholder<11> t2_;
150 const placeholder<12> t3_;
151 const placeholder<13> bl_;
152 const placeholder<14> bl1_;
153 const placeholder<15> bl2_;
154 const placeholder<16> iW_;
155 const placeholder<17> iwp_;
156 } // anonymous namespace
157
158} // namespace triqs_ctint
159
160namespace triqs::gfs {
161
163 //FIXME Implement with is_array trait
164 template <typename Value_t, int Rank> double max_norm(array_const_view<Value_t, Rank> const &arr) {
165 auto max_itr = std::max_element(arr.begin(), arr.end(), [](auto a, auto b) { return std::abs(a) < std::abs(b); });
166 return std::abs(*max_itr);
167 }
168 //FIXME array_const_view should be constructable from array_view
169 template <typename Value_t, int Rank> double max_norm(array_view<Value_t, Rank> const &arr) { return max_norm(make_const_view(arr)); }
170
172 template <typename Gf> std::enable_if_t<is_gf_v<Gf>, double> max_norm(Gf const &G) { return max_norm(G.data()); }
173
174 template <typename M, typename Target = tensor_valued<4>> block2_gf<M, Target> make_block2_gf(M const &m, gf_struct_t const &gf_struct) {
175
176 std::vector<std::vector<gf<M, Target>>> gf_vecvec;
177 std::vector<std::string> block_names;
178
179 for (auto const &[bl1, bl1_size] : gf_struct) {
180 block_names.push_back(bl1);
181 std::vector<gf<M, Target>> gf_vec;
182 for (auto const &[bl2, bl2_size] : gf_struct) {
183 if constexpr (Target::rank == 4)
184 gf_vec.emplace_back(m, make_shape(bl1_size, bl1_size, bl2_size, bl2_size));
185 else
186 gf_vec.emplace_back(m, make_shape(bl1_size, bl2_size));
187 }
188 gf_vecvec.emplace_back(std::move(gf_vec));
189 }
190
191 return make_block2_gf(block_names, block_names, std::move(gf_vecvec));
192 }
193
194 template <typename M1, typename M2, typename Target = tensor_valued<4>>
195 block2_gf<M1, Target> make_block2_gf(M1 const &m, block2_gf_const_view<M2, Target> g_in) {
196
197 std::vector<std::vector<gf<M1, Target>>> gf_vecvec;
198
199 int n_blocks0 = g_in.block_names()[0].size();
200 int n_blocks1 = g_in.block_names()[1].size();
201
202 for (int i : range(n_blocks0)) {
203 std::vector<gf<M1, Target>> gf_vec;
204 for (int j : range(n_blocks1)) { gf_vec.emplace_back(m, g_in(i, j).target_shape()); }
205 gf_vecvec.emplace_back(std::move(gf_vec));
206 }
207
208 return make_block2_gf(g_in.block_names()[0], g_in.block_names()[1], std::move(gf_vecvec));
209 }
210
211 template <typename Scalar_t> std::vector<matrix<Scalar_t>> make_block_vector(gf_struct_t const &gf_struct) {
212
213 std::vector<matrix<Scalar_t>> res;
214 for (auto const &[bl, bl_size] : gf_struct) { res.emplace_back(nda::zeros<Scalar_t>(bl_size, bl_size)); }
215 return res;
216 }
217} // namespace triqs::gfs
218
219namespace triqs::operators {
221 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; }
222
224 inline std::pair<int, int> get_int_indices(canonical_ops_t const &op, hilbert_space::gf_struct_t const &gf_struct) {
225
226 // The Fundamental operator-set allows for easy check of index validity
227 hilbert_space::fundamental_operator_set fs(gf_struct);
228 if (!fs.has_indices(op.indices)) TRIQS_RUNTIME_ERROR << " Index of c/c^+ operator not compatible with Green Function structure ";
229
230 // Get block-name with apply visitor, lambda(0) is called to determine return type ...
231 std::string op_bl_name = visit([](auto idx) { return std::to_string(idx); }, op.indices[0]);
232 long nonbl_int_idx = std::get<long>(op.indices[1]);
233
234 // Capture positions in block and nonblock list
235 for (auto [bl_int_idx, bl] : itertools::enumerate(gf_struct)) {
236 auto const &[bl_name, bl_size] = bl;
237 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); }
238 }
239 TRIQS_RUNTIME_ERROR << "Error: Failed to retrieve integer indices for operator";
240 }
241
242 // Function that takes a bosonic operator Op = Sum_i a_i c^+(bi, ui) c(bi, vi)
243 // and returns a vector<tuple> with v[i] = (b_i, a_i, (c^+(bi, ui), c(bi, vi)))
244 inline auto get_terms(many_body_operator const &A, hilbert_space::gf_struct_t const &gf_struct) {
245 std::vector<std::tuple<std::complex<double>, std::pair<int, int>, std::pair<int, int>>> terms;
246 for (auto const &term : A) {
247 auto const &m = term.monomial;
248 if (m.size() != 2 or !m[0].dagger or m[1].dagger)
249 TRIQS_RUNTIME_ERROR << " Monomial in bosonic operator of chiAB measurement not of the proper form c^+ c \n";
250 auto [bl1, i] = get_int_indices(m[0], gf_struct);
251 auto [bl2, j] = get_int_indices(m[1], gf_struct);
252 auto bl_pair = std::make_pair(bl1, bl2);
253 auto idx_pair = std::make_pair(i, j);
254 terms.emplace_back(term.coef, bl_pair, idx_pair);
255 }
256 return terms;
257 }
258
259} // namespace triqs::operators
260
261// Useful macros
262
263#define STR(x) #x
264#define STRINGIZE(x) STR(x)
265
266#ifdef DEBUG_CTINT
267#define TRIQS_EXCEPTION_SHOW_CPP_TRACE
268#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
269#define DEBUG(X) std::cerr << AS_STRING(X) << " = " << X << " at " << __FILENAME__ << ':' << __LINE__ << std::endl
270#define BREAK(X) \
271 std::cerr << X << " ... " << std::endl; \
272 getchar()
273#else
274#define DEBUG(X)
275#define BREAK(X)
276#endif