/******************************************************************************* * * 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; }; // singularity template <> struct gf_default_singularity { using type = tail; }; template <> struct gf_default_singularity { using type = tail; }; namespace gfs_implementation { /// --------------------------- hdf5 --------------------------------- template struct h5_name { static std::string invoke() { return "ImFreq"; } }; /// --------------------------- data access --------------------------------- template struct data_proxy : data_proxy_array, 3> {}; template struct data_proxy : data_proxy_array, 1> {}; /// --------------------------- 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_DECL operator()(F const &f) const RETURN(w*f(n)); }; // ------------- evaluator ------------------- // handle the case where the matsu. freq is out of grid... struct _eval_imfreq_base_impl { static constexpr int arity = 1; template int sh(G const * g) const { return (g->mesh().domain().statistic == Fermion ? 1 : 0);} // int -> replace by matsubara_freq template AUTO_DECL operator()(G const *g, int n) const RETURN((*g)(matsubara_freq(n, g->mesh().domain().beta, g->mesh().domain().statistic))); template typename G::singularity_t operator()(G const *g, tail_view t) const { return compose(g->singularity(),t); //return g->singularity(); } }; // --- various 4 specializations // scalar_valued, tail template struct evaluator : _eval_imfreq_base_impl { using _eval_imfreq_base_impl::operator(); template std::complex operator()(G const *g, matsubara_freq const &f) 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 - this->sh(g)) < g->mesh().size())) return conj((*g)[-f.n - this->sh(g)]); } else { if ((f.n >= g->mesh().first_index()) && (f.n < g->mesh().size() + g->mesh().first_index())) return (*g)[f.n]; } return evaluate(g->singularity(),f)(0, 0); } }; // scalar_valued, no tail template struct evaluator : _eval_imfreq_base_impl { using _eval_imfreq_base_impl::operator(); template std::complex operator()(G const *g, matsubara_freq const &f) 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 - this->sh(g)) < g->mesh().size())) return conj((*g)[-f.n - this->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; } }; // matrix_valued, tail template struct evaluator : _eval_imfreq_base_impl { using _eval_imfreq_base_impl::operator(); template arrays::matrix_const_view> operator()(G const *g, matsubara_freq const &f) 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 - this->sh(g)) < g->mesh().size())) return arrays::matrix>{conj((*g)[-f.n - this->sh(g)]())}; } else { if ((f.n >= g->mesh().first_index()) && (f.n < g->mesh().size() + g->mesh().first_index())) return (*g)[f.n]; } return evaluate(g->singularity(), f); } }; // matrix_valued, no tail template struct evaluator : _eval_imfreq_base_impl { using _eval_imfreq_base_impl::operator(); template arrays::matrix_const_view> operator()(G const *g, matsubara_freq const &f) 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 - this->sh(g)) < g->mesh().size())) return arrays::matrix>{conj((*g)[-f.n - this->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; } }; } // gfs_implementation // specific operations (for legacy python code). // +=, -= with a matrix inline void operator+=(gf_view g, arrays::matrix> m) { for (int u = 0; u < int(first_dim(g.data())); ++u) g.data()(u, arrays::ellipsis()) += m; g.singularity()(0) += m; } inline void operator-=(gf_view g, arrays::matrix> m) { for (int u = 0; u < int(first_dim(g.data())); ++u) g.data()(u, arrays::ellipsis()) -= m; g.singularity()(0) -= m; } } }