/******************************************************************************* * * TRIQS: a Toolbox for Research in Interacting Quantum Systems * * Copyright (C) 2012 by M. Ferrero, 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 #include "triqs/utility/complex_ops.hpp" #include #include #include #include namespace triqs { namespace gfs { namespace mpl = boost::mpl; namespace tag { struct composite {}; struct mesh_point {}; } // scalar_valued, matrix_valued, tensor_valued struct scalar_valued {}; template struct tensor_valued { static_assert(R > 0, "tensor_valued only for rank >0"); }; struct matrix_valued {}; //------------------------------------------------------ using dcomplex = std::complex; /** The statistics : Boson or Fermion */ enum statistic_enum { Boson, Fermion }; struct freq_infty {}; // the point at infinity //------------------------------------------------------ template struct closest_pt_wrap; template struct closest_pt_wrap : tag::mesh_point { T value; template explicit closest_pt_wrap(U &&x) : value(std::forward(x)) {} }; template struct closest_pt_wrap : tag::mesh_point { std::tuple value_tuple; template explicit closest_pt_wrap(U &&... x) : value_tuple(std::forward(x)...) {} }; template closest_pt_wrap closest_mesh_pt(T &&... x) { return closest_pt_wrap{std::forward(x)...}; } //------------------------------------------------------ // A simple indice struct // Replace empty state by optional ? struct indices_2 { std::vector> ind; indices_2() = default; indices_2(std::vector> _ind) : ind(std::move(_ind)) {} bool is_empty() const { return ind.size() == 0; } template bool check_size(G *g) const { return (is_empty() || ((ind.size() == 2) && (ind[0].size() == get_target_shape(*g)[0]) && (ind[1].size() == get_target_shape(*g)[1]))); } std::vector operator[](int i) const { if (is_empty()) return std::vector {}; else return ind[i]; } arrays::range convert_index(std::string const &s, int l_r) const { if (!is_empty()) { auto b = ind[l_r].begin(), e = ind[l_r].end(); auto it = std::find(b, e, s); if (it != e) return it - b; } TRIQS_RUNTIME_ERROR << "There are no string indices for this Green function"; } friend class boost::serialization::access; template void serialize(Archive &ar, const unsigned int version) { ar &TRIQS_MAKE_NVP("ind", ind); } friend void h5_write(h5::group fg, std::string subgroup_name, indices_2 const &g) { if (g.is_empty()) return; auto gr = fg.create_group(subgroup_name); h5_write(gr, "left", g.ind[0]); h5_write(gr, "right", g.ind[1]); } friend void h5_read(h5::group fg, std::string subgroup_name, indices_2 &g) { h5::group gr; try { gr = fg.open_group(subgroup_name); } catch (...) { g = indices_2{}; // empty, no file return; } h5_read(gr, "left", g.ind[0]); h5_read(gr, "right", g.ind[1]); } }; // inline indices_2 slice(indices_2 const & ind, arrays::range rl, arrays::range rr) { // return {}; // } inline indices_2 slice(indices_2 const &ind, arrays::range rl, arrays::range rr) { if (ind.is_empty()) return {}; return {}; // MODIFY : slice the indices !!! TRIQS_RUNTIME_ERROR << "Not implemented : slice of string indices"; } inline indices_2 transpose(indices_2 const &x) { auto ind2 = x.ind; if (x.ind.size() > 0) { int im = x.ind.size(), jm = x.ind[0].size(); for (int i = 0; i < im; ++i) for (int j = 0; j < jm; ++j) ind2[i][j] = x.ind[j][i]; } return indices_2(std::move(ind2)); } //------------------------------------------------------ // A simple replacement of tail when there is none to maintain generic code simple... struct nothing { template explicit nothing(Args &&...) {} // takes anything, do nothing.. nothing() {} using view_type = nothing; using regular_type = nothing; void rebind(nothing) {} template void operator=(RHS &&) {} friend void h5_write(h5::group, std::string subgroup_name, nothing) {} friend void h5_read(h5::group, std::string subgroup_name, nothing) {} template friend nothing slice(nothing, A...) { return nothing(); } friend class boost::serialization::access; template void serialize(Archive &ar, const unsigned int version) {} friend nothing operator+(nothing, nothing) { return nothing(); } template friend void assign_from_expression(nothing &, RHS) {} template bool check_size(A) {return true;} }; inline nothing transpose(nothing) { return {};} inline nothing inverse(nothing) { return {};} inline nothing conj(nothing) { return {};} template nothing slice_target(nothing, T...) { return nothing(); } template nothing operator+(nothing, T const &) { return nothing(); } template nothing operator-(nothing, T const &) { return nothing(); } template nothing operator*(nothing, T const &) { return nothing(); } template nothing operator/(nothing, T const &) { return nothing(); } template TYPE_DISABLE_IF(nothing, std::is_same) operator+(T const &, nothing) { return nothing(); } template TYPE_DISABLE_IF(nothing, std::is_same) operator-(T const &, nothing) { return nothing(); } template TYPE_DISABLE_IF(nothing, std::is_same) operator*(T const &, nothing) { return nothing(); } template TYPE_DISABLE_IF(nothing, std::is_same) operator/(T const &, nothing) { return nothing(); } } }