49#include <itertools/itertools.hpp>
60 using nda::array_const_view;
63 template <
typename V>
using _mesh_fourier_image =
decltype(
make_adjoint_mesh(V()));
71 gf_vec_t<mesh::imfreq> _fourier_impl(mesh::imfreq
const &iw_mesh, gf_vec_cvt<mesh::imtime> gt, array_const_view<dcomplex, 2> known_moments = {});
72 gf_vec_t<mesh::imtime> _fourier_impl(mesh::imtime
const &tau_mesh, gf_vec_cvt<mesh::imfreq> gw, array_const_view<dcomplex, 2> known_moments = {});
75 inline gf_vec_t<mesh::dlr_imfreq> _fourier_impl(mesh::dlr_imfreq
const &, gf_vec_cvt<mesh::dlr_imtime> gt) {
return make_gf_dlr_imfreq(gt); }
76 inline gf_vec_t<mesh::dlr_imtime> _fourier_impl(mesh::dlr_imtime
const &, gf_vec_cvt<mesh::dlr_imfreq> gw) {
return make_gf_dlr_imtime(gw); }
79 gf_vec_t<mesh::refreq> _fourier_impl(mesh::refreq
const &w_mesh, gf_vec_cvt<mesh::retime> gt, array_const_view<dcomplex, 2> known_moments = {});
80 gf_vec_t<mesh::retime> _fourier_impl(mesh::retime
const &t_mesh, gf_vec_cvt<mesh::refreq> gw, array_const_view<dcomplex, 2> known_moments = {});
83 gf_vec_t<mesh::cyclat> _fourier_impl(mesh::cyclat
const &r_mesh, gf_vec_cvt<mesh::brzone> gk);
84 gf_vec_t<mesh::brzone> _fourier_impl(mesh::brzone
const &k_mesh, gf_vec_cvt<mesh::cyclat> gr);
87 template <
int N,
typename M1,
typename M2,
typename T1,
typename T2,
typename... OptArgs>
90 static_assert(std::is_same_v<typename T1::complex_t, T2>,
"Incompatible target types for fourier transform");
93 auto const &out_mesh = [&gout]() ->
auto const & {
94 using m_t = std::decay_t<
decltype(gout.mesh())>;
96 return std::get<N>(gout.mesh());
105 auto gin_fl = [&gin]() {
110 auto gout_fl = _fourier_impl(out_mesh, gin_fl,
flatten_2d(opt_args)...);
140 template <
int N = 0,
typename M1,
typename M2,
typename T,
typename... OptArgs>
142 static_assert(N >= 0 && N < n_variables<M1>,
"Mesh index exceeds Gf Mesh Rank");
143 static_assert(
n_variables<M2> == 1,
"Cannot fourier transform on cartesian product mesh");
147 static_assert(N == 0,
"Fourier transforming gf with mesh of rank 1 but fourier index N > 1");
148 static_assert(std::is_same_v<M2, _mesh_fourier_image<M1>>,
"There is no Fourier transform between these two meshes");
150 _fourier<N>(gin, gout(), opt_args...);
153 static_assert(std::is_same_v<M2, _mesh_fourier_image<std::tuple_element_t<N, M1>>>,
"There is no Fourier transform between these two meshes");
156 using mesh_t =
typename std::decay_t<
decltype(out_mesh)>;
158 _fourier<N>(gin, gout(), opt_args...);
199 template <
int N = 0,
typename T>
205 template <
int N>
struct _fou_wk {};
208 template <
int N,
typename G>
209 auto operator&(G &&gin, _fou_wk<N>
const &) {
228 template <
int N1,
int N2,
typename M1,
typename M2,
typename... Vs,
typename T>
230 static_assert(
sizeof...(Vs) >= 2,
"Green function mesh rank incompatible with mesh indices");
239 template <
int N1,
int N2,
int N3,
typename M1,
typename M2,
typename M3,
typename... Vs,
typename T>
241 static_assert(
sizeof...(Vs) >= 3,
"Green function mesh rank incompatible with mesh indices");
255 template <
int N = 0,
typename G,
typename M,
int R>
261 std::vector<r_t> g_vec;
263 TRIQS_ASSERT2(gin.size() == known_moments.size(),
"Fourier: Require equal number of blocks in block_gf and known_moments vector");
265 for (
auto [gin_bl, km_bl] : itertools::zip(gin, known_moments)) g_vec.push_back(
make_gf_from_fourier<N>(gin_bl, m, km_bl));
270 template <
int N = 0,
typename G,
typename M,
int R>
271 auto make_gf_from_fourier(G
const &gin, M
const &m, std::vector<std::vector<array<dcomplex, R>>>
const &known_moments)
276 std::vector<std::vector<r_t>> g_vecvec;
278 TRIQS_ASSERT2(gin.size1() == known_moments.size(),
"Fourier: Require matching block structure between gin and known_moments");
280 for (
int i : range(gin.size1())) {
281 TRIQS_ASSERT2(gin.size2() == known_moments[i].size(),
"Fourier: Require matching block structure between gin and known_moments");
283 std::vector<r_t> g_vec;
286 g_vecvec.push_back(std::move(g_vec));
292 template <
int N = 0,
int... Ns,
typename G,
typename... Args>
311 template <
int N,
typename GCV,
typename... Args>
struct _fourier_lazy {
313 std::tuple<Args...> args;
331 template <
int N = 0,
typename G,
typename... Args> _fourier_lazy<N,
typename G::const_view_type, Args...>
fourier(G
const &g, Args &&...args) {
332 return {g(), {std::forward<Args>(args)...}};
336 template <
int N,
typename M1,
typename T1,
typename M2,
typename T2,
typename... Args>
337 void triqs_gf_view_assign_delegation(gf_view<M1, T1> lhs_g, _fourier_lazy<N, gf_const_view<M2, T2>, Args...>
const &rhs) {
338 static_assert(std::is_same_v<typename T1::real_t, typename T2::real_t>,
"Error : in gx = fourier(gy), gx and gy must have the same target");
340 if constexpr (n_variables<M1> == 1)
341 static_assert(std::is_same_v<M2, _mesh_fourier_image<M1>>,
"There is no Fourier transform between these two meshes");
343 using mesh_res_t =
decltype(
triqs::tuple::replace<N>(rhs.g.mesh().components(), make_adjoint_mesh(std::get<N>(rhs.g.mesh()))));
344 static_assert(std::is_same_v<typename M1::m_tuple_t, mesh_res_t>,
"Meshes in assignment don't match");
349 std::apply([&](
auto &&...u) { _fourier<N>(rhs.g, lhs_g, u...); }, rhs.args);
356 TRIQS_CLEF_MAKE_FNT_LAZY(fourier);
Provides functions to create adjoint meshes.
Provides the block Green's function container.
Provides a mesh type for Brillouin zones.
A read-only, non-owning view of a Green's function.
mesh_t const & mesh() const
Get the mesh of the Green's function.
std::array< long, Target::rank > target_shape() const
Get the shape of the target.
A mutable, non-owning view of a Green's function.
The owning Green's function container.
Product mesh type for combining multiple meshes.
Provides a mesh type for Bravais lattices with Born-von Karman periodic boundary conditions.
static constexpr int n_variables
Constexpr variable that holds the number of meshes in a triqs::mesh::Mesh type ( for non-product mes...
Provides a mesh type for the discrete Lehmann representation in imaginary frequency space.
Provides a mesh type for the discrete Lehmann representation in imaginary time.
TRIQS exception hierarchy and related macros.
Provides utilities to flatten the data of arrays and Green's functions into a two-dimensional form.
Provides the triqs::gfs::gf_const_view container, a read-only non-owning view of a Green's function.
Provides a mutable non-owning view of a Green's function.
Provides conversions between Green's functions and the Discrete Lehmann Representation (DLR).
Provides the Green's function class.
imfreq make_adjoint_mesh(imtime const &m, long n_iw=-1)
Create the adjoint imaginary-frequency mesh to a given imaginary-time mesh.
auto make_gf_dlr_imtime(G const &g)
Build a DLR imaginary-time Green's function from a DLR-coefficient or DLR-Matsubara input.
auto make_gf_dlr_imfreq(G const &g)
Build a DLR Matsubara Green's function from a DLR-coefficient or DLR-imaginary-time input.
block_gf< V, T, L > make_block_gf(int n, gf< V, T, L > const &g)
Make a triqs::gfs::block_gf of n copies of a Green's function (block names default to "0",...
auto make_gf_from_multi_fourier(gf_const_view< V, T > gin)
Fourier transform several components of a product-mesh Green's function at once.
auto make_gf_from_fourier(block_gf< M, T, L, A > &g)
Apply make_gf_from_fourier block-wise to each block of the block Green's function.
auto fourier(block_gf< V, T, L, A > const &g)
Lazily apply the Fourier transform block by block to a block Green's function.
auto map_block_gf(F &&f, G &&g)
Apply a callable to each block of a block Green's function.
auto flatten_2d(A const &v)
Flatten an array into two dimensions, keeping one dimension and collapsing the rest.
auto make_const_view(Gf const &g)
Make a const view of a Green's function.
void unflatten_gf_2d(MemoryGf auto &g, Gfl const &gfl)
Inverse of triqs::gfs::flatten_gf_2d: scatter a flattened Green's function back into a higher-rank on...
auto flatten_gf_2d(G const &g)
Flatten a Green's function into a single-mesh, tensor-valued Green's function.
constexpr bool is_block_gf_v
Trait to check whether a type is a block Green's function.
block2_gf< get_mesh_t< G >, get_target_t< G > > block2_gf_of
The triqs::gfs::block2_gf type matching the mesh and target of G.
static constexpr bool is_product
Constexpr bool that is true if the given triqs::mesh::Mesh type is a product of meshes,...
#define TRIQS_ASSERT2(X,...)
Like TRIQS_ASSERT but lets the caller add a custom message.
auto replace(T &&t, R &&r)
Return a copy of a tuple with the elements at the given positions replaced by a given value.
Provides the function applying a callable block by block to a block Green's function.
Provides a mesh type on the imaginary frequency axis.
Provides a mesh type on the imaginary time axis.
Provides a product mesh type.
Provides a mesh type on the real frequency axis.
Provides a mesh type on the real time axis.
Provides the target types that fix the value stored at each mesh point of a Green's function.