diff --git a/CMakeLists.txt b/CMakeLists.txt index 2469fe96..3208e16b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -417,6 +417,10 @@ endif() #------------------------ if (Build_Documentation) + if (NOT USE_CPP14) + message(FATAL_ERROR " The documentation can only be compiled in C++14 mode") + endif() + message( STATUS "-------- Prepare documentation -------------") add_subdirectory (${TRIQS_SOURCE_DIR}/doc ) #add_dependencies(docs_sphinx py_sources) diff --git a/test/triqs/gfs/CMakeLists.txt b/test/triqs/gfs/CMakeLists.txt index 82067bf6..4423d27c 100644 --- a/test/triqs/gfs/CMakeLists.txt +++ b/test/triqs/gfs/CMakeLists.txt @@ -1,3 +1,3 @@ link_libraries (triqs) all_tests() -#add_subdirectory(multivar) +add_subdirectory(multivar) diff --git a/test/triqs/gfs/multivar/CMakeLists.txt b/test/triqs/gfs/multivar/CMakeLists.txt new file mode 100644 index 00000000..0f046f98 --- /dev/null +++ b/test/triqs/gfs/multivar/CMakeLists.txt @@ -0,0 +1,5 @@ +link_libraries (triqs) + +if (USE_CPP14) +all_tests() +endif() diff --git a/test/triqs/gfs/curry1.cpp b/test/triqs/gfs/multivar/curry1.cpp similarity index 100% rename from test/triqs/gfs/curry1.cpp rename to test/triqs/gfs/multivar/curry1.cpp diff --git a/test/triqs/gfs/curry_and_fourier.cpp b/test/triqs/gfs/multivar/curry_and_fourier.cpp similarity index 100% rename from test/triqs/gfs/curry_and_fourier.cpp rename to test/triqs/gfs/multivar/curry_and_fourier.cpp diff --git a/test/triqs/gfs/g_k_om.cpp b/test/triqs/gfs/multivar/g_k_om.cpp similarity index 100% rename from test/triqs/gfs/g_k_om.cpp rename to test/triqs/gfs/multivar/g_k_om.cpp diff --git a/test/triqs/gfs/g_k_om2.cpp b/test/triqs/gfs/multivar/g_k_om2.cpp similarity index 100% rename from test/triqs/gfs/g_k_om2.cpp rename to test/triqs/gfs/multivar/g_k_om2.cpp diff --git a/test/triqs/gfs/g_k_tail.cpp b/test/triqs/gfs/multivar/g_k_tail.cpp similarity index 100% rename from test/triqs/gfs/g_k_tail.cpp rename to test/triqs/gfs/multivar/g_k_tail.cpp diff --git a/test/triqs/gfs/g_nu_nup.cpp b/test/triqs/gfs/multivar/g_nu_nup.cpp similarity index 100% rename from test/triqs/gfs/g_nu_nup.cpp rename to test/triqs/gfs/multivar/g_nu_nup.cpp diff --git a/test/triqs/gfs/g_om_nu_nup.cpp b/test/triqs/gfs/multivar/g_om_nu_nup.cpp similarity index 100% rename from test/triqs/gfs/g_om_nu_nup.cpp rename to test/triqs/gfs/multivar/g_om_nu_nup.cpp diff --git a/test/triqs/gfs/gf_2times.cpp b/test/triqs/gfs/multivar/gf_2times.cpp similarity index 100% rename from test/triqs/gfs/gf_2times.cpp rename to test/triqs/gfs/multivar/gf_2times.cpp diff --git a/test/triqs/gfs/vertex.cpp b/test/triqs/gfs/multivar/vertex.cpp similarity index 100% rename from test/triqs/gfs/vertex.cpp rename to test/triqs/gfs/multivar/vertex.cpp diff --git a/test/triqs/mpi/CMakeLists.txt b/test/triqs/mpi/CMakeLists.txt index 917a5baf..22d7bd91 100644 --- a/test/triqs/mpi/CMakeLists.txt +++ b/test/triqs/mpi/CMakeLists.txt @@ -1,2 +1,3 @@ -all_tests() - +if (USE_CPP14) + all_tests() +endif() diff --git a/test/triqs/mpi/mpi_generic.cpp b/test/triqs/mpi/mpi_generic.cpp index 1201f7d5..d3a93247 100644 --- a/test/triqs/mpi/mpi_generic.cpp +++ b/test/triqs/mpi/mpi_generic.cpp @@ -61,6 +61,7 @@ auto view_as_tuple(my_object &x) RETURN(std::tie(x.a, x.b)); int main(int argc, char *argv[]) { +#ifdef TRIQS_C11 mpi::environment env(argc, argv); mpi::communicator world; @@ -93,5 +94,6 @@ int main(int argc, char *argv[]) { out << " allgather b = " << ob.b << std::endl; out << "----------------------------"<< std::endl; +#endif } diff --git a/test/triqs/utility/tuple_tools.cpp b/test/triqs/utility/tuple_tools.cpp index 41408e07..9c92e7a1 100644 --- a/test/triqs/utility/tuple_tools.cpp +++ b/test/triqs/utility/tuple_tools.cpp @@ -68,6 +68,7 @@ int main(int argc, char **argv) { if ( std::abs((res - fun()(1,2.3,4.3,8))) > 1.e-13) throw std::runtime_error(" "); } +#ifndef TRIQS_C11 { auto r = triqs::tuple::map_on_zip_v2([](double x, double y) { return x + y; }, t1, t2); std::cerr << " [f(a,b) for (a,b) in zip(t1,t2)] =" << r << std::endl; @@ -189,7 +190,7 @@ int main(int argc, char **argv) { std::cout << "replace 1,3,5"<< t << triqs::tuple::replace<1,3,5>(t,s)<< std::endl; } - +#endif } diff --git a/triqs/gfs.hpp b/triqs/gfs.hpp index 1d1ebdb6..9747b3c6 100644 --- a/triqs/gfs.hpp +++ b/triqs/gfs.hpp @@ -29,8 +29,12 @@ #include #include #include + +// multivariable gf in C++14 only +#ifndef TRIQS_C11 #include #include +#endif #include #include diff --git a/triqs/gfs/gf.hpp b/triqs/gfs/gf.hpp index e9004548..7dcd0d04 100644 --- a/triqs/gfs/gf.hpp +++ b/triqs/gfs/gf.hpp @@ -88,11 +88,6 @@ namespace gfs { // closest_point mechanism template struct get_closest_point; - // singularity - //template struct singularity { - // using type = nothing; - //}; - // symmetry template struct symmetry { using type = nothing; @@ -426,6 +421,7 @@ namespace gfs { } } +//#ifndef TRIQS_CPP11 template void triqs_clef_auto_assign_impl(gf_impl &g, RHS const &rhs, std::integral_constant) { @@ -434,6 +430,7 @@ namespace gfs { //(*this)[w] = triqs::tuple::apply(rhs, w.components_tuple()); } } +//#endif // -------------------------The regular class of GF -------------------------------------------------------- diff --git a/triqs/gfs/meshes/product.c11.hpp b/triqs/gfs/meshes/product.c11.hpp deleted file mode 100644 index 519dd8fe..00000000 --- a/triqs/gfs/meshes/product.c11.hpp +++ /dev/null @@ -1,269 +0,0 @@ -/******************************************************************************* - * - * 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 "./mesh_tools.hpp" -#include "../domains/product.hpp" -#include -#include -#include -namespace triqs { -namespace gfs { - - /** Cartesian product of meshes - */ - template struct mesh_product : tag::composite { - using domain_t = domain_product; - using index_t = std::c14::tuple; - using m_tuple_t = std::tuple; - using m_pt_tuple_t = std::tuple; - using domain_pt_t = typename domain_t::point_t; - - static constexpr int dim = sizeof...(Meshes); - - mesh_product() {} - mesh_product(Meshes const &... meshes) : m_tuple(meshes...), _dom(meshes.domain()...) {} - - domain_t const &domain() const { return _dom; } - m_tuple_t const &components() const { return m_tuple; } - m_tuple_t &components() { return m_tuple; } - - private: - struct _aux0 { - template size_t operator()(M const &m, size_t R) { return R * m.size(); } - }; - - public: - /// size of the mesh is the product of size - size_t size() const { return triqs::tuple::fold(_aux0(), m_tuple, 1); } - - private: - struct _aux1 { - template void operator()(P &p, M const &m, I const &i) { p = m.index_to_point(i); } - }; - - public: - /// Conversions point <-> index <-> linear_index - typename domain_t::point_t index_to_point(index_t const &ind) const { - domain_pt_t res; - triqs::tuple::map_on_zip(_aux1(), res, m_tuple, ind); - return res; - } - - private: - struct _aux2 { - template size_t operator()(M const &m, I const &i, size_t R) { - return m.index_to_linear(i) + R * m.size(); - } - }; - - public: - /// Flattening index to linear : index[0] + component[0].size * (index[1] + component[1].size* (index[2] + ....)) - size_t index_to_linear(index_t const &ii) const { - return triqs::tuple::fold(_aux2(), reverse(m_tuple), reverse(ii), size_t(0)); - } - - private: - struct _aux3 { - template size_t operator()(M const &m, P const &p, size_t R) { - return p.linear_index() + R * m.size(); - } - }; - - public: - /// Flattening index to linear : index[0] + component[0].size * (index[1] + component[1].size* (index[2] + ....)) - size_t mp_to_linear(m_pt_tuple_t const &mp) const { - return triqs::tuple::fold(_aux3(), reverse(m_tuple), reverse(mp), size_t(0)); - } - - // - private: - struct _aux4 { - template V *operator()(M const &m, V *v) { - *v = m.size(); - return ++v; - } - }; - - public: - utility::mini_vector shape() const { - utility::mini_vector res; - triqs::tuple::fold(_aux4(), m_tuple, &res[0]); - return res; - } - - // Same but a variadic list of mesh_point_t - template size_t mesh_pt_components_to_linear(MP const &... mp) const { - static_assert(std::is_same, m_pt_tuple_t>::value, "Call incorrect "); - // static_assert(std::is_same< std::tuple::type>::type...>, - // m_pt_tuple_t>::value, "Call incorrect "); - return mp_to_linear(std::forward_as_tuple(mp...)); - } // speed test ? or make a variadic fold... - - /// The wrapper for the mesh point - class mesh_point_t : tag::mesh_point { - const mesh_product *m; - m_pt_tuple_t _c; - bool _atend; - struct F2 { - template typename M::mesh_point_t operator()(M const &m, typename M::index_t const &i) const { return m[i]; } - }; - struct F1 { - template typename M::mesh_point_t operator()(M const &m) const { return {m}; } - }; - - public: - mesh_point_t() = default; - mesh_point_t(mesh_product const &m_, index_t index_) - : m(&m_), _c(triqs::tuple::map_on_zip(F2(), m_.m_tuple, index_)), _atend(false) {} - mesh_point_t(mesh_product const &m_) : m(&m_), _c(triqs::tuple::map(F1(), m_.m_tuple)), _atend(false) {} - m_pt_tuple_t const &components_tuple() const { return _c; } - size_t linear_index() const { return m->mp_to_linear(_c); } - const mesh_product *mesh() const { return m; } - - using cast_t = domain_pt_t; - operator cast_t() const { return m->index_to_point(index); } - - // index[0] +=1; if index[0]==m.component[0].size() { index[0]=0; index[1] +=1; if ....} and so on until dim - private: - struct _aux1 { - template bool operator()(P &p, bool done) { - if (done) return true; - p.advance(); - if (!p.at_end()) return true; - p.reset(); - return false; - } - }; - - public: - void advance() { _atend = ! (triqs::tuple::fold(_aux1(), _c, false)) ; } - - // index_t index() const { return _index;} // not implemented yet - bool at_end() const { return _atend; } - - private: - struct _aux { - template size_t operator()(M &m, size_t) { - m.reset(); - return 0; - } - }; - - public: - void reset() { - _atend = false; - triqs::tuple::fold(_aux(), _c, 0); - } - }; // end mesh_point_t - - /// Accessing a point of the mesh - mesh_point_t operator[](index_t i) const { return mesh_point_t(*this, i); } - mesh_point_t operator()(typename Meshes::index_t... i) const { return (*this)[std::make_tuple(i...)]; } - - /// Iterating on all the points... - using const_iterator = mesh_pt_generator; - const_iterator begin() const { return const_iterator(this); } - const_iterator end() const { return const_iterator(this, true); } - const_iterator cbegin() const { return const_iterator(this); } - const_iterator cend() const { return const_iterator(this, true); } - - /// Mesh comparison - friend bool operator==(mesh_product const &M1, mesh_product const &M2) { return M1.m_tuple == M2.m_tuple; } - - private: - - /// Write into HDF5 - struct _auxh5w { - h5::group gr; - _auxh5w(h5::group gr_) : gr(gr_) {} // icc has yet another bug on new initialization form with {}... - template size_t operator()(M const &m, size_t N) { - std::stringstream fs; - fs << "MeshComponent" << N; - h5_write(gr, fs.str(), m); - return N + 1; - } - }; - - friend void h5_write(h5::group fg, std::string subgroup_name, mesh_product const &m) { - h5::group gr = fg.create_group(subgroup_name); - // h5_write(gr,"domain",m.domain()); - triqs::tuple::fold(_auxh5w(gr), m.components(), size_t(0)); - } - - /// Read from HDF5 - struct _auxh5r { - h5::group gr; - _auxh5r(h5::group gr_) : gr(gr_) {} - template size_t operator()(M &m, size_t N) { - std::stringstream fs; - fs << "MeshComponent" << N; - h5_read(gr, fs.str(), m); - return N + 1; - } - }; - friend void h5_read(h5::group fg, std::string subgroup_name, mesh_product &m) { - h5::group gr = fg.open_group(subgroup_name); - // h5_read(gr,"domain",m._dom); - triqs::tuple::fold(_auxh5r(gr), m.components(), size_t(0)); - } - - // BOOST Serialization - friend class boost::serialization::access; - template struct _aux_ser { - Archive &ar; - _aux_ser(Archive &ar_) : ar(ar_) {} - template size_t operator()(M &m, size_t N) { - std::stringstream fs; - fs << "MeshComponent" << N; - ar &TRIQS_MAKE_NVP(fs.str().c_str(), m); - return N + 1; - } - }; - template void serialize(Archive &ar, const unsigned int version) { - triqs::tuple::fold(_aux_ser(ar), m_tuple, size_t(0)); - } - - friend std::ostream &operator<<(std::ostream &sout, mesh_product const &m) { return sout << "Product Mesh"; } - - private: - m_tuple_t m_tuple; - domain_t _dom; - }; - - template auto get_index(P const &p) DECL_AND_RETURN(std::get(p.components_tuple()).index()); - - template - auto get_point(P const &p) - DECL_AND_RETURN(std::get(p.mesh() -> components()).index_to_point(std::get(p.components_tuple()).index())); - - template auto get_component(P const &p) DECL_AND_RETURN(std::get(p.components_tuple())); - - // Given a composite mesh m , and a linear array of storage A - // reinterpret_linear_array(m,A) returns a d-dimensionnal view of the array - // with indices egal to the indices of the components of the mesh. - // Very useful for slicing, currying functions. - template - arrays::array_view - reinterpret_linear_array(mesh_product const &m, arrays::array_view A) { - return {{join(m.shape(), get_shape(A).front_pop())}, A.storage()}; - } -} -} diff --git a/triqs/gfs/meshes/product.c14.hpp b/triqs/gfs/meshes/product.c14.hpp deleted file mode 100644 index dd0f3e28..00000000 --- a/triqs/gfs/meshes/product.c14.hpp +++ /dev/null @@ -1,197 +0,0 @@ -/******************************************************************************* - * - * TRIQS: a Toolbox for Research in Interacting Quantum Systems - * - * Copyright (C) 2012-2014 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 "./mesh_tools.hpp" -#include "../domains/product.hpp" -#include -#include -#include -namespace triqs { -namespace gfs { - - /** Cartesian product of meshes */ - template struct mesh_product : tag::composite { - using domain_t = domain_product; - using index_t = std::c14::tuple; - using m_tuple_t = std::tuple; - using m_pt_tuple_t = std::tuple; - using domain_pt_t = typename domain_t::point_t; - using linear_index_t = std::tuple; - - static constexpr int dim = sizeof...(Meshes); - - mesh_product() {} - mesh_product(Meshes const &... meshes) : m_tuple(meshes...), _dom(meshes.domain()...) {} - mesh_product(mesh_product const &) = default; - - domain_t const &domain() const { return _dom; } - m_tuple_t const &components() const { return m_tuple; } - m_tuple_t &components() { return m_tuple; } - - /// size of the mesh is the product of size - size_t size() const { - return triqs::tuple::fold([](auto const &m, size_t R) { return R * m.size(); }, m_tuple, 1); - } -/* - /// Scatter the first mesh over the communicator c - friend mesh_product mpi_scatter(mesh_product const &m, mpi::communicator c, int root) { - auto r = m; // same domain, but mesh with a window. Ok ? - std::get<0>(r.m_tuple) = mpi_scatter(std::get<0>(r.m_tuple), c, root); - return r; - } - - /// Opposite of scatter : rebuild the original mesh, without a window - friend mesh_product mpi_gather(mesh_product m, mpi::communicator c, int root) { - auto r = m; // same domain, but mesh with a window. Ok ? - std::get<0>(r.m_tuple) = mpi_gather(std::get<0>(r.m_tuple), c, root); - return r; - */ - - /// The sizes of all mesh components - utility::mini_vector size_of_components() const { - utility::mini_vector res; - auto l = [&res](int i, auto const &m) mutable { res[i] = m.size(); }; - triqs::tuple::for_each_enumerate(m_tuple, l); - return res; - } - - /// Conversions point <-> index <-> linear_index - typename domain_t::point_t index_to_point(index_t const &ind) const { - domain_pt_t res; - auto l = [](auto &p, auto const &m, auto const &i) { p = m.index_to_point(i); }; - triqs::tuple::map_on_zip(l, res, m_tuple, ind); - return res; - } - - /// The linear_index is the tuple of the linear_index of the components - linear_index_t index_to_linear(index_t const &ind) const { - auto l = [](auto const &m, auto const &i) { return m.index_to_linear(i); }; - return triqs::tuple::map_on_zip(l, m_tuple, ind); - } - - /// - linear_index_t mp_to_linear(m_pt_tuple_t const &mp) const { - auto l = [](auto const &p) { return p.linear_index(); }; - return triqs::tuple::map(l, mp); - } - - // Same but a variadic list of mesh_point_t - template size_t mesh_pt_components_to_linear(MP const &... mp) const { - static_assert(std::is_same, m_pt_tuple_t>::value, "Call incorrect "); - return mp_to_linear(std::forward_as_tuple(mp...)); - } - - /// The wrapper for the mesh point - class mesh_point_t : tag::mesh_point { - const mesh_product *m; - m_pt_tuple_t _c; - bool _atend; - struct F1 { - template typename M::mesh_point_t operator()(M const &m) const { return {m}; } - }; - - public: - mesh_point_t() = default; - mesh_point_t(mesh_product const &m_, index_t index_) - : m(&m_) - , _c(triqs::tuple::map_on_zip([](auto const & m, auto const & i) { return m[i]; }, m_.m_tuple, index_)) - , _atend(false) {} - mesh_point_t(mesh_product const &m_) : m(&m_), _c(triqs::tuple::map(F1(), m_.m_tuple)), _atend(false) {} - m_pt_tuple_t const &components_tuple() const { return _c; } - linear_index_t linear_index() const { return m->mp_to_linear(_c); } - const mesh_product *mesh() const { return m; } - - using cast_t = domain_pt_t; - operator cast_t() const { return m->index_to_point(index); } - - // index[0] +=1; if index[0]==m.component[0].size() { index[0]=0; index[1] +=1; if ....} and so on until dim - void advance() { - auto l = [](auto &p, bool done) { - if (done) return true; - p.advance(); - if (!p.at_end()) return true; - p.reset(); - return false; - }; - _atend = !(triqs::tuple::fold(l, _c, false)); - } - - // index_t index() const { return _index;} // not implemented yet - bool at_end() const { return _atend; } - - void reset() { - _atend = false; - triqs::tuple::for_each(_c, [](auto &m) { m.reset(); }); - } - }; // end mesh_point_t - - /// Accessing a point of the mesh - mesh_point_t operator[](index_t i) const { return mesh_point_t(*this, i); } - mesh_point_t operator()(typename Meshes::index_t... i) const { return (*this)[std::make_tuple(i...)]; } - - /// Iterating on all the points... - using const_iterator = mesh_pt_generator; - const_iterator begin() const { return const_iterator(this); } - const_iterator end() const { return const_iterator(this, true); } - const_iterator cbegin() const { return const_iterator(this); } - const_iterator cend() const { return const_iterator(this, true); } - - /// Mesh comparison - friend bool operator==(mesh_product const &M1, mesh_product const &M2) { return M1.m_tuple == M2.m_tuple; } - - /// Write into HDF5 - friend void h5_write(h5::group fg, std::string subgroup_name, mesh_product const &m) { - h5::group gr = fg.create_group(subgroup_name); - auto l = [gr](int N, auto const &m) { h5_write(gr, "MeshComponent" + std::to_string(N), m); }; - triqs::tuple::for_each_enumerate(m.components(), l); - } - - /// Read from HDF5 - friend void h5_read(h5::group fg, std::string subgroup_name, mesh_product &m) { - h5::group gr = fg.open_group(subgroup_name); - auto l = [gr](int N, auto &m) { h5_read(gr, "MeshComponent" + std::to_string(N), m); }; - triqs::tuple::for_each_enumerate(m.components(), l); - } - - /// BOOST Serialization - friend class boost::serialization::access; - template void serialize(Archive &ar, const unsigned int version) { - auto l = [&ar](int N, auto &m) { ar &TRIQS_MAKE_NVP("MeshComponent" + std::to_string(N), m); }; - triqs::tuple::for_each_enumerate(m_tuple, l); - } - - friend std::ostream &operator<<(std::ostream &sout, mesh_product const &m) { return sout << "Product Mesh"; } - - private: - m_tuple_t m_tuple; - domain_t _dom; - }; - - template decltype(auto) get_index(P const &p) {return std::get(p.components_tuple()).index();} - - template decltype(auto) get_point(P const &p) { - return std::get(p.mesh()->components()).index_to_point(std::get(p.components_tuple()).index()); - } - - template decltype(auto) get_component(P const &p) { return std::get(p.components_tuple()); } - -} -} diff --git a/triqs/gfs/meshes/product.hpp b/triqs/gfs/meshes/product.hpp index 6af90566..dd0f3e28 100644 --- a/triqs/gfs/meshes/product.hpp +++ b/triqs/gfs/meshes/product.hpp @@ -2,7 +2,7 @@ * * TRIQS: a Toolbox for Research in Interacting Quantum Systems * - * Copyright (C) 2012-2013 by O. Parcollet + * Copyright (C) 2012-2014 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 @@ -19,11 +19,179 @@ * ******************************************************************************/ #pragma once -#if defined(__cpp_generic_lambdas) && defined (__cpp_decltype_auto) && defined(__cpp_return_type_deduction) -// simplest code, in c++14 -#include "./product.c14.hpp" -#else -// workaround for C++11 -#include "./product.c11.hpp" -#endif +#include "./mesh_tools.hpp" +#include "../domains/product.hpp" +#include +#include +#include +namespace triqs { +namespace gfs { + /** Cartesian product of meshes */ + template struct mesh_product : tag::composite { + using domain_t = domain_product; + using index_t = std::c14::tuple; + using m_tuple_t = std::tuple; + using m_pt_tuple_t = std::tuple; + using domain_pt_t = typename domain_t::point_t; + using linear_index_t = std::tuple; + + static constexpr int dim = sizeof...(Meshes); + + mesh_product() {} + mesh_product(Meshes const &... meshes) : m_tuple(meshes...), _dom(meshes.domain()...) {} + mesh_product(mesh_product const &) = default; + + domain_t const &domain() const { return _dom; } + m_tuple_t const &components() const { return m_tuple; } + m_tuple_t &components() { return m_tuple; } + + /// size of the mesh is the product of size + size_t size() const { + return triqs::tuple::fold([](auto const &m, size_t R) { return R * m.size(); }, m_tuple, 1); + } +/* + /// Scatter the first mesh over the communicator c + friend mesh_product mpi_scatter(mesh_product const &m, mpi::communicator c, int root) { + auto r = m; // same domain, but mesh with a window. Ok ? + std::get<0>(r.m_tuple) = mpi_scatter(std::get<0>(r.m_tuple), c, root); + return r; + } + + /// Opposite of scatter : rebuild the original mesh, without a window + friend mesh_product mpi_gather(mesh_product m, mpi::communicator c, int root) { + auto r = m; // same domain, but mesh with a window. Ok ? + std::get<0>(r.m_tuple) = mpi_gather(std::get<0>(r.m_tuple), c, root); + return r; + */ + + /// The sizes of all mesh components + utility::mini_vector size_of_components() const { + utility::mini_vector res; + auto l = [&res](int i, auto const &m) mutable { res[i] = m.size(); }; + triqs::tuple::for_each_enumerate(m_tuple, l); + return res; + } + + /// Conversions point <-> index <-> linear_index + typename domain_t::point_t index_to_point(index_t const &ind) const { + domain_pt_t res; + auto l = [](auto &p, auto const &m, auto const &i) { p = m.index_to_point(i); }; + triqs::tuple::map_on_zip(l, res, m_tuple, ind); + return res; + } + + /// The linear_index is the tuple of the linear_index of the components + linear_index_t index_to_linear(index_t const &ind) const { + auto l = [](auto const &m, auto const &i) { return m.index_to_linear(i); }; + return triqs::tuple::map_on_zip(l, m_tuple, ind); + } + + /// + linear_index_t mp_to_linear(m_pt_tuple_t const &mp) const { + auto l = [](auto const &p) { return p.linear_index(); }; + return triqs::tuple::map(l, mp); + } + + // Same but a variadic list of mesh_point_t + template size_t mesh_pt_components_to_linear(MP const &... mp) const { + static_assert(std::is_same, m_pt_tuple_t>::value, "Call incorrect "); + return mp_to_linear(std::forward_as_tuple(mp...)); + } + + /// The wrapper for the mesh point + class mesh_point_t : tag::mesh_point { + const mesh_product *m; + m_pt_tuple_t _c; + bool _atend; + struct F1 { + template typename M::mesh_point_t operator()(M const &m) const { return {m}; } + }; + + public: + mesh_point_t() = default; + mesh_point_t(mesh_product const &m_, index_t index_) + : m(&m_) + , _c(triqs::tuple::map_on_zip([](auto const & m, auto const & i) { return m[i]; }, m_.m_tuple, index_)) + , _atend(false) {} + mesh_point_t(mesh_product const &m_) : m(&m_), _c(triqs::tuple::map(F1(), m_.m_tuple)), _atend(false) {} + m_pt_tuple_t const &components_tuple() const { return _c; } + linear_index_t linear_index() const { return m->mp_to_linear(_c); } + const mesh_product *mesh() const { return m; } + + using cast_t = domain_pt_t; + operator cast_t() const { return m->index_to_point(index); } + + // index[0] +=1; if index[0]==m.component[0].size() { index[0]=0; index[1] +=1; if ....} and so on until dim + void advance() { + auto l = [](auto &p, bool done) { + if (done) return true; + p.advance(); + if (!p.at_end()) return true; + p.reset(); + return false; + }; + _atend = !(triqs::tuple::fold(l, _c, false)); + } + + // index_t index() const { return _index;} // not implemented yet + bool at_end() const { return _atend; } + + void reset() { + _atend = false; + triqs::tuple::for_each(_c, [](auto &m) { m.reset(); }); + } + }; // end mesh_point_t + + /// Accessing a point of the mesh + mesh_point_t operator[](index_t i) const { return mesh_point_t(*this, i); } + mesh_point_t operator()(typename Meshes::index_t... i) const { return (*this)[std::make_tuple(i...)]; } + + /// Iterating on all the points... + using const_iterator = mesh_pt_generator; + const_iterator begin() const { return const_iterator(this); } + const_iterator end() const { return const_iterator(this, true); } + const_iterator cbegin() const { return const_iterator(this); } + const_iterator cend() const { return const_iterator(this, true); } + + /// Mesh comparison + friend bool operator==(mesh_product const &M1, mesh_product const &M2) { return M1.m_tuple == M2.m_tuple; } + + /// Write into HDF5 + friend void h5_write(h5::group fg, std::string subgroup_name, mesh_product const &m) { + h5::group gr = fg.create_group(subgroup_name); + auto l = [gr](int N, auto const &m) { h5_write(gr, "MeshComponent" + std::to_string(N), m); }; + triqs::tuple::for_each_enumerate(m.components(), l); + } + + /// Read from HDF5 + friend void h5_read(h5::group fg, std::string subgroup_name, mesh_product &m) { + h5::group gr = fg.open_group(subgroup_name); + auto l = [gr](int N, auto &m) { h5_read(gr, "MeshComponent" + std::to_string(N), m); }; + triqs::tuple::for_each_enumerate(m.components(), l); + } + + /// BOOST Serialization + friend class boost::serialization::access; + template void serialize(Archive &ar, const unsigned int version) { + auto l = [&ar](int N, auto &m) { ar &TRIQS_MAKE_NVP("MeshComponent" + std::to_string(N), m); }; + triqs::tuple::for_each_enumerate(m_tuple, l); + } + + friend std::ostream &operator<<(std::ostream &sout, mesh_product const &m) { return sout << "Product Mesh"; } + + private: + m_tuple_t m_tuple; + domain_t _dom; + }; + + template decltype(auto) get_index(P const &p) {return std::get(p.components_tuple()).index();} + + template decltype(auto) get_point(P const &p) { + return std::get(p.mesh()->components()).index_to_point(std::get(p.components_tuple()).index()); + } + + template decltype(auto) get_component(P const &p) { return std::get(p.components_tuple()); } + +} +} diff --git a/triqs/mpi.hpp b/triqs/mpi.hpp index 43625d92..1714224b 100644 --- a/triqs/mpi.hpp +++ b/triqs/mpi.hpp @@ -18,12 +18,13 @@ * TRIQS. If not, see . * ******************************************************************************/ -#ifndef TRIQS_MPI_H -#define TRIQS_MPI_H +#pragma once #include "./mpi/arrays.hpp" #include "./mpi/vector.hpp" -#include "./mpi/generic.hpp" +#ifndef TRIQS_C11 +#include "./mpi/generic.hpp" #endif + diff --git a/triqs/mpi/generic.hpp b/triqs/mpi/generic.hpp index c64764a6..c537018a 100644 --- a/triqs/mpi/generic.hpp +++ b/triqs/mpi/generic.hpp @@ -48,7 +48,6 @@ namespace mpi { return invoke_impl(std::integral_constant(), Tag(), c, a, root); } -#ifdef __cpp_generic_lambdas static void reduce_in_place(communicator c, T &a, int root) { tuple::for_each(view_as_tuple(a), [c, root](auto &x) { triqs::mpi::reduce_in_place(x, c, root); }); } @@ -62,45 +61,6 @@ namespace mpi { triqs::tuple::for_each_zip(l, view_as_tuple(target), view_as_tuple(laz.ref)); return target; } - -#else - - struct aux1 { - communicator c; - int root; - - template void operator()(T1 &x) const { triqs::mpi::reduce_in_place(c, x, root); } - }; - - static void reduce_in_place(communicator c, T &a, int root) { - tuple::for_each(aux1{c, root}, view_as_tuple(a)); - } - - struct aux2 { - communicator c; - int root; - - template void operator()(T2 &x) const { triqs::mpi::broadcast(c, x, root); } - }; - - static void broadcast(communicator c, T &a, int root) { - tuple::for_each(aux2{c, root}, view_as_tuple(a)); - } - - template struct aux3 { - mpi_lazy laz; - - template void operator()(T1 &t, T2 &s) const { - t = triqs::mpi::mpi_impl::invoke(Tag(), laz.c, laz.s); - } - }; - - template static T& complete_operation(T &target, mpi_lazy laz) { - auto l = aux3{laz}; - triqs::tuple::for_each_zip(l, view_as_tuple(target), view_as_tuple(laz.ref)); - return target; - } -#endif }; // If type T has a mpi_implementation nested struct, then it is mpi_impl. diff --git a/triqs/mpi/gf.hpp b/triqs/mpi/gf.hpp index f11a8c1e..a2c1d949 100644 --- a/triqs/mpi/gf.hpp +++ b/triqs/mpi/gf.hpp @@ -20,7 +20,6 @@ ******************************************************************************/ #pragma once #include "./base.hpp" -#include namespace triqs { namespace mpi { diff --git a/triqs/operators/serialization.hpp b/triqs/operators/serialization.hpp new file mode 100644 index 00000000..4930dc53 --- /dev/null +++ b/triqs/operators/serialization.hpp @@ -0,0 +1,27 @@ +/******************************************************************************* + * + * TRIQS: a Toolbox for Research in Interacting Quantum Systems + * + * Copyright (C) 2014 by I. Krivenko, O. Parcollet, M. Ferrero + * + * 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 +#include +#include + + diff --git a/triqs/utility/tuple_tools.hpp b/triqs/utility/tuple_tools.hpp index 9d20401f..ac9fe71f 100644 --- a/triqs/utility/tuple_tools.hpp +++ b/triqs/utility/tuple_tools.hpp @@ -68,6 +68,7 @@ namespace std { namespace triqs { namespace tuple { + /* /// Repeat an element template struct make_tuple_repeat_impl; @@ -86,6 +87,7 @@ namespace triqs { namespace tuple { }; template auto make_tuple_repeat(T &&x) { return make_tuple_repeat_impl::invoke(std::forward(x)); } +*/ /// _get_seq() : from a tuple T, return the index sequence of the tuple length template std14::make_index_sequence>::value> _get_seq() { @@ -286,13 +288,16 @@ namespace triqs { namespace tuple { auto map_on_zip(F &&f, T0 &&t0, T1 &&t1, T2 &&t2) RETURN(_map_impl(std::forward(f), std::forward(t0), std::forward(t1), std::forward(t2), _get_seq())); +#ifdef TRIQS_C11 +}} +#else + /** * fold(f, t1, r_init) * f : a callable object : f(x,r) -> r' * t a tuple * Returns : f(xN,f(x_N-1,...f(x0,r_init)) on the tuple */ -#ifndef TRIQS_C11 template decltype(auto) fold_impl(_int, F &&f, T &&t, R &&r) { return fold_impl(_int(), std::forward(f), std::forward(t), f(std::get<_get_seq_len() - 1 - pos>(t), std::forward(r))); @@ -302,26 +307,6 @@ namespace triqs { namespace tuple { template decltype(auto) fold(F &&f, T &&t, R &&r) { return fold_impl(_int<_get_seq_len() - 1>(), std::forward(f), std::forward(t), std::forward(r)); } -#else - // old implementation, not modified for C++11 - - template struct fold_impl { - template - auto operator()(F &&f, T &&t, - R &&r)DECL_AND_RETURN(fold_impl()(std::forward(f), std::forward(t), - f(std::get(t), std::forward(r)))); - }; - - template struct fold_impl { - template R operator()(F &&f, T &&t, R &&r) { return std::forward(r); } - }; - - template - auto fold(F &&f, T &&t, R &&r) - DECL_AND_RETURN(fold_impl>::value, std::tuple_size>::value - 1, - T>()(std::forward(f), std::forward(t), std::forward(r))); - -#endif /** * fold(f, r_init, t1, t2) @@ -330,7 +315,6 @@ namespace triqs { namespace tuple { * Returns : f(x0,y0,f(x1,y1,,f(....)) for t1 = (x0,x1 ...) and t2 = (y0,y1...). */ -#ifndef TRIQS_C11 template decltype(auto) fold_impl(_int, F &&f, T0 &&t0, T1 &&t1, R &&r) { constexpr int n = _get_seq_len() - 1 - pos; @@ -346,24 +330,6 @@ namespace triqs { namespace tuple { return fold_impl(_int<_get_seq_len() - 1>(), std::forward(f), std::forward(t0), std::forward(t1), std::forward(r)); } -#else -// old implementation, not modified for C++11 - - template struct fold_on_zip_impl { - template - auto operator()(F &&f, T1 const &t1, T2 const &t2, R &&r)DECL_AND_RETURN(fold_on_zip_impl()( - std::forward(f), t1, t2, f(std::get(t1), std::get(t2), std::forward(r)))); - }; - - template struct fold_on_zip_impl<-1, T1, T2> { - template R operator()(F &&f, T1 const &t1, T2 const &t2, R &&r) { return std::forward(r); } - }; - - template - auto fold(F &&f, T1 const &t1, T2 const &t2, R &&r) - DECL_AND_RETURN(fold_on_zip_impl::value - 1, T1, T2>()(std::forward(f), t1, t2, std::forward(r))); - -#endif /** * replace(t,r) @@ -527,4 +493,4 @@ auto get(c14::tuple const &t) DECL_AND_RETURN(std::get(static_cast class tuple_size> : public tuple_size> {}; } - +#endif