TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
block_gf.hpp
Go to the documentation of this file.
1// Copyright (c) 2020-2023 Simons Foundation
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You may obtain a copy of the License at
14// https://www.gnu.org/licenses/gpl-3.0.txt
15//
16// Authors: Michel Ferrero, Olivier Parcollet, Nils Wentzell
17
22
23#pragma once
24
25#include "./gf_struct.hpp"
26#include "../gf/gf.hpp"
27#include "../gf/targets.hpp"
31#include "../../utility/macros.hpp" // IWYU pragma: keep (used by ./_block_gf_view_common.hpp)
32
33#include <itertools/itertools.hpp>
34#include <mpi/mpi.hpp>
35
36#include <string>
37#include <type_traits>
38#include <utility>
39#include <vector>
40
41namespace triqs::gfs {
42
44
45 // Forward declarations of the main block types: block_gf, block_gf_view.
46 template <typename Mesh, typename Target = matrix_valued, typename Layout = nda::C_layout, int Arity = 1> class block_gf;
47 template <typename Mesh, typename Target = matrix_valued, typename Layout = nda::C_stride_layout, int Arity = 1, bool IsConst = false>
48 class block_gf_view;
49
59 template <typename Mesh, typename Target = matrix_valued, typename Layout = nda::C_stride_layout, int Arity = 1>
61
62 /**
63 * @ingroup triqs-gfs-block
64 * @brief Owning two-index block Green's function (a matrix of blocks).
65 *
66 * @tparam Mesh Mesh type of each block.
67 * @tparam Target Target type of each block.
68 * @tparam Layout Memory layout policy of each block.
69 */
70 template <typename Mesh, typename Target = matrix_valued, typename Layout = nda::C_layout> using block2_gf = block_gf<Mesh, Target, Layout, 2>;
71
79 */
80 template <typename Mesh, typename Target = matrix_valued, typename Layout = nda::C_stride_layout>
82
84
89 * @tparam Layout Memory layout policy of each block.
90 */
91 template <typename Mesh, typename Target = matrix_valued, typename Layout = nda::C_stride_layout>
93
94 // --------------------------- CTAD ---------------------------------
95
96 // Deduce a triqs::gfs::block_gf type from a vector of Green's functions.
97 template <typename Mesh, typename Target, typename Layout> block_gf(std::vector<gf<Mesh, Target, Layout>>) -> block_gf<Mesh, Target, Layout, 1>;
98
99 // Deduce a (matrix-valued) triqs::gfs::block_gf type from a mesh and a triqs::gfs::gf_struct_t.
100 template <typename Mesh> block_gf(Mesh const &, gf_struct_t const &) -> block_gf<Mesh, matrix_valued>;
101
102 // Deduce a triqs::gfs::block_gf type from a triqs::gfs::block_gf_view.
103 template <typename Mesh, typename Target, typename Layout, int Arity, bool IsConst>
104 block_gf(block_gf_view<Mesh, Target, Layout, Arity, IsConst>) -> block_gf<Mesh, Target, typename Layout::contiguous_t, Arity>;
105
109 */
110
116
119 template <typename G, int n = 0> inline constexpr bool is_block_gf_v = false;
120
121 // Specialization of is_block_gf_v for cvref types, which decays G first.
122 template <typename G, int n>
123 requires(!std::is_same_v<G, std::remove_cvref_t<G>>)
124 inline constexpr bool is_block_gf_v<G, n> = is_block_gf_v<std::remove_cvref_t<G>, n>;
125
126 // Specialization of is_block_gf_v for a one-index block_gf.
127 template <typename Mesh, typename Target, typename Layout, int Arity>
128 inline constexpr bool is_block_gf_v<block_gf<Mesh, Target, Layout, Arity>, Arity> = true;
129
130 // Specialization of is_block_gf_v for a one-index block_gf_view.
131 template <typename Mesh, typename Target, typename Layout, int Arity, bool IsConst>
133
134 // Specialization of is_block_gf_v without an arity constraint.
135 template <typename G> inline constexpr bool is_block_gf_v<G, 0> = is_block_gf_v<G, 1> or is_block_gf_v<G, 2>;
138 template <typename, typename = std::void_t<>> inline constexpr int arity_of = -1;
140 // Specialization of arity_of for types exposing a static `arity` member.
141 template <typename T> inline constexpr int arity_of<T, std::void_t<decltype(T::arity)>> = T::arity;
142
146 * @details Assumes a uniform mesh across all blocks: only the 0th block (block (0,0) for a block2_gf) is inspected;
147 * the meshes of all other blocks are ignored.
148 *
149 * Delegates to the MemoryGf overload triqs::gfs::get_mesh(G const &) for the per-block logic.
150 *
151 * @tparam N Index of the mesh component to return (default 0). Ignored for non-product meshes.
152 * @tparam BG The type of the block Green's function.
153 * @param bg The block Green's function.
154 * @return A const reference to the (N-th component of the) mesh of the 0th block.
155 */
156 template <int N = 0, typename BG>
157 requires is_block_gf_v<BG>
158 auto const &get_mesh(BG const &bg) {
159 if constexpr (is_block_gf_v<BG, 1>)
160 return get_mesh<N>(bg[0]);
161 else // block2_gf: inspect block (0,0)
162 return get_mesh<N>(bg(0, 0));
163 }
164
166 template <typename G> using get_mesh_t = typename std::decay_t<G>::mesh_t;
167
169 template <typename G> using get_target_t = typename std::decay_t<G>::target_t;
172 template <typename G> using block_gf_of = block_gf<get_mesh_t<G>, get_target_t<G>>;
173
176
179
181 template <typename G> using block2_gf_of = block2_gf<get_mesh_t<G>, get_target_t<G>>;
182
189
190
191 // The trait and concept tag marking a type as a block Green's function.
197
200 * `true` for it.
201 *
202 * @tparam G Type to check.
203 */
204 template <typename G>
205 concept BlockGf = BlockGreenFunction_v<G>;
206
207 // Forward declarations with default arguments. The corresponding friend declarations inside `block_gf` and
208 // the definitions in `./mpi.hpp` may then re-declare these templates without re-introducing defaults.
209 template <BlockGf BG> void mpi_broadcast(BG &&bg, mpi::communicator c = {}, int root = 0);
210 template <BlockGf BG1, BlockGf BG2>
211 void mpi_reduce_into(BG1 const &bg_in, BG2 &&bg_out, mpi::communicator c = {}, int root = 0, bool all = false, MPI_Op op = MPI_SUM);
212
213 // ------------- Helper Types -----------------------------
214
215 // Lightweight pairing of a lambda with a value, used to defer a per-block transform (e.g. fourier(block_gf)).
216 template <typename Lambda, typename T> struct lazy_transform_t {
217 Lambda lambda;
218 T value;
219 };
220
221 // Build a lazy_transform_t from a lambda and a value.
222 template <typename Lambda, typename T> lazy_transform_t<Lambda, T> make_lazy_transform(Lambda &&l, T &&x) {
223 return {std::forward<Lambda>(l), std::forward<T>(x)};
225
226 // --------------------------- details ---------------------------------
227
228 namespace details {
229 // Build default block names "0", "1", ... for a one-index block_gf of n blocks.
230 inline auto _make_block_names1(int n) {
231 std::vector<std::string> r(n);
232 for (int i = 0; i < n; ++i) r[i] = std::to_string(i);
233 return r;
234 }
235 // Build default block names for a two-index block2_gf of n x p blocks.
236 inline std::vector<std::vector<std::string>> _make_block_names2(int n, int p) { return {_make_block_names1(n), _make_block_names1(p)}; }
237 } // namespace details
238
239 // --------------------------- implementation ---------------------------------
240
244
247 *
248 * For `Arity == 1` the blocks form a simple vector (a block_gf). For `Arity == 2` they form a matrix of blocks (a
249 * triqs::gfs::block2_gf).
250 *
251 * Each block is accessed by index (or block name) via `operator[]` (`operator()` for a block2_gf). Non-owning views
252 * are provided by triqs::gfs::block_gf_view.
253 *
254 * @tparam Mesh Mesh type of each block, modeling triqs::mesh::Mesh.
255 * @tparam Target Target type of each block.
256 * @tparam Layout Memory layout policy of each block's data array.
257 * @tparam Arity Number of block indices (1 for block_gf, 2 for block2_gf).
258 */
259 template <typename Mesh, typename Target, typename Layout, int Arity> class block_gf : TRIQS_CONCEPT_TAG_NAME(BlockGreenFunction) {
260 using this_t = block_gf; // for common code
261 public:
263 static constexpr bool is_view = false;
264
266 static constexpr bool is_const = false;
269 static constexpr int arity = Arity;
270
272 using mesh_t = Mesh;
273
275 using target_t = Target;
276
278 using regular_type = block_gf<Mesh, Target, Layout, Arity>;
279
295
296 using data_t = std::conditional_t<Arity == 1, std::vector<g_t>, std::vector<std::vector<g_t>>>;
297
299 using block_names_t = std::conditional_t<Arity == 1, std::vector<std::string>, std::vector<std::vector<std::string>>>;
300
302 std::string name;
303
304 private:
305 block_names_t _block_names;
306 data_t _glist;
307
308 // --------------- Constructors --------------------
309
310 // Tag and constructor used internally to build from another block-gf-like object.
311 struct impl_tag {};
312 // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward): x is only read to copy its data, not forwarded
313 template <typename G> block_gf(impl_tag, G &&x) : name(x.name), _block_names(x.block_names()), _glist(factory<data_t>(x.data())) {} // NOLINT
314
315 public:
320 block_gf(block_gf const &x) = default;
321
323 block_gf(block_gf &&) = default;
324
333 block_gf(block_names_t b, data_t d) : _block_names(std::move(b)), _glist(std::move(d)) {
334 if constexpr (Arity == 1) {
335 if (_glist.size() != _block_names.size())
336 TRIQS_RUNTIME_ERROR << "block_gf(vector<string>, vector<gf>) : the two vectors do not have the same size !";
337 } else {
338 if (_glist.size() != _block_names[0].size())
339 TRIQS_RUNTIME_ERROR << "block2_gf(vector<vector<string>>, vector<vector<gf>>) : Outer vectors have different sizes !";
340 if (_glist.size() != 0)
341 if (_glist[0].size() != _block_names[1].size())
342 TRIQS_RUNTIME_ERROR << "block2_gf(vector<vector<string>>, vector<vector<gf>>) : Inner vectors have different sizes !";
344 }
345
347 block_gf() = default;
348
356 template <typename L, bool Cnst> block_gf(block_gf_view<Mesh, Target, L, Arity, Cnst> const &g) : block_gf(impl_tag{}, g) {}
357
367 // TODO: We would like to refine this, G should have the same mesh, target, at least ...
368 template <typename G>
369 block_gf(G const &x)
370 requires(BlockGreenFunction_v<G> and (std::is_same_v<get_target_t<G>, Target> or std::is_same_v<typename get_target_t<G>::complex_t, Target>))
371 : block_gf() {
372 static_assert(G::arity == Arity, "Impossible");
373 *this = x;
374 }
375
377 * @brief Construct a one-index block_gf from a vector of Green's functions (block names default to "0", "1", ...).
378 * @param V Blocks (Green's functions).
379 */
381 requires(Arity == 1)
382 : _block_names(details::_make_block_names1(V.size())), _glist(std::move(V)) {}
383
384
388 block_gf(int n)
389 requires(Arity == 1)
390 : block_gf(data_t(n)) {}
391
393
395 * @param n Number of blocks.
396 * @param g Green's function to copy into each block.
397 */
398 block_gf(int n, g_t const &g)
399 requires(Arity == 1)
400 : block_gf(data_t(n, g)) {}
401
409 requires(Arity == 1)
410 : _block_names(std::move(b)), _glist(_block_names.size(), g) {}
411
417 requires(Arity == 1)
418 : _block_names(std::move(b)), _glist(_block_names.size()) {}
419
429 block_gf(Mesh const &m, gf_struct_t const &gf_struct)
430 requires(Arity == 1)
431 {
433 for (auto const &[bl_name, bl_size] : gf_struct) {
434 _block_names.push_back(bl_name);
435 if constexpr (Target::rank == 0)
436 _glist.emplace_back(m);
437 else
438 _glist.emplace_back(m, make_shape(bl_size, bl_size));
439 }
440 }
441
449 template <typename Int>
450 block_gf(Mesh const &m, std::vector<Int> const &bl_sizes)
451 requires(Arity == 1 && std::is_integral_v<Int>)
452 {
453
454 for (auto const &[bl, bl_size] : itertools::enumerate(bl_sizes)) {
455 _block_names.push_back(std::to_string(bl));
456 if constexpr (Target::rank == 0)
457 _glist.emplace_back(m);
458 else
459 _glist.emplace_back(m, make_shape(bl_size, bl_size));
460 }
461 }
462
470 block_gf(int n, int p, g_t const &g)
471 requires(Arity == 2)
472 : _block_names(details::_make_block_names2(n, p)), _glist(n, std::vector<g_t>(p, g)) {}
473
479 requires(Arity == 2)
480 : _block_names(details::_make_block_names2(V.size(), V[0].size())), _glist(std::move(V)) {}
481
482 // --------------- Operator = --------------------
483
490 block_gf &operator=(block_gf const &rhs) = default;
491
498 block_gf &operator=(block_gf &&rhs) = default;
499
511 template <typename RHS>
512 requires(BlockGreenFunction_v<RHS>)
513 block_gf &operator=(RHS &&rhs) { // NOLINT(cppcoreguidelines-missing-std-forward): rhs is read block-wise, not forwarded
514 if constexpr (Arity == 1) {
515 _glist.resize(rhs.size());
516 _block_names.resize(rhs.size());
517 _assign_impl(rhs);
518 } else {
519 _block_names.resize(2);
520 _glist.resize(rhs.size1());
521 for (auto &g_bl : _glist) g_bl.resize(rhs.size2());
522 _block_names[0].resize(rhs.size1());
523 _block_names[1].resize(rhs.size2());
524 _assign_impl(rhs);
525 }
526 return *this;
527 }
528
529 public:
530 //----------------------------- print -----------------------------
531
533 friend std::ostream &operator<<(std::ostream &out, block_gf const &) { return out << "block_gf"; }
534
536 // Friend declarations (hidden from doxygen; documented as free functions in block/mpi.hpp).
537 template <BlockGf BG> friend void mpi_broadcast(BG &&, mpi::communicator c, int root);
538 template <BlockGf BG1, BlockGf BG2> friend void mpi_reduce_into(BG1 const &, BG2 &&, mpi::communicator, int, bool, MPI_Op);
540
541 // Common code for gf, gf_view, gf_const_view
543 };
544
545} // namespace triqs::gfs
Member code shared by triqs::gfs::block_gf and triqs::gfs::block_gf_view.
data_t & data()
Direct access to the blocks.
block_names_t const & block_names() const
Get the block names.
T factory(U &&...x)
Generic factory to construct an object of a given type from an arbitrary parameter pack of arguments.
Definition factory.hpp:95
A non-owning view of a block Green's function.
The owning block Green's function container.
Definition block_gf.hpp:259
block_gf()=default
Construct an empty block Green's function (with no blocks).
int size() const
Get the total number of blocks.
Definition block_gf.hpp:109
block_gf(int n)
Construct a one-index block_gf of n default-constructed blocks.
Definition block_gf.hpp:388
block_gf_view< M, T, typename nda::C_layout::with_lowest_guarantee_t, Arity > mutable_view_type
Definition block_gf.hpp:281
block_gf(int n, g_t const &g)
Construct a one-index block_gf of n copies of a Green's function.
Definition block_gf.hpp:398
block_gf(Mesh const &m, std::vector< Int > const &bl_sizes)
Construct a one-index block_gf from a mesh and a vector of block sizes (block names default to "0",...
Definition block_gf.hpp:450
std::conditional_t< Arity==1, std::vector< std::string >, std::vector< std::vector< std::string > > > block_names_t
Definition block_gf.hpp:299
block_gf< M, typename T::real_t, nda::C_layout, Arity > real_t
Definition block_gf.hpp:290
block_gf(data_t V)
Construct a one-index block_gf from a vector of Green's functions (block names default to "0",...
Definition block_gf.hpp:380
block_gf_view< M, T, typename nda::C_layout::with_lowest_guarantee_t, Arity, false > view_type
Definition block_gf.hpp:284
block_gf(block_names_t b)
Construct a one-index block_gf with the given block names and default-constructed blocks.
Definition block_gf.hpp:416
block_gf(block_gf &&)=default
Move constructor.
block_gf< M, T, nda::C_layout, Arity > regular_type
Definition block_gf.hpp:278
block_gf(G const &x)
Construct from any object modeling the BlockGreenFunction concept with a compatible target.
Definition block_gf.hpp:369
block_gf_view< M, T, typename nda::C_layout::with_lowest_guarantee_t, Arity, true > const_view_type
Definition block_gf.hpp:287
block_gf(block_names_t b, g_t const &g)
Construct a one-index block_gf from block names and one Green's function copied into every block.
Definition block_gf.hpp:408
block_gf & operator=(block_gf const &rhs)=default
Copy assignment.
block_gf & operator=(block_gf &&rhs)=default
Move assignment.
block_gf(block_names_t b, data_t d)
Construct from a list of block names and a list of Green's functions.
Definition block_gf.hpp:333
block_gf(block_gf_view< Mesh, Target, L, Arity, Cnst > const &g)
Construct from a view of the same kind, making a deep copy of the data.
Definition block_gf.hpp:356
block_gf(int n, int p, g_t const &g)
Construct a two-index block2_gf of n x p copies of a Green's function.
Definition block_gf.hpp:470
std::conditional_t< Arity==1, std::vector< g_t >, std::vector< std::vector< g_t > > > data_t
Definition block_gf.hpp:296
block_gf(data_t V)
Construct a two-index block2_gf from a matrix of Green's functions.
Definition block_gf.hpp:478
block_gf(Mesh const &m, gf_struct_t const &gf_struct)
Construct a one-index block_gf from a mesh and a triqs::gfs::gf_struct_t.
Definition block_gf.hpp:429
friend std::ostream & operator<<(std::ostream &out, block_gf const &)
Writing a block Green's function to an output stream is not supported.
Definition block_gf.hpp:533
block_gf(block_gf const &x)=default
Copy constructor.
The owning Green's function container.
Definition gf.hpp:194
Macros that define a legacy (pre C++20) concept-tag trait pair.
Concept checking that a type is a block Green's function.
Definition block_gf.hpp:205
TRIQS exception hierarchy and related macros.
Generic factory for constructing objects of a given type.
Provides the type describing the block structure of a block Green's function.
Provides the Green's function class.
block_gf_view< Mesh, Target, Layout, Arity, true > block_gf_const_view
Const view alias for a block Green's function.
Definition block_gf.hpp:60
block_gf_view< Mesh, Target, Layout, 2, false > block2_gf_view
Mutable view of a two-index block Green's function.
Definition block_gf.hpp:81
block_gf_view< Mesh, Target, Layout, 2, true > block2_gf_const_view
Const view of a two-index block Green's function.
Definition block_gf.hpp:92
std::vector< std::pair< std::string, long > > gf_struct_t
Type describing the structure of a block Green's function.
Definition gf_struct.hpp:41
block_gf< Mesh, Target, Layout, 2 > block2_gf
Owning two-index block Green's function (a matrix of blocks).
Definition block_gf.hpp:70
void mpi_broadcast(BG &&bg, mpi::communicator c={}, int root=0)
Implementation of an MPI broadcast for triqs::gfs::block_gf and triqs::gfs::block_gf_view types.
Definition mpi.hpp:79
void mpi_reduce_into(BG1 const &bg_in, BG2 &&bg_out, mpi::communicator c={}, int root=0, bool all=false, MPI_Op op=MPI_SUM)
Implementation of an MPI reduce for triqs::gfs::block_gf and triqs::gfs::block_gf_view types that red...
Definition mpi.hpp:124
typename std::decay_t< G >::target_t get_target_t
The target type of a block Green's function type G.
Definition block_gf.hpp:169
typename std::decay_t< G >::mesh_t get_mesh_t
The mesh type of a block Green's function type G.
Definition block_gf.hpp:166
block_gf< get_mesh_t< G >, get_target_t< G > > block_gf_of
The triqs::gfs::block_gf type matching the mesh and target of G.
Definition block_gf.hpp:172
block2_gf_const_view< get_mesh_t< G >, get_target_t< G > > block2_gf_const_view_of
The triqs::gfs::block2_gf_const_view type matching the mesh and target of G.
Definition block_gf.hpp:187
block2_gf_view< get_mesh_t< G >, get_target_t< G > > block2_gf_view_of
The triqs::gfs::block2_gf_view type matching the mesh and target of G.
Definition block_gf.hpp:184
constexpr bool is_block_gf_v
Trait to check whether a type is a block Green's function.
Definition block_gf.hpp:119
constexpr int arity_of
Block arity of a type: T::arity if present, -1 otherwise.
Definition block_gf.hpp:138
block_gf_const_view< get_mesh_t< G >, get_target_t< G > > block_gf_const_view_of
The triqs::gfs::block_gf_const_view type matching the mesh and target of G.
Definition block_gf.hpp:178
block2_gf< get_mesh_t< G >, get_target_t< G > > block2_gf_of
The triqs::gfs::block2_gf type matching the mesh and target of G.
Definition block_gf.hpp:181
auto const & get_mesh(BG const &bg)
Get the mesh of a block Green's function, or its N-th component for a product mesh.
Definition block_gf.hpp:158
block_gf_view< get_mesh_t< G >, get_target_t< G > > block_gf_view_of
The triqs::gfs::block_gf_view type matching the mesh and target of G.
Definition block_gf.hpp:175
#define TRIQS_RUNTIME_ERROR
Throw a triqs::runtime_error with the current source location.
#define TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT(MyBeautifulConcept)
Define a tag-based pseudo-concept.
#define TRIQS_CONCEPT_TAG_NAME(MyBeautifulConcept)
Helper macro that produces the name of the tag for TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT.
T factory(U &&...x)
Generic factory to construct an object of a given type from an arbitrary parameter pack of arguments.
Definition factory.hpp:95
string to_string(string const &str)
Identity overload for std::string.
Common macros used in TRIQS.
Provides the target types that fix the value stored at each mesh point of a Green's function.