TRIQS/triqs_tprf 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
fourier.hpp
1// Copyright (c) 2018 Commissariat à l'énergie atomique et aux énergies alternatives (CEA)
2// Copyright (c) 2018 Centre national de la recherche scientifique (CNRS)
3// Copyright (c) 2018-2020 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: Hugo Strand, Michel Ferrero, Nils Wentzell
19
20#pragma once
21
22#include <nda/nda.hpp>
23
24#include <triqs/gfs.hpp>
25#include <triqs/mesh.hpp>
26#include <triqs/utility/tuple_tools.hpp>
27
28#include "fourier_common.hpp"
29
30namespace triqs_tprf::fourier {
31
32 using namespace nda;
33 using namespace triqs::gfs;
34 using namespace triqs::mesh;
35
36 /*------------------------------------------------------------------------------------------------------
37 Implementation
38 *-----------------------------------------------------------------------------------------------------*/
39
40 template <typename V> using gf_vec_t = gf<V, tensor_valued<1>>;
41 template <typename V> using gf_vec_vt = gf_view<V, tensor_valued<1>>;
42 template <typename V> using gf_vec_cvt = gf_const_view<V, tensor_valued<1>>;
43
44 // matsubara
45 gf_vec_t<imfreq> _fourier_impl(mesh::imfreq const &iw_mesh, gf_vec_cvt<imtime> gt, fourier_plan &p, array_const_view<dcomplex, 2> mom_23 = {});
46 gf_vec_t<imtime> _fourier_impl(mesh::imtime const &tau_mesh, gf_vec_cvt<imfreq> gw, fourier_plan &p, array_const_view<dcomplex, 2> mom_123 = {});
47 fourier_plan _fourier_plan(mesh::imfreq const &iw_mesh, gf_vec_cvt<imtime> gt);
48 fourier_plan _fourier_plan(mesh::imtime const &tau_mesh, gf_vec_cvt<imfreq> gw);
49
50 // lattice
51 gf_vec_t<cyclat> _fourier_impl(mesh::cyclat const &r_mesh, gf_vec_cvt<brzone> gk, fourier_plan &p);
52 gf_vec_t<brzone> _fourier_impl(mesh::brzone const &k_mesh, gf_vec_cvt<cyclat> gr, fourier_plan &p);
53 fourier_plan _fourier_plan(mesh::cyclat const &r_mesh, gf_vec_cvt<brzone> gk);
54 fourier_plan _fourier_plan(mesh::brzone const &k_mesh, gf_vec_cvt<cyclat> gr);
55
56 /*------------------------------------------------------------------------------------------------------
57 *
58 * The general Fourier function
59 * gin : input
60 * gout : output
61 * opt_args : e.g. moments. Must be flatten_2d
62 *
63 *-----------------------------------------------------------------------------------------------------*/
64
65 // this function just regroups the function, and calls the vector_valued gf core
66 // implementation
67 template <int N, typename V1, typename V2, typename T, typename... OptArgs>
68 void _fourier_with_plan(gf_const_view<V1, T> gin, gf_view<V2, T> gout, fourier_plan &p, OptArgs const &...opt_args) {
69
70 // pb std::get<0> would not work on a non composite mesh. We use a little lambda to deduce ref and type
71 auto const &out_mesh = [&gout]() -> auto const & { // NB must return a reference
72 using m_t = std::decay_t<decltype(gout.mesh())>;
73 if constexpr (triqs::mesh::is_product<m_t>)
74 return std::get<N>(gout.mesh());
75 else
76 return gout.mesh();
77 }
78 ();
79
80 auto gout_flatten = _fourier_impl(out_mesh, flatten_gf_2d<N>(gin), p, flatten_2d<0>(make_array_const_view(opt_args))...);
81 auto _ = ellipsis();
82 if constexpr (gin.data_rank == 1)
83 gout.data() = gout_flatten.data()(_, 0); // gout is scalar, gout_flatten vectorial
84 else {
85 // inverse operation as flatten_2d, exactly
86 auto g_rot = nda::rotate_index_view<N>(gout.data());
87 for (auto mp : out_mesh) {
88 auto g_rot_sl = g_rot(mp.data_index(), _); // if the array is long, it is faster to precompute the view ...
89 auto gout_col = gout_flatten.data()(mp.data_index(), _);
90 nda::for_each(g_rot_sl.shape(), [&g_rot_sl, &gout_col, c = long(0)](auto &&...i) mutable { return g_rot_sl(i...) = gout_col(c++); });
91 }
92 }
93 }
94
95 // this function just regroups the function, and calls the vector_valued gf core
96 // implementation
97 template <int N, typename V1, typename V2, typename T, typename... OptArgs>
98 fourier_plan _fourier_plan(gf_const_view<V1, T> gin, gf_view<V2, T> gout, OptArgs const &...opt_args) {
99
100 // pb std::get<0> would not work on a non composite mesh. We use a little lambda to deduce ref and type
101 auto const &out_mesh = [&gout]() -> auto const & { // NB must return a reference
102 using m_t = std::decay_t<decltype(gout.mesh())>;
103 if constexpr (triqs::mesh::is_product<m_t>)
104 return std::get<N>(gout.mesh());
105 else
106 return gout.mesh();
107 }
108 ();
109
110 return _fourier_plan(out_mesh, flatten_gf_2d<N>(gin), flatten_2d(opt_args, N)...);
111 }
112} // namespace triqs_tprf::fourier