TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
dlr.hpp
Go to the documentation of this file.
1// Copyright (c) 2023 Simons Foundation
2// Copyright (c) 2023 Hugo U.R. Strand
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You may obtain a copy of the License at
15// https://www.gnu.org/licenses/gpl-3.0.txt
16//
17// Authors: Alexander Hampel, Olivier Parcollet, Hugo U.R. Strand, Nils Wentzell
18
23
24#pragma once
25
26#include "./matsubara_freq.hpp"
27#include "./mesh_iterator.hpp"
28#include "./utils.hpp"
29#include "../utility/macros.hpp"
30
31#include <cppdlr/cppdlr.hpp>
32#include <h5/h5.hpp>
33#include <fmt/format.h>
34#include <itertools/itertools.hpp>
35#include <nda/nda.hpp>
36
37#include <cstdint>
38#include <iostream>
39#include <memory>
40#include <string>
41#include <string_view>
42#include <utility>
43
44namespace triqs::mesh {
45
46 namespace detail {
47
48 // Struct that combines the DLR frequencies, DLR imaginary time operations and DLR Matsubara frequency operations.
49 struct dlr_ops {
50 nda::vector<double> freq;
51 cppdlr::imtime_ops imt;
52 cppdlr::imfreq_ops imf;
53 };
54
55 } // namespace detail
56
57 // Forward declarations.
58 class dlr_imtime;
59 class dlr_imfreq;
60
65
96 class C2PY_RENAME(MeshDLR) dlr {
97 public:
99 using value_t = double;
100
102 using index_t = long;
103
105 using data_index_t = long;
106
113 class C2PY_IGNORE mesh_point_t {
114 public:
116 using mesh_t = dlr;
117
119 mesh_point_t() = default;
120
130 mesh_point_t(long l, long d, uint64_t mhash, double w_l) : index_(l), data_index_(d), mesh_hash_(mhash), value_(w_l) {}
131
133 [[nodiscard]] long index() const { return index_; }
134
136 [[nodiscard]] long data_index() const { return data_index_; }
137
139 [[nodiscard]] double value() const { return value_; }
140
142 [[nodiscard]] uint64_t mesh_hash() const noexcept { return mesh_hash_; }
143
145 operator double() const { return value_; }
146
147 private:
148 long index_ = 0;
149 long data_index_ = 0;
150 uint64_t mesh_hash_ = 0;
151 double value_ = {};
152 };
153
154 private:
155 // Construct a DLR mesh with a given set of DLR frequencies.
156 dlr(double beta, statistic_enum statistic, double w_max, double eps, bool symmetrize, nda::vector<double> const &dlr_freq)
157 : dlr(beta, statistic, w_max, eps, symmetrize,
158 detail::dlr_ops{.freq = dlr_freq,
159 .imt = {w_max * beta, dlr_freq, symmetrize},
160 .imf = {w_max * beta, dlr_freq, static_cast<cppdlr::statistic_t>(statistic), symmetrize}}) {}
161
162 // Construct a DLR mesh with given DLR operations.
163 dlr(double beta, statistic_enum statistic, double w_max, double eps, bool symmetrize, detail::dlr_ops ops)
164 : beta_(beta),
165 stat_(statistic),
166 w_max_(w_max),
167 eps_(eps),
168 symmetrize_(symmetrize),
169 mesh_hash_(hash(beta, statistic, w_max, eps, symmetrize, hash_bytes(ops.imf.get_ifnodes()), std::string_view{"dlr"})),
170 dlr_{std::make_shared<detail::dlr_ops>(std::move(ops))} {}
171
172 public:
174 dlr() = default;
175
190 dlr(double beta, statistic_enum statistic, double w_max, double eps, bool symmetrize = true)
191 : dlr(beta, statistic, w_max, eps, symmetrize, cppdlr::build_dlr_rf(w_max * beta, eps, symmetrize)) {}
192
199 template <nda::AnyOf<dlr_imtime, dlr_imfreq> M>
200 explicit dlr(M const &m)
201 : beta_(m.beta_),
202 stat_(m.stat_),
203 w_max_(m.w_max_),
204 eps_(m.eps_),
205 symmetrize_(m.symmetrize_),
206 mesh_hash_(hash(beta_, stat_, w_max_, eps_, symmetrize_, hash_bytes(m.dlr_->imf.get_ifnodes()), std::string_view{"dlr"})),
207 dlr_(m.dlr_) {}
208
210 bool operator==(dlr const &m) const { return mesh_hash_ == m.mesh_hash_; }
211
218 [[nodiscard]] bool is_index_valid(long l) const noexcept { return 0 <= l and l < size(); }
219
226 [[nodiscard]] long to_data_index(long l) const noexcept {
227 EXPECTS(is_index_valid(l));
228 return l;
229 }
230
237 [[nodiscard]] long to_index(long d) const noexcept {
238 EXPECTS(is_index_valid(d));
239 return d;
240 }
241
249 [[nodiscard]] mesh_point_t operator[](long d) const { return (*this)(d); }
250
258 [[nodiscard]] mesh_point_t operator()(long l) const { return {l, l, mesh_hash_, to_value(l)}; }
259
266 [[nodiscard]] double to_value(long l) const noexcept {
267 EXPECTS(is_index_valid(l));
268 return (dlr_->freq)[l];
269 }
270
272 [[nodiscard]] C2PY_PROPERTY_GET(beta) double beta() const noexcept { return beta_; }
273
275 [[nodiscard]] C2PY_PROPERTY_GET(statistic) statistic_enum statistic() const noexcept { return stat_; }
276
278 [[nodiscard]] C2PY_PROPERTY_GET(w_max) double w_max() const noexcept { return w_max_; }
279
281 [[nodiscard]] C2PY_PROPERTY_GET(eps) double eps() const noexcept { return eps_; }
282
284 [[nodiscard]] C2PY_PROPERTY_GET(symmetrize) bool symmetrize() const noexcept { return symmetrize_; }
285
287 [[nodiscard]] C2PY_PROPERTY_GET(dlr_freq) auto const &dlr_freq() const { return dlr_->freq; }
288
290 [[nodiscard]] C2PY_IGNORE auto const &dlr_it() const { return dlr_->imt; }
291
293 [[nodiscard]] C2PY_IGNORE auto const &dlr_if() const { return dlr_->imf; }
294
296 [[nodiscard]] C2PY_PROPERTY_GET(mesh_hash) uint64_t mesh_hash() const noexcept { return mesh_hash_; }
297
299 [[nodiscard]] long size() const noexcept { return (dlr_ ? dlr_->freq.size() : 0); }
300
302 [[nodiscard]] auto begin() const { return mesh_iterator<dlr>{.mesh_ptr = this, .data_index = 0}; }
303
305 [[nodiscard]] auto cbegin() const { return begin(); }
306
308 [[nodiscard]] auto end() const { return mesh_iterator<dlr>{.mesh_ptr = this, .data_index = size()}; }
309
311 [[nodiscard]] auto cend() const { return end(); }
312
320 friend std::ostream &operator<<(std::ostream &sout, dlr const &m) {
321 auto stat_cstr = (m.stat_ == Boson ? "Boson" : "Fermion");
322 return sout << fmt::format("DLR coefficient mesh of size {} with beta = {}, statistics = {}, w_max = {}, eps = {}, symmetrized = {}", m.size(),
323 m.beta_, stat_cstr, m.w_max_, m.eps_, m.symmetrize_);
324 }
325
330 void serialize(auto &ar) const {
331 EXPECTS(dlr_);
332 ar & beta_ & stat_ & w_max_ & eps_ & symmetrize_ & mesh_hash_ & dlr_->freq;
333 dlr_->imt.serialize(ar);
334 dlr_->imf.serialize(ar);
335 }
336
341 void deserialize(auto &ar) {
342 nda::vector<double> freq;
343 cppdlr::imtime_ops imt;
344 cppdlr::imfreq_ops imf;
345 ar & beta_ & stat_ & w_max_ & eps_ & symmetrize_ & mesh_hash_ & freq;
346 imt.deserialize(ar);
347 imf.deserialize(ar);
348 dlr_ = std::make_shared<detail::dlr_ops>(freq, imt, imf);
349 }
350
352 [[nodiscard]] static std::string hdf5_format() { return "MeshDLR"; }
353
361 friend void h5_write(h5::group g, std::string const &name, dlr const &m) {
362 h5::group gr = g.create_group(name);
363 h5::write_hdf5_format(gr, m); // NOLINT (downcasting to base class)
364 h5::write(gr, "beta", m.beta_);
365 h5::write(gr, "statistic", (m.stat_ == Fermion ? "F" : "B"));
366 h5::write(gr, "w_max", m.w_max_);
367 h5::write(gr, "eps", m.eps_);
368 h5::write(gr, "symmetrize", m.symmetrize_);
369 h5::write(gr, "dlr_freq", m.dlr_freq());
370 h5::write(gr, "dlr_it", m.dlr_it());
371 h5::write(gr, "dlr_if", m.dlr_if());
372 }
373
381 friend void h5_read(h5::group g, std::string const &name, dlr &m) {
382 h5::group gr = g.open_group(name);
383 h5::assert_hdf5_format(gr, m, true); // NOLINT (downcasting to base class)
384 auto b = h5::read<double>(gr, "beta");
385 auto stat = (h5::read<std::string>(gr, "statistic") == "F" ? Fermion : Boson);
386 auto wmax = h5::read<double>(gr, "w_max");
387 auto epsilon = h5::read<double>(gr, "eps");
388 bool sym = false;
389 h5::try_read(gr, "symmetrize", sym);
390 auto freq = h5::read<nda::vector<double>>(gr, "dlr_freq");
391 auto imt = h5::read<cppdlr::imtime_ops>(gr, "dlr_it");
392 auto imf = h5::read<cppdlr::imfreq_ops>(gr, "dlr_if");
393 m = dlr(b, stat, wmax, epsilon, sym, {.freq = freq, .imt = imt, .imf = imf});
394 }
395
396 // Friend declarations.
397 friend class dlr_imtime;
398 friend class dlr_imfreq;
399
400 private:
401 double beta_ = 1.0;
402 statistic_enum stat_ = Fermion;
403 double w_max_ = 0.0;
404 double eps_ = 1e-10;
405 bool symmetrize_ = false;
406 uint64_t mesh_hash_ = 0;
407 std::shared_ptr<const detail::dlr_ops> dlr_ = {};
408 };
409
429 auto evaluate(dlr const &m, auto const &f, double tau) {
430 EXPECTS(m.size() > 0);
431 EXPECTS(tau >= 0 and tau <= m.beta());
432 return detail::sum_to_regular(nda::range(m.size()), [&](auto l) { return f(l) * cppdlr::k_it(tau / m.beta(), m.dlr_freq()[l]); });
433 }
434
453 auto evaluate(dlr const &m, auto const &f, matsubara_freq const &iw) {
454 EXPECTS(m.size() > 0);
455 return detail::sum_to_regular(nda::range(m.size()),
456 [&](auto l) { return f(l) * cppdlr::k_if(iw.n, m.dlr_freq()[l], (cppdlr::statistic_t)iw.statistic) * m.beta(); });
457 }
458
460
461} // namespace triqs::mesh
iterator end()
Get an iterator past the last block.
iterator begin()
Get an iterator to the first block.
int size() const
Get the total number of blocks.
mesh_point_t()=default
Default constructor leaves the mesh point uninitialized.
Mesh point of a triqs::mesh::dlr mesh.
Definition dlr.hpp:113
mesh_point_t(long l, long d, uint64_t mhash, double w_l)
Construct a mesh point with a given index , data index , hash value of the parent mesh and value .
Definition dlr.hpp:130
uint64_t mesh_hash() const noexcept
Get the hash value of the parent mesh.
Definition dlr.hpp:142
dlr mesh_t
Parent mesh type.
Definition dlr.hpp:116
mesh_point_t()=default
Default constructor leaves the mesh point uninitialized.
long index() const
Get the index of the mesh point.
Definition dlr.hpp:133
long data_index() const
Get the data index of the mesh point.
Definition dlr.hpp:136
double value() const
Get the value of the mesh point.
Definition dlr.hpp:139
Imaginary frequency discrete Lehmann representation (DLR) mesh type.
Imaginary time discrete Lehmann representation (DLR) mesh type.
Discrete Lehmann representation (DLR) mesh type.
Definition dlr.hpp:96
mesh_point_t operator[](long d) const
Subscript operator to access a mesh point by its data index .
Definition dlr.hpp:249
double to_value(long l) const noexcept
Map an index to its corresponding value .
Definition dlr.hpp:266
long to_data_index(long l) const noexcept
Map an index to its corresponding data index .
Definition dlr.hpp:226
auto const & dlr_freq() const
Get the array of DLR frequencies .
Definition dlr.hpp:287
friend std::ostream & operator<<(std::ostream &sout, dlr const &m)
Write a triqs::mesh::dlr mesh to a std::ostream.
Definition dlr.hpp:320
double beta() const noexcept
Get the inverse temperature .
Definition dlr.hpp:272
long size() const noexcept
Get the size of the mesh, i.e. the DLR rank .
Definition dlr.hpp:299
dlr(M const &m)
Construct a DLR mesh from another DLR type mesh.
Definition dlr.hpp:200
bool operator==(dlr const &m) const
Equal-to comparison operator compares the hash values.
Definition dlr.hpp:210
statistic_enum statistic() const noexcept
Get the particle statistics.
Definition dlr.hpp:275
double w_max() const noexcept
Get the DLR energy cutoff .
Definition dlr.hpp:278
void serialize(auto &ar) const
Serialize the mesh to a generic archive.
Definition dlr.hpp:330
auto begin() const
Get an iterator to the beginning of the mesh.
Definition dlr.hpp:302
mesh_point_t operator()(long l) const
Function call operator to access a mesh point by its index .
Definition dlr.hpp:258
auto const & dlr_it() const
Get the imaginary time DLR operations object (see also cppdlr::imtime_ops).
Definition dlr.hpp:290
void deserialize(auto &ar)
Deserialize the mesh from a generic archive.
Definition dlr.hpp:341
uint64_t mesh_hash() const noexcept
Get the hash value of the mesh.
Definition dlr.hpp:296
auto const & dlr_if() const
Get the Matsubara frequency DLR operations object (see also cppdlr::imfreq_ops).
Definition dlr.hpp:293
long data_index_t
Data index type.
Definition dlr.hpp:105
dlr(double beta, statistic_enum statistic, double w_max, double eps, bool symmetrize=true)
Construct a DLR mesh with a given energy cutoff and error tolerance .
Definition dlr.hpp:190
auto cbegin() const
Get a const iterator to the beginning of the mesh.
Definition dlr.hpp:305
bool symmetrize() const noexcept
Is the mesh symmetric around ?
Definition dlr.hpp:284
double value_t
Value type.
Definition dlr.hpp:99
long index_t
Index type.
Definition dlr.hpp:102
auto cend() const
Get a const iterator to the end of the mesh.
Definition dlr.hpp:311
auto end() const
Get an iterator to the end of the mesh.
Definition dlr.hpp:308
friend void h5_write(h5::group g, std::string const &name, dlr const &m)
Write a triqs::mesh::dlr mesh to HDF5.
Definition dlr.hpp:361
double eps() const noexcept
Get the DLR error tolerance .
Definition dlr.hpp:281
bool is_index_valid(long l) const noexcept
Check if an index is valid.
Definition dlr.hpp:218
static std::string hdf5_format()
Get the HDF5 format tag.
Definition dlr.hpp:352
dlr()=default
Default constructor constructs an empty mesh.
long to_index(long d) const noexcept
Map a data index to the corresponding index .
Definition dlr.hpp:237
friend void h5_read(h5::group g, std::string const &name, dlr &m)
Read a triqs::mesh::dlr mesh from HDF5.
Definition dlr.hpp:381
statistic_enum
Enum to specify particle statistics.
Definition utils.hpp:163
std::size_t hash_bytes(std::span< std::byte const > bytes)
Hash the raw bytes of a span via the standard library's std::hash<std::string_view>.
Definition utils.hpp:80
uint64_t hash(Ts &&...ts)
Generic hash function for multiple arguments.
Definition utils.hpp:70
Common macros used in TRIQS.
Provides a struct to represent Matsubara frequencies.
Provides various utilities used with Meshes.
Provides a generic random access iterator for 1D meshes.
Represents a Matsubara frequency .
A generic random access iterator for 1D meshes.