47 using mesh::dlr_imfreq;
48 using mesh::dlr_imtime;
60 template <
int N,
int... Ns,
typename F,
typename G>
62 auto apply_to_mesh(F
const &f, G
const &g) {
63 using M =
typename G::mesh_t;
64 if constexpr (
sizeof...(Ns) > 0) {
65 return apply_to_mesh<Ns...>(f, apply_to_mesh<N>(f, g));
67 return map_block_gf([&](
auto const &gbl) {
return apply_to_mesh<N>(f, gbl); }, g);
72 auto g_out =
gf{out_mesh, g.target_shape()};
92 template <
int N = 0,
int... Ns,
typename G>
95 using M =
typename G::mesh_t;
99 return apply_to_mesh<N, Ns...>([&](
auto const &gfl) {
return make_gf_dlr(gfl); }, g);
101 static_assert(N == 0,
"N must be 0 for non-product meshes");
102 static_assert(nda::AnyOf<M, dlr_imtime, dlr_imfreq>,
"Mesh must be dlr_imtime or dlr_imfreq");
103 auto result =
gf{
dlr{g.mesh()}, g.target_shape()};
104 if constexpr (std::is_same_v<M, dlr_imtime>)
105 result.
data() = result.mesh().dlr_it().vals2coefs(g.data());
107 auto beta_inv = 1. / result.mesh().beta();
108 result.data() = beta_inv * result.mesh().dlr_if().vals2coefs(g.data());
127 template <
int N = 0,
int... Ns,
typename G>
130 using M =
typename G::mesh_t;
134 return apply_to_mesh<N, Ns...>([&](
auto const &gfl) {
return fit_gf_dlr(gfl, dlr_mesh); }, g);
136 static_assert(N == 0,
"N must be 0 for non-product meshes");
137 static_assert(std::is_same_v<M, mesh::imtime>,
"Input mesh must be imtime");
138 auto tvals = nda::array_adapter(std::array{g.mesh().size()}, [&](
auto i) {
return g.mesh()[i].value() / g.mesh().beta(); });
139 auto result =
gf{dlr_mesh, g.target_shape()};
140 result.
data() = result.mesh().dlr_it().fitvals2coefs(make_regular(tvals), g.data());
161 template <
int N = 0,
int... Ns,
typename G>
163 auto fit_gf_dlr(G
const &g,
double w_max,
double eps,
bool symmetrize =
true) {
167 auto dlr_mesh =
dlr{imt.beta(), imt.statistic(), w_max, eps, symmetrize};
183 template <
int N = 0,
int... Ns,
typename G>
186 using M =
typename G::mesh_t;
190 return apply_to_mesh<N, Ns...>([&](
auto const &gfl) {
return make_gf_dlr_imtime(gfl); }, g);
191 }
else if constexpr (std::is_same_v<M, dlr_imfreq>) {
194 static_assert(N == 0,
"N must be 0 for non-product meshes");
195 static_assert(std::is_same_v<M, mesh::dlr>,
"Input mesh must be dlr");
196 auto result =
gf{
dlr_imtime{g.mesh()}, g.target_shape()};
197 result.
data() = g.mesh().dlr_it().coefs2vals(g.data());
214 template <
int N = 0,
int... Ns,
typename G>
217 using M =
typename G::mesh_t;
221 return apply_to_mesh<N, Ns...>([&](
auto const &gfl) {
return make_gf_dlr_imfreq(gfl); }, g);
222 }
else if constexpr (std::is_same_v<M, dlr_imtime>) {
225 static_assert(N == 0,
"N must be 0 for non-product meshes");
226 static_assert(std::is_same_v<M, mesh::dlr>,
"Input mesh must be dlr");
227 auto result =
gf{
dlr_imfreq{g.mesh()}, g.target_shape()};
228 auto beta = result.
mesh().beta();
229 result.data() = beta * g.mesh().dlr_if().coefs2vals(g.data());
235 template <
typename G>
246 template <
typename G>
248 auto sample_on_dlr_imfreq(G
const &g, dlr_imfreq
const &dlr_mesh) {
250 return map_block_gf([&](
auto const &gbl) {
return sample_on_dlr_imfreq(gbl, dlr_mesh); }, g);
252 static_assert(std::is_same_v<typename G::mesh_t, mesh::imfreq>,
"Input mesh must be imfreq");
253 auto const &iw_mesh = g.mesh();
254 auto [iw_lo, iw_hi] = dlr_mesh.min_max_frequencies();
255 if (not iw_mesh.is_index_valid(iw_lo.n) or not iw_mesh.is_index_valid(iw_hi.n))
256 TRIQS_RUNTIME_ERROR <<
"make_gf_dlr_imfreq: input imfreq mesh does not cover the requested DLR frequency range";
257 auto result =
gf{dlr_mesh, g.target_shape()};
258 for (
auto const &mp : dlr_mesh) result[mp] = g[iw_mesh(mp.index())];
289 template <
int N = 0,
int... Ns,
typename G>
292 using M =
typename G::mesh_t;
294 return apply_to_mesh<N, Ns...>([&](
auto const &gfl) {
return make_gf_dlr_imfreq(gfl, w_max, eps, symmetrize); }, g);
296 static_assert(N == 0,
"N must be 0 for non-product meshes");
297 auto const &m0 = detail::imfreq_mesh_of(g);
298 auto dlr_mesh =
dlr_imfreq{m0.beta(), m0.statistic(), w_max, eps, symmetrize};
299 return detail::sample_on_dlr_imfreq(g, dlr_mesh);
333 template <
int = 0,
typename G>
335 double find_w_max(G
const &g,
double eps = 1e-10,
bool symmetrize =
true,
double w_max_init = 1.0,
double w_max_max = 200.0) {
336 if (w_max_init > w_max_max)
TRIQS_RUNTIME_ERROR <<
"find_w_max: w_max_init (" << w_max_init <<
") > w_max_max (" << w_max_max <<
")";
338 auto const &m0 = detail::imfreq_mesh_of(g);
341 for (
double w_max = w_max_init; w_max <= w_max_max; w_max *= 1.5) {
342 auto dlr_mesh =
dlr_imfreq{m0.beta(), m0.statistic(), w_max, eps, symmetrize};
344 if (not m0.is_index_valid(iw_lo.n) or not m0.is_index_valid(iw_hi.n))
continue;
346 auto g_dlr_iw = detail::sample_on_dlr_imfreq(g, dlr_mesh);
348 auto data_err = [](
auto const &x,
auto const &y) {
return double(max_element(abs(x.data() - y.data()))); };
349 double max_err = 0.0;
351 for (
long b = 0; b < long(g.size()); ++b) max_err = std::max(max_err, data_err(g[b], g_rec[b]));
353 max_err = data_err(g, g_rec);
355 if (max_err < eps)
return w_max;
357 TRIQS_RUNTIME_ERROR <<
"find_w_max: no w_max <= " << w_max_max <<
" yields round-trip error < eps = " << eps;
373 template <
int N = 0,
int... Ns,
typename G>
376 using M =
typename G::mesh_t;
380 return apply_to_mesh<N, Ns...>([&](
auto const &gfl) {
return make_gf_imtime(gfl, n_tau); }, g);
381 }
else if constexpr (nda::AnyOf<M, dlr_imtime, dlr_imfreq>) {
384 static_assert(N == 0,
"N must be 0 for non-product meshes");
385 static_assert(std::is_same_v<M, dlr>,
"Input mesh must be dlr");
386 auto result =
gf{
mesh::imtime{g.mesh().beta(), g.mesh().statistic(), n_tau}, g.target_shape()};
387 for (
auto tau : result.mesh()) result[tau] = g(tau.value());
405 template <
int N = 0,
int... Ns,
typename G>
408 using M =
typename G::mesh_t;
412 return apply_to_mesh<N, Ns...>([&](
auto const &gfl) {
return make_gf_imfreq(gfl, n_iw); }, g);
413 }
else if constexpr (nda::AnyOf<M, dlr_imtime, dlr_imfreq>) {
416 static_assert(N == 0,
"N must be 0 for non-product meshes");
417 static_assert(std::is_same_v<M, dlr>,
"Input mesh must be dlr");
418 auto result =
gf{
mesh::imfreq{g.mesh().beta(), g.mesh().statistic(), n_iw}, g.target_shape()};
419 for (
auto w : result.mesh()) result[w] = g(w.value());
432 template <
typename G>
435 using M =
typename G::mesh_t;
436 static_assert(nda::AnyOf<M, dlr, dlr_imfreq, dlr_imtime>,
"Input mesh must be one of dlr, dlr_imfreq, dlr_imtime");
442 constexpr int rank = std::decay_t<G>::g_t::target_t::rank;
443 if constexpr (rank == 0) {
444 std::vector<double> result;
445 result.reserve(g.data().size());
446 for (
auto const &gbl : g.data()) result.push_back(
tau_L2_norm(gbl));
449 std::vector<nda::array<double, rank>> result;
450 result.reserve(g.data().size());
451 for (
auto const &gbl : g.data()) result.push_back(
tau_L2_norm(gbl));
454 }
else if constexpr (nda::AnyOf<M, dlr_imtime, dlr_imfreq>) {
457 if constexpr (G::target_rank == 0) {
459 return std::sqrt(std::abs(g.mesh().dlr_it().innerprod(g.data(), g.data())));
461 auto result = nda::array<double, G::target_rank>(g.target_shape());
462 nda::for_each(g.target_shape(), [&](
auto... is) {
463 auto dat = g.data()(nda::range::all, is...);
464 result(is...) = std::sqrt(std::abs(g.mesh().dlr_it().innerprod(dat, dat)));
Provides the block Green's function container.
The owning Green's function container.
data_t & data() &
Get the data array.
mesh_t const & mesh() const
Get the mesh of the Green's function.
Imaginary frequency discrete Lehmann representation (DLR) mesh type.
auto min_max_frequencies() const noexcept
Get a pair containing the smallest and largest Matsubara frequency in the mesh.
Imaginary time discrete Lehmann representation (DLR) mesh type.
Discrete Lehmann representation (DLR) mesh type.
Imaginary frequency mesh type.
Imaginary time mesh type.
Concept checking that a type behaves like an in-memory Green's function.
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 Green's function class.
gf(M, DataArray) -> gf< M, target_from_array< DataArray, n_variables< M > > >
Deduce a triqs::gfs::gf type from a mesh and a data array.
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(G const &g)
Transform a DLR imaginary-time or DLR Matsubara Green's function to its DLR-coefficient representatio...
auto fit_gf_dlr(G const &g, mesh::dlr const &dlr_mesh)
Fit an imaginary-time Green's function on a given DLR coefficient mesh.
auto make_gf_dlr_imfreq(G const &g)
Build a DLR Matsubara Green's function from a DLR-coefficient or DLR-imaginary-time input.
auto make_gf_imfreq(G const &g, long n_iw)
Build a uniform Matsubara Green's function from any DLR representation.
auto tau_L2_norm(G const &g)
Calculate the norm of a DLR Green's function.
auto make_gf_imtime(G const &g, long n_tau)
Build a uniform imaginary-time Green's function from any DLR representation.
double find_w_max(G const &g, double eps=1e-10, bool symmetrize=true, double w_max_init=1.0, double w_max_max=200.0)
Find a DLR energy cutoff that reproduces an imfreq Green's function within tolerance eps after a DLR...
auto map_block_gf(F &&f, G &&g)
Apply a callable to each block of a block 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.
auto const & get_mesh(BG const &bg)
Get the mesh of a block Green's function, or its N-th component for a product mesh.
static constexpr bool is_product
Constexpr bool that is true if the given triqs::mesh::Mesh type is a product of meshes,...
#define TRIQS_RUNTIME_ERROR
Throw a triqs::runtime_error with the current source location.
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 a mesh type for the discrete Lehmann representation.
Provides a mesh type on the imaginary frequency axis.
Provides a mesh type on the imaginary time axis.
Provides a product mesh type.