7 #ifndef ALPSCORE_GF_TAIL_BASE_H 8 #define ALPSCORE_GF_TAIL_BASE_H 18 template<
typename HEADGF,
typename TAILGF>
22 template <
typename TAILT>
24 int& min_order,
int& max_order,
25 std::vector<TAILT>& tails,
26 const TAILT& tail_init,
33 if (min_order==TAIL_NOT_SET)
return;
34 if (comm.
rank()!=root) {
35 tails.resize(max_order+1, tail_init);
37 for (
int i=min_order; i<=max_order; ++i) {
38 tails[i].broadcast(comm,root);
43 template<
typename HEADGF,
typename TAILGF>
44 using gf_tail = detail::gf_tail_base<HEADGF, TAILGF>;
58 template<
typename HEADGF,
typename TAILGF>
59 class gf_tail_base :
public HEADGF {
65 using Storage =
typename HEADGF::storage_type;
67 using VTYPE =
typename HEADGF::value_type;
68 using mesh_tuple =
typename HEADGF::mesh_types;
70 typedef HEADGF gf_type;
72 typedef TAILGF tail_type;
74 typedef gf_tail_base< HEADGF, TAILGF > gf_type_with_tail;
77 std::vector<tail_type> tails_;
84 gf_tail_base() : gf_type(), min_tail_order_(TAIL_NOT_SET), max_tail_order_(TAIL_NOT_SET) {}
86 gf_tail_base(
const gf_type& gf): gf_type(gf), min_tail_order_(TAIL_NOT_SET), max_tail_order_(TAIL_NOT_SET)
89 gf_tail_base(
const gf_type_with_tail& gft): gf_type(gft), tails_(gft.tails_),
90 min_tail_order_(gft.min_tail_order_),
91 max_tail_order_(gft.max_tail_order_)
95 int min_tail_order()
const {
return min_tail_order_; }
97 int max_tail_order()
const {
return max_tail_order_; }
100 const tail_type& tail(
int order)
const{
101 if (order<min_tail_order_ || order > max_tail_order_)
102 throw std::runtime_error(
"tails are known between min and max order, your order is outside.");
103 return tails_[order];
107 const std::vector<tail_type>& tail()
const{
120 bool operator==(
const gf_type_with_tail &rhs)
const {
121 bool tail_eq = (min_tail_order_ == rhs.min_tail_order_) && (max_tail_order_ == rhs.max_tail_order_);
122 if(tail_eq && min_tail_order_!=TAIL_NOT_SET) {
123 for (
int i = min_tail_order_; i <= max_tail_order_; ++i) {
124 tail_eq &= (tails_[i] == rhs.tails_[i]);
130 template<
typename RHS_GF>
141 gf_type_with_tail& set_tail(
int order,
const tail_type &tail){
142 static_assert(std::is_same<
typename tail_type::mesh_types,
143 decltype(
tuple_tail < 1, std::tuple_size<typename HEADGF::mesh_types>::value >(HEADGF::meshes())) >::value,
"Incorrect tail mesh types" );
145 int tail_size=tails_.size();
146 if(order>=tail_size){
147 tails_.resize(order+1, tail_type (
tuple_tail < 1, std::tuple_size<typename HEADGF::mesh_types>::value >(meshes())));
148 for(
int i=tail_size;i<=order;++i) tails_[i].initialize();
153 if(min_tail_order_==TAIL_NOT_SET || min_tail_order_>order) min_tail_order_=order;
154 if(max_tail_order_==TAIL_NOT_SET || max_tail_order_<=order) max_tail_order_=order;
162 ar[path+
"/tail/descriptor"]=
"INFINITY_TAIL";
163 ar[path+
"/tail/min_tail_order"]=min_tail_order_;
164 ar[path+
"/tail/max_tail_order"]=max_tail_order_;
165 if(min_tail_order_==TAIL_NOT_SET)
return;
166 for (
int i=min_tail_order_; i<=max_tail_order_; ++i) {
167 ar[path+
"/tail/"+std::to_string(i)] << tails_[i].data();
175 std::string descr; ar[path+
"/tail/descriptor"] >> descr;
176 if (descr!=
"INFINITY_TAIL")
throw std::runtime_error(
"Wrong tail format '"+descr+
"', expected INFINITY_TAIL");
179 ar[path+
"/tail/min_tail_order"] >> min_tail_order_;
180 ar[path+
"/tail/max_tail_order"] >> max_tail_order_;
183 if(min_tail_order_==TAIL_NOT_SET)
return;
185 if(min_tail_order_>0) tails_.resize(min_tail_order_, tail_type (
tuple_tail < 1, std::tuple_size<typename HEADGF::mesh_types>::value >(meshes())));
187 for (
int i=min_tail_order_; i<=max_tail_order_; ++i) {
188 typename tail_type::storage_type buffer;
189 ar[path+
"/tail/"+std::to_string(i)] >> buffer;
190 tails_.push_back(tail_type(buffer,
tuple_tail < 1, std::tuple_size<typename HEADGF::mesh_types>::value >(meshes())));
212 detail::broadcast_tail(comm,
213 min_tail_order_, max_tail_order_,
214 tails_, tail_type(
tuple_tail < 1, std::tuple_size<typename HEADGF::mesh_types>::value >(meshes())),
223 #endif //ALPSCORE_GF_TAIL_BASE_H void load(archive &ar, std::string const &path, T &value, std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())
void broadcast(C const &c, P &p, int r=0)
bool operator==(const dictionary &lhs, const dictionary &rhs)
auto tuple_tail(T &t) -> DECLTYPE(tuple_tail_< Trim >(t, make_index_sequence< Count-Trim >()))
Encapsulation of an MPI communicator and some communicator-related operations.
detail::gf_tail_base< HEADGF, TAILGF > gf_tail
static const int TAIL_NOT_SET
Special tail order meaning the tail is not set.
std::string get_context() const
int rank() const
Returns process rank in this communicator.
void broadcast(const communicator &comm, T *vals, std::size_t count, int root)
Broadcasts array vals of a primitive type T, length count on communicator comm with root root ...
bool operator!=(const dictionary &lhs, const dictionary &rhs)
void save(archive &ar, std::string const &path, T const &value, std::vector< std::size_t >=std::vector< std::size_t >(), std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t >=std::vector< std::size_t >())