/******************************************************************************* * * TRIQS: a Toolbox for Research in Interacting Quantum Systems * * Copyright (C) 2012-2013 by O. Parcollet * * TRIQS is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * TRIQS. If not, see . * ******************************************************************************/ #pragma once #include "./tools.hpp" #include "./gf.hpp" #include "./local/tail.hpp" #include "./local/no_tail.hpp" #include "./meshes/matsubara_freq.hpp" #include "./evaluators.hpp" namespace triqs { namespace gfs { struct imfreq {}; template struct gf_mesh : matsubara_freq_mesh { template gf_mesh(T &&... x) : matsubara_freq_mesh(std::forward(x)...) {} //using matsubara_freq_mesh::matsubara_freq_mesh; }; namespace gfs_implementation { // singularity template <> struct singularity { using type = local::tail; }; template <> struct singularity { using type = local::tail; }; // h5 name template struct h5_name { static std::string invoke() { return "ImFreq"; } }; /// --------------------------- evaluator --------------------------------- // simple evaluation : take the point on the grid... template <> struct evaluator_fnt_on_mesh { long n; double w; evaluator_fnt_on_mesh() = default; template evaluator_fnt_on_mesh(MeshType const &m, long p) { n = p; w=1; } template evaluator_fnt_on_mesh(MeshType const &m, matsubara_freq const &p) { if ((p.n >= m.first_index()) && (p.n < m.size()+m.first_index())) {w=1; n =p.n;} else {w=0; n=0;} } template auto operator()(F const &f) const DECL_AND_RETURN(w*f(n)); }; // ------------- evaluator ------------------- // handle the case where the matsu. freq is out of grid... template struct evaluator { static constexpr int arity = 1; private: template int sh(G const * g) const { return (g->mesh().domain().statistic == Fermion ? 1 : 0);} // dispatch for 2x2 cases : matrix/scalar and tail/no_tail ( true means no_tail) template std::complex _call_impl(G const *g, matsubara_freq const &f, scalar_valued, std::false_type) const { if (g->mesh().positive_only()){//only positive Matsubara frequencies if ((f.n >= 0) && (f.n < g->mesh().size())) return (*g)[f.n]; if ((f.n < 0) && ((-f.n-sh(g)) < g->mesh().size())) return conj((*g)[-f.n-sh(g)]); } else{ if ((f.n >= g->mesh().first_index()) && (f.n < g->mesh().size()+g->mesh().first_index())) return (*g)[f.n]; } return g->singularity().evaluate(f)(0, 0); } template std::complex _call_impl(G const *g, matsubara_freq const &f, scalar_valued, std::true_type) const { if (g->mesh().positive_only()){//only positive Matsubara frequencies if ((f.n >= 0) && (f.n < g->mesh().size())) return (*g)[f.n]; if ((f.n < 0) && ((-f.n-sh(g)) < g->mesh().size())) return conj((*g)[-f.n-sh(g)]); } else{ if ((f.n >= g->mesh().first_index()) && (f.n < g->mesh().size()+g->mesh().first_index())) return (*g)[f.n]; } return 0; } template arrays::matrix_const_view> _call_impl(G const *g, matsubara_freq const &f, matrix_valued, std::false_type) const { if (g->mesh().positive_only()){//only positive Matsubara frequencies if ((f.n >= 0) && (f.n < g->mesh().size())) return (*g)[f.n](); if ((f.n < 0) && ((-f.n-sh(g)) < g->mesh().size())) return arrays::matrix>{conj((*g)[-f.n-sh(g)]())}; } else{ if ((f.n >= g->mesh().first_index()) && (f.n < g->mesh().size()+g->mesh().first_index())) return (*g)[f.n]; } return g->singularity().evaluate(f); } template arrays::matrix_const_view> _call_impl(G const *g, matsubara_freq const &f, matrix_valued, std::true_type) const { if (g->mesh().positive_only()){//only positive Matsubara frequencies if ((f.n >= 0) && (f.n < g->mesh().size())) return (*g)[f.n](); if ((f.n < 0) && ((-f.n-sh(g)) < g->mesh().size())) return arrays::matrix>{conj((*g)[-f.n-sh(g)]())}; } else{ if ((f.n >= g->mesh().first_index()) && (f.n < g->mesh().size()+g->mesh().first_index())) return (*g)[f.n]; } auto r = arrays::matrix>{get_target_shape(*g)}; r() = 0; return r; } // does not work on gcc 4.8.1 ??? /* template auto operator()(G const *g, matsubara_freq const &f) const DECL_AND_RETURN(_call_impl(g, f, Target{}, std::integral_constant::value>{})); */ public: template typename std::conditional::value, arrays::matrix_const_view>, std::complex>::type operator()(G const *g, matsubara_freq const &f) const { return _call_impl(g, f, Target{}, std::integral_constant::value>{}); } // int -> replace by matsubara_freq template auto operator()(G const *g, int n) const DECL_AND_RETURN((*g)(matsubara_freq(n,g->mesh().domain().beta,g->mesh().domain().statistic))); #ifdef __clang__ // to generate a clearer error message ? . Only ok on clang ? template struct error { static_assert(n > 0, "Green function cannot be evaluated on a complex number !"); }; template error<0> operator()(G const *g, std::complex) const { return {}; } #endif template typename G::singularity_t const &operator()(G const *g, freq_infty const &) const { return g->singularity(); } }; /// --------------------------- data access --------------------------------- template struct data_proxy : data_proxy_array, 3> {}; template struct data_proxy : data_proxy_array, 1> {}; } // gfs_implementation } }