TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
refreq_pts.hpp
Go to the documentation of this file.
1// Copyright (c) 2019-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: Rok Zitko, Nils Wentzell
17
22
23#pragma once
24
25#include "./mesh_iterator.hpp"
26#include "./utils.hpp"
28#include "../utility/macros.hpp"
29
30#include <fmt/format.h>
31#include <h5/h5.hpp>
32
33#include <algorithm>
34#include <cmath>
35#include <cstdint>
36#include <initializer_list>
37#include <iostream>
38#include <numeric>
39#include <string>
40#include <vector>
41
42namespace triqs::mesh {
43
48
68 class C2PY_RENAME(MeshReFreqPts) refreq_pts {
69 public:
71 using value_t = double;
72
74 using index_t = long;
75
77 using data_index_t = long;
78
88 class C2PY_IGNORE mesh_point_t {
89 public:
92
94 mesh_point_t() = default;
95
104 mesh_point_t(long n, long d, uint64_t mhash, double w) : index_(n), data_index_(d), mesh_hash_(mhash), value_(w) {}
105
107 [[nodiscard]] long index() const noexcept { return index_; }
108
110 [[nodiscard]] long data_index() const noexcept { return data_index_; }
111
113 [[nodiscard]] double value() const noexcept { return value_; }
114
116 [[nodiscard]] uint64_t mesh_hash() const noexcept { return mesh_hash_; }
117
119 operator double() const { return value_; } // NOLINT (implicit conversion intended)
120
121 // Arithmetic operations with scalars.
122#define IMPL_OP(OP) \
123 template <typename U> friend auto operator OP(mesh_point_t const &mp, U &&y) { return mp.value() OP std::forward<U>(y); } \
124 template <typename U> \
125 requires(not std::is_same_v<std::decay_t<U>, mesh_point_t>) \
126 friend auto operator OP(U &&x, mesh_point_t const &mp) { \
127 return std::forward<U>(x) OP mp.value(); \
128 }
129 IMPL_OP(+)
130 IMPL_OP(-)
131 IMPL_OP(*)
132 IMPL_OP(/)
133#undef IMPL_OP
134
135 private:
136 long index_ = 0;
137 long data_index_ = 0;
138 uint64_t mesh_hash_ = 0;
139 double value_ = 0.0;
140 };
141
143 refreq_pts() = default;
144
150 refreq_pts(std::vector<double> pts)
151 : pts_(std::move(pts)),
152 mesh_hash_(hash(std::accumulate(pts_.begin(), pts_.end(), 0.0), pts_.empty() ? 0.0 : pts_.front(), pts_.empty() ? 0.0 : pts_.back(),
153 static_cast<long>(pts_.size()))) {
154 if (not std::ranges::is_sorted(pts_)) TRIQS_RUNTIME_ERROR << "refreq_pts mesh must be constructed with a sorted list of points";
155 }
156
162 C2PY_IGNORE refreq_pts(std::initializer_list<double> l) : refreq_pts(std::vector<double>(l)) {}
163
165 bool operator==(refreq_pts const &) const = default;
166
173 [[nodiscard]] bool is_index_valid(index_t n) const noexcept { return 0 <= n and n < size(); }
174
181 [[nodiscard]] bool is_value_valid(double w) const noexcept { return !pts_.empty() and pts_.front() <= w and w <= pts_.back(); }
182
189 [[nodiscard]] data_index_t to_data_index(index_t n) const noexcept {
190 EXPECTS(is_index_valid(n));
191 return n;
192 }
193
200 [[nodiscard]] C2PY_IGNORE data_index_t to_data_index(closest_mesh_point_t<double> const &cmp) const noexcept {
201 return to_data_index(to_index(cmp));
202 }
203
210 [[nodiscard]] index_t to_index(data_index_t d) const noexcept {
211 EXPECTS(is_index_valid(d));
212 return d;
213 }
214
221 [[nodiscard]] C2PY_IGNORE index_t to_index(closest_mesh_point_t<double> const &cmp) const noexcept {
222 EXPECTS(is_value_valid(cmp.value));
223
224 auto itr_r = std::ranges::lower_bound(pts_, cmp.value);
225 long i_r = itr_r - pts_.begin();
226
227 if (i_r == 0) { return 0; }
228 if (i_r == size()) { return size() - 1; }
229
230 long i_l = i_r - 1;
231 if (std::abs(cmp.value - pts_[i_l]) < std::abs(cmp.value - pts_[i_r]))
232 return i_l;
233 else
234 return i_r;
235 }
236
243 [[nodiscard]] mesh_point_t operator[](long d) const noexcept { return (*this)(d); }
244
251 [[nodiscard]] C2PY_IGNORE mesh_point_t operator[](closest_mesh_point_t<double> const &cmp) const noexcept { return (*this)[to_data_index(cmp)]; }
252
259 [[nodiscard]] mesh_point_t operator()(index_t n) const noexcept {
260 EXPECTS(is_index_valid(n));
261 return {n, n, mesh_hash_, pts_[n]};
262 }
263
270 [[nodiscard]] double to_value(index_t n) const noexcept {
271 EXPECTS(is_index_valid(n));
272 return pts_[n];
273 }
274
276 [[nodiscard]] C2PY_PROPERTY_GET(mesh_hash) uint64_t mesh_hash() const noexcept { return mesh_hash_; }
277
279 [[nodiscard]] long size() const noexcept { return static_cast<long>(pts_.size()); }
280
282 [[nodiscard]] C2PY_PROPERTY_GET(points) std::vector<double> const &points() const noexcept { return pts_; }
283
285 [[nodiscard]] auto begin() const { return mesh_iterator<refreq_pts>{.mesh_ptr = this, .data_index = 0}; }
286
288 [[nodiscard]] auto cbegin() const { return begin(); }
289
291 [[nodiscard]] auto end() const { return mesh_iterator<refreq_pts>{.mesh_ptr = this, .data_index = size()}; }
292
294 [[nodiscard]] auto cend() const { return end(); }
295
303 friend std::ostream &operator<<(std::ostream &sout, refreq_pts const &m) {
304 return sout << fmt::format("Real frequency point mesh of size {}", m.size());
305 }
306
311 void serialize(auto &ar) const { ar & pts_ & mesh_hash_; }
312
317 void deserialize(auto &ar) { ar & pts_ & mesh_hash_; }
318
320 [[nodiscard]] static std::string hdf5_format() { return "MeshReFreqPts"; }
321
329 friend void h5_write(h5::group g, std::string const &name, refreq_pts const &m) {
330 h5::group gr = g.create_group(name);
331 h5::write_hdf5_format(gr, m); // NOLINT (downcasting to base class)
332 h5::write(gr, "points", m.pts_);
333 }
334
342 friend void h5_read(h5::group g, std::string const &name, refreq_pts &m) {
343 h5::group gr = g.open_group(name);
344 h5::assert_hdf5_format(gr, m, true); // NOLINT (downcasting to base class)
345 auto pts = h5::read<std::vector<double>>(gr, "points");
346 m = refreq_pts(std::move(pts));
347 }
348
349 private:
350 std::vector<double> pts_;
351 uint64_t mesh_hash_ = 0;
352 };
353
370 inline auto evaluate(refreq_pts const &m, auto const &f, double w) {
371 EXPECTS(m.is_value_valid(w));
372
373 auto const &pts = m.points();
374 auto itr_r = std::ranges::lower_bound(pts, w);
375 long i_r = itr_r - pts.begin();
376
377 if (i_r == 0) { return f(0); }
378 if (i_r == m.size()) { return f(m.size() - 1); }
379
380 long i_l = i_r - 1;
381
382 double w_l = pts[i_l];
383 double w_r = pts[i_r];
384 double del = w_r - w_l;
385
386 double wt_r = (w - w_l) / del;
387 double wt_l = (w_r - w) / del;
388
389 return f(i_l) * wt_l + f(i_r) * wt_r;
390 }
391
393
394} // 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_pts mesh.
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.
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.
refreq_pts mesh_t
Parent mesh type.
long index() const noexcept
Get the index of the mesh point.
long data_index() const noexcept
Get the data index of the mesh point.
double value() const noexcept
Get the value of the mesh point.
Real frequency mesh type from arbitrary sorted frequency points.
friend void h5_read(h5::group g, std::string const &name, refreq_pts &m)
Read a triqs::mesh::refreq_pts mesh from HDF5.
auto end() const
Get an iterator to the end of the mesh.
long data_index_t
Data index type.
refreq_pts()=default
Default constructor creates an empty mesh.
void deserialize(auto &ar)
Deserialize the mesh from a generic archive.
refreq_pts(std::initializer_list< double > l)
Construct a real frequency mesh from an initializer list of frequency points.
bool is_value_valid(double w) const noexcept
Check if a value is within the mesh range.
friend void h5_write(h5::group g, std::string const &name, refreq_pts const &m)
Write a triqs::mesh::refreq_pts mesh to HDF5.
data_index_t to_data_index(index_t n) const noexcept
Map an index to its corresponding data index .
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.
auto cend() const
Get a const iterator to the end of the mesh.
auto cbegin() const
Get a const iterator to the beginning of the mesh.
long size() const noexcept
Get the size of the mesh, i.e. the number of mesh points.
static std::string hdf5_format()
Get the HDF5 format tag.
friend std::ostream & operator<<(std::ostream &sout, refreq_pts const &m)
Write a triqs::mesh::refreq_pts mesh to a std::ostream.
uint64_t mesh_hash() const noexcept
Get the hash value of the mesh.
auto begin() const
Get an iterator to the beginning of the mesh.
index_t to_index(data_index_t d) const noexcept
Map a data index to the corresponding index .
double to_value(index_t n) const noexcept
Map an index to its corresponding value .
std::vector< double > const & points() const noexcept
Get the vector of frequency point values.
mesh_point_t operator()(index_t n) const noexcept
Function call operator to access a mesh point by its index.
refreq_pts(std::vector< double > pts)
Construct a real frequency mesh from a sorted vector of frequency points.
bool is_index_valid(index_t n) const noexcept
Check if an index is valid.
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.
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.
mesh_point_t operator[](long d) const noexcept
Subscript operator to access a mesh point by its data index.
bool operator==(refreq_pts const &) const =default
Equal-to comparison operator.
double value_t
Value type.
TRIQS exception hierarchy and related macros.
uint64_t hash(Ts &&...ts)
Generic hash function for multiple arguments.
Definition utils.hpp:70
#define TRIQS_RUNTIME_ERROR
Throw a triqs::runtime_error with the current source location.
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.