Actual source code: ALE_containers.hh
petsc-3.4.2 2013-07-02

      1: #ifndef included_ALE_containers_hh
      2: #define included_ALE_containers_hh
      3: // This should be included indirectly -- only by including ALE.hh

      5: #include <boost/multi_index_container.hpp>
      6: #include <boost/multi_index/member.hpp>
      7: #include <boost/multi_index/ordered_index.hpp>
      8: #include <boost/multi_index/composite_key.hpp>

     10: #include <iostream>
     11: #include <map>
     12: #include <set>
     13: #include <vector>

     15: #ifndef  included_ALE_exception_hh
     16: #include <sieve/ALE_exception.hh>
     17: #endif
     18: #ifndef  included_ALE_mem_hh
     19: #include <sieve/ALE_mem.hh>
     20: #endif
     21: #ifndef  included_ALE_log_hh
     22: #include <sieve/ALE_log.hh>
     23: #endif

     25: namespace ALE {
     26:   class ParallelObject {
     27:   protected:
     28:     int         _debug;
     29:     MPI_Comm    _comm;
     30:     int         _commRank;
     31:     int         _commSize;
     32:     std::string _name;
     33:     std::string _className;
     34:   protected:
     35:     void __init(MPI_Comm comm) {

     38:       this->_comm = comm;
     39:       MPI_Comm_rank(this->_comm, &this->_commRank);CHKERROR(ierr, "Error in MPI_Comm_rank");
     40:       MPI_Comm_size(this->_comm, &this->_commSize);CHKERROR(ierr, "Error in MPI_Comm_size");
     41:       const char *class_name = ALE::getClassName(this);
     42:       this->_className = class_name;
     43:       ALE::restoreClassName(this, class_name);
     44:     };
     45:   public:
     46:     ParallelObject(MPI_Comm comm = PETSC_COMM_SELF, const int debug = 0) : _debug(debug) {__init(comm);}
     47:     ~ParallelObject() {};
     48:   public:
     49:     int                debug()    const {return this->_debug;};
     50:     void               setDebug(const int debug) {this->_debug = debug;};
     51:     MPI_Comm           comm()     const {return this->_comm;};
     52:     int                commSize() const {return this->_commSize;};
     53:     int                commRank() const {return this->_commRank;}
     54:     const std::string& getName() const {return this->_name;};
     55:     void               setName(const std::string& name) {this->_name = name;};
     56:     const std::string& getClassName() const {return this->_className;};
     57:     void               setClassName(const std::string& name) {this->_className = name;};
     58:   public:
     59:     void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
     60:       ostringstream txt;
     61:       int           rank;

     63:       if (comm == MPI_COMM_NULL) {
     64:         comm = this->comm();
     65:         rank = this->commRank();
     66:       } else {
     67:         MPI_Comm_rank(comm, &rank);
     68:       }
     69:       if (name == "") {
     70:         if(rank == 0) {
     71:           txt << "viewing a " << this->getClassName() << std::endl;
     72:         }
     73:       } else {
     74:         if(rank == 0) {
     75:           txt << "viewing " << this->getClassName() << " '" << name << "'" << std::endl;
     76:         }
     77:       }
     78:       PetscSynchronizedPrintf(comm, txt.str().c_str());
     79:       PetscSynchronizedFlush(comm);
     80:     };
     81:   };

     83:   // Use for ArrowSections
     84:   template<typename Source_, typename Target_>
     85:   struct MinimalArrow {
     86:     typedef Source_ source_type;
     87:     typedef Target_ target_type;
     88:     source_type source;
     89:     target_type target;
     90:     MinimalArrow() {};
     91:     MinimalArrow(const source_type& source, const target_type& target) : source(source), target(target) {};
     92:     MinimalArrow(const MinimalArrow& a) : source(a.source), target(a.target) {};
     93:     friend std::ostream& operator<<(std::ostream& os, const MinimalArrow& a) {
     94:       os << a.source << " ----> " << a.target;
     95:       return os;
     96:     }
     97:     // Comparisons
     98:     class less_than {
     99:     public:
    100:       bool operator()(const MinimalArrow& p, const MinimalArrow& q) const {
    101:         return((p.source < q.source) || ((p.source == q.source) && (p.target < q.target)));
    102:       };
    103:     };
    104:     typedef less_than Cmp;
    105:     bool operator==(const MinimalArrow& q) const {
    106:       return((this->source == q.source) && (this->target == q.target));
    107:     };
    108:     bool operator!=(const MinimalArrow& q) const {
    109:       return((this->source != q.source) || (this->target != q.target));
    110:     };
    111:     bool operator<(const MinimalArrow& q) const {
    112:       return((this->source < q.source) || ((this->source == q.source) && (this->target < q.target)));
    113:     };
    114:   };

    116:   //
    117:   // This is a set of classes and class templates describing an interface to point containers.
    118:   //

    120:   // Basic object
    121:   class Point {
    122:   public:
    123:     typedef ALE_ALLOCATOR<Point> allocator;
    124:     typedef int32_t prefix_type;
    125:     typedef int32_t index_type;
    126:     prefix_type prefix;
    127:     index_type  index;
    128:     // Constructors
    129:     Point() : prefix(0), index(0){};
    130:     Point(int p) : prefix(p), index(0){};
    131:     Point(int p, int i) : prefix(p), index(i){};
    132:     Point(const Point& p) : prefix(p.prefix), index(p.index){};
    133:     // Comparisons
    134:     class less_than {
    135:     public:
    136:       bool operator()(const Point& p, const Point& q) const {
    137:         return( (p.prefix < q.prefix) || ((p.prefix == q.prefix) && (p.index < q.index)));
    138:       };
    139:     };
    140:     typedef less_than Cmp;

    142:     bool operator==(const Point& q) const {
    143:       return ( (this->prefix == q.prefix) && (this->index == q.index) );
    144:     };
    145:     bool operator!=(const Point& q) const {
    146:       return ( (this->prefix != q.prefix) || (this->index != q.index) );
    147:     };
    148:     bool operator<(const Point& q) const {
    149:       return( (this->prefix < q.prefix) || ((this->prefix == q.prefix) && (this->index < q.index)));
    150:     };
    151:     void operator+=(const Point& q) {
    152:       this->prefix += q.prefix;
    153:       this->index  += q.index;
    154:     };
    155:     // Printing
    156:     friend std::ostream& operator<<(std::ostream& os, const Point& p) {
    157:       os << "(" << p.prefix << ", "<< p.index << ")";
    158:       return os;
    159:     };
    160:     // Reading
    161:     friend std::istream& operator>>(std::istream& is, Point& p) {
    162:       // Read "("
    163:       char tmp = '\0';

    165:       while (tmp != '(') {is.get(tmp);}
    166:       is >> p.prefix;
    167:       // Read ","
    168:       while (tmp != ',') {is.get(tmp);}
    169:       is >> p.index;
    170:       // Read ")"
    171:       while (tmp != ')') {is.get(tmp);}
    172:       return is;
    173:     };
    174:   };
    175:   template<typename FirstType, typename SecondType>
    176:   class Pair {
    177:   public:
    178:     typedef FirstType  first_type;
    179:     typedef SecondType second_type;
    180:     first_type  first;
    181:     second_type second;
    182:     // Constructors
    183:     Pair() : first(0), second(0) {};
    184:     Pair(FirstType f) : first(f), second(0) {};
    185:     Pair(FirstType f, SecondType s) : first(f), second(s) {};
    186:     Pair(const Pair& p) : first(p.first), second(p.second) {};
    187:     // Comparisons
    188:     class less_than {
    189:     public:
    190:       bool operator()(const Pair& p, const Pair& q) const {
    191:         return( (p.first < q.first) || ((p.first == q.first) && (p.second < q.second)));
    192:       };
    193:     };
    194:     typedef less_than Cmp;

    196:     bool operator==(const Pair& q) const {
    197:       return((this->first == q.first) && (this->second == q.second));
    198:     };
    199:     bool operator!=(const Pair& q) const {
    200:       return((this->first != q.first) || (this->second != q.second));
    201:     };
    202:     bool operator<(const Pair& q) const {
    203:       return((this->first < q.first) || ((this->first == q.first) && (this->second < q.second)));
    204:     };
    205:     void operator+=(const Pair& q) {
    206:       this->first  += q.first;
    207:       this->second += q.second;
    208:     };
    209:     // Printing
    210:     friend std::ostream& operator<<(std::ostream& os, const Pair& p) {
    211:       os << "(" << p.first << ", "<< p.second << ")";
    212:       return os;
    213:     };
    214:   };

    216:   template <typename Element_>
    217:   class array : public std::vector<Element_, ALE_ALLOCATOR<Element_> > {
    218:   public:
    219:     array()             : std::vector<Element_, ALE_ALLOCATOR<Element_> >(){};
    220:     array(int32_t size) : std::vector<Element_, ALE_ALLOCATOR<Element_> >(size){};
    221:     //
    222:     template <typename ostream_type>
    223:     void view(ostream_type& os, const char *name = NULL) {
    224:       os << "Viewing array";
    225:       if(name != NULL) {
    226:         os << " " << name;
    227:       }
    228:       os << " of size " << (int) this->size() << std::endl;
    229:       os << "[";
    230:       for(unsigned int cntr = 0; cntr < this->size(); cntr++) {
    231:         Element_ e = (*this)[cntr];
    232:         os << e;
    233:       }
    234:       os << " ]" << std::endl;

    236:     }
    237:   };

    240:   template <typename Element_>
    241:   class set : public std::set<Element_, typename Element_::less_than,  ALE_ALLOCATOR<Element_> > {
    242:   public:
    243:     // Encapsulated types
    244:     typedef std::set<Element_, typename Element_::less_than, ALE_ALLOCATOR<Element_> > super;
    245:     typedef typename super::iterator                                                   iterator;
    246:     typedef Element_                                                                   element_type;
    247:     typedef element_type                                                               value_type;
    248:     //
    249:     // Basic interface
    250:     //
    251:     set()        : super(){};
    252:     // FIX: this is a little weird that there is a specific constructor with Point
    253:     set(Point p) : super(){insert(p);};
    254:     //
    255:     set(const element_type& e) : super() {insert(e);}
    256:     //
    257:     template<typename ElementSequence_>
    258:     set(const ElementSequence_& eseq) : super(eseq.begin(), eseq.end()){}
    259:     //
    260:     // Standard interface
    261:     //
    262:     // Redirection:
    263:     // FIX: it is a little weird that 'insert' methods aren't inherited
    264:     //      but perhaps can be fixed by calling insert<Element_> (i.e., insert<Point> etc)?
    265:         std::pair<iterator, bool>
    266:     inline insert(const Element_& e) { return super::insert(e); };
    267:     //
    268:     iterator
    269:     inline insert(iterator position, const Element_& e) {return super::insert(position,e);};
    270:     //
    271:     template <class InputIterator>
    272:     void
    273:     inline insert(InputIterator b, InputIterator e) { return super::insert(b,e);}
    274:     //
    275:     // Extended interface
    276:     //
    277:     inline iterator last() {
    278:       return this->rbegin();
    279:     };// last()
    280:     //
    281:     inline bool contains(const Element_& e) {return (this->find(e) != this->end());};
    282:     //
    283:     inline void join(Obj<set> s) {
    284:       for(iterator s_itor = s->begin(); s_itor != s->end(); s_itor++) {
    285:         this->insert(*s_itor);
    286:       }
    287:     };
    288:     //
    289:     inline void meet(Obj<set> s) {// this should be called 'intersect' (the verb)
    290:       set removal;
    291:       for(iterator self_itor = this->begin(); self_itor != this->end(); self_itor++) {
    292:         Element_ e = *self_itor;
    293:         if(!s->contains(e)){
    294:           removal.insert(e);
    295:         }
    296:       }
    297:       for(iterator rem_itor = removal.begin(); rem_itor != removal.end(); rem_itor++) {
    298:         Element_ ee = *rem_itor;
    299:         this->erase(ee);
    300:       }
    301:     };
    302:     //
    303:     inline void subtract(Obj<set> s) {
    304:       set removal;
    305:       for(iterator self_itor = this->begin(); self_itor != this->end(); self_itor++) {
    306:         Element_ e = *self_itor;
    307:         if(s->contains(e)){
    308:           removal.insert(e);
    309:         }
    310:       }
    311:       for(iterator rem_itor = removal.begin(); rem_itor != removal.end(); rem_itor++) {
    312:         Element_ ee = *rem_itor;
    313:         this->erase(ee);
    314:       }
    315:     };
    316:     //
    317:     template <typename ostream_type>
    318:     void view(ostream_type& os, const char *name = NULL) {
    319:       os << "Viewing set";
    320:       if(name != NULL) {
    321:         os << " " << name;
    322:       }
    323:       os << " of size " << (int) this->size() << std::endl;
    324:       os << "[";
    325:       for(iterator s_itor = this->begin(); s_itor != this->end(); s_itor++) {
    326:         Element_ e = *s_itor;
    327:         os << e;
    328:       }
    329:       os << " ]" << std::endl;
    330:     }
    331:   };

    333:   template <typename X>
    334:   struct singleton {
    335:     X first;
    336:     //
    337:     singleton(const X& x)         : first(x) {};
    338:     singleton(const singleton& s) : first(s.first) {};
    339:   };

    341:   template <typename X, typename Y>
    342:   struct pair : public std::pair<X,Y> {
    343:     pair() : std::pair<X,Y>(){};
    344:     pair(const pair& p) : std::pair<X,Y>(p.first, p.second) {};
    345:     pair(const X& x, const Y& y) : std::pair<X,Y>(x,y) {};
    346:     ~pair(){};
    347:     friend std::ostream& operator<<(std::ostream& os, const pair& p) {
    348:       os << "<" << p.first << ", "<< p.second << ">";
    349:       return os;
    350:     };
    351:   };// struct pair

    353:   //
    354:   // Arrow definitions
    355:   //
    356:   template<typename Source_, typename Target_, typename Color_>
    357:   struct  Arrow { //: public ALE::def::Arrow<Source_, Target_, Color_> {
    358:     typedef Arrow   arrow_type;
    359:     typedef Source_ source_type;
    360:     typedef Target_ target_type;
    361:     typedef Color_  color_type;
    362:     source_type source;
    363:     target_type target;
    364:     color_type  color;
    365:     // Arrow modifiers
    366:     struct sourceChanger {
    367:       sourceChanger(const source_type& newSource) : _newSource(newSource) {};
    368:       void operator()(arrow_type& a) {a.source = this->_newSource;}
    369:     private:
    370:       source_type _newSource;
    371:     };

    373:     struct targetChanger {
    374:       targetChanger(const target_type& newTarget) : _newTarget(newTarget) {};
    375:       void operator()(arrow_type& a) { a.target = this->_newTarget;}
    376:     private:
    377:       const target_type _newTarget;
    378:     };
    379:     // Flipping
    380:     template <typename OtherSource_, typename OtherTarget_, typename OtherColor_>
    381:     struct rebind {
    382:       typedef Arrow<OtherSource_, OtherTarget_, OtherColor_> type;
    383:     };
    384:     struct flip {
    385:       typedef Arrow<target_type, source_type, color_type> type;
    386:       type arrow(const arrow_type& a) { return type(a.target, a.source, a.color);};
    387:     };
    388:   public:
    389:     //
    390:     // Basic interface
    391:     Arrow(const source_type& s, const target_type& t, const color_type& c) : source(s), target(t), color(c) {};
    392:     Arrow(const Arrow& a) : source(a.source), target(a.target), color(a.color) {};
    393:     ~Arrow(){};
    394:     //
    395:     // Extended interface
    396:     // Printing
    397:     template <typename Stream_>
    398:     friend Stream_& operator<<(Stream_& os, const Arrow& a) {
    399:       os << a.source << " --(" << a.color << ")--> " << a.target;
    400:       return os;
    401:     }
    402:   };// struct Arrow

    404:   // Defines a sequence representing a subset of a multi_index container Index_.
    405:   // A sequence defines output (input in std terminology) iterators for traversing an Index_ object.
    406:   // Upon dereferencing values are extracted from each result record using a ValueExtractor_ object.
    407:   template <typename Index_, typename ValueExtractor_ = ::boost::multi_index::identity<typename Index_::value_type> >
    408:   struct IndexSequence {
    409:     typedef Index_                                   index_type;
    410:     typedef ValueExtractor_                          extractor_type;
    411:     //
    412:     template <typename Sequence_ = IndexSequence>
    413:     class iterator {
    414:     public:
    415:       // Parent sequence type
    416:       typedef Sequence_                              sequence_type;
    417:       // Standard iterator typedefs
    418:       typedef std::input_iterator_tag                iterator_category;
    419:       typedef typename extractor_type::result_type   value_type;
    420:       typedef int                                    difference_type;
    421:       typedef value_type*                            pointer;
    422:       typedef value_type&                            reference;
    423:       // Underlying iterator type
    424:       typedef typename index_type::iterator          itor_type;
    425:     protected:
    426:       // Parent sequence
    427:       sequence_type&  _sequence;
    428:       // Underlying iterator
    429:       itor_type      _itor;
    430:       // Member extractor
    431:       extractor_type _ex;
    432:     public:
    433:       iterator(sequence_type& sequence, itor_type itor)       : _sequence(sequence),_itor(itor) {};
    434:       iterator(const iterator& iter)                          : _sequence(iter._sequence),_itor(iter._itor) {}
    435:       virtual ~iterator() {};
    436:       virtual bool              operator==(const iterator& iter) const {return this->_itor == iter._itor;};
    437:       virtual bool              operator!=(const iterator& iter) const {return this->_itor != iter._itor;};
    438:       // FIX: operator*() should return a const reference, but it won't compile that way, because _ex() returns const value_type
    439:       virtual const value_type  operator*() const {return _ex(*(this->_itor));};
    440:       virtual iterator   operator++() {++this->_itor; return *this;};
    441:       virtual iterator   operator++(int n) {iterator tmp(*this); ++this->_itor; return tmp;};
    442:     };// class iterator
    443:   protected:
    444:     index_type& _index;
    445:   public:
    446:     //
    447:     // Basic interface
    448:     //
    449:     IndexSequence(const IndexSequence& seq)  : _index(seq._index) {};
    450:     IndexSequence(index_type& index)         : _index(index) {};
    451:     virtual ~IndexSequence() {};
    452:     //
    453:     // Extended interface
    454:     //
    455:     virtual bool         empty() {return this->_index.empty();};

    457:     virtual typename index_type::size_type  size()  {
    458:       typename index_type::size_type sz = 0;
    459:       for(typename index_type::iterator itor = this->_index.begin(); itor != this->_index.end(); itor++) {
    460:         ++sz;
    461:       }
    462:       return sz;
    463:     };
    464:     template<typename ostream_type>
    465:     void view(ostream_type& os, const char* label = NULL){
    466:       if(label != NULL) {
    467:         os << "Viewing " << label << " sequence:" << std::endl;
    468:       }
    469:       os << "[";
    470:       for(iterator<> i = this->_index.begin(); i != this->_index.end(); i++) {
    471:         os << " "<< *i;
    472:       }
    473:       os << " ]" << std::endl;
    474:     }
    475:   };// class IndexSequence

    477: } // namespace ALE

    480: #endif