TRIQS/triqs_cthyb 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
nfft_array.hpp
1/*******************************************************************************
2 *
3 * TRIQS: a Toolbox for Research in Interacting Quantum Systems
4 *
5 * Copyright (C) 2016, P. Seth, I. Krivenko, M. Ferrero and O. Parcollet
6 *
7 * TRIQS is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later
10 * version.
11 *
12 * TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * TRIQS. If not, see <http://www.gnu.org/licenses/>.
19 *
20 ******************************************************************************/
21#pragma once
22
23#include <vector>
24#include <triqs/utility/time_pt.hpp>
25#include <triqs/experimental/nfft_buf.hpp>
26
27namespace triqs {
28 namespace experimental {
29
30 using namespace nda;
31 using namespace triqs::gfs;
32 using namespace triqs::mesh;
33 using triqs::utility::time_pt;
34
35 // NFFT transform of an array-valued function of MeshRank tau arguments
36 template <int MeshRank, int TargetRank> class nfft_array_t {
37
38 public:
39 using freq_mesh_t = typename nfft_buf_t<MeshRank>::freq_mesh_t;
40 using res_gf_t = gf<freq_mesh_t, tensor_valued<TargetRank>>;
41 static constexpr int result_rank = MeshRank + TargetRank;
42
43 nfft_array_t() = default;
44
45 nfft_array_t(nfft_array_t const &other) = delete;
46 nfft_array_t(nfft_array_t &&other) : indexmap(other.indexmap), buffers(std::move(other.buffers)) { fiw_arr.rebind(other.fiw_arr); }
47
48 nfft_array_t &operator=(nfft_array_t const &other) = delete;
49 nfft_array_t &operator=(nfft_array_t &&other) {
50 indexmap = other.indexmap;
51 buffers = std::move(other.buffers);
52 fiw_arr.rebind(other.fiw_arr);
53 return *this;
54 }
55
56 // fiw_mesh - Matsubara frequency mesh
57 // fiw_arr_ - array to contain the final NFFT output
58 // buf_sizes - sizes of NFFT buffers
59 nfft_array_t(freq_mesh_t const &fiw_mesh, array_view<dcomplex, result_rank> fiw_arr_, array<long, TargetRank> const &buf_sizes)
60 : indexmap(make_target_shape(fiw_arr_.shape())), fiw_arr(fiw_arr_) {
61 buffers.reserve(indexmap.size());
62 for_each(buf_sizes.shape(), [this, &fiw_mesh, &buf_sizes](auto... ind) {
63#ifdef NDEBUG
64 buffers.emplace_back(fiw_mesh, fiw_arr(ellipsis(), ind...), buf_sizes(ind...), false);
65#else
66 buffers.emplace_back(fiw_mesh, fiw_arr(ellipsis(), ind...), buf_sizes(ind...), true);
67#endif
68 });
69 }
70
71 // Add a new element to the NFFT buffer
72 void push_back(std::array<double, MeshRank> const &tau_arr, std::array<int, TargetRank> const &ind_arr, dcomplex fxy) {
73 select_buffer(ind_arr, std::make_index_sequence<TargetRank>()).push_back(tau_arr, fxy);
74 }
75
76 // Run transformation
77 void flush() {
78 for (auto &buf : buffers) buf.flush();
79 }
80
81 private:
82 template <size_t... Is> inline nfft_buf_t<MeshRank> &select_buffer(std::array<int, TargetRank> const &ind_arr, std::index_sequence<Is...>) {
83 return buffers[indexmap(ind_arr[Is]...)];
84 }
85
86 std::array<long, TargetRank> make_target_shape(std::array<long, result_rank> const &shape) {
87 std::array<long, TargetRank> res;
88 for (int n = 0; n < TargetRank; ++n) res[n] = shape[n + MeshRank];
89 return std::array<long, TargetRank>(res);
90 }
91
92 // Index map for the target array
93 nda::idx_map<TargetRank, 0, C_stride_order<TargetRank>, layout_prop_e::none> indexmap;
94
95 // NFFT buffers
96 std::vector<nfft_buf_t<MeshRank>> buffers;
97
98 // NFFT transformation result
99 array_view<dcomplex, result_rank> fiw_arr;
100 };
101 } // namespace experimental
102} // namespace triqs