mirror of
https://github.com/triqs/dft_tools
synced 2024-10-31 19:23:45 +01:00
A few parts of the lib only in C++14 mode
- multivariable gf - some part of tuple tools. - modified tests
This commit is contained in:
parent
f8aef6a290
commit
672834fd68
@ -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)
|
||||
|
@ -1,3 +1,3 @@
|
||||
link_libraries (triqs)
|
||||
all_tests()
|
||||
#add_subdirectory(multivar)
|
||||
add_subdirectory(multivar)
|
||||
|
5
test/triqs/gfs/multivar/CMakeLists.txt
Normal file
5
test/triqs/gfs/multivar/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
link_libraries (triqs)
|
||||
|
||||
if (USE_CPP14)
|
||||
all_tests()
|
||||
endif()
|
@ -1,2 +1,3 @@
|
||||
if (USE_CPP14)
|
||||
all_tests()
|
||||
|
||||
endif()
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
}
|
||||
|
@ -29,8 +29,12 @@
|
||||
#include <triqs/gfs/retime.hpp>
|
||||
#include <triqs/gfs/refreq.hpp>
|
||||
#include <triqs/gfs/legendre.hpp>
|
||||
|
||||
// multivariable gf in C++14 only
|
||||
#ifndef TRIQS_C11
|
||||
#include <triqs/gfs/product.hpp>
|
||||
#include <triqs/gfs/curry.hpp>
|
||||
#endif
|
||||
|
||||
#include <triqs/gfs/local/fourier_matsubara.hpp>
|
||||
#include <triqs/gfs/local/fourier_real.hpp>
|
||||
|
@ -88,11 +88,6 @@ namespace gfs {
|
||||
// closest_point mechanism
|
||||
template <typename Variable, typename Target, typename Singularity, typename Opt> struct get_closest_point;
|
||||
|
||||
// singularity
|
||||
//template <typename Variable, typename Target, typename Opt> struct singularity {
|
||||
// using type = nothing;
|
||||
//};
|
||||
|
||||
// symmetry
|
||||
template <typename Variable, typename Target, typename Singularity, typename Opt> struct symmetry {
|
||||
using type = nothing;
|
||||
@ -426,6 +421,7 @@ namespace gfs {
|
||||
}
|
||||
}
|
||||
|
||||
//#ifndef TRIQS_CPP11
|
||||
template <typename RHS, typename Variable, typename Target, typename Singularity, typename Opt, bool IsView>
|
||||
void triqs_clef_auto_assign_impl(gf_impl<Variable, Target, Singularity, Opt, IsView, false> &g, RHS const &rhs,
|
||||
std::integral_constant<bool, true>) {
|
||||
@ -434,6 +430,7 @@ namespace gfs {
|
||||
//(*this)[w] = triqs::tuple::apply(rhs, w.components_tuple());
|
||||
}
|
||||
}
|
||||
//#endif
|
||||
|
||||
// -------------------------The regular class of GF --------------------------------------------------------
|
||||
|
||||
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
#include "./mesh_tools.hpp"
|
||||
#include "../domains/product.hpp"
|
||||
#include <triqs/utility/tuple_tools.hpp>
|
||||
#include <triqs/utility/mini_vector.hpp>
|
||||
#include <triqs/utility/c14.hpp>
|
||||
namespace triqs {
|
||||
namespace gfs {
|
||||
|
||||
/** Cartesian product of meshes
|
||||
*/
|
||||
template <typename... Meshes> struct mesh_product : tag::composite {
|
||||
using domain_t = domain_product<typename Meshes::domain_t...>;
|
||||
using index_t = std::c14::tuple<typename Meshes::index_t...>;
|
||||
using m_tuple_t = std::tuple<Meshes...>;
|
||||
using m_pt_tuple_t = std::tuple<typename Meshes::mesh_point_t...>;
|
||||
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 <typename M> 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 <typename P, typename M, typename I> 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 <typename I, typename M> 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 <typename P, typename M> 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 <typename M, typename V> V *operator()(M const &m, V *v) {
|
||||
*v = m.size();
|
||||
return ++v;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
utility::mini_vector<size_t, dim> shape() const {
|
||||
utility::mini_vector<size_t, dim> res;
|
||||
triqs::tuple::fold(_aux4(), m_tuple, &res[0]);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Same but a variadic list of mesh_point_t
|
||||
template <typename... MP> size_t mesh_pt_components_to_linear(MP const &... mp) const {
|
||||
static_assert(std::is_same<std::tuple<MP...>, m_pt_tuple_t>::value, "Call incorrect ");
|
||||
// static_assert(std::is_same< std::tuple<typename std::remove_cv<typename std::remove_reference<MP>::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> typename M::mesh_point_t operator()(M const &m, typename M::index_t const &i) const { return m[i]; }
|
||||
};
|
||||
struct F1 {
|
||||
template <typename M> 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 <typename P> 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 <typename M> 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<mesh_product>;
|
||||
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 <typename M> 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 <typename M> 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 <typename Archive> struct _aux_ser {
|
||||
Archive &ar;
|
||||
_aux_ser(Archive &ar_) : ar(ar_) {}
|
||||
template <typename M> 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 <class Archive> void serialize(Archive &ar, const unsigned int version) {
|
||||
triqs::tuple::fold(_aux_ser<Archive>(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 <int pos, typename P> auto get_index(P const &p) DECL_AND_RETURN(std::get<pos>(p.components_tuple()).index());
|
||||
|
||||
template <int pos, typename P>
|
||||
auto get_point(P const &p)
|
||||
DECL_AND_RETURN(std::get<pos>(p.mesh() -> components()).index_to_point(std::get<pos>(p.components_tuple()).index()));
|
||||
|
||||
template <int pos, typename P> auto get_component(P const &p) DECL_AND_RETURN(std::get<pos>(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 <typename... Meshes, typename T, ull_t OptionsFlags, ull_t To, int R, bool B, bool C>
|
||||
arrays::array_view<T, sizeof...(Meshes) + R - 1, OptionsFlags, To, true, C>
|
||||
reinterpret_linear_array(mesh_product<Meshes...> const &m, arrays::array_view<T, R, OptionsFlags, To, B, C> A) {
|
||||
return {{join(m.shape(), get_shape(A).front_pop())}, A.storage()};
|
||||
}
|
||||
}
|
||||
}
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
#include "./mesh_tools.hpp"
|
||||
#include "../domains/product.hpp"
|
||||
#include <triqs/utility/tuple_tools.hpp>
|
||||
#include <triqs/utility/mini_vector.hpp>
|
||||
#include <triqs/utility/c14.hpp>
|
||||
namespace triqs {
|
||||
namespace gfs {
|
||||
|
||||
/** Cartesian product of meshes */
|
||||
template <typename... Meshes> struct mesh_product : tag::composite {
|
||||
using domain_t = domain_product<typename Meshes::domain_t...>;
|
||||
using index_t = std::c14::tuple<typename Meshes::index_t...>;
|
||||
using m_tuple_t = std::tuple<Meshes...>;
|
||||
using m_pt_tuple_t = std::tuple<typename Meshes::mesh_point_t...>;
|
||||
using domain_pt_t = typename domain_t::point_t;
|
||||
using linear_index_t = std::tuple<typename Meshes::linear_index_t...>;
|
||||
|
||||
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_t, dim> size_of_components() const {
|
||||
utility::mini_vector<size_t, dim> 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 <typename... MP> size_t mesh_pt_components_to_linear(MP const &... mp) const {
|
||||
static_assert(std::is_same<std::tuple<MP...>, 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> 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<mesh_product>;
|
||||
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 <class Archive> 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 <int pos, typename P> decltype(auto) get_index(P const &p) {return std::get<pos>(p.components_tuple()).index();}
|
||||
|
||||
template <int pos, typename P> decltype(auto) get_point(P const &p) {
|
||||
return std::get<pos>(p.mesh()->components()).index_to_point(std::get<pos>(p.components_tuple()).index());
|
||||
}
|
||||
|
||||
template <int pos, typename P> decltype(auto) get_component(P const &p) { return std::get<pos>(p.components_tuple()); }
|
||||
|
||||
}
|
||||
}
|
@ -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 <triqs/utility/tuple_tools.hpp>
|
||||
#include <triqs/utility/mini_vector.hpp>
|
||||
#include <triqs/utility/c14.hpp>
|
||||
namespace triqs {
|
||||
namespace gfs {
|
||||
|
||||
/** Cartesian product of meshes */
|
||||
template <typename... Meshes> struct mesh_product : tag::composite {
|
||||
using domain_t = domain_product<typename Meshes::domain_t...>;
|
||||
using index_t = std::c14::tuple<typename Meshes::index_t...>;
|
||||
using m_tuple_t = std::tuple<Meshes...>;
|
||||
using m_pt_tuple_t = std::tuple<typename Meshes::mesh_point_t...>;
|
||||
using domain_pt_t = typename domain_t::point_t;
|
||||
using linear_index_t = std::tuple<typename Meshes::linear_index_t...>;
|
||||
|
||||
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_t, dim> size_of_components() const {
|
||||
utility::mini_vector<size_t, dim> 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 <typename... MP> size_t mesh_pt_components_to_linear(MP const &... mp) const {
|
||||
static_assert(std::is_same<std::tuple<MP...>, 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> 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<mesh_product>;
|
||||
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 <class Archive> 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 <int pos, typename P> decltype(auto) get_index(P const &p) {return std::get<pos>(p.components_tuple()).index();}
|
||||
|
||||
template <int pos, typename P> decltype(auto) get_point(P const &p) {
|
||||
return std::get<pos>(p.mesh()->components()).index_to_point(std::get<pos>(p.components_tuple()).index());
|
||||
}
|
||||
|
||||
template <int pos, typename P> decltype(auto) get_component(P const &p) { return std::get<pos>(p.components_tuple()); }
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -18,12 +18,13 @@
|
||||
* TRIQS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
******************************************************************************/
|
||||
#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
|
||||
|
||||
|
||||
|
@ -48,7 +48,6 @@ namespace mpi {
|
||||
return invoke_impl(std::integral_constant<bool, with_lazy>(), 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 <typename T1> 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 <typename T2> 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 <typename Tag> struct aux3 {
|
||||
mpi_lazy<Tag, T> laz;
|
||||
|
||||
template <typename T1, typename T2> void operator()(T1 &t, T2 &s) const {
|
||||
t = triqs::mpi::mpi_impl<T2>::invoke(Tag(), laz.c, laz.s);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tag> static T& complete_operation(T &target, mpi_lazy<Tag, T> laz) {
|
||||
auto l = aux3<Tag>{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<T>.
|
||||
|
@ -20,7 +20,6 @@
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
#include "./base.hpp"
|
||||
#include <triqs/mpi/generic.hpp>
|
||||
|
||||
namespace triqs {
|
||||
namespace mpi {
|
||||
|
27
triqs/operators/serialization.hpp
Normal file
27
triqs/operators/serialization.hpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
#include <triqs/operators/many_body_operator.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
#include <boost/serialization/map.hpp>
|
||||
#include <boost/serialization/variant.hpp>
|
||||
|
||||
|
@ -68,6 +68,7 @@ namespace std {
|
||||
|
||||
namespace triqs { namespace tuple {
|
||||
|
||||
/*
|
||||
/// Repeat an element
|
||||
template<typename T, int R> struct make_tuple_repeat_impl;
|
||||
|
||||
@ -86,6 +87,7 @@ namespace triqs { namespace tuple {
|
||||
};
|
||||
|
||||
template <int R, typename T> auto make_tuple_repeat(T &&x) { return make_tuple_repeat_impl<T, R>::invoke(std::forward<T>(x)); }
|
||||
*/
|
||||
|
||||
/// _get_seq<T>() : from a tuple T, return the index sequence of the tuple length
|
||||
template <typename T> std14::make_index_sequence<std::tuple_size<std14::decay_t<T>>::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>(f), std::forward<T0>(t0), std::forward<T1>(t1), std::forward<T2>(t2), _get_seq<T0>()));
|
||||
|
||||
#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 <int pos, typename F, typename T, typename R> decltype(auto) fold_impl(_int<pos>, F &&f, T &&t, R &&r) {
|
||||
return fold_impl(_int<pos - 1>(), std::forward<F>(f), std::forward<T>(t),
|
||||
f(std::get<_get_seq_len<T>() - 1 - pos>(t), std::forward<R>(r)));
|
||||
@ -302,26 +307,6 @@ namespace triqs { namespace tuple {
|
||||
template <typename F, typename T, typename R> decltype(auto) fold(F &&f, T &&t, R &&r) {
|
||||
return fold_impl(_int<_get_seq_len<T>() - 1>(), std::forward<F>(f), std::forward<T>(t), std::forward<R>(r));
|
||||
}
|
||||
#else
|
||||
// old implementation, not modified for C++11
|
||||
|
||||
template <int N, int pos, typename T> struct fold_impl {
|
||||
template <typename F, typename R>
|
||||
auto operator()(F &&f, T &&t,
|
||||
R &&r)DECL_AND_RETURN(fold_impl<N, pos - 1, T>()(std::forward<F>(f), std::forward<T>(t),
|
||||
f(std::get<N - 1 - pos>(t), std::forward<R>(r))));
|
||||
};
|
||||
|
||||
template <int N, typename T> struct fold_impl<N, -1, T> {
|
||||
template <typename F, typename R> R operator()(F &&f, T &&t, R &&r) { return std::forward<R>(r); }
|
||||
};
|
||||
|
||||
template <typename F, typename T, typename R>
|
||||
auto fold(F &&f, T &&t, R &&r)
|
||||
DECL_AND_RETURN(fold_impl<std::tuple_size<std::c14::decay_t<T>>::value, std::tuple_size<std::c14::decay_t<T>>::value - 1,
|
||||
T>()(std::forward<F>(f), std::forward<T>(t), std::forward<R>(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 <int pos, typename F, typename T0, typename T1, typename R>
|
||||
decltype(auto) fold_impl(_int<pos>, F &&f, T0 &&t0, T1 &&t1, R &&r) {
|
||||
constexpr int n = _get_seq_len<T0>() - 1 - pos;
|
||||
@ -346,24 +330,6 @@ namespace triqs { namespace tuple {
|
||||
return fold_impl(_int<_get_seq_len<T0>() - 1>(), std::forward<F>(f), std::forward<T0>(t0), std::forward<T1>(t1),
|
||||
std::forward<R>(r));
|
||||
}
|
||||
#else
|
||||
// old implementation, not modified for C++11
|
||||
|
||||
template <int pos, typename T1, typename T2> struct fold_on_zip_impl {
|
||||
template <typename F, typename R>
|
||||
auto operator()(F &&f, T1 const &t1, T2 const &t2, R &&r)DECL_AND_RETURN(fold_on_zip_impl<pos - 1, T1, T2>()(
|
||||
std::forward<F>(f), t1, t2, f(std::get<pos>(t1), std::get<pos>(t2), std::forward<R>(r))));
|
||||
};
|
||||
|
||||
template <typename T1, typename T2> struct fold_on_zip_impl<-1, T1, T2> {
|
||||
template <typename F, typename R> R operator()(F &&f, T1 const &t1, T2 const &t2, R &&r) { return std::forward<R>(r); }
|
||||
};
|
||||
|
||||
template <typename F, typename T1, typename T2, typename R>
|
||||
auto fold(F &&f, T1 const &t1, T2 const &t2, R &&r)
|
||||
DECL_AND_RETURN(fold_on_zip_impl<std::tuple_size<T1>::value - 1, T1, T2>()(std::forward<F>(f), t1, t2, std::forward<R>(r)));
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* replace<int ... I>(t,r)
|
||||
@ -527,4 +493,4 @@ auto get(c14::tuple<Args...> const &t) DECL_AND_RETURN(std::get<i>(static_cast<s
|
||||
|
||||
template <typename... Args> class tuple_size<c14::tuple<Args...>> : public tuple_size<std::tuple<Args...>> {};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user