TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
refreq_log.hpp
Go to the documentation of this file.
1// Copyright (c) 2025 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: Nils Wentzell
17
22
23#pragma once
24
25#include "./mesh_iterator.hpp"
26#include "./utils.hpp"
27#include "../utility/macros.hpp"
28
29#include <fmt/format.h>
30#include <h5/h5.hpp>
31
32#include <algorithm>
33#include <cmath>
34#include <cstdint>
35#include <iostream>
36#include <string>
37#include <vector>
38
39namespace triqs::mesh {
40
45
74 class C2PY_RENAME(MeshReFreqLog) refreq_log {
75 public:
77 using value_t = double;
78
80 using index_t = long;
81
83 using data_index_t = long;
84
94 class C2PY_IGNORE mesh_point_t {
95 public:
98
100 mesh_point_t() = default;
101
110 mesh_point_t(long n, long d, uint64_t mhash, double w) : index_(n), data_index_(d), mesh_hash_(mhash), value_(w) {}
111
113 [[nodiscard]] long index() const noexcept { return index_; }
114
116 [[nodiscard]] long data_index() const noexcept { return data_index_; }
117
119 [[nodiscard]] double value() const noexcept { return value_; }
120
122 [[nodiscard]] uint64_t mesh_hash() const noexcept { return mesh_hash_; }
123
125 operator double() const { return value_; } // NOLINT (implicit conversion intended)
126
127 // Arithmetic operations with scalars.
128#define IMPL_OP(OP) \
129 template <typename U> friend auto operator OP(mesh_point_t const &mp, U &&y) { return mp.value() OP std::forward<U>(y); } \
130 template <typename U> \
131 requires(not std::is_same_v<std::decay_t<U>, mesh_point_t>) \
132 friend auto operator OP(U &&x, mesh_point_t const &mp) { \
133 return std::forward<U>(x) OP mp.value(); \
134 }
135 IMPL_OP(+)
136 IMPL_OP(-)
137 IMPL_OP(*)
138 IMPL_OP(/)
139#undef IMPL_OP
140
141 private:
142 long index_ = 0;
143 long data_index_ = 0;
144 uint64_t mesh_hash_ = 0;
145 double value_ = 0.0;
146 };
147
149 refreq_log() = default;
150
158 refreq_log(double eps, double w_max, double ratio) : eps_(eps), w_max_(w_max), ratio_(ratio), mesh_hash_(hash(eps, w_max, ratio)) {
159 EXPECTS(eps_ > 0);
160 EXPECTS(w_max_ >= eps_);
161 EXPECTS(ratio_ > 1.0);
162 init_points();
163 }
164
166 bool operator==(refreq_log const &) const = default;
167
174 [[nodiscard]] bool is_index_valid(index_t n) const noexcept { return 0 <= n and n < size(); }
175
182 [[nodiscard]] bool is_value_valid(double w) const noexcept { return !pts_.empty() and pts_.front() <= w and w <= pts_.back(); }
183
190 [[nodiscard]] data_index_t to_data_index(index_t n) const noexcept {
191 EXPECTS(is_index_valid(n));
192 return n;
193 }
194
201 [[nodiscard]] C2PY_IGNORE data_index_t to_data_index(closest_mesh_point_t<double> const &cmp) const noexcept {
202 return to_data_index(to_index(cmp));
203 }
204
211 [[nodiscard]] index_t to_index(data_index_t d) const noexcept {
212 EXPECTS(is_index_valid(d));
213 return d;
214 }
215
222 [[nodiscard]] C2PY_IGNORE index_t to_index(closest_mesh_point_t<double> const &cmp) const noexcept {
223 EXPECTS(is_value_valid(cmp.value));
224
225 auto itr_r = std::ranges::lower_bound(pts_, cmp.value);
226 long i_r = itr_r - pts_.begin();
227
228 if (i_r == 0) { return 0; }
229 if (i_r == size()) { return size() - 1; }
230
231 long i_l = i_r - 1;
232 if (std::abs(cmp.value - pts_[i_l]) < std::abs(cmp.value - pts_[i_r]))
233 return i_l;
234 else
235 return i_r;
236 }
237
244 [[nodiscard]] mesh_point_t operator[](long d) const noexcept { return (*this)(d); }
245
252 [[nodiscard]] C2PY_IGNORE mesh_point_t operator[](closest_mesh_point_t<double> const &cmp) const noexcept { return (*this)[to_data_index(cmp)]; }
253
260 [[nodiscard]] mesh_point_t operator()(index_t n) const noexcept {
261 EXPECTS(is_index_valid(n));
262 return {n, n, mesh_hash_, pts_[n]};
263 }
264
271 [[nodiscard]] double to_value(index_t n) const noexcept {
272 EXPECTS(is_index_valid(n));
273 return pts_[n];
274 }
275
277 [[nodiscard]] C2PY_PROPERTY_GET(eps) double eps() const noexcept { return eps_; }
278
280 [[nodiscard]] C2PY_PROPERTY_GET(w_max) double w_max() const noexcept { return w_max_; }
281
283 [[nodiscard]] C2PY_PROPERTY_GET(ratio) double ratio() const noexcept { return ratio_; }
284
286 [[nodiscard]] C2PY_PROPERTY_GET(mesh_hash) uint64_t mesh_hash() const noexcept { return mesh_hash_; }
287
289 [[nodiscard]] long size() const noexcept { return static_cast<long>(pts_.size()); }
290
292 [[nodiscard]] C2PY_PROPERTY_GET(points) std::vector<double> const &points() const noexcept { return pts_; }
293
295 [[nodiscard]] auto begin() const { return mesh_iterator<refreq_log>{.mesh_ptr = this, .data_index = 0}; }
296
298 [[nodiscard]] auto cbegin() const { return begin(); }
299
301 [[nodiscard]] auto end() const { return mesh_iterator<refreq_log>{.mesh_ptr = this, .data_index = size()}; }
302
304 [[nodiscard]] auto cend() const { return end(); }
305
313 friend std::ostream &operator<<(std::ostream &sout, refreq_log const &m) {
314 return sout << fmt::format("Logarithmic real frequency mesh with eps = {}, w_max = {}, ratio = {}, N = {}", m.eps_, m.w_max_, m.ratio_,
315 m.size());
316 }
317
322 void serialize(auto &ar) const { ar & eps_ & w_max_ & ratio_ & mesh_hash_; }
323
328 void deserialize(auto &ar) {
329 ar & eps_ & w_max_ & ratio_ & mesh_hash_;
330 if (w_max_ > 0) init_points();
331 }
332
334 [[nodiscard]] static std::string hdf5_format() { return "MeshReFreqLog"; }
335
343 friend void h5_write(h5::group g, std::string const &name, refreq_log const &m) {
344 h5::group gr = g.create_group(name);
345 h5::write_hdf5_format(gr, m); // NOLINT (downcasting to base class)
346 h5::write(gr, "eps", m.eps_);
347 h5::write(gr, "w_max", m.w_max_);
348 h5::write(gr, "ratio", m.ratio_);
349 }
350
358 friend void h5_read(h5::group g, std::string const &name, refreq_log &m) {
359 h5::group gr = g.open_group(name);
360 h5::assert_hdf5_format(gr, m, true); // NOLINT (downcasting to base class)
361 auto e = h5::read<double>(gr, "eps");
362 auto w = h5::read<double>(gr, "w_max");
363 auto r = h5::read<double>(gr, "ratio");
364 m = refreq_log(e, w, r);
365 }
366
367 private:
369 void init_points() {
370 pts_.clear();
371 for (double w = w_max_; w >= eps_; w /= ratio_) {
372 pts_.push_back(w);
373 pts_.push_back(-w);
374 }
375 std::ranges::sort(pts_);
376 }
377
378 double eps_ = 0.0;
379 double w_max_ = 0.0;
380 double ratio_ = 0.0;
381 uint64_t mesh_hash_ = 0;
382 std::vector<double> pts_;
383 };
384
401 inline auto evaluate(refreq_log const &m, auto const &f, double w) {
402 EXPECTS(m.is_value_valid(w));
403
404 auto const &pts = m.points();
405 auto itr_r = std::ranges::lower_bound(pts, w);
406 long i_r = itr_r - pts.begin();
407
408 if (i_r == 0) { return f(0); }
409 if (i_r == m.size()) { return f(m.size() - 1); }
410
411 long i_l = i_r - 1;
412
413 double w_l = pts[i_l];
414 double w_r = pts[i_r];
415 double del = w_r - w_l;
416
417 double wt_r = (w - w_l) / del;
418 double wt_l = (w_r - w) / del;
419
420 return f(i_l) * wt_l + f(i_r) * wt_r;
421 }
422
424
425} // 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 of a triqs::mesh::refreq_log mesh.
double value() const noexcept
Get the value of the mesh point.
mesh_point_t(long n, long d, uint64_t mhash, double w)
Construct a mesh point with a given index, data index, hash value and value.
refreq_log mesh_t
Parent mesh type.
long data_index() const noexcept
Get the data index of the mesh point.
long index() const noexcept
Get the index of the mesh point.
mesh_point_t()=default
Default constructor leaves the mesh point uninitialized.
uint64_t mesh_hash() const noexcept
Get the hash value of the parent mesh.
Logarithmic real frequency mesh type.
friend std::ostream & operator<<(std::ostream &sout, refreq_log const &m)
Write a triqs::mesh::refreq_log mesh to a std::ostream.
bool is_value_valid(double w) const noexcept
Check if a value is within the mesh range.
mesh_point_t operator[](long d) const noexcept
Subscript operator to access a mesh point by its data index.
std::vector< double > const & points() const noexcept
Get the vector of frequency point values.
mesh_point_t operator[](closest_mesh_point_t< double > const &cmp) const noexcept
Subscript operator to access the mesh point closest to a given value.
void serialize(auto &ar) const
Serialize the mesh to a generic archive.
mesh_point_t operator()(index_t n) const noexcept
Function call operator to access a mesh point by its index.
refreq_log()=default
Default constructor creates an empty mesh.
uint64_t mesh_hash() const noexcept
Get the hash value of the mesh.
double w_max() const noexcept
Get the largest frequency .
index_t to_index(data_index_t d) const noexcept
Map a data index to the corresponding index .
refreq_log(double eps, double w_max, double ratio)
Construct a logarithmic real frequency mesh.
data_index_t to_data_index(closest_mesh_point_t< double > const &cmp) const noexcept
Map a value to the closest mesh point and return its data index.
void deserialize(auto &ar)
Deserialize the mesh from a generic archive.
auto cbegin() const
Get a const iterator to the beginning of the mesh.
data_index_t to_data_index(index_t n) const noexcept
Map an index to its corresponding data index .
friend void h5_read(h5::group g, std::string const &name, refreq_log &m)
Read a triqs::mesh::refreq_log mesh from HDF5.
auto cend() const
Get a const iterator to the end of the mesh.
bool is_index_valid(index_t n) const noexcept
Check if an index is valid.
double to_value(index_t n) const noexcept
Map an index to its corresponding value .
double eps() const noexcept
Get the smallest positive frequency .
long data_index_t
Data index type.
friend void h5_write(h5::group g, std::string const &name, refreq_log const &m)
Write a triqs::mesh::refreq_log mesh to HDF5.
double value_t
Value type.
auto end() const
Get an iterator to the end of the mesh.
double ratio() const noexcept
Get the common ratio of the geometric sequence.
auto begin() const
Get an iterator to the beginning of the mesh.
index_t to_index(closest_mesh_point_t< double > const &cmp) const noexcept
Map a value to the closest mesh point and return its index using binary search.
long index_t
Index type.
static std::string hdf5_format()
Get the HDF5 format tag.
long size() const noexcept
Get the size of the mesh, i.e. the number of mesh points.
bool operator==(refreq_log const &) const =default
Equal-to comparison operator compares , and the ratio.
uint64_t hash(Ts &&...ts)
Generic hash function for multiple arguments.
Definition utils.hpp:70
Common macros used in TRIQS.
Provides various utilities used with Meshes.
Provides a generic random access iterator for 1D meshes.
Lazy struct used in various function overloads as a placeholder for the closest mesh point to a given...
Definition utils.hpp:186
A generic random access iterator for 1D meshes.