Actual source code: ALE_containers.hh
petsc-3.3-p7 2013-05-11
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: //
119:
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;
141:
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;
195:
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;
235:
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: };
372:
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