ALPSCore reference
mesh.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 #pragma once
7 #include <complex>
8 #include <cassert>
9 #include <array>
10 #include <type_traits>
11 #include <boost/multi_array.hpp>
12 #include <boost/operators.hpp>
13 
14 #include <alps/hdf5/archive.hpp>
15 #include <alps/hdf5/complex.hpp>
16 #include <alps/hdf5/vector.hpp>
18 
19 
20 #ifdef ALPS_HAVE_MPI
21 #include "mpi_bcast.hpp"
22 #endif
23 
24 #include"flagcheck.hpp"
26 
27 namespace alps {
28  namespace gf {
29 
30  namespace statistics {
34  };
35  }
36 
38  template <typename X>
39  class generic_index :
40  boost::additive2<generic_index<X>, int,
41  boost::unit_steppable< generic_index<X>,
42  boost::totally_ordered2< generic_index<X>, int> > >
43  {
44  private:
45  int index_;
46  public:
47  explicit generic_index(int i): index_(i) {}
48  generic_index() : index_(0) {}
49 
50  void operator=(int i) { index_=i; }
51 
52  generic_index& operator++() { index_++; return *this; }
53  generic_index& operator--() { index_--; return *this; }
54 
55  generic_index& operator+=(int i) { index_+=i; return *this; }
56  generic_index& operator-=(int i) { index_-=i; return *this; }
57 
58  bool operator<(int x) const { return index_ <x; }
59  bool operator>(int x) const { return index_ >x; }
60  bool operator==(int x) const { return index_==x; }
61 
62  int operator()() const { return index_; }
63 
64 #ifdef ALPS_HAVE_MPI
65  void broadcast(const alps::mpi::communicator& comm, int root) {
66  alps::mpi::broadcast(comm, index_, root);
67  }
68 #endif
69  };
70  namespace mesh {
74  };
75  }
77  class base_mesh {
78  public:
79  base_mesh() {}
80  base_mesh(const base_mesh& rhs) : points_(rhs.points_) {}
82  const std::vector<double> &points() const{return points_;}
83  protected:
84  // we do not want external functions be able to change a grid.
85  std::vector<double> &_points() {return points_;}
86  void swap(base_mesh &other) {
87  using std::swap;
88  swap(this->points_, other.points_);
89  }
90  private:
91  std::vector<double> points_;
92  };
93 
96  inline void throw_if_empty() const {
97  if (extent() == 0) {
98  throw std::runtime_error("real_frequency_mesh is empty");
99  }
100  }
101  public:
105 
106  template<typename GRID>
107  explicit real_frequency_mesh(const GRID & grid) {
108  grid.compute_points(_points());
109  }
110  int extent() const {return points().size();}
111 
112  int operator()(index_type idx) const {
113 #ifndef NDEBUG
114  throw_if_empty();
115 #endif
116  return idx();
117  }
118  void save(alps::hdf5::archive& ar, const std::string& path) const
119  {
120  throw_if_empty();
121  ar[path+"/kind"] << "REAL_FREQUENCY";
122  ar[path+"/points"] << points();
123  }
124 
125  void load(alps::hdf5::archive& ar, const std::string& path)
126  {
127  std::string kind;
128  ar[path+"/kind"] >> kind;
129  if (kind!="REAL_FREQUENCY") throw std::runtime_error("Attempt to read real frequency mesh from non-real frequency data, kind="+kind);
130  ar[path+"/points"] >> _points();
131  }
132 
134  void save(alps::hdf5::archive& ar) const
135  {
136  save(ar, ar.get_context());
137  }
138 
141  {
142  load(ar, ar.get_context());
143  }
144 
146  bool operator==(const real_frequency_mesh &mesh) const {
147  throw_if_empty();
148  return extent()==mesh.extent() && std::equal ( mesh.points().begin(), mesh.points().end(), points().begin() );;
149  }
150 
152  bool operator!=(const real_frequency_mesh &mesh) const {
153  throw_if_empty();
154  return !(*this==mesh);
155  }
156 #ifdef ALPS_HAVE_MPI
157  void broadcast(const alps::mpi::communicator& comm, int root)
158  {
159  using alps::mpi::broadcast;
160  if(comm.rank() == root) throw_if_empty();
161  int size = extent();
162  broadcast(comm, size, root);
164  if(root!=comm.rank()) {
166  _points().resize(size);
167  }
168  broadcast(comm, _points().data(), extent(), root);
169  }
170 #endif
171  };
172  std::ostream &operator<<(std::ostream &os, const real_frequency_mesh &M);
173 
174  template <mesh::frequency_positivity_type PTYPE>
175  class matsubara_mesh : public base_mesh {
176  double beta_;
177  int nfreq_;
178 
179  statistics::statistics_type statistics_;
180  static const mesh::frequency_positivity_type positivity_=PTYPE;
181 
182  //FIXME: we had this const, but that prevents copying.
183  int offset_;
184 
185  inline void throw_if_empty() const {
186  if (extent() == 0) {
187  throw std::runtime_error("matsubara_mesh is empty");
188  }
189  }
190 
191  public:
194  matsubara_mesh(const matsubara_mesh& rhs) : beta_(rhs.beta_), nfreq_(rhs.nfreq_), statistics_(rhs.statistics_), offset_(rhs.offset_) {check_range();compute_points();}
196  beta_(0.0), nfreq_(0), statistics_(statistics::FERMIONIC), offset_(-1)
197  {
198  }
199 
201  beta_(b), nfreq_(nfr), statistics_(statistics), offset_((PTYPE==mesh::POSITIVE_ONLY)?0:nfr/2) {
202  check_range();
203  compute_points();
204  }
205  int extent() const{return nfreq_;}
206 
207 
208  int operator()(index_type idx) const {
209 #ifndef NDEBUG
210  throw_if_empty();
211 #endif
212  return offset_+idx(); // FIXME: can be improved by specialization?
213  }
214 
216  bool operator==(const matsubara_mesh &mesh) const {
217  throw_if_empty();
218  return beta_==mesh.beta_ && nfreq_==mesh.nfreq_ && statistics_==mesh.statistics_ && offset_ == mesh.offset_;
219  }
220 
222  bool operator!=(const matsubara_mesh &mesh) const {
223  throw_if_empty();
224  return !(*this==mesh);
225  }
226 
228  double beta() const{ return beta_;}
229  statistics::statistics_type statistics() const{ return statistics_;}
230  mesh::frequency_positivity_type positivity() const{ return positivity_;}
231 
233  // It's a member function to avoid dealing with templated friend decalration.
234  void swap(matsubara_mesh& other) {
235  throw_if_empty();
236  if(statistics_!=other.statistics_)
237  throw std::runtime_error("Attempt to swap two meshes with different statistics.");// FIXME: specific exception
238  using std::swap;
239  swap(this->beta_, other.beta_);
240  swap(this->nfreq_, other.nfreq_);
241  base_mesh::swap(other);
242  }
243 
244  void save(alps::hdf5::archive& ar, const std::string& path) const
245  {
246  throw_if_empty();
247  ar[path+"/kind"] << "MATSUBARA";
248  ar[path+"/N"] << nfreq_;
249  ar[path+"/statistics"] << int(statistics_); //
250  ar[path+"/beta"] << beta_;
251  ar[path+"/positive_only"] << int(positivity_);
252  ar[path+"/points"] << points();
253  }
254 
255  void load(alps::hdf5::archive& ar, const std::string& path)
256  {
257  std::string kind;
258  ar[path+"/kind"] >> kind;
259  if (kind!="MATSUBARA") throw std::runtime_error("Attempt to read Matsubara mesh from non-Matsubara data, kind="+kind); // FIXME: specific exception
260  double nfr, beta;
261  int stat, posonly;
262 
263  ar[path+"/N"] >> nfr;
264  ar[path+"/statistics"] >> stat;
265  ar[path+"/beta"] >> beta;
266  ar[path+"/positive_only"] >> posonly;
267 
268  statistics_=statistics::statistics_type(stat);
269  if (mesh::frequency_positivity_type(posonly)!=positivity_) {
270  throw std::invalid_argument("Attempt to read Matsubara mesh with the wrong positivity type "+std::to_string(posonly) ); // FIXME: specific exception? Verbose positivity?
271  };
272  beta_=beta;
273  nfreq_=nfr;
274  offset_ = ((PTYPE==mesh::POSITIVE_ONLY)?0:nfr/2);
275  check_range();
276  compute_points();
277  }
278 
280  void save(alps::hdf5::archive& ar) const
281  {
282  save(ar, ar.get_context());
283  }
284 
287  {
288  load(ar, ar.get_context());
289  }
290 
291 #ifdef ALPS_HAVE_MPI
292  void broadcast(const alps::mpi::communicator& comm, int root)
293  {
294  using alps::mpi::broadcast;
295  if(comm.rank() == root) throw_if_empty();
296  // FIXME: introduce (debug-only?) consistency check, like type checking? akin to load()?
297  broadcast(comm, beta_, root);
298  broadcast(comm, nfreq_, root);
299  int stat = int(statistics_);
300  broadcast(comm, stat, root);
301  statistics_ = statistics::statistics_type(stat);
302  int pos = int(positivity_);
303  broadcast(comm, pos, root);
304  if (mesh::frequency_positivity_type(pos)!=positivity_) {
305  throw std::invalid_argument("Attempt to broadcast Matsubara mesh with the wrong positivity type "+std::to_string(pos) ); // FIXME: specific exception? Verbose positivity?
306  };
307  offset_ = ((PTYPE==mesh::POSITIVE_ONLY)?0:nfreq_/2);
308 
309  try {
310  check_range();
311  } catch (const std::exception& exc) {
312  int wrank=alps::mpi::communicator().rank();
313  // FIXME? Try to communiucate the error with all ranks, at least in debug mode?
314  std::cerr << "matsubara_mesh<>::broadcast() exception at WORLD rank=" << wrank << std::endl
315  << exc.what()
316  << "\nAborting." << std::endl;
317  MPI_Abort(MPI_COMM_WORLD,1);
318  }
319  compute_points(); // recompute points rather than sending them over MPI
320  }
321 #endif
322 
323  void check_range(){
324  if(statistics_!=statistics::FERMIONIC && statistics_!=statistics::BOSONIC) throw std::invalid_argument("statistics should be bosonic or fermionic");
325  if(positivity_!=mesh::POSITIVE_ONLY &&
326  positivity_!=mesh::POSITIVE_NEGATIVE) {
327  throw std::invalid_argument("positivity should be POSITIVE_ONLY or POSITIVE_NEGATIVE");
328  }
329  throw_if_empty();
330  }
332  throw_if_empty();
333  _points().resize(extent());
334  for(int i=0;i<nfreq_;++i){
335  _points()[i]=(2*(i-offset_)+statistics_)*M_PI/beta_;
336  }
337  }
338  };
340  template<mesh::frequency_positivity_type PTYPE> std::ostream &operator<<(std::ostream &os, const matsubara_mesh<PTYPE> &M){
341  os<<"# "<<"MATSUBARA"<<" mesh: N: "<<M.extent()<<" beta: "<<M.beta()<<" statistics: ";
342  os<<(M.statistics()==statistics::FERMIONIC?"FERMIONIC":"BOSONIC")<<" ";
343  os<<(M.positivity()==mesh::POSITIVE_ONLY?"POSITIVE_ONLY":"POSITIVE_NEGATIVE");
344  os<<std::endl;
345  return os;
346  }
347 
349  template <mesh::frequency_positivity_type PTYPE>
351  a.swap(b);
352  }
353 
354  class itime_mesh {
355  double beta_;
356  int ntau_;
357  bool last_point_included_;
358  bool half_point_mesh_;
359  statistics::statistics_type statistics_;
360  std::vector<double> points_;
361 
362  inline void throw_if_empty() const {
363  if (extent() == 0) {
364  throw std::runtime_error("itime_mesh is empty");
365  }
366  }
367 
368  public:
370 
371  itime_mesh(): beta_(0.0), ntau_(0), last_point_included_(true), half_point_mesh_(false), statistics_(statistics::FERMIONIC)
372  {
373  }
374 
375  itime_mesh(const itime_mesh&rhs): beta_(rhs.beta_), ntau_(rhs.ntau_),
376  last_point_included_(rhs.last_point_included_), half_point_mesh_(rhs.half_point_mesh_), statistics_(rhs.statistics_){
377  compute_points();
378 
379  }
380 
381  itime_mesh(double beta, int ntau): beta_(beta), ntau_(ntau), last_point_included_(true), half_point_mesh_(false), statistics_(statistics::FERMIONIC){
382  compute_points();
383 
384  }
385  int operator()(index_type idx) const {
386 #ifndef NDEBUG
387  throw_if_empty();
388 #endif
389  return idx();
390  }
391  int extent() const{return ntau_;}
392 
394  bool operator==(const itime_mesh &mesh) const {
395  throw_if_empty();
396  return beta_==mesh.beta_ && ntau_==mesh.ntau_ && last_point_included_==mesh.last_point_included_ &&
397  half_point_mesh_ == mesh.half_point_mesh_ && statistics_==mesh.statistics_;
398  }
399 
401  double beta() const{ return beta_;}
402  statistics::statistics_type statistics() const{ return statistics_;}
403  const std::vector<double> &points() const{return points_;}
404 
406  bool operator!=(const itime_mesh &mesh) const {
407  throw_if_empty();
408  return !(*this==mesh);
409  }
410 
411  void save(alps::hdf5::archive& ar, const std::string& path) const
412  {
413  throw_if_empty();
414  ar[path+"/kind"] << "IMAGINARY_TIME";
415  ar[path+"/N"] << ntau_;
416  ar[path+"/statistics"] << int(statistics_); //
417  ar[path+"/beta"] << beta_;
418  ar[path+"/half_point_mesh"] << int(half_point_mesh_);
419  ar[path+"/last_point_included"] << int(last_point_included_);
420  ar[path+"/points"] << points_;
421  }
422 
423  void load(alps::hdf5::archive& ar, const std::string& path)
424  {
425  std::string kind;
426  ar[path+"/kind"] >> kind;
427  if (kind!="IMAGINARY_TIME") throw std::runtime_error("Attempt to read Imaginary time mesh from non-itime data, kind="+kind); // FIXME: specific exception
428  double ntau, beta;
429  int stat, half_point_mesh, last_point_included;
430 
431  ar[path+"/N"] >> ntau;
432  ar[path+"/statistics"] >> stat;
433  ar[path+"/beta"] >> beta;
434  ar[path+"/half_point_mesh"] >> half_point_mesh;
435  ar[path+"/last_point_included"] >> last_point_included;
436 
437  statistics_=statistics::statistics_type(stat); // FIXME: check range
438  half_point_mesh_=half_point_mesh;
439  last_point_included_=last_point_included;
440  beta_=beta;
441  ntau_=ntau;
442  compute_points();
443  }
444 
446  void save(alps::hdf5::archive& ar) const
447  {
448  save(ar, ar.get_context());
449  }
450 
453  {
454  load(ar, ar.get_context());
455  }
456 
457 #ifdef ALPS_HAVE_MPI
458  void broadcast(const alps::mpi::communicator& comm, int root)
459  {
460  using alps::mpi::broadcast;
461  if(comm.rank() == root) throw_if_empty();
462  // FIXME: introduce (debug-only?) consistency check, like type checking? akin to load()?
463  broadcast(comm, beta_, root);
464  broadcast(comm, ntau_, root);
465  broadcast(comm, last_point_included_, root);
466  broadcast(comm, half_point_mesh_, root);
467  int stat=statistics_;
468  broadcast(comm, stat, root);
469  statistics_=static_cast<statistics::statistics_type>(stat);
470  compute_points(); // recompute points rather than sending them over MPI
471  }
472 #endif
473 
475  points_.resize(extent());
476  if(half_point_mesh_){
477  double dtau=beta_/ntau_;
478  for(int i=0;i<ntau_;++i){
479  points_[i]=(i+0.5)*dtau;
480  }
481  }
482  for(int i=0;i<ntau_;++i){
483  double dtau=last_point_included_?beta_/(ntau_-1):beta_/ntau_;
484  for(int i=0;i<ntau_;++i){
485  points_[i]=i*dtau;
486  }
487  }
488  }
489 
490  };
492  std::ostream &operator<<(std::ostream &os, const itime_mesh &M);
493 
494  class power_mesh {
495  double beta_;
496  int ntau_;
497  int power_;
498  int uniform_;
499 
500  statistics::statistics_type statistics_;
501  std::vector<double> points_;
502  std::vector<double> weights_;
503 
504  inline void throw_if_empty() const {
505  if (extent() == 0) {
506  throw std::runtime_error("power_mesh is empty");
507  }
508  }
509 
510  public:
512 
513  power_mesh(const power_mesh& rhs): beta_(rhs.beta_), power_(rhs.power_), uniform_(rhs.uniform_), statistics_(rhs.statistics_){
514  compute_points();
515  compute_weights();
516  }
517 
518  power_mesh(): beta_(0.0), ntau_(0), power_(0), uniform_(0), statistics_(statistics::FERMIONIC){
519  }
520 
521  power_mesh(double beta, int power, int uniform): beta_(beta), power_(power), uniform_(uniform), statistics_(statistics::FERMIONIC){
522  compute_points();
523  compute_weights();
524  }
525  int operator()(index_type idx) const {
526 #ifndef NDEBUG
527  throw_if_empty();
528 #endif
529  return idx();
530  }
531  int extent() const{return ntau_;}
532  int power() const{return power_;}
533  int uniform() const{return uniform_;}
534 
536  bool operator==(const power_mesh &mesh) const {
537  throw_if_empty();
538  return beta_==mesh.beta_ && ntau_==mesh.ntau_ && power_==mesh.power_ &&
539  uniform_ == mesh.uniform_ && statistics_==mesh.statistics_;
540  }
541 
543  double beta() const{ return beta_;}
544  statistics::statistics_type statistics() const{ return statistics_;}
545  const std::vector<double> &points() const{return points_;}
546  const std::vector<double> &weights() const{return weights_;}
547 
549  bool operator!=(const power_mesh &mesh) const {
550  throw_if_empty();
551  return !(*this==mesh);
552  }
553 
554  void save(alps::hdf5::archive& ar, const std::string& path) const
555  {
556  throw_if_empty();
557  ar[path+"/kind"] << "IMAGINARY_TIME_POWER";
558  ar[path+"/N"] << ntau_;
559  ar[path+"/statistics"] << int(statistics_); //
560  ar[path+"/beta"] << beta_;
561  ar[path+"/power"] << power_;
562  ar[path+"/uniform"] << uniform_;
563  ar[path+"/points"] << points_;
564  }
565 
566  void load(alps::hdf5::archive& ar, const std::string& path)
567  {
568  std::string kind;
569  ar[path+"/kind"] >> kind;
570  if (kind!="IMAGINARY_TIME_POWER") throw std::runtime_error("Attempt to read Imaginary time power mesh from non-itime power data, kind="+kind); // FIXME: specific exception
571  double ntau, beta;
572  int stat, power, uniform;
573 
574  ar[path+"/N"] >> ntau;
575  ar[path+"/statistics"] >> stat;
576  ar[path+"/beta"] >> beta;
577  ar[path+"/power"] >> power;
578  ar[path+"/uniform"] >> uniform;
579 
580  statistics_=statistics::statistics_type(stat); // FIXME: check range
581  power_=power;
582  uniform_=uniform;
583  beta_=beta;
584  ntau_=ntau;
585  compute_points();
586  compute_weights();
587  }
588 
590  void save(alps::hdf5::archive& ar) const
591  {
592  save(ar, ar.get_context());
593  }
594 
597  {
598  load(ar, ar.get_context());
599  }
600 
601 #ifdef ALPS_HAVE_MPI
602  void broadcast(const alps::mpi::communicator& comm, int root)
603  {
604  using alps::mpi::broadcast;
605  if(comm.rank() == root) throw_if_empty();
606  // FIXME: introduce (debug-only?) consistency check, like type checking? akin to load()?
607  broadcast(comm, beta_, root);
608  broadcast(comm, ntau_, root);
609  broadcast(comm, power_, root);
610  broadcast(comm, uniform_, root);
611  int stat=statistics_;
612  broadcast(comm, stat, root);
613  statistics_=static_cast<statistics::statistics_type>(stat);
614  compute_points(); // recompute points rather than sending them over MPI
615  compute_weights();
616  }
617 #endif
618 
620  //create a power grid spacing
621  if(uniform_%2 !=0) throw std::invalid_argument("Simpson weights in power grid only work for even uniform spacing.");
622  std::vector<double> power_points;
623  power_points.push_back(0);
624  for(int i=power_;i>=0;--i){
625  power_points.push_back(beta_*0.5*std::pow(2.,-i));
626  }
627  for(int i=power_;i>0;--i){
628  power_points.push_back(beta_*(1.-0.5*std::pow(2.,-i)));
629  }
630  power_points.push_back(beta_);
631  std::sort(power_points.begin(),power_points.end());
632 
633  //create the uniform grid within each power grid
634  points_.resize(0);
635  for(std::size_t i=0;i<power_points.size()-1;++i){
636  for(int j=0;j<uniform_;++j){
637  double dtau=(power_points[i+1]-power_points[i])/(double)(uniform_);
638  points_.push_back(power_points[i]+dtau*j);
639  }
640  }
641  points_.push_back(power_points.back());
642  ntau_=points_.size();
643  }
644 
646  weights_.resize(extent());
647  weights_[0 ]=(points_[1] -points_[0 ])/(2.*beta_);
648  weights_[extent()-1]=(points_.back()-points_[extent()-2])/(2.*beta_);
649 
650  for(int i=1;i<extent()-1;++i){
651  weights_[i]=(points_[i+1]-points_[i-1])/(2.*beta_);
652  }
653  }
654  };
656  std::ostream &operator<<(std::ostream &os, const power_mesh &M);
657 
658 
660  public:
661  typedef boost::multi_array<double,2> container_type;
662  momentum_realspace_index_mesh(const momentum_realspace_index_mesh& rhs) : points_(boost::extents[rhs.points_.shape()[0]][rhs.points_.shape()[1]]),
663  kind_(rhs.kind_){
664  points_ = rhs.points_;
665  }
667  points_.resize(boost::extents[rhs.points_.shape()[0]][rhs.points_.shape()[1]]);
668  points_ = rhs.points_;
669  kind_ = rhs.kind_;
670  return *this;
671  }
672  protected:
673  container_type points_;
674  private:
675  std::string kind_;
676 
677  inline void throw_if_empty() const {
678  if (extent() == 0) {
679  throw std::runtime_error("momentum_realspace_index_mesh is empty");
680  }
681  }
682 
683  protected:
684  momentum_realspace_index_mesh(): points_(boost::extents[0][0]), kind_("")
685  {
686  }
687 
688  momentum_realspace_index_mesh(const std::string& kind, int ns,int ndim): points_(boost::extents[ns][ndim]), kind_(kind)
689  {
690  }
691 
692  momentum_realspace_index_mesh(const std::string& kind, const container_type& mesh_points): points_(mesh_points), kind_(kind)
693  {
694  }
695 
696  public:
698  int extent() const { return points_.shape()[0];}
700  int dimension() const { return points_.shape()[1];}
702  const std::string &kind() const{return kind_;}
703 
705  bool operator==(const momentum_realspace_index_mesh &mesh) const {
706  throw_if_empty();
707  return kind_ == mesh.kind_ &&
708  points_ == mesh.points_;
709  }
710 
712  bool operator!=(const momentum_realspace_index_mesh &mesh) const {
713  throw_if_empty();
714  return !(*this==mesh);
715  }
716 
717  const container_type &points() const{return points_;}
718  container_type &points() {return points_;}
719 
720  void save(alps::hdf5::archive& ar, const std::string& path) const
721  {
722  throw_if_empty();
723  ar[path+"/kind"] << kind_;
724  ar[path+"/points"] << points_;
725  }
726 
727  void load(alps::hdf5::archive& ar, const std::string& path)
728  {
729  std::string kind;
730  ar[path+"/kind"] >> kind;
731  if (kind!=kind_) throw std::runtime_error("Attempt to load momentum/realspace index mesh from incorrect mesh kind="+kind+ " (expected: "+kind_+")");
732  ar[path+"/points"] >> points_;
733  }
734 
736  void save(alps::hdf5::archive& ar) const
737  {
738  save(ar, ar.get_context());
739  }
740 
743  {
744  load(ar, ar.get_context());
745  }
746 
747 #ifdef ALPS_HAVE_MPI
748  void broadcast(const alps::mpi::communicator& comm, int root)
749  {
750  using alps::mpi::broadcast;
751  if (comm.rank()==root) {
752  throw_if_empty();
753  }
754  // FIXME: introduce (debug-only?) consistency check, like type checking? akin to load()?
755  std::array<size_t, 2> sizes{{points_.shape()[0], points_.shape()[1]}};
756  alps::mpi::broadcast(comm, &sizes[0], 2, root);
757  if (comm.rank()!=root) points_.resize(sizes);
758  detail::broadcast(comm, points_, root);
759  broadcast(comm, kind_, root);
760  }
761 #endif
762 
763  };
765  std::ostream &operator<<(std::ostream &os, const momentum_realspace_index_mesh &M);
766 
767 
770 
771  public:
772 
774  momentum_index_mesh(const momentum_index_mesh& rhs) : base_type(rhs) {}
775 
777  base_type::operator=(rhs);
778  return *this;
779  }
780 
781  momentum_index_mesh(): base_type("MOMENTUM_INDEX",0,0)
782  {
783  }
784 
785  momentum_index_mesh(int ns,int ndim): base_type("MOMENTUM_INDEX",ns,ndim)
786  {
787  }
788 
789  momentum_index_mesh(const container_type& mesh_points): base_type("MOMENTUM_INDEX",mesh_points)
790  {
791  }
792 
794  int operator()(index_type idx) const { return idx(); }
795  };
796 
799 
800  public:
801 
803  real_space_index_mesh(const real_space_index_mesh& rhs) : base_type(rhs) {}
804 
805  real_space_index_mesh(): base_type("REAL_SPACE_INDEX",0,0)
806  {
807  }
808 
809  real_space_index_mesh(int ns,int ndim): base_type("REAL_SPACE_INDEX",ns,ndim)
810  {
811  }
812 
813  real_space_index_mesh(const container_type& mesh_points): base_type("REAL_SPACE_INDEX",mesh_points)
814  {
815  }
816 
818  int operator()(index_type idx) const { return idx(); }
819  };
820 
821  class index_mesh {
822  int npoints_;
823  std::vector<int> points_;
824  public:
826 
827  index_mesh(const index_mesh& rhs) : npoints_(rhs.npoints_) {compute_points();}
828  index_mesh& operator=(const index_mesh& rhs) {npoints_ = rhs.npoints_; compute_points();return * this;}
829  index_mesh(): npoints_(0) { compute_points();}
830  index_mesh(int np): npoints_(np) { compute_points();}
831  int extent() const{return npoints_;}
832  int operator()(index_type idx) const { return idx(); }
833  const std::vector<int> &points() const{return points_;}
834 
835  inline void throw_if_empty() const {
836  if (extent() == 0) {
837  throw std::runtime_error("index_mesh is empty");
838  }
839  }
840 
842  bool operator==(const index_mesh &mesh) const {
843  throw_if_empty();
844  return npoints_==mesh.npoints_;
845  }
846 
848  bool operator!=(const index_mesh &mesh) const {
849  throw_if_empty();
850  return !(*this==mesh);
851  }
852 
853  void save(alps::hdf5::archive& ar, const std::string& path) const
854  {
855  throw_if_empty();
856  ar[path+"/kind"] << "INDEX";
857  ar[path+"/N"] << npoints_;
858  }
859 
860  void load(alps::hdf5::archive& ar, const std::string& path)
861  {
862  std::string kind;
863  ar[path+"/kind"] >> kind;
864  if (kind!="INDEX") throw std::runtime_error("Attempt to read Index mesh from non-Index data, kind="+kind); // FIXME: specific exception
865 
866  int np;
867  ar[path+"/N"] >> np;
868  npoints_=np;
869  compute_points();
870  }
871 
873  void save(alps::hdf5::archive& ar) const
874  {
875  save(ar, ar.get_context());
876  }
877 
880  {
881  load(ar, ar.get_context());
882  }
883 
884  void compute_points(){ points_.resize(npoints_); for(int i=0;i<npoints_;++i){points_[i]=i;} }
885 
886 #ifdef ALPS_HAVE_MPI
887  void broadcast(const alps::mpi::communicator& comm, int root)
888  {
889  using alps::mpi::broadcast;
890  if(comm.rank() == root) throw_if_empty();
891  broadcast(comm, npoints_, root);
892  compute_points();
893  }
894 #endif
895  };
897  std::ostream &operator<<(std::ostream &os, const index_mesh &M);
898 
899  class legendre_mesh : public base_mesh {
900  double beta_;
901  int n_max_;//number of legendre polynomials
902 
903  statistics::statistics_type statistics_;
904 
905  inline void throw_if_empty() const {
906  if (extent() == 0) {
907  throw std::runtime_error("legendre_mesh is empty");
908  }
909  }
910 
911  public:
913  legendre_mesh(const legendre_mesh& rhs) : beta_(rhs.beta_), n_max_(rhs.n_max_), statistics_(rhs.statistics_) {compute_points();}
915  beta_(0.0), n_max_(0), statistics_(statistics) {}
916 
918  beta_(b), n_max_(n_max), statistics_(statistics) {
919  check_range();
920  compute_points();
921  }
922  int extent() const{return n_max_;}
923 
924  int operator()(index_type idx) const {
925 #ifndef NDEBUG
926  throw_if_empty();
927 #endif
928  return idx();
929  }
930 
932  bool operator==(const legendre_mesh &mesh) const {
933  throw_if_empty();
934  return beta_==mesh.beta_ && n_max_==mesh.n_max_ && statistics_==mesh.statistics_;
935  }
936 
938  bool operator!=(const legendre_mesh &mesh) const {
939  throw_if_empty();
940  return !(*this==mesh);
941  }
942 
944  double beta() const{ return beta_;}
945  statistics::statistics_type statistics() const{ return statistics_;}
946 
948  // It's a member function to avoid dealing with templated friend decalration.
949  void swap(legendre_mesh& other) {
950  using std::swap;
951  throw_if_empty();
952  if (this->statistics_ != other.statistics_) {
953  throw std::runtime_error("Attempt to swap LEGENDRE meshes with different statistics");
954  }
955  swap(this->beta_, other.beta_);
956  swap(this->n_max_, other.n_max_);
957  base_mesh::swap(other);
958  }
959 
960  void save(alps::hdf5::archive& ar, const std::string& path) const
961  {
962  throw_if_empty();
963  ar[path+"/kind"] << "LEGENDRE";
964  ar[path+"/N"] << n_max_;
965  ar[path+"/statistics"] << int(statistics_);
966  ar[path+"/beta"] << beta_;
967  }
968 
969  void load(alps::hdf5::archive& ar, const std::string& path)
970  {
971  std::string kind;
972  ar[path+"/kind"] >> kind;
973  if (kind!="LEGENDRE") throw std::runtime_error("Attempt to read LEGENDRE mesh from non-LEGENDRE data, kind="+kind); // FIXME: specific exception
974  double n_max, beta;
975  int stat;
976 
977  ar[path+"/N"] >> n_max;
978  ar[path+"/statistics"] >> stat;
979  ar[path+"/beta"] >> beta;
980 
981  statistics_=statistics::statistics_type(stat);
982  beta_=beta;
983  n_max_=n_max;
984  check_range();
985  compute_points();
986  }
987 
989  void save(alps::hdf5::archive& ar) const
990  {
991  save(ar, ar.get_context());
992  }
993 
996  {
997  load(ar, ar.get_context());
998  }
999 
1000 #ifdef ALPS_HAVE_MPI
1001  void broadcast(const alps::mpi::communicator& comm, int root)
1002  {
1003  using alps::mpi::broadcast;
1004  if(comm.rank() == root) throw_if_empty();
1005  broadcast(comm, beta_, root);
1006  broadcast(comm, n_max_, root);
1007  {
1008  int stat = static_cast<int>(statistics_);
1009  broadcast(comm, stat, root);
1010  statistics_=statistics::statistics_type(stat);
1011  }
1012 
1013  try {
1014  check_range();
1015  } catch (const std::exception& exc) {
1016  // FIXME? Try to communiucate the error with all ranks, at least in debug mode?
1017  int wrank=alps::mpi::communicator().rank();
1018  std::cerr << "legendre_mesh<>::broadcast() exception at WORLD rank=" << wrank << std::endl
1019  << exc.what()
1020  << "\nAborting." << std::endl;
1021  MPI_Abort(MPI_COMM_WORLD,1);
1022  }
1023  compute_points(); // recompute points rather than sending them over MPI
1024  }
1025 #endif
1026 
1027  void check_range(){
1028  if(statistics_!=statistics::FERMIONIC && statistics_!=statistics::BOSONIC) throw std::invalid_argument("statistics should be bosonic or fermionic");
1029  }
1031  //This is sort of trivial in the current implementation.
1032  //We use P_0, P_1, P_2, ..., P_{n_max_-1}
1033  _points().resize(extent());
1034  for(int i=0;i<n_max_;++i){
1035  _points()[i]=i;
1036  }
1037  }
1038  };
1040  std::ostream &operator<<(std::ostream &os, const legendre_mesh &M);
1041 
1045  template<class T>
1046  class numerical_mesh : public base_mesh {
1047  double beta_;
1048  int dim_;//dimension of the basis
1049 
1050  statistics::statistics_type statistics_;
1051 
1052  std::vector<piecewise_polynomial<T> > basis_functions_;
1053 
1054  bool valid_;
1055 
1056  void set_validity() {
1057  valid_ = true;
1058  valid_ = valid_ && dim_ > 0;
1059  valid_ = valid_ && std::size_t(dim_) == basis_functions_.size();
1060  valid_ = valid_ && beta_ >= 0.0;
1061  valid_ = valid_ && (statistics_==statistics::FERMIONIC || statistics_==statistics::BOSONIC);
1062 
1063  if (basis_functions_.size() > 1u) {
1064  for (std::size_t l=0; l < basis_functions_.size()-1; ++l) {
1065  valid_ = valid_ && (basis_functions_[l].section_edges() == basis_functions_[l+1].section_edges());
1066  }
1067  }
1068  }
1069 
1070  void check_validity() const {
1071  if (!valid_) {
1072  throw std::runtime_error("numerical mesh has not been properly constructed!");
1073  }
1074  }
1075 
1076  public:
1078  numerical_mesh(const numerical_mesh<T>& rhs) : beta_(rhs.beta_), dim_(rhs.dim_), basis_functions_(rhs.basis_functions_), statistics_(rhs.statistics_), valid_(rhs.valid_) {
1079  set_validity();
1080  compute_points();
1081  }
1083  beta_(0.0), dim_(0), statistics_(statistics), basis_functions_(), valid_(false) {}
1084 
1085  numerical_mesh(double b, const std::vector<piecewise_polynomial<T> >&basis_functions,
1087  beta_(b), dim_(basis_functions.size()), statistics_(statistics), basis_functions_(basis_functions), valid_(false) {
1088  set_validity();
1089  //check_range();
1090  compute_points();
1091  }
1092 
1093  int extent() const{
1094  check_validity();
1095  return dim_;
1096  }
1097 
1098  int operator()(index_type idx) const {
1099  check_validity();
1100  return idx();
1101  }
1102 
1104  bool operator==(const numerical_mesh &mesh) const {
1105  check_validity();
1106  return beta_==mesh.beta_ && dim_==mesh.dim_ && statistics_==mesh.statistics_ && basis_functions_==mesh.basis_functions_;
1107  }
1108 
1110  bool operator!=(const numerical_mesh &mesh) const {
1111  check_validity();
1112  return !(*this==mesh);
1113  }
1114 
1116  double beta() const{ return beta_;}
1117  statistics::statistics_type statistics() const{ return statistics_;}
1119  assert(l>=0 && l < dim_);
1120  check_validity();
1121  return basis_functions_[l];
1122  }
1123 
1124 
1126  // It's a member function to avoid dealing with templated friend decalration.
1127  void swap(numerical_mesh& other) {
1128  using std::swap;
1129  check_validity();
1130  swap(this->beta_, other.beta_);
1131  swap(this->dim_, other.dim_);
1132  if (this->statistics_ != other.statistics_) {
1133  throw std::runtime_error("Do not swap numerical meshes with different statistics!");
1134  }
1135  swap(this->basis_functions_, other.basis_functions_);
1136  base_mesh::swap(other);
1137  }
1138 
1140  this->beta_ = other.beta_;
1141  this->dim_ = other.dim_;
1142  this->statistics_ = other.statistics_;
1143  this->basis_functions_ = other.basis_functions_;
1144  base_mesh::operator=(other);
1145  }
1146 
1147  void save(alps::hdf5::archive& ar, const std::string& path) const
1148  {
1149  check_validity();
1150  ar[path+"/kind"] << "NUMERICAL_MESH";
1151  ar[path+"/N"] << dim_;
1152  ar[path+"/statistics"] << int(statistics_);
1153  ar[path+"/beta"] << beta_;
1154  for (int l=0; l < dim_; ++l) {
1155  basis_functions_[l].save(ar, path+"/basis_functions"+std::to_string(l));
1156  }
1157  }
1158 
1159  void load(alps::hdf5::archive& ar, const std::string& path)
1160  {
1161  std::string kind;
1162  ar[path+"/kind"] >> kind;
1163  if (kind!="NUMERICAL_MESH") throw std::runtime_error("Attempt to read NUMERICAL_MESH mesh from non-numerical-mesh data, kind="+kind); // FIXME: specific exception
1164  double dim, beta;
1165  int stat;
1166 
1167  ar[path+"/N"] >> dim;
1168  ar[path+"/statistics"] >> stat;
1169  if (valid_ && stat != statistics_) {
1170  throw std::runtime_error("Attemp to load data with different statistics!");
1171  }
1172 
1173  ar[path+"/beta"] >> beta;
1174  basis_functions_.resize(dim);
1175  for (int l=0; l < dim; ++l) {
1176  basis_functions_[l].load(ar, path+"/basis_functions"+std::to_string(l));
1177  }
1178 
1179  statistics_ = static_cast<statistics::statistics_type>(stat);
1180  beta_=beta;
1181  dim_=dim;
1182  set_validity();
1183  compute_points();
1184  }
1185 
1187  void save(alps::hdf5::archive& ar) const
1188  {
1189  save(ar, ar.get_context());
1190  }
1191 
1194  {
1195  load(ar, ar.get_context());
1196  }
1197 
1198 #ifdef ALPS_HAVE_MPI
1199  void broadcast(const alps::mpi::communicator& comm, int root)
1200  {
1201  using alps::mpi::broadcast;
1202  if(comm.rank() == root) check_validity();
1203 
1204  broadcast(comm, beta_, root);
1205  broadcast(comm, dim_, root);
1206  {
1207  int stat = static_cast<int>(statistics_);
1208  broadcast(comm, stat, root);
1209  statistics_=statistics::statistics_type(stat);
1210  }
1211 
1212  basis_functions_.resize(dim_);
1213  for (int l=0; l < dim_; ++l) {
1214  basis_functions_[l].broadcast(comm, root);
1215  }
1216 
1217  set_validity();
1218  try {
1219  check_validity();
1220  } catch (const std::exception& exc) {
1221  // FIXME? Try to communiucate the error with all ranks, at least in debug mode?
1222  int wrank=alps::mpi::communicator().rank();
1223  std::cerr << "numerical_mesh<>::broadcast() exception at WORLD rank=" << wrank << std::endl
1224  << exc.what()
1225  << "\nAborting." << std::endl;
1226  MPI_Abort(MPI_COMM_WORLD,1);
1227  }
1228  compute_points(); // recompute points rather than sending them over MPI
1229  }
1230 #endif
1231 
1233  _points().resize(extent());
1234  for(int i=0;i<dim_;++i){
1235  _points()[i]=i;
1236  }
1237  }
1238  };
1239 
1251 
1252  namespace detail {
1253  /* The following is an in-house implementation of a static_assert
1254  with the intent to generate a compile-time error message
1255  that has some relevance to the asserted condition
1256  (unlike BOOST_STATIC_ASSERT).
1257  */
1258 
1260  struct can_have_tail_yes { typedef bool mesh_can_have_tail; };
1262  struct can_have_tail_no { typedef bool mesh_cannot_have_tail; };
1263 
1265  template <typename> struct can_have_tail: public can_have_tail_no {};
1266 
1268  template <> struct can_have_tail<matsubara_positive_mesh>: public can_have_tail_yes {};
1270  template <> struct can_have_tail<matsubara_pn_mesh>: public can_have_tail_yes {};
1272  template <> struct can_have_tail<itime_mesh>: public can_have_tail_yes {};
1273 
1274  /* ^^^^ End of static_assert code */
1275 
1277 
1278  std::ostream& operator<<(std::ostream& s, const boost::multi_array<double, 1>& data);
1279 
1280  } // ::detail
1281  }
1282 }
int uniform() const
Definition: mesh.hpp:533
generic_index< index_mesh > index_type
Definition: mesh.hpp:825
bool operator>(int x) const
Definition: mesh.hpp:59
bool operator==(const real_frequency_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:146
void save(alps::hdf5::archive &ar, const std::string &path) const
Definition: mesh.hpp:960
const std::vector< int > & points() const
Definition: mesh.hpp:833
generic_index & operator+=(int i)
Definition: mesh.hpp:55
generic_index< itime_mesh > index_type
Definition: mesh.hpp:369
index_mesh::index_type index
Definition: mesh.hpp:1247
bool operator==(const numerical_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:1104
void swap(matsubara_mesh< PTYPE > &a, matsubara_mesh< PTYPE > &b)
Swaps two Matsubara meshes.
Definition: mesh.hpp:350
momentum_index_mesh(int ns, int ndim)
Definition: mesh.hpp:785
int extent() const
Definition: mesh.hpp:391
const std::vector< double > & weights() const
Definition: mesh.hpp:546
void save(alps::hdf5::archive &ar) const
Save to HDF5.
Definition: mesh.hpp:134
numerical_mesh< double >::index_type numerical_mesh_index
Definition: mesh.hpp:1250
bool operator==(const legendre_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:932
bool operator<(int x) const
Definition: mesh.hpp:58
mesh::frequency_positivity_type positivity() const
Definition: mesh.hpp:230
matsubara_mesh(const matsubara_mesh &rhs)
copy constructor
Definition: mesh.hpp:194
void save(alps::hdf5::archive &ar, const std::string &path) const
Definition: mesh.hpp:118
int operator()(index_type idx) const
Definition: mesh.hpp:924
generic_index & operator--()
Definition: mesh.hpp:53
void save(alps::hdf5::archive &ar) const
Save to HDF5.
Definition: mesh.hpp:280
momentum_realspace_index_mesh(const momentum_realspace_index_mesh &rhs)
Definition: mesh.hpp:662
const piecewise_polynomial< T > & basis_function(int l) const
Definition: mesh.hpp:1118
statistics::statistics_type statistics() const
Definition: mesh.hpp:402
itime_mesh(const itime_mesh &rhs)
Definition: mesh.hpp:375
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
void save(alps::hdf5::archive &ar, const std::string &path) const
Definition: mesh.hpp:1147
generic_index< real_frequency_mesh > index_type
Definition: mesh.hpp:102
void operator=(int i)
Definition: mesh.hpp:50
int power() const
Definition: mesh.hpp:532
legendre_mesh(const legendre_mesh &rhs)
Definition: mesh.hpp:913
int operator()() const
Definition: mesh.hpp:62
std::ostream & operator<<(std::ostream &os, const real_frequency_mesh &M)
Definition: mesh.cpp:40
std::enable_if<!is_sequence< T >::value, std::size_t >::type size(T const &)
Definition: size.hpp:20
int operator()(index_type idx) const
Definition: mesh.hpp:385
int dimension() const
returns the spatial dimension
Definition: mesh.hpp:700
void load(alps::hdf5::archive &ar, const std::string &path)
Definition: mesh.hpp:255
void broadcast(C const &c, P &p, int r=0)
Definition: api.hpp:56
momentum_index_mesh & operator=(const momentum_index_mesh &rhs)
Definition: mesh.hpp:776
bool operator!=(const itime_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:406
int operator()(index_type idx) const
Definition: mesh.hpp:208
generic_index< matsubara_mesh > index_type
Definition: mesh.hpp:192
statistics::statistics_type statistics() const
Definition: mesh.hpp:544
void swap(legendre_mesh &other)
Swaps this and another mesh.
Definition: mesh.hpp:949
bool operator!=(const numerical_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:1110
index_mesh(const index_mesh &rhs)
Definition: mesh.hpp:827
bool operator!=(const momentum_realspace_index_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:712
bool operator==(const power_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:536
momentum_index_mesh(const momentum_index_mesh &rhs)
Definition: mesh.hpp:774
numerical_mesh(double b, const std::vector< piecewise_polynomial< T > > &basis_functions, gf::statistics::statistics_type statistics=statistics::FERMIONIC)
Definition: mesh.hpp:1085
real_frequency_mesh(const GRID &grid)
Definition: mesh.hpp:107
bool operator!=(const power_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:549
void load(alps::hdf5::archive &ar, const std::string &path)
Definition: mesh.hpp:125
bool operator!=(const matsubara_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:222
momentum_realspace_index_mesh & operator=(const momentum_realspace_index_mesh &rhs)
Definition: mesh.hpp:666
int operator()(index_type idx) const
Returns the index of the mesh point in the data array.
Definition: mesh.hpp:794
real_space_index_mesh(const real_space_index_mesh &rhs)
Definition: mesh.hpp:803
const std::vector< double > & points() const
Definition: mesh.hpp:403
matsubara_mesh< mesh::POSITIVE_ONLY > matsubara_positive_mesh
Definition: mesh.hpp:1240
void save(alps::hdf5::archive &ar, const std::string &path) const
Definition: mesh.hpp:554
Encapsulation of an MPI communicator and some communicator-related operations.
Definition: mpi.hpp:111
generic_index< legendre_mesh > index_type
Definition: mesh.hpp:912
int extent() const
Definition: mesh.hpp:205
itime_mesh::index_type itime_index
Definition: mesh.hpp:1244
int operator()(index_type idx) const
Definition: mesh.hpp:1098
numerical_mesh & operator=(const numerical_mesh &other)
Definition: mesh.hpp:1139
void swap(matsubara_mesh &other)
Swaps this and another mesh.
Definition: mesh.hpp:234
boost::multi_array< double, 2 > container_type
Definition: mesh.hpp:661
Common part of interface and implementation for GF meshes.
Definition: mesh.hpp:77
bool operator==(const matsubara_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:216
generic_index & operator++()
Definition: mesh.hpp:52
void load(alps::hdf5::archive &ar)
Load from HDF5.
Definition: mesh.hpp:140
void compute_weights()
Definition: mesh.hpp:645
const container_type & points() const
Definition: mesh.hpp:717
void compute_points()
Definition: mesh.hpp:474
int operator()(index_type idx) const
Definition: mesh.hpp:112
legendre_mesh(gf::statistics::statistics_type statistics=statistics::FERMIONIC)
Definition: mesh.hpp:914
void save(alps::hdf5::archive &ar) const
Save to HDF5.
Definition: mesh.hpp:446
int operator()(index_type idx) const
Returns the index of the mesh point in the data array.
Definition: mesh.hpp:818
matsubara_mesh< mesh::POSITIVE_NEGATIVE > matsubara_pn_mesh
Definition: mesh.hpp:1241
bool operator==(const momentum_realspace_index_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:705
void save(alps::hdf5::archive &ar, const std::string &path) const
Definition: mesh.hpp:720
void load(alps::hdf5::archive &ar, const std::string &path)
Definition: mesh.hpp:423
Mesh of real frequencies.
Definition: mesh.hpp:95
void save(alps::hdf5::archive &ar) const
Save to HDF5.
Definition: mesh.hpp:590
bool operator==(const index_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:842
real_space_index_mesh::index_type real_space_index
Definition: mesh.hpp:1246
bool operator!=(const index_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:848
real_space_index_mesh(int ns, int ndim)
Definition: mesh.hpp:809
void save(alps::hdf5::archive &ar, const std::string &path) const
Definition: mesh.hpp:244
void save(alps::hdf5::archive &ar, const std::string &path) const
Definition: mesh.hpp:853
void compute_points()
Definition: mesh.hpp:884
void load(alps::hdf5::archive &ar)
Load from HDF5.
Definition: mesh.hpp:452
void load(alps::hdf5::archive &ar, const std::string &path)
Definition: mesh.hpp:727
int extent() const
Definition: mesh.hpp:922
itime_mesh(double beta, int ntau)
Definition: mesh.hpp:381
bool operator!=(const real_frequency_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:152
void save(alps::hdf5::archive &ar) const
Save to HDF5.
Definition: mesh.hpp:989
bool operator==(int x) const
Definition: mesh.hpp:60
statistics::statistics_type statistics() const
Definition: mesh.hpp:1117
int extent() const
Returns the number of points.
Definition: mesh.hpp:698
base_mesh(const base_mesh &rhs)
Definition: mesh.hpp:80
void load(alps::hdf5::archive &ar)
Load from HDF5.
Definition: mesh.hpp:742
void load(alps::hdf5::archive &ar)
Load from HDF5.
Definition: mesh.hpp:1193
momentum_realspace_index_mesh(const std::string &kind, int ns, int ndim)
Definition: mesh.hpp:688
std::string get_context() const
Definition: archive.cpp:144
int extent() const
Definition: mesh.hpp:831
numerical_mesh(const numerical_mesh< T > &rhs)
Definition: mesh.hpp:1078
statistics::statistics_type statistics() const
Definition: mesh.hpp:945
matsubara_mesh< mesh::POSITIVE_ONLY >::index_type matsubara_index
Definition: mesh.hpp:1242
numerical_mesh(gf::statistics::statistics_type statistics=statistics::FERMIONIC)
Definition: mesh.hpp:1082
generic_index< numerical_mesh > index_type
Definition: mesh.hpp:1077
legendre_mesh::index_type legendre_index
Definition: mesh.hpp:1249
void load(alps::hdf5::archive &ar)
Load from HDF5.
Definition: mesh.hpp:596
real_frequency_mesh(const real_frequency_mesh &rhs)
Definition: mesh.hpp:104
int operator()(index_type idx) const
Definition: mesh.hpp:832
double beta() const
Getter variables for members.
Definition: mesh.hpp:401
void load(alps::hdf5::archive &ar, const std::string &path)
Definition: mesh.hpp:969
const std::vector< double > & points() const
Definition: mesh.hpp:545
void swap(base_mesh &other)
Definition: mesh.hpp:86
Functions to MPI-broadcast internal data structures.
std::vector< double > & _points()
Definition: mesh.hpp:85
legendre_mesh(double b, int n_max, gf::statistics::statistics_type statistics=statistics::FERMIONIC)
Definition: mesh.hpp:917
void save(alps::hdf5::archive &ar) const
Save to HDF5.
Definition: mesh.hpp:1187
void compute_points()
Definition: mesh.hpp:619
momentum_realspace_index_mesh(const std::string &kind, const container_type &mesh_points)
Definition: mesh.hpp:692
void load(alps::hdf5::archive &ar, const std::string &path)
Definition: mesh.hpp:1159
std::vector< T > pow(std::vector< T > vec, U index)
void load(alps::hdf5::archive &ar, const std::string &path)
Definition: mesh.hpp:566
int rank() const
Returns process rank in this communicator.
Definition: mpi.hpp:156
momentum_index_mesh(const container_type &mesh_points)
Definition: mesh.hpp:789
void save(alps::hdf5::archive &ar) const
Save to HDF5.
Definition: mesh.hpp:873
double beta() const
Getter variables for members.
Definition: mesh.hpp:543
void load(alps::hdf5::archive &ar, const std::string &path)
Definition: mesh.hpp:860
bool operator==(const itime_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:394
void load(alps::hdf5::archive &ar)
Load from HDF5.
Definition: mesh.hpp:995
statistics::statistics_type statistics() const
Definition: mesh.hpp:229
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
power_mesh(const power_mesh &rhs)
Definition: mesh.hpp:513
generic_index< momentum_index_mesh > index_type
Definition: mesh.hpp:802
index_mesh(int np)
Definition: mesh.hpp:830
void swap(numerical_mesh &other)
Swaps this and another mesh.
Definition: mesh.hpp:1127
frequency_positivity_type
Definition: mesh.hpp:71
const std::string & kind() const
returns the mesh kind
Definition: mesh.hpp:702
bool operator!=(const legendre_mesh &mesh) const
Comparison operators.
Definition: mesh.hpp:938
double beta() const
getter functions for member variables
Definition: mesh.hpp:944
matsubara_mesh(double b, int nfr, gf::statistics::statistics_type statistics=statistics::FERMIONIC)
Definition: mesh.hpp:200
power_mesh(double beta, int power, int uniform)
Definition: mesh.hpp:521
index_mesh & operator=(const index_mesh &rhs)
Definition: mesh.hpp:828
void load(alps::hdf5::archive &ar)
Load from HDF5.
Definition: mesh.hpp:286
void throw_if_empty() const
Definition: mesh.hpp:835
void save(alps::hdf5::archive &ar) const
Save to HDF5.
Definition: mesh.hpp:736
int operator()(index_type idx) const
Definition: mesh.hpp:525
int extent() const
Definition: mesh.hpp:1093
matsubara_mesh< mesh::POSITIVE_NEGATIVE >::index_type matsubara_pn_index
Definition: mesh.hpp:1243
generic_index< power_mesh > index_type
Definition: mesh.hpp:511
double beta() const
getter functions for member variables
Definition: mesh.hpp:228
void load(alps::hdf5::archive &ar)
Load from HDF5.
Definition: mesh.hpp:879
int extent() const
Definition: mesh.hpp:531
real_space_index_mesh(const container_type &mesh_points)
Definition: mesh.hpp:813
double beta() const
getter functions for member variables
Definition: mesh.hpp:1116
momentum_index_mesh::index_type momentum_index
Definition: mesh.hpp:1245
generic_index< momentum_index_mesh > index_type
Definition: mesh.hpp:773
real_frequency_mesh::index_type real_freq_index
Definition: mesh.hpp:1248
const std::vector< double > & points() const
Const access to mesh points.
Definition: mesh.hpp:82
generic_index & operator-=(int i)
Definition: mesh.hpp:56
Class representing a piecewise polynomial and utilities.
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
A generic index.
Definition: mesh.hpp:39
void save(alps::hdf5::archive &ar, const std::string &path) const
Definition: mesh.hpp:411