/******************************************************************************* * * TRIQS: a Toolbox for Research in Interacting Quantum Systems * * Copyright (C) 2011 by M. Ferrero, 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 . * ******************************************************************************/ #ifndef MC_MEASURE1_H #define MC_MEASURE1_H #include #include #include #include #include #include namespace triqs { namespace mc_tools { namespace mpi=boost::mpi; using std::size_t; //-------------------------------------------------------------------- namespace details { template class measure_base { public: virtual ~measure_base(){} virtual void accumulate(MCSignType signe)=0; virtual void collect_results(mpi::communicator const & c)=0; virtual uint64_t count() const=0; }; //-------------------------------------------------------------------- template struct IsMeasure { BOOST_CONCEPT_USAGE(IsMeasure) { i.accumulate(MCSignType(1.0)); i.collect_results (*c); } private: X i; boost::mpi::communicator const * c; }; //-------------------------------------------------------------------- template class measure_impl : public measure_base { BOOST_CONCEPT_ASSERT((IsMeasure)); void operator=(measure_impl const &); // forbidden protected: boost::shared_ptr ptr; uint64_t count_; public: measure_impl(MeasureType * _ptr):measure_base(), ptr(_ptr),count_(0) {} measure_impl(boost::shared_ptr sptr) : measure_base(), ptr(sptr),count_(0) {} measure_impl( measure_impl const & X):measure_base(X), ptr( new MeasureType (*X.ptr.get())),count_(X.count_) {} virtual ~measure_impl(){} virtual void accumulate(MCSignType signe){ count_++; ptr->accumulate(signe); } virtual void collect_results(mpi::communicator const & c) { ptr->collect_results (c); } virtual uint64_t count() const { return count_;} }; }//details namespace //-------------------------------------------------------------------- template class mcmeasure { boost::shared_ptr< details::measure_base > impl_; public : template mcmeasure ( MeasureType * p) : impl_( new details::measure_impl (p)) {} template mcmeasure ( boost::shared_ptr sptr) : impl_( new details::measure_impl (sptr)) {} mcmeasure() {} void accumulate(MCSignType const & signe) { assert(impl_); impl_->accumulate(signe);} void collect_results(boost::mpi::communicator const & communicator) { assert(impl_); impl_-> collect_results(communicator);} uint64_t count() const { assert(impl_); return impl_->count();} // Recover the measure in its original type /* template T const & get() const { assert(impl_); details::measure_impl * res = dynamic_cast< details::measure_impl *> (impl_.get()); if (!res) TRIQS_RUNTIME_ERROR<<"Internal error in measure_set : Measure is not of the required type"; return res.get(); } */ }; //-------------------------------------------------------------------- template class measure_set : public std::map > { typedef std::map > BaseType; typedef mcmeasure measure_type; public : typedef typename BaseType::iterator iterator; typedef typename BaseType::const_iterator const_iterator; /** * Register the Measure M with a name * WARNING : the pointer is deleted automatically by the class at destruction. */ template void insert (T * && M, std::string const & name) { if (has(name)) TRIQS_RUNTIME_ERROR <<"measure_set : insert : measure '"< void insert(boost::shared_ptr ptr, std::string const & name) { if (has(name)) TRIQS_RUNTIME_ERROR <<"measure_set : insert : measure '"<second; } measure_type const & operator[](std::string const & name) const { if (!has(name)) throw std::out_of_range("No result found with the name: " + name); return BaseType::find(name)->second; } /// void accumulate( MCSignType & signe) { for (iterator it= this->begin(); it != this->end(); ++it) it->second.accumulate(signe); } /// //size_t size() const {return name_to_mes.size(); } /// std::vector names() const { std::vector res; for (const_iterator it= this->begin(); it !=this->end(); ++it) res.push_back(it->first); return res; } // gather result for all measure, on communicator c void collect_results (boost::mpi::communicator const & c ) { for (typename BaseType::iterator it = this->begin(); it != this->end(); ++it) it->second.collect_results(c); } }; }}// end namespace #endif