TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
prod.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2018 Commissariat à l'énergie atomique et aux énergies alternatives (CEA)
2// Copyright (c) 2013-2018 Centre national de la recherche scientifique (CNRS)
3// Copyright (c) 2018-2023 Simons Foundation
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You may obtain a copy of the License at
16// https://www.gnu.org/licenses/gpl-3.0.txt
17//
18// Authors: Philipp Dumitrescu, Olivier Parcollet, Nils Wentzell
19
24
25#pragma once
26
27#include "./concepts.hpp"
28#include "./utils.hpp"
30
31#include <array>
32#include <cstdint>
33#include <iostream>
34#include <string>
35#include <tuple>
36#include <type_traits>
37#include <utility>
38
39// to silence some clangd warning and make gf independent of triqs::lattice. cf l 64. backward compat check.
40namespace triqs::lattice {
41 class brillouin_zone;
42}
43
44namespace triqs::mesh {
45
50
51 // Forward declaration.
52 template <Mesh... Ms>
53 requires(((n_variables<Ms> == 1) and ...) and (not(std::is_reference_v<Ms> or ...)))
54 class prod;
55
56 // Specialize some traits for the product mesh type.
57 template <Mesh... Ms> static constexpr bool is_product<prod<Ms...>> = true;
58 template <Mesh... Ms> static constexpr int n_variables<prod<Ms...>> = sizeof...(Ms);
59
67 template <Mesh... Ms> class prod_mesh_point : public std::tuple<typename Ms::mesh_point_t...> {
68 public:
70 using mesh_t = prod<Ms...>;
71
73 using index_t = typename mesh_t::index_t;
74
77
79 using tuple_t = std::tuple<typename Ms::mesh_point_t...>;
80
82 prod_mesh_point() = default;
83
88 prod_mesh_point(tuple_t mpt) : tuple_t(std::move(mpt)) {}
89
91 [[nodiscard]] index_t index() const { return index_; }
92
94 [[nodiscard]] data_index_t data_index() const { return data_index_; }
95
97 [[nodiscard]] uint64_t mesh_hash() const noexcept { return mesh_hash_; }
98
100 tuple_t const &as_tuple() const { return *this; }
101
102 private:
103 index_t index_ = std::apply([](auto &...ms) { return std::make_tuple(ms.index()...); }, as_tuple());
104 data_index_t data_index_ = std::apply([](auto &...ms) { return std::make_tuple(ms.data_index()...); }, as_tuple());
105 uint64_t mesh_hash_ = std::apply([](auto &...ms) { return (ms.mesh_hash() + ...); }, as_tuple());
106 };
107
136 template <Mesh... Ms>
137 requires(((n_variables<Ms> == 1) and ...) and (not(std::is_reference_v<Ms> or ...)))
138 class prod : public std::tuple<Ms...> {
139 public:
141 using index_t = std::tuple<typename Ms::index_t...>;
142
144 using data_index_t = std::tuple<typename Ms::data_index_t...>;
145
148
150 using m_tuple_t = std::tuple<Ms...>;
151
153 prod() = default;
154
159 prod(Ms const &...ms)
160 requires(sizeof...(Ms) > 0)
161 : m_tuple_t{ms...}, mesh_hash_((ms.mesh_hash() + ...)) {}
162
167 template <typename... U>
168 prod(std::tuple<U...> const &mt) : m_tuple_t{mt}, mesh_hash_(std::apply([](auto &...m) { return (m.mesh_hash() + ...); }, mt)) {}
169
171 bool operator==(prod const &m) const { return as_tuple() == m.as_tuple(); }
172
179 template <typename... Args> [[nodiscard]] bool is_index_valid(Args const &...ns) const {
180 return triqs::tuple::fold([](auto &m, auto &n, bool res) { return res && (m.is_index_valid(n)); }, as_tuple(), std::tie(ns...), true);
181 }
182
189 template <typename... Args> [[nodiscard]] bool is_index_valid(index_t const &n) const {
190 return triqs::tuple::fold([](auto &m, auto &n, bool res) { return res && (m.is_index_valid(n)); }, as_tuple(), n, true);
191 }
192
200 [[nodiscard]] data_index_t to_data_index(index_t const &n) const {
201 auto l = [](auto const &m, auto const &n_i) { return m.to_data_index(n_i); };
202 return triqs::tuple::map_on_zip(l, *this, n);
203 }
204
212 [[nodiscard]] index_t to_index(data_index_t const &d) const {
213 auto l = [](auto const &m, auto const &d_i) { return m.to_index(d_i); };
214 return triqs::tuple::map_on_zip(l, *this, d);
215 }
216
226 [[nodiscard]] mesh_point_t operator[](data_index_t const &d) const {
227 auto l = [](auto const &m, auto const &d_i) { return m[d_i]; };
228 return triqs::tuple::map_on_zip(l, *this, d);
229 }
230
240 [[nodiscard]] mesh_point_t operator()(index_t const &n) const {
241 auto l = [](auto const &m, auto const &n_i) { return m(n_i); };
242 return triqs::tuple::map_on_zip(l, *this, n);
243 }
244
246 [[nodiscard]] uint64_t mesh_hash() const { return mesh_hash_; }
247
249 [[nodiscard]] long size() const {
250 return triqs::tuple::fold([](auto const &m, size_t n) { return n * m.size(); }, as_tuple(), 1);
251 }
252
254 [[nodiscard]] auto size_of_components() const {
255 std::array<long, std::tuple_size_v<m_tuple_t>> res;
256 auto l = [&res](int i, auto const &m) mutable { res[i] = m.size(); };
258 return res;
259 }
260
261 // Get the underlying tuple of individual meshes, i.e. \f$ (M_1, \dots, M_k) \f$.
262 [[nodiscard]] m_tuple_t const &components() const { return *this; }
263
265 [[nodiscard]] m_tuple_t &components() { return *this; }
266
268 [[nodiscard]] m_tuple_t const &as_tuple() const { return *this; }
269
271 [[nodiscard]] m_tuple_t &as_tuple() { return *this; }
272
273 private:
274 // Get a lazy range that generates the mesh points.
275 [[nodiscard]] auto r_() const {
276 auto f = [](auto &&...ms) { return itertools::product(ms...); };
277 auto to_mesh_point = [](auto &&n_mp) { return mesh_point_t{n_mp}; };
278 return itertools::transform(std::apply(f, components()), to_mesh_point);
279 }
280
281 public:
283 [[nodiscard]] auto begin() const { return r_().begin(); }
284
286 [[nodiscard]] auto cbegin() const { return r_().cbegin(); }
287
289 [[nodiscard]] auto end() const { return r_().end(); }
290
292 [[nodiscard]] auto cend() const { return r_().cend(); }
293
301 friend std::ostream &operator<<(std::ostream &sout, prod const &m) {
302 sout << "Product Mesh";
303 triqs::tuple::for_each(m.as_tuple(), [&sout](auto &mesh) { sout << "\n -- " << mesh; });
304 return sout;
305 }
306
311 void serialize(auto &ar) const { ar &as_tuple(); }
312
317 void deserialize(auto &ar) { ar &as_tuple(); }
318
320 [[nodiscard]] static std::string hdf5_format() { return "MeshProduct"; }
321
329 friend void h5_write(h5::group g, std::string name, prod const &m) {
330 h5::group gr = g.create_group(name);
331 h5::write_hdf5_format(gr, m);
332 auto l = [gr](int N, auto const &mc) { h5::write(gr, "MeshComponent" + std::to_string(N), mc); };
333 triqs::tuple::for_each_enumerate(m.components(), l);
334 }
335
343 friend void h5_read(h5::group g, std::string name, prod &m) {
344 h5::group gr = g.open_group(name);
345 h5::assert_hdf5_format(gr, m, true);
346 auto l = [gr](int N, auto &mc) { h5::read(gr, "MeshComponent" + std::to_string(N), mc); };
347 triqs::tuple::for_each_enumerate(m.components(), l);
348 }
349
350 private:
351 uint64_t mesh_hash_ = 0;
352 };
353
354 // Class template argument deduction rules (CTAD).
355 template <typename M1, typename M2, typename... Ms> prod(M1, M2, Ms...) -> prod<M1, M2, Ms...>;
356
357 template <typename M1, typename M2, typename... Ms>
358 prod(std::tuple<M1, M2, Ms...>) -> prod<std::decay_t<M1>, std::decay_t<M2>, std::decay_t<Ms>...>;
359
370 template <Mesh... Ls, Mesh... Rs> auto operator*(prod<Ls...> const &m, prod<Rs...> const &n) {
371 return prod<Ls..., Rs...>{std::tuple_cat(m.components(), n.components())};
372 }
373
384 template <Mesh L, Mesh... Rs> auto operator*(L const &n, prod<Rs...> const &m) {
385 return prod<L, Rs...>{std::tuple_cat(std::make_tuple(n), m.components())};
386 }
387
398 template <Mesh... Ls, Mesh R> auto operator*(prod<Ls...> const &m, R const &n) {
399 return prod<Ls..., R>{std::tuple_cat(m.components(), std::make_tuple(n))};
400 }
401
411 template <Mesh L, Mesh R> auto operator*(L const &m, R const &n) { return prod<L, R>{m, n}; }
412
414
415} // namespace triqs::mesh
416
418template <typename... Ms> struct std::tuple_size<triqs::mesh::prod<Ms...>> : public std::integral_constant<size_t, sizeof...(Ms)> {};
419
421template <typename... Ms> struct std::tuple_size<triqs::mesh::prod_mesh_point<Ms...>> : public std::integral_constant<size_t, sizeof...(Ms)> {};
422
424template <size_t N, typename... Ms> struct std::tuple_element<N, triqs::mesh::prod<Ms...>> : public std::tuple_element<N, std::tuple<Ms...>> {};
425
427template <size_t N, typename... Ms>
428struct std::tuple_element<N, triqs::mesh::prod_mesh_point<Ms...>> : public std::tuple_element<N, std::tuple<typename Ms::mesh_point_t...>> {};
prod()=default
Default constructor calls the default constructor of all its components.
A Brillouin zone class.
Mesh point type for the triqs::mesh::prod mesh.
Definition prod.hpp:67
prod_mesh_point()=default
Default constructor leaves the mesh point uninitialized.
typename mesh_t::index_t index_t
Index type of the parent mesh.
Definition prod.hpp:73
typename mesh_t::data_index_t data_index_t
Data index type of the parent mesh.
Definition prod.hpp:76
index_t index() const
Get the index tuple of the mesh point.
Definition prod.hpp:91
data_index_t data_index() const
Get the data index tuple of the mesh point.
Definition prod.hpp:94
prod_mesh_point(tuple_t mpt)
Construct a mesh point from a tuple of mesh points.
Definition prod.hpp:88
uint64_t mesh_hash() const noexcept
Get the hash value of the parent mesh.
Definition prod.hpp:97
tuple_t const & as_tuple() const
Get the underlying tuple of mesh points.
Definition prod.hpp:100
prod< Ms... > mesh_t
Parent mesh type.
Definition prod.hpp:70
std::tuple< typename Ms::mesh_point_t... > tuple_t
Underlying tuple type of mesh points.
Definition prod.hpp:79
Product mesh type for combining multiple meshes.
Definition prod.hpp:138
void deserialize(auto &ar)
Deserialize the mesh from a generic archive.
Definition prod.hpp:317
m_tuple_t & as_tuple()
Get the underlying tuple of individual meshes, i.e. .
Definition prod.hpp:271
m_tuple_t & components()
Get the underlying tuple of individual meshes, i.e. .
Definition prod.hpp:265
friend std::ostream & operator<<(std::ostream &sout, prod const &m)
Write a triqs::mesh::prod mesh to a std::ostream.
Definition prod.hpp:301
bool is_index_valid(Args const &...ns) const
Check if the given indices are valid.
Definition prod.hpp:179
friend void h5_write(h5::group g, std::string name, prod const &m)
Write a triqs::mesh::prod mesh to HDF5.
Definition prod.hpp:329
bool operator==(prod const &m) const
Equal-to comparison operator compares the tuple of meshes in the product.
Definition prod.hpp:171
auto end() const
Get an iterator to the end of the mesh.
Definition prod.hpp:289
prod(std::tuple< U... > const &mt)
Construct a product mesh from the given tuple of meshes.
Definition prod.hpp:168
m_tuple_t const & as_tuple() const
Definition prod.hpp:268
auto cend() const
Get a const iterator to the end of the mesh.
Definition prod.hpp:292
prod()=default
Default constructor calls the default constructor of all its components.
mesh_point_t operator[](data_index_t const &d) const
Subscript operator to access a mesh point by its data index tuple .
Definition prod.hpp:226
uint64_t mesh_hash() const
Definition prod.hpp:246
void serialize(auto &ar) const
Serialize the mesh to a generic archive.
Definition prod.hpp:311
auto cbegin() const
Get a const iterator to the beginning of the mesh.
Definition prod.hpp:286
data_index_t to_data_index(index_t const &n) const
Map an index tuple to its corresponding data index tuple .
Definition prod.hpp:200
std::tuple< typename Ms::index_t... > index_t
Definition prod.hpp:141
mesh_point_t operator()(index_t const &n) const
Function call operator to access a mesh point by its index tuple .
Definition prod.hpp:240
prod_mesh_point< Ms... > mesh_point_t
Definition prod.hpp:147
std::tuple< Ms... > m_tuple_t
Definition prod.hpp:150
index_t to_index(data_index_t const &d) const
Map a data index tuple to its corresponding index tuple .
Definition prod.hpp:212
auto size_of_components() const
Get the sizes of the components as a std::array, i.e. .
Definition prod.hpp:254
bool is_index_valid(index_t const &n) const
Check if given index tuple is valid.
Definition prod.hpp:189
std::tuple< typename Ms::data_index_t... > data_index_t
Definition prod.hpp:144
friend void h5_read(h5::group g, std::string name, prod &m)
Read a triqs::mesh::prod mesh from HDF5.
Definition prod.hpp:343
long size() const
Get the size of the mesh, i.e. the product of the sizes of its components.
Definition prod.hpp:249
auto begin() const
Get an iterator to the beginning of the mesh.
Definition prod.hpp:283
prod(Ms const &...ms)
Construct a product mesh with the given meshes .
Definition prod.hpp:159
static std::string hdf5_format()
Get the HDF5 format tag.
Definition prod.hpp:320
Concept for a mesh.
Definition concepts.hpp:85
k_expr<' *', long, R > operator*(Int l, R &&r)
Lazy multiplication of a triqs::mesh::BzMeshPoint object with a scalar.
Definition brzone.hpp:670
static constexpr int n_variables
Constexpr variable that holds the number of meshes in a triqs::mesh::Mesh type ( for non-product mes...
Definition utils.hpp:154
static constexpr bool is_product
Constexpr bool that is true if the given triqs::mesh::Mesh type is a product of meshes,...
Definition utils.hpp:151
string to_string(string const &str)
Identity overload for std::string.
void for_each(T &&t, F &&f)
Apply a callable to every element of a tuple, in order.
decltype(auto) fold(F &&f, T &&t, R &&r)
Left-fold a callable over the elements of a tuple.
auto map_on_zip(F &&f, Ts &&...ts)
Map an N-ary callable across N tuples zipped together.
void for_each_enumerate(T &&t, F &&f)
Apply a callable to every (index, element) pair of a tuple.
Provides concepts for mesh points and meshes.
Provides various utilities used with Meshes.
Generic tuple manipulation tools.