⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stored_range.h

📁 一个用来实现偏微分方程中网格的计算库
💻 H
字号:
// $Id: elem.h 2575 2007-12-06 20:36:07Z roystgnr $// The libMesh Finite Element Library.// Copyright (C) 2002-2007  Benjamin S. Kirk, John W. Peterson  // This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.  // This library 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// Lesser General Public License for more details.  // You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA#ifndef __stored_range_h__#define __stored_range_h__// C++ includes#include <vector>// Local includes#include "threads.h"/** * The \p StoredRange class defined a contiguous, divisible set of objects * This class is used primarily as the argument to function objects.  The * range can then be subdivided into a number of "tasks" which can be executed * in parallel.  This concept is central to the Threading Building Blocks * template library which can optionally be used by \p libMesh to implement * shared-memory parallelism. * * The implementation takes a user-provided object range and packs it into * a contiguous vector which can then be subdivided efficiently.  A first-cut * implementation using raw element iterators incurred simply too much overhead * by using the predicated iterators, specifically operations such as advancing * such iterators has a cost proportional to the amount the iterator is advanced. * Hence in this implementation the user-provided range is packed into a vector.  * * \author Benjamin S. Kirk, 2008. */template <typename iterator_type, typename object_type>class StoredRange {public:  /**   * Allows an \p StoredRange to behave like an STL container.   */  typedef typename std::vector<object_type>::const_iterator const_iterator;  /**   * Constructor. Optionally takes the \p grainsize parameter, which is the   * smallest chunk the range may be broken into for parallel   * execution.   */  StoredRange (const unsigned int grainsize = 1000) :  _grainsize(grainsize)  {}  /**   * Constructor.  Takes the beginning and end of the range.     * Optionally takes the \p grainsize parameter, which is the   * smallest chunk the range may be broken into for parallel   * execution.   */  StoredRange (const iterator_type &first,	       const iterator_type &last,	       const unsigned int grainsize = 1000) :  _grainsize(grainsize)  {    this->reset(first, last);  }  /**   * Copy constructor.  The \p StoredRange can be copied into   * subranges for parallel execution.  In this way the    * initial \p StoredRange can be thought of as the root of   * a binary tree.  The root element is the only element   * which interacts with the user.  It takes a specified   * range of objects and packs it into a contiguous vector   * which can be split efficiently. However, there is no need   * for the child ranges to contain this vector, so long as   * the parent outlives the children.  So we implement   * the copy constructor to specifically omit the \p _objs   * vector.   */  StoredRange (const StoredRange<iterator_type,object_type> &er):    _end(er._end),     _begin(er._begin),    _last(er._last),    _first(er._first),    _grainsize(er._grainsize)  {    // specifically, do *not* copy the vector  }      /**   * Splits the range \p r.  The first half   * of the range is left in place, the second   * half of the range is placed in *this.   */  StoredRange (StoredRange<iterator_type,object_type> &r, Threads::split ) :     _end(r._end),    _begin(r._begin),    _last(r._last),    _first(r._first),    _grainsize(r._grainsize)  {    const_iterator      beginning = r._begin,      ending    = r._end,      middle    = beginning + std::distance(beginning, ending)/2u;        r._end = _begin = middle;    unsigned int      first = r._first,      last  = r._last,      half  = first + (last-first)/2u;    r._last = _first = half;  }      /**   * Resets the \p StoredRange to contain [first,last).   */   void reset (const iterator_type &first,	      const iterator_type &last)  {    _objs.clear();    for (iterator_type it=first; it!=last; ++it)      _objs.push_back(*it);        _begin = _objs.begin();    _end   = _objs.end();    _first = 0;    _last  = _objs.size();  }  /**   * Resets the range to the last specified range.  This method only exists   * for efficiency -- it is more efficient to set the range to its previous   * value without rebuilding the underlying vector.   */  void reset ()  {    _begin = _objs.begin();    _end   = _objs.end();    _first = 0;    _last  = _objs.size();  }    /**   * Beginning of the range.   */  const_iterator begin () const { return _begin; }      /**   * End of the range.   */  const_iterator end () const { return _end; }  /**   * Index in the stored vector of the first object.   */  unsigned int first_idx () const { return _first; }  /**   * Index in the stored vector of the last object.   */  unsigned int last_idx () const { return _last; }  /**   * The grain size for the range.  The range will be subdivided into    * subranges not to exceed the grain size.   */  unsigned int grainsize () const {return _grainsize;}  /**   * Set the grain size.   */  void  grainsize (const unsigned int &gs) {_grainsize = gs;}  /**   * \return the size of the range.   */  unsigned int size () const { return std::distance(_begin, _end); }  //------------------------------------------------------------------------  // Methods that implement Range concept  //------------------------------------------------------------------------  /**   * Returns true if the range is empty.   */    bool empty() const { return (_begin == _end); }  /**   * Returns true if the range can be subdivided.   */  bool is_divisible() const { return this->grainsize() < static_cast<unsigned int>(std::distance(_begin, _end)); }private:  const_iterator _end;  const_iterator _begin;  unsigned int _last;  unsigned int _first;  unsigned int _grainsize;  std::vector<object_type> _objs;};#endif // end #ifndef __stored_range_h__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -