ALPSCore reference
gf_base.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 
7 #ifndef ALPSCORE_GF_H
8 #define ALPSCORE_GF_H
9 
10 
11 #include <tuple>
12 #include <vector>
13 
14 #include <boost/preprocessor/cat.hpp>
15 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
16 
17 #include <alps/hdf5/archive.hpp>
18 #include <alps/hdf5/tensor.hpp>
19 #ifdef ALPS_HAVE_MPI
20 #include <alps/utilities/mpi.hpp>
21 #endif
22 
23 #include <alps/gf/mesh.hpp>
27 
28 
29 namespace alps {
30  namespace gf {
31  namespace detail {
35  template<class VTYPE, class Storage, class ...MESHES>
36  class gf_base;
37 
38  template <typename Tuple, std::size_t...Is>
39  std::ostream & output(std::ostream & os, const Tuple& t, index_sequence<Is...>) {
40  using swallow = int[];
41  (void)swallow{0, (void(os << std::get<Is>(t)), 0)...};
42  return os;
43  };
44 
45  template <typename ...Args>
46  auto operator<<(std::ostream & os, const std::tuple<Args...>& t) ->
47  DECLTYPE(detail::output(os, t, make_index_sequence<sizeof...(Args)>()))
48 
49  template<typename T> inline void print_no_complex(std::ostream &os, const T &z){
50  os<<z;
51  }
52  template<> inline void print_no_complex(std::ostream &os, const std::complex<double> &z){
53  //specialization for printing complex as ... real imag ...
54  os<<z.real()<<" "<<z.imag();
55  }
56  }
57 
61  template<class VTYPE, class ...MESHES>
62  using greenf = detail::gf_base<VTYPE, numerics::tensor<VTYPE, sizeof...(MESHES)>, MESHES...>;
66  template<class VTYPE, class ...MESHES>
67  using greenf_view = detail::gf_base<VTYPE, numerics::tensor_view<VTYPE, sizeof...(MESHES)>, MESHES...>;
68 
69  namespace detail {
73  template<class VTYPE, class Storage, class ...MESHES>
74  class gf_base {
75  // types definition
76  public:
77  // Current GF types
79  using value_type = VTYPE;
81  using storage_type = Storage;
83  using mesh_types = std::tuple < MESHES... >;
85  using index_types = std::tuple < typename MESHES::index_type... >;
86  private:
88  using gf_type = gf_base < VTYPE, Storage, MESHES... >;
90  using data_storage = numerics::tensor < VTYPE, sizeof...(MESHES) >;
91  using data_view = numerics::tensor_view < VTYPE, sizeof...(MESHES) >;
93  template<typename St>
94  using generic_gf = gf_base < VTYPE, St, MESHES... >;
96  template<typename RHS_VTYPE>
97  using gf_op_type = gf_base < decltype(RHS_VTYPE{} + VTYPE{}), numerics::tensor<decltype(RHS_VTYPE{} + VTYPE{}),
98  sizeof...(MESHES)>, MESHES... >;
99 
100  // fields definition
101  private:
103  static constexpr int minor_version = 1;
104  static constexpr int major_version = 0;
106  static constexpr int N_ = sizeof...(MESHES);
108  Storage data_;
110  std::tuple < MESHES... > meshes_;
112  bool empty_;
113 
114  // template hacks
121  template <typename S, class Tup> struct subpack_impl;
122  template<typename S, template<class...> class Tup, class... T>
123  struct subpack_impl<S, Tup<T...> >
124  {
125  using type = gf_base<S, numerics::tensor_view < S, sizeof...(T)>, T...>;
126  };
127  template<typename S, size_t I>
128  using subpack = typename subpack_impl<S, decltype(tuple_tail < I, MESHES... >(meshes_) )>::type;
129 
130  template<typename RHS_VTYPE, typename LHS_VTYPE>
131  struct convert {
132  typedef typename std::conditional<std::is_integral<RHS_VTYPE>::value, VTYPE, RHS_VTYPE>::type type;
133  };
134 
140  template<typename ...IndicesTypes>
141  struct check_mesh {
142  using type = typename std::conditional<std::is_convertible<std::tuple<IndicesTypes...>, index_types>::value,
143  std::true_type, std::false_type>::type;
144  };
145 
146  public:
147 
152  gf_base(const gf_type &g) = default;
153 
157  gf_base(gf_type &&g) = default;
158 
162  gf_base() : data_(std::array < size_t, N_ >{{0}}), empty_(true) {}
163 
168  gf_base(MESHES...meshes) : gf_base(std::make_tuple(meshes...)) {}
173  gf_base(const mesh_types &meshes) : data_(get_sizes(meshes)), meshes_(meshes), empty_(false) {}
175  gf_base(VTYPE* data, const mesh_types &meshes) : data_(data, get_sizes(meshes)), meshes_(meshes), empty_(false) {}
177  gf_base(const data_storage &data, const mesh_types &meshes) : data_(data), meshes_(meshes), empty_(false) {}
179  gf_base(data_storage &&data, const mesh_types &meshes) : data_(data), meshes_(meshes), empty_(false) {}
181  gf_base(const data_storage &data, MESHES...meshes) : data_(data), meshes_(std::make_tuple(meshes...)), empty_(false) {}
183  gf_base(data_storage && data, MESHES...meshes) : data_(std::move(data)), meshes_(std::make_tuple(meshes...)), empty_(false) {}
184 
186  template<typename St, typename = std::enable_if<!std::is_same<St, Storage>::value && std::is_same<St, data_view>::value > >
187  gf_base(const gf_base<VTYPE, St, MESHES...> &g) : data_(g.data()), meshes_(g.meshes()), empty_(g.is_empty()) {}
188  template<typename St, typename = std::enable_if<!std::is_same<St, Storage>::value && std::is_same<St, data_storage>::value > >
189  gf_base(gf_base<VTYPE, St, MESHES...> &g) : data_(g.data()), meshes_(g.meshes()), empty_(g.is_empty()) {}
190 
192  template<typename RHS_VTYPE, typename St, typename = std::enable_if<std::is_same<data_storage, Storage>::value> >
193  gf_base(const gf_base<RHS_VTYPE, St, MESHES...> &g) : data_(g.data()), meshes_(g.meshes()), empty_(g.is_empty()) {
194  static_assert(std::is_convertible<RHS_VTYPE, VTYPE>::value, "Right-hand side data type is not convertible into left-hand side.");
195  }
196  template<typename RHS_VTYPE, typename St, typename = std::enable_if<std::is_same<data_storage, Storage>::value>>
197  gf_base(gf_base<RHS_VTYPE, St, MESHES...> &&g) noexcept : data_(std::move(g.data())), meshes_(std::move(g.meshes())), empty_(g.is_empty()) {
198  static_assert(std::is_convertible<RHS_VTYPE, VTYPE>::value, "Right-hand side data type is not convertible into left-hand side.");
199  }
200 
202  template<typename St, typename...OLDMESHES, typename Index, typename ...Indices>
203  gf_base(gf_base<VTYPE, numerics::detail::tensor_base < VTYPE, sizeof...(OLDMESHES), St >, OLDMESHES...> & g,
204  std::tuple<OLDMESHES...>& oldmesh, const mesh_types &meshes, const Index ind, const Indices... idx) :
205  data_(g.data()(ind(), idx()...)), meshes_(meshes), empty_(false) {}
206 
208  template<typename RHSTYPE ,typename St, typename...OLDMESHES, typename ...Indices>
209  gf_base(const gf_base<RHSTYPE, numerics::detail::tensor_base < RHSTYPE, sizeof...(OLDMESHES), St >, OLDMESHES...> & g,
210  const std::tuple<OLDMESHES...>& oldmesh, mesh_types &meshes, const Indices... idx) :
211  data_(g.data()(idx()...)), meshes_(meshes), empty_(false) {}
212 
214  gf_type& operator=(const gf_type & rhs) {
215  swap_meshes(rhs.meshes_, make_index_sequence<sizeof...(MESHES)>());
216  data_ = rhs.data();
217  empty_= rhs.empty_;
218  return *this;
219  }
221  gf_type& operator=(gf_type && rhs) noexcept {
222  swap_meshes(rhs.meshes_, make_index_sequence<sizeof...(MESHES)>());
223  using std::swap;
224  swap(data_, rhs.data_);
225  swap(empty_, rhs.empty_);
226  return *this;
227  }
228 
230  void initialize() {
231  data_.set_zero();
232  }
233 
235  void check_meshes(const gf_type& rhs) const
236  {
237  if (meshes_ != rhs.meshes_) {
238  throw std::invalid_argument("Green Functions have incompatible meshes");
239  }
240  }
241 
242  /*
243  * Data access operations
244  */
250  template<class...Indices>
251  typename std::enable_if < (sizeof...(Indices) == sizeof...(MESHES)), const VTYPE & >::type
252  operator()(Indices...inds) const {
253  // check that index types are the same as mesh indices
254  static_assert(check_mesh<Indices...>::type::value, "Index type is inconsistent with mesh index type.");
255  return value(std::forward < Indices >(inds)...);
256  }
257 
259  template<class...Indices>
260  typename std::enable_if < (sizeof...(Indices) == sizeof...(MESHES)), VTYPE & >::type
261  operator()(Indices...inds) {
262  // check that index types are the same as mesh indices
263  static_assert(check_mesh<Indices...>::type::value, "Index type is inconsistent with mesh index type.");
264  return value(std::forward < Indices >(inds)...);
265  }
266 
275  template<class...Indices>
276  auto operator()(typename std::enable_if<(sizeof...(Indices)+1 < N_),
277  typename std::tuple_element<0,mesh_types>::type::index_type >::type ind, Indices...inds) ->
278  subpack<VTYPE, sizeof...(Indices) + 1> {
279  return subpack<VTYPE, sizeof...(Indices) + 1 >
280  (*this, meshes_, tuple_tail < sizeof...(Indices) + 1, MESHES...>(meshes_), ind, std::forward<Indices>(inds)...);
281  }
282 
283  template<class...Indices>
284  auto operator()(typename std::enable_if<(sizeof...(Indices)+1 < N_),
285  typename std::tuple_element<0,mesh_types>::type::index_type >::type ind, Indices...inds) const ->
286  subpack<const VTYPE, sizeof...(Indices) + 1> {
287  auto t = tuple_tail < sizeof...(Indices) + 1, MESHES...>(meshes_);
288  return subpack<const VTYPE, sizeof...(Indices) + 1> (*this, meshes_, t, ind, std::forward<Indices>(inds)...);
289  }
290 
291 
292  /*
293  * Basic GF arithmetics
294  */
295 
303  template<typename RHS_VTYPE, typename RHS_STORAGE>
304  gf_op_type<RHS_VTYPE> operator+(const gf_base<RHS_VTYPE, RHS_STORAGE, MESHES...> &rhs) const {
305  throw_if_empty();
306  gf_op_type<RHS_VTYPE> res(*this);
307  return res += rhs;
308  }
309 
317  template<typename RHS_GF>
318  typename std::enable_if < std::is_convertible < RHS_GF, generic_gf<data_storage>>::value ||
319  std::is_convertible < RHS_GF, generic_gf<data_view>>::value, gf_type & >::type
320  operator+=(const RHS_GF &rhs) {
321  throw_if_empty();
322  data_ += rhs.data();
323  return *this;
324  }
325 
333  template<typename RHS_VTYPE, typename RHS_STORAGE>
334  gf_op_type<RHS_VTYPE> operator-(const gf_base<RHS_VTYPE, RHS_STORAGE, MESHES...> &rhs) const {
335  throw_if_empty();
336  gf_op_type<RHS_VTYPE> res(*this);
337  return res -= rhs;
338  }
339 
343  template<typename RHS_GF>
344  typename std::enable_if < std::is_convertible < RHS_GF, generic_gf<data_storage>>::value ||
345  std::is_convertible < RHS_GF, generic_gf<data_view>>::value, gf_type & >::type
346  operator-=(const RHS_GF &rhs) {
347  throw_if_empty();
348  data_ -= rhs.data();
349  return *this;
350  }
351 
359  template<typename RHS>
360  typename std::enable_if < std::is_scalar < RHS >::value || std::is_same < VTYPE, RHS >::value, gf_type & >::type operator*=(RHS rhs) {
361  throw_if_empty();
362  data_ *= VTYPE(rhs);
363  return *this;
364  }
365 
373  template<typename RHS>
374  gf_op_type<typename convert<RHS,VTYPE>::type> operator*(RHS rhs) const {
375  throw_if_empty();
376  gf_op_type<typename convert<RHS,VTYPE>::type> res(*this);
377  return res *= rhs;
378  }
379 
380  template<typename LHS>
381  friend gf_op_type<typename convert<LHS,VTYPE>::type> operator*(LHS lhs, const gf_type & g) {
382  return g * lhs;
383  }
384 
393  template<typename RHS>
394  typename std::enable_if < std::is_scalar < RHS >::value || std::is_same < VTYPE, RHS >::value, gf_type & >::type operator/=(RHS rhs) {
395  throw_if_empty();
396  data_ /= VTYPE(rhs);
397  return *this;
398  }
399 
407  template<typename RHS>
408  gf_op_type<typename convert<RHS,VTYPE>::type> operator/(RHS rhs) const {
409  throw_if_empty();
410  gf_op_type<typename convert<RHS,VTYPE>::type> res(*this);
411  return res /= rhs;
412  }
413 
414  template<typename LHS>
415  friend gf_op_type<typename convert<LHS,VTYPE>::type> operator/(LHS lhs, const gf_type & g) {
416  return g / lhs;
417  }
418 
422  gf_base < VTYPE, numerics::tensor<VTYPE, N_>, MESHES... > operator-() const {
423  throw_if_empty();
424  return (*this)*(VTYPE(-1.0));
425  }
426 
434  template<typename RHS_GF>
435  typename std::enable_if < std::is_convertible < RHS_GF, generic_gf<data_storage> >::value
436  || std::is_convertible < RHS_GF, generic_gf<data_view> >::value, bool >::type
437  operator==(const RHS_GF &rhs) const {
438  return (empty_ && rhs.is_empty()) || (data_.shape() == rhs.data().shape() && data_.storage() == rhs.data().storage() );
439  }
440 
441  template<typename RHS_GF>
442  bool operator!=(const RHS_GF &rhs) const {
443  return !(*this==rhs);
444  }
445 
449  double norm() const {
450  throw_if_empty();
451  return std::abs(*std::max_element(data_.data(), data_.num_elements() + data_.data(),
452  [](VTYPE a, VTYPE b) {return std::abs(a) < std::abs(b);} ) );
453  }
454 
455  // reshape green's function
456  void reshape(MESHES...meshes) {
457  std::array<size_t, N_> new_shape = get_sizes(std::make_tuple(meshes...));
458  size_t new_size = std::accumulate(new_shape.begin(), new_shape.end(), size_t(1), std::multiplies<size_t>());
459  if(std::is_same<data_view, Storage>::value) {
460  if (data_.size() != new_size) {
461  throw std::invalid_argument("The total size of resulting Green's function view should be the same as before.");
462  }
463  }
464  data_.reshape(new_shape);
465  meshes_ = std::make_tuple(meshes...);
466  empty_ = false;
467  }
468 
473  void save(alps::hdf5::archive &ar) const {
475  save(ar, ar.get_context());
476  }
477 
479  void load(alps::hdf5::archive &ar) {
480  load(ar, ar.get_context());
481  }
482 
484  void save(alps::hdf5::archive &ar, const std::string &path) const {
485  throw_if_empty();
486  save_version(ar, path);
487  ar[path + "/data"] << data_;
488  ar[path + "/mesh/N"] << int(N_);
489  save_meshes(ar, path, make_index_sequence<sizeof...(MESHES)>());
490  }
491 
493  void load(alps::hdf5::archive &ar, const std::string &path) {
494  if (!check_version(ar, path)) throw std::runtime_error("Incompatible archive version");
495  int ndim;
496  ar[path + "/mesh/N"] >> ndim;
497  if (ndim != N_) throw std::runtime_error("Wrong number of dimension reading GF, ndim=" + std::to_string(ndim)
498  + ", should be N=" + std::to_string(N_));
499  load_meshes(ar, path, make_index_sequence<sizeof...(MESHES)>());
500  data_ = numerics::tensor < VTYPE, N_ >(get_sizes(meshes_));
501  ar[path + "/data"] >> data_;
502  empty_ = false;
503  }
504 
506  void save_version(alps::hdf5::archive &ar, const std::string &path) const {
507  std::string vp = path + "/version/";
508  ar[vp + "minor"] << int(minor_version);
509  ar[vp + "major"] << int(major_version);
510  ar[vp + "reference"] << "https://github.com/ALPSCore/H5GF/blob/master/H5GF.rst";
511  ar[vp + "originator"] << "ALPSCore GF library, see http://www.alpscore.org";
512  }
513 
515  bool check_version(alps::hdf5::archive &ar, const std::string &path) const {
516  std::string vp = path + "/version/";
517  int ver;
518  ar[vp + "major"] >> ver;
519  return (major_version == ver);
520  }
521 
522  /*
523  * Access to storage
524  */
528  const Storage &data() const { return data_; };
532  Storage &data() { return data_; };
533 
537  bool is_empty() const {
538  return empty_;
539  }
540 
544  const mesh_types& meshes() const {return meshes_;}
545 
546  /*
547  * MPI routines
548  */
549 #ifdef ALPS_HAVE_MPI
550 
556  void broadcast(const alps::mpi::communicator& comm, int root) {
557  // check that root GF has been initilized
558  if(comm.rank() == root) throw_if_empty();
559  // broadcast grid meshes
560  broadcast_mesh(comm, root);
561  size_t root_sz=data_.size();
562  alps::mpi::broadcast(comm, root_sz, root);
563  // as long as all grids have been broadcasted we can define tensor object
564  if(comm.rank() != root) data_ = numerics::tensor < VTYPE, N_ >(get_sizes(meshes_));
565  alps::mpi::broadcast(comm, &data_.storage().data(0), root_sz, root);
566  }
567 #endif
568 
569  private:
570 
571  /*
572  * MPI routines
573  */
574 #ifdef ALPS_HAVE_MPI
575 
578  void broadcast_mesh(const alps::mpi::communicator& comm, int root) {
579  // start from the zeroth mesh
580  bcast_mesh(comm, root, std::integral_constant < int, 0 >());
581  }
582  template<int M>
583  void bcast_mesh(const alps::mpi::communicator& comm, int root, std::integral_constant < int, M > i) {
584  std::get<M>(meshes_).broadcast(comm, root);
585  bcast_mesh(comm, root, std::integral_constant < int, M+1 >());
586  }
587  // Until we reach the last mesh object
588  void bcast_mesh(const alps::mpi::communicator& comm, int root, std::integral_constant < int, N_ - 1> i) {
589  std::get<N_ - 1>(meshes_).broadcast(comm, root);
590  }
591 #endif
592 
596  inline void throw_if_empty() const {
597 #ifndef NDEBUG
598  if (empty_) {
599  throw std::runtime_error("gf is empty");
600  }
601 #endif
602  }
603 
611  template<class ... Indices>
612  const VTYPE & value(Indices...inds) const {
613  return data_(inds()...);
614  }
615 
616  template<class ... Indices>
617  VTYPE &value(Indices...inds) {
618  return data_(inds()...);
619  }
620 
627  std::array < size_t, N_ > get_sizes(MESHES...meshes) {
628  return get_sizes(std::forward_as_tuple(meshes...));
629  };
630 
637  std::array < size_t, N_ > get_sizes(const mesh_types &meshes) {
638  std::array < size_t, N_ > sizes;
639  sizes = fill_sizes(meshes, make_index_sequence<sizeof...(MESHES)>());
640  return sizes;
641  };
642 
653  template<size_t...Is>
654  inline std::array < size_t, N_ > fill_sizes(const mesh_types &grids, index_sequence<Is...>) {
655  return {{size_t(std::get<Is>(grids).extent())...}};
656  };
657 
663  template<size_t...Is>
664  void swap_meshes(const mesh_types & old_meshes, index_sequence<Is...>) {
665  std::tie(std::get < Is >(meshes_) = std::get < Is >(old_meshes)...);
666  }
667 
675  template<size_t...Is>
676  void save_meshes(alps::hdf5::archive &ar, const std::string &path, index_sequence<Is...>) const {
677  std::tie(ar[path + "/mesh/" + std::to_string(Is+1)] << std::get < Is >(meshes_)...);
678  }
679 
680 
688  template<size_t...Is>
689  void load_meshes(alps::hdf5::archive &ar, const std::string &path, index_sequence<Is...>) {
690  std::tie(ar[path + "/mesh/" + std::to_string(Is+1)] >> std::get < Is >(meshes_)...);
691  }
692 
701  struct void_type {
702  using type = void;
703  };
704  // Argument types.
705  template<size_t i>
706  struct args {
707  using type
708  = typename std::conditional < (i <= N_),
709  std::tuple_element < i - 1, mesh_types >,
710  void_type>::type::type;
711  };
712 
713  public:
714 
718  #define MESH_FUNCTION(z, num, c) \
719  template<typename = typename std::enable_if< (N_ >= num)> >\
720  typename std::add_lvalue_reference<const typename args<num>::type>::type mesh##num() const {\
721  return std::get<int(num-1)>(meshes_); \
722  }
723 
724  #define MESH_TYPES(z, num, c) \
725  /*template<typename = typename std::enable_if< (N_ >= num)> >*/\
726  typedef typename args<num>::type mesh##num##_type;
727  // = typename args<num>::type;
728 
729  /*
730  * I guess 10 functions would be enough
731  */
732  BOOST_PP_REPEAT_FROM_TO (1, 11, MESH_FUNCTION, int)
733  BOOST_PP_REPEAT_FROM_TO (1, 11, MESH_TYPES, int)
734 
738  friend std::ostream &operator<<(std::ostream &os, const gf_type & G ){
739  using detail::operator<<;
740  os<<G.meshes();
741  for(int i=0;i<G.mesh1().extent();++i){
742  os<<(G.mesh1().points()[i])<<" ";
743  size_t points = G.data().size()/G.data().shape()[0];
744  for(size_t j = 0; j< points; ++j) {
745  detail::print_no_complex<value_type>(os, G.data().data()[j + G.data().index(i)]);
746  os<<" ";
747  }
748  os<<std::endl;
749  }
750  return os;
751  }
752  };
753  }
754  }
755 }
756 
757 #endif //ALPSCORE_GF_H
piecewise_polynomial< T > operator+(const piecewise_polynomial< T > &f1, const piecewise_polynomial< T > &f2)
Add piecewise_polynomial objects.
detail::gf_base< VTYPE, numerics::tensor_view< VTYPE, sizeof...(MESHES)>, MESHES... > greenf_view
Definition: gf_base.hpp:67
void swap(matsubara_mesh< PTYPE > &a, matsubara_mesh< PTYPE > &b)
Swaps two Matsubara meshes.
Definition: mesh.hpp:350
#define DECLTYPE(ret)
Definition: common.hpp:12
make_integer_sequence< size_t, N > make_index_sequence
detail::tensor_base< T, D, detail::data_storage< T > > tensor
Definition: tensor_base.hpp:62
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 >())
Definition: archive.hpp:309
boost::array< T, N > abs(boost::array< T, N > arg)
std::ostream & operator<<(std::ostream &os, const real_frequency_mesh &M)
Definition: mesh.cpp:40
void broadcast(C const &c, P &p, int r=0)
Definition: api.hpp:56
piecewise_polynomial< T > operator-(const piecewise_polynomial< T > &f1, const piecewise_polynomial< T > &f2)
Substract piecewise_polynomial objects.
const piecewise_polynomial< T > operator*(T scalar, const piecewise_polynomial< T > &pp)
Multiply piecewise_polynomial by a scalar.
STL namespace.
void swap(params &p1, params &p2)
boost::array< T, N > operator/(boost::array< T, N > lhs, boost::array< U, N > const &rhs)
bool operator==(const dictionary &lhs, const dictionary &rhs)
Definition: dictionary.hpp:96
auto tuple_tail(T &t) -> DECLTYPE(tuple_tail_< Trim >(t, make_index_sequence< Count-Trim >()))
Header for object-oriented interface to MPI (similar to boost::mpi)
Encapsulation of an MPI communicator and some communicator-related operations.
Definition: mpi.hpp:111
T norm(T x, T y=T(), T z=T())
boost::array< T, N > & operator+=(boost::array< T, N > &lhs, boost::array< T, N > const &rhs)
#define MESH_FUNCTION(z, num, c)
Definition: gf_base.hpp:718
boost::array< T, N > & operator/=(boost::array< T, N > &lhs, boost::array< T, N > const &rhs)
detail::gf_base< VTYPE, numerics::tensor< VTYPE, sizeof...(MESHES)>, MESHES... > greenf
Definition: gf_base.hpp:62
#define MESH_TYPES(z, num, c)
Definition: gf_base.hpp:724
boost::array< T, N > & operator*=(boost::array< T, N > &lhs, boost::array< T, N > const &rhs)
std::string get_context() const
Definition: archive.cpp:144
int rank() const
Returns process rank in this communicator.
Definition: mpi.hpp:156
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 ...
Definition: mpi.hpp:270
detail::tensor_base< T, D, detail::data_view< T > > tensor_view
Definition: tensor_base.hpp:74
bool operator!=(const dictionary &lhs, const dictionary &rhs)
Definition: dictionary.hpp:100
boost::array< T, N > & operator-=(boost::array< T, N > &lhs, boost::array< T, N > const &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 >())
Definition: archive.hpp:292