Actual source code: INumbering.hh
petsc-3.4.5 2014-06-29
1: #ifndef included_ALE_INumbering_hh
2: #define included_ALE_INumbering_hh
4: #ifndef included_ALE_IField_hh
5: #include <sieve/IField.hh>
6: #endif
8: #ifndef included_ALE_Completion_hh
9: #include <sieve/Completion.hh>
10: #endif
12: namespace ALE {
13: template<typename Point_, typename Value_ = int, typename Alloc_ = malloc_allocator<Point_> >
14: class INumbering : public IUniformSection<Point_, Value_, 1, Alloc_> {
15: public:
16: typedef IUniformSection<Point_, Value_, 1, Alloc_> base_type;
17: typedef typename base_type::point_type point_type;
18: typedef typename base_type::value_type value_type;
19: typedef typename base_type::atlas_type atlas_type;
20: protected:
21: int _localSize;
22: int *_offsets;
23: std::map<int, point_type> _invOrder;
24: public:
25: INumbering(MPI_Comm comm, const int debug = 0) : IUniformSection<Point_, Value_, 1, Alloc_>(comm, debug), _localSize(0) {
26: this->_offsets = new int[this->commSize()+1];
27: this->_offsets[0] = 0;
28: };
29: ~INumbering() {
30: delete [] this->_offsets;
31: };
32: public: // Sizes
33: int getLocalSize() const {return this->_localSize;};
34: void setLocalSize(const int size) {this->_localSize = size;};
35: int getGlobalSize() const {return this->_offsets[this->commSize()];};
36: int getGlobalOffset(const int p) const {return this->_offsets[p];};
37: const int *getGlobalOffsets() const {return this->_offsets;};
38: void setGlobalOffsets(const int offsets[]) {
39: for(int p = 0; p <= this->commSize(); ++p) {
40: this->_offsets[p] = offsets[p];
41: }
42: };
43: public: // Indices
44: virtual int getIndex(const point_type& point) {
45: const value_type& idx = this->restrictPoint(point)[0];
46: if (idx >= 0) {
47: return idx;
48: }
49: return -(idx+1);
50: };
51: virtual void setIndex(const point_type& point, const int index) {this->updatePoint(point, &index);};
52: virtual bool isLocal(const point_type& point) {return this->restrictPoint(point)[0] >= 0;};
53: virtual bool isRemote(const point_type& point) {return this->restrictPoint(point)[0] < 0;};
54: point_type getPoint(const int& index) {return this->_invOrder[index];};
55: void setPoint(const int& index, const point_type& point) {this->_invOrder[index] = point;};
56: };
57: template<typename Point_, typename Value_ = ALE::Point, typename Alloc_ = malloc_allocator<Point_> >
58: class IGlobalOrder : public IUniformSection<Point_, Value_, 1, Alloc_> {
59: public:
60: typedef IUniformSection<Point_, Value_, 1, Alloc_> base_type;
61: typedef typename base_type::point_type point_type;
62: typedef typename base_type::value_type value_type;
63: typedef typename base_type::atlas_type atlas_type;
64: protected:
65: int _localSize;
66: int *_offsets;
67: public:
68: IGlobalOrder(MPI_Comm comm, const int debug = 0) : IUniformSection<Point_, Value_, 1, Alloc_>(comm, debug), _localSize(0) {
69: this->_offsets = new int[this->commSize()+1];
70: this->_offsets[0] = 0;
71: };
72: ~IGlobalOrder() {
73: delete [] this->_offsets;
74: };
75: public: // Sizes
76: int getLocalSize() const {return this->_localSize;};
77: void setLocalSize(const int size) {this->_localSize = size;};
78: int getGlobalSize() const {return this->_offsets[this->commSize()];};
79: int getGlobalOffset(const int p) const {return this->_offsets[p];};
80: const int *getGlobalOffsets() const {return this->_offsets;};
81: void setGlobalOffsets(const int offsets[]) {
82: for(int p = 0; p <= this->commSize(); ++p) {
83: this->_offsets[p] = offsets[p];
84: }
85: };
86: public: // Indices
87: virtual int getIndex(const point_type& p) {
88: const int idx = this->restrictPoint(p)[0].first;
89: if (idx >= 0) {
90: return idx;
91: }
92: return -(idx+1);
93: };
94: virtual void setIndex(const point_type& p, const int index) {
95: const value_type idx(index, this->restrictPoint(p)[0].second);
96: this->updatePoint(p, &idx);
97: };
98: virtual bool isLocal(const point_type& p) {return this->restrictPoint(p)[0].first >= 0;};
99: virtual bool isRemote(const point_type& p) {return this->restrictPoint(p)[0].first < 0;};
100: };
101: template<typename Bundle_, typename Value_ = int, typename Alloc_ = typename Bundle_::alloc_type>
102: class INumberingFactory : public ALE::ParallelObject {
103: public:
104: typedef Bundle_ bundle_type;
105: typedef typename bundle_type::point_type point_type;
106: typedef Value_ value_type;
107: typedef Alloc_ alloc_type;
108: typedef INumbering<point_type, value_type, alloc_type> numbering_type;
109: typedef std::map<bundle_type*, std::map<std::string, std::map<int, Obj<numbering_type> > > > numberings_type;
110: typedef typename ALE::Pair<value_type, value_type> oValue_type;
111: typedef typename alloc_type::template rebind<oValue_type>::other oAlloc_type;
112: typedef IGlobalOrder<point_type, oValue_type, oAlloc_type> order_type;
113: typedef std::map<bundle_type*, std::map<std::string, Obj<order_type> > > orders_type;
114: typedef typename bundle_type::send_overlap_type send_overlap_type;
115: typedef typename bundle_type::recv_overlap_type recv_overlap_type;
116: protected:
117: numberings_type _localNumberings;
118: numberings_type _numberings;
119: orders_type _orders;
120: const value_type _unknownNumber;
121: const oValue_type _unknownOrder;
122: protected:
123: INumberingFactory(MPI_Comm comm, const int debug = 0) : ALE::ParallelObject(comm, debug), _unknownNumber(-1), _unknownOrder(-1, 0) {};
124: public:
125: ~INumberingFactory() {};
126: public:
127: static const INumberingFactory& singleton(MPI_Comm comm, const int debug, bool cleanup = false) {
128: static INumberingFactory *_singleton = NULL;
130: if (cleanup) {
131: if (debug) {std::cout << "Destroying NumberingFactory" << std::endl;}
132: if (_singleton) {delete _singleton;}
133: _singleton = NULL;
134: } else if (_singleton == NULL) {
135: if (debug) {std::cout << "Creating new NumberingFactory" << std::endl;}
136: _singleton = new INumberingFactory(comm, debug);
137: }
138: return *_singleton;
139: };
140: void clear() {
141: this->_localNumberings.clear();
142: this->_numberings.clear();
143: this->_orders.clear();
144: };
145: protected: // Local numberings
146: // Number all local points
147: // points in the overlap are only numbered by the owner with the lowest rank
148: template<typename Sequence_>
149: void constructLocalNumbering(const Obj<numbering_type>& numbering, const Obj<send_overlap_type>& sendOverlap, const Obj<Sequence_>& points) {
150: const int debug = sendOverlap->debug();
151: int localSize = 0;
153: if (debug) {std::cout << "["<<numbering->commRank()<<"] Constructing local numbering" << std::endl;}
154: numbering->setChart(typename order_type::chart_type(*std::min_element(points->begin(), points->end()), *std::max_element(points->begin(), points->end())+1));
155: numbering->setFiberDimension(points, 1);
156: numbering->allocatePoint();
157: for(typename Sequence_::iterator l_iter = points->begin(); l_iter != points->end(); ++l_iter) {
158: value_type val;
160: if (debug) {std::cout << "["<<numbering->commRank()<<"] Checking point " << *l_iter << std::endl;}
161: if (sendOverlap->capContains(*l_iter)) {
162: const Obj<typename send_overlap_type::traits::supportSequence>& sendPatches = sendOverlap->support(*l_iter);
163: int minRank = sendOverlap->commSize();
165: for(typename send_overlap_type::traits::supportSequence::iterator p_iter = sendPatches->begin(); p_iter != sendPatches->end(); ++p_iter) {
166: if (*p_iter < minRank) minRank = *p_iter;
167: }
168: if (minRank < sendOverlap->commRank()) {
169: if (debug) {std::cout << "["<<numbering->commRank()<<"] remote point, on proc " << minRank << std::endl;}
170: val = this->_unknownNumber;
171: } else {
172: if (debug) {std::cout << "["<<numbering->commRank()<<"] local point" << std::endl;}
173: val = localSize++;
174: }
175: } else {
176: if (debug) {std::cout << "["<<numbering->commRank()<<"] local point" << std::endl;}
177: val = localSize++;
178: }
179: if (debug) {std::cout << "["<<numbering->commRank()<<"] has number " << val << std::endl;}
180: numbering->updatePoint(*l_iter, &val);
181: }
182: if (debug) {std::cout << "["<<numbering->commRank()<<"] local points" << std::endl;}
183: numbering->setLocalSize(localSize);
184: }
185: // Order all local points
186: // points in the overlap are only ordered by the owner with the lowest rank
187: template<typename Sequence_, typename Section_>
188: void constructLocalOrder(const Obj<order_type>& order, const Obj<send_overlap_type>& sendOverlap, const Sequence_& points, const Obj<Section_>& section) {
189: int localSize = 0;
191: ///std::cout << "["<<order->commRank()<<"] Constructing local ordering" << std::endl;
192: order->setChart(typename order_type::chart_type(*std::min_element(points.begin(), points.end()), *std::max_element(points.begin(), points.end())+1));
193: for(typename Sequence_::const_iterator l_iter = points.begin(); l_iter != points.end(); ++l_iter) {
194: order->setFiberDimension(*l_iter, 1);
195: }
196: order->allocatePoint();
197: for(typename Sequence_::const_iterator l_iter = points.begin(); l_iter != points.end(); ++l_iter) {
198: oValue_type val;
200: ///std::cout << "["<<order->commRank()<<"] Checking point " << *l_iter << std::endl;
201: if (sendOverlap->capContains(*l_iter)) {
202: const Obj<typename send_overlap_type::traits::supportSequence>& sendPatches = sendOverlap->support(*l_iter);
203: int minRank = sendOverlap->commSize();
205: for(typename send_overlap_type::traits::supportSequence::iterator p_iter = sendPatches->begin(); p_iter != sendPatches->end(); ++p_iter) {
206: if (*p_iter < minRank) minRank = *p_iter;
207: }
208: if (minRank < sendOverlap->commRank()) {
209: ///std::cout << "["<<order->commRank()<<"] remote point, on proc " << minRank << std::endl;
210: val = this->_unknownOrder;
211: } else {
212: ///std::cout << "["<<order->commRank()<<"] local point" << std::endl;
213: val.first = localSize;
214: val.second = section->getConstrainedFiberDimension(*l_iter);
215: }
216: } else {
217: ///std::cout << "["<<order->commRank()<<"] local point" << std::endl;
218: val.first = localSize;
219: val.second = section->getConstrainedFiberDimension(*l_iter);
220: }
221: ///std::cout << "["<<order->commRank()<<"] has offset " << val.prefix << " and size " << val.index << std::endl;
222: localSize += val.second;
223: order->updatePoint(*l_iter, &val);
224: }
225: ///std::cout << "["<<order->commRank()<<"] local size" << std::endl;
226: order->setLocalSize(localSize);
227: }
228: protected: // Global offsets
229: // Calculate process offsets
230: template<typename Numbering>
231: void calculateOffsets(const Obj<Numbering>& numbering) {
232: int localSize = numbering->getLocalSize();
233: int *offsets = new int[numbering->commSize()+1];
235: offsets[0] = 0;
236: MPI_Allgather(&localSize, 1, MPI_INT, &(offsets[1]), 1, MPI_INT, numbering->comm());
237: for(int p = 2; p <= numbering->commSize(); p++) {
238: offsets[p] += offsets[p-1];
239: }
240: numbering->setGlobalOffsets(offsets);
241: delete [] offsets;
242: }
243: // Update local offsets based upon process offsets
244: template<typename Numbering, typename Sequence>
245: void updateOrder(const Obj<Numbering>& numbering, Sequence& points) {
246: const typename Numbering::value_type val = numbering->getGlobalOffset(numbering->commRank());
248: for(typename Sequence::const_iterator l_iter = points.begin(); l_iter != points.end(); ++l_iter) {
249: if (numbering->isLocal(*l_iter)) {
250: numbering->updateAddPoint(*l_iter, &val);
251: }
252: }
253: }
254: template<typename OverlapSection, typename RecvOverlap>
255: static void fuseNumbering(const Obj<OverlapSection>& overlapSection, const Obj<RecvOverlap>& recvOverlap, const Obj<numbering_type>& numbering) {
256: typedef typename OverlapSection::point_type overlap_point_type;
257: const Obj<typename RecvOverlap::traits::baseSequence> rPoints = recvOverlap->base();
258: const typename RecvOverlap::traits::baseSequence::iterator rEnd = rPoints->end();
259: const int debug = numbering->debug();
260: const bool allowDuplicates = false;
262: numbering->reallocatePoint(rPoints->begin(), rEnd, Identity<typename recv_overlap_type::target_type>());
263: for(typename RecvOverlap::traits::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
264: const Obj<typename recv_overlap_type::traits::coneSequence>& ranks = recvOverlap->cone(*p_iter);
265: const typename recv_overlap_type::target_type& localPoint = *p_iter;
267: for(typename recv_overlap_type::traits::coneSequence::iterator r_iter = ranks->begin(); r_iter != ranks->end(); ++r_iter) {
268: const typename recv_overlap_type::target_type& remotePoint = r_iter.color();
269: const int rank = *r_iter;
270: const int size = overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint));
271: const typename OverlapSection::value_type *values = overlapSection->restrictPoint(overlap_point_type(rank, remotePoint));
273: if (size == 0) continue;
274: if (debug) {std::cout << "["<<numbering->commRank()<<"] local point " << localPoint << " remote point " << remotePoint << " number " << values[0] << std::endl;}
275: if (values[0] >= 0) {
276: if (debug) {std::cout << "["<<numbering->commRank()<<"] local point " << localPoint << " dim " << numbering->getAtlas()->getFiberDimension(localPoint) << std::endl;}
277: if (numbering->isLocal(localPoint) && !allowDuplicates) {
278: ostringstream msg;
279: msg << "["<<numbering->commRank()<<"]Multiple indices for local point " << localPoint << " remote point " << remotePoint << " from " << rank << " with index " << values[0];
280: throw ALE::Exception(msg.str().c_str());
281: }
282: if (numbering->getAtlas()->getFiberDimension(localPoint) == 0) {
283: ostringstream msg;
284: msg << "["<<numbering->commRank()<<"]Unexpected local point " << localPoint << " remote point " << remotePoint << " from " << rank << " with index " << values[0];
285: throw ALE::Exception(msg.str().c_str());
286: }
287: const typename numbering_type::value_type val = -(values[0]+1);
288: numbering->updatePoint(localPoint, &val);
289: }
290: }
291: }
292: }
293: template<typename OverlapSection, typename RecvOverlap>
294: static void fuse(const Obj<OverlapSection>& overlapSection, const Obj<RecvOverlap>& recvOverlap, const Obj<order_type>& order) {
295: typedef typename OverlapSection::point_type overlap_point_type;
296: const Obj<typename RecvOverlap::traits::baseSequence> rPoints = recvOverlap->base();
297: const typename RecvOverlap::traits::baseSequence::iterator rEnd = rPoints->end();
298: const bool allowDuplicates = false;
300: order->reallocatePoint(rPoints->begin(), rEnd, Identity<typename recv_overlap_type::target_type>());
301: for(typename RecvOverlap::traits::baseSequence::iterator p_iter = rPoints->begin(); p_iter != rEnd; ++p_iter) {
302: const Obj<typename recv_overlap_type::traits::coneSequence>& ranks = recvOverlap->cone(*p_iter);
303: const typename recv_overlap_type::target_type& localPoint = *p_iter;
305: for(typename recv_overlap_type::traits::coneSequence::iterator r_iter = ranks->begin(); r_iter != ranks->end(); ++r_iter) {
306: const typename recv_overlap_type::target_type& remotePoint = r_iter.color();
307: const int rank = *r_iter;
308: const int size = overlapSection->getFiberDimension(overlap_point_type(rank, remotePoint));
309: const typename OverlapSection::value_type *values = overlapSection->restrictPoint(overlap_point_type(rank, remotePoint));
311: if (size == 0) continue;
312: if (values[0].second == 0) continue;
313: if (values[0].first >= 0) {
314: if (order->isLocal(localPoint)) {
315: if (!allowDuplicates) {
316: ostringstream msg;
317: msg << "["<<order->commRank()<<"]Multiple indices for local point " << localPoint << " remote point " << remotePoint << " from " << rank << " with index " << values[0];
318: throw ALE::Exception(msg.str().c_str());
319: }
320: continue;
321: }
322: const typename order_type::value_type val(-(values[0].first+1), values[0].second);
323: order->updatePoint(localPoint, &val);
324: } else {
325: if (order->isLocal(localPoint)) continue;
326: order->updatePoint(localPoint, values);
327: }
328: }
329: }
330: }
331: public: // Completion
332: void completeNumbering(const Obj<numbering_type>& numbering, const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, bool allowDuplicates = false) {
333: #if 0
334: ALE::Completion::completeSection(sendOverlap, recvOverlap, numbering, numbering);
335: #else
336: typedef ALE::UniformSection<ALE::Pair<int, typename send_overlap_type::source_type>, typename numbering_type::value_type> OverlapSection;
337: Obj<OverlapSection> overlapSection = new OverlapSection(numbering->comm(), numbering->debug());
339: if (numbering->debug()) {numbering->view("Local Numbering");}
340: ALE::Pullback::SimpleCopy::copy(sendOverlap, recvOverlap, numbering, overlapSection);
341: if (overlapSection->debug()) {overlapSection->view("Overlap Section");}
342: fuseNumbering(overlapSection, recvOverlap, numbering);
343: if (numbering->debug()) {numbering->view("Global Numbering");}
344: #endif
345: }
346: void completeOrder(const Obj<order_type>& order, const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, bool allowDuplicates = false) {
347: #if 0
348: ALE::Completion::completeSection(sendOverlap, recvOverlap, order, order);
349: #else
350: typedef ALE::UniformSection<ALE::Pair<int, typename send_overlap_type::source_type>, typename order_type::value_type> OverlapSection;
351: Obj<OverlapSection> overlapSection = new OverlapSection(order->comm(), order->debug());
353: if (order->debug()) {order->view("Local Order");}
354: ALE::Pullback::SimpleCopy::copy(sendOverlap, recvOverlap, order, overlapSection);
355: if (overlapSection->debug()) {overlapSection->view("Overlap Section");}
356: fuse(overlapSection, recvOverlap, order);
357: if (order->debug()) {order->view("Global Order");}
358: #endif
359: }
360: public: // Construct a full global numberings
361: template<typename Sequence>
362: void constructNumbering(const Obj<numbering_type>& numbering, const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, const Obj<Sequence>& points) {
363: this->constructLocalNumbering(numbering, sendOverlap, points);
364: this->calculateOffsets(numbering);
365: this->updateOrder(numbering, *points.ptr());
366: this->completeNumbering(numbering, sendOverlap, recvOverlap);
367: }
368: template<typename Sequence, typename Section>
369: void constructOrder(const Obj<order_type>& order, const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, const Sequence& points, const Obj<Section>& section) {
370: this->constructLocalOrder(order, sendOverlap, points, section);
371: this->calculateOffsets(order);
372: this->updateOrder(order, points);
373: this->completeOrder(order, sendOverlap, recvOverlap);
374: }
375: template<typename Sequence, typename Section>
376: void constructOrder(const Obj<order_type>& order, const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, const Obj<Sequence>& points, const Obj<Section>& section) {
377: this->constructLocalOrder(order, sendOverlap, *points.ptr(), section);
378: this->calculateOffsets(order);
379: this->updateOrder(order, *points.ptr());
380: this->completeOrder(order, sendOverlap, recvOverlap);
381: }
382: public: // Real interface
383: template<typename ABundle_>
384: const Obj<numbering_type>& getLocalNumbering(const Obj<ABundle_>& bundle, const int depth) {
385: if ((this->_localNumberings.find(bundle.ptr()) == this->_localNumberings.end()) ||
386: (this->_localNumberings[bundle.ptr()].find("depth") == this->_localNumberings[bundle.ptr()].end()) ||
387: (this->_localNumberings[bundle.ptr()]["depth"].find(depth) == this->_localNumberings[bundle.ptr()]["depth"].end())) {
388: Obj<numbering_type> numbering = new numbering_type(bundle->comm(), bundle->debug());
389: Obj<send_overlap_type> sendOverlap = new send_overlap_type(bundle->comm(), bundle->debug());
391: this->constructLocalNumbering(numbering, sendOverlap, bundle->depthStratum(depth));
392: if (this->_debug) {std::cout << "Creating new local numbering: ptr " << bundle.ptr() << " depth " << depth << std::endl;}
393: this->_localNumberings[bundle.ptr()]["depth"][depth] = numbering;
394: } else {
395: if (this->_debug) {std::cout << "Using old local numbering: ptr " << bundle.ptr() << " depth " << depth << std::endl;}
396: }
397: return this->_localNumberings[bundle.ptr()]["depth"][depth];
398: }
399: template<typename ABundle_>
400: const Obj<numbering_type>& getNumbering(const Obj<ABundle_>& bundle, const int depth) {
401: if ((this->_numberings.find(bundle.ptr()) == this->_numberings.end()) ||
402: (this->_numberings[bundle.ptr()].find("depth") == this->_numberings[bundle.ptr()].end()) ||
403: (this->_numberings[bundle.ptr()]["depth"].find(depth) == this->_numberings[bundle.ptr()]["depth"].end())) {
404: bundle->constructOverlap();
405: Obj<numbering_type> numbering = new numbering_type(bundle->comm(), bundle->debug());
406: Obj<send_overlap_type> sendOverlap = bundle->getSendOverlap();
407: Obj<recv_overlap_type> recvOverlap = bundle->getRecvOverlap();
409: this->constructNumbering(numbering, sendOverlap, recvOverlap, bundle->depthStratum(depth));
410: if (this->_debug) {std::cout << "Creating new numbering: depth " << depth << std::endl;}
411: this->_numberings[bundle.ptr()]["depth"][depth] = numbering;
412: } else {
413: if (this->_debug) {std::cout << "["<<bundle->commRank()<<"]Using old numbering: depth " << depth << std::endl;}
414: }
415: return this->_numberings[bundle.ptr()]["depth"][depth];
416: }
417: template<typename ABundle_>
418: const Obj<numbering_type>& getNumbering(const Obj<ABundle_>& bundle, const std::string& labelname, const int value) {
419: if ((this->_numberings.find(bundle.ptr()) == this->_numberings.end()) ||
420: (this->_numberings[bundle.ptr()].find(labelname) == this->_numberings[bundle.ptr()].end()) ||
421: (this->_numberings[bundle.ptr()][labelname].find(value) == this->_numberings[bundle.ptr()][labelname].end())) {
422: bundle->constructOverlap();
423: Obj<numbering_type> numbering = new numbering_type(bundle->comm(), bundle->debug());
424: Obj<send_overlap_type> sendOverlap = bundle->getSendOverlap();
425: Obj<recv_overlap_type> recvOverlap = bundle->getRecvOverlap();
427: numbering->setDefault(&_unknownNumber);
428: if (this->_debug) {std::cout << "["<<bundle->commRank()<<"]Creating new numbering: " << labelname << " value " << value << std::endl;}
429: this->constructNumbering(numbering, sendOverlap, recvOverlap, bundle->getLabelStratum(labelname, value));
430: this->_numberings[bundle.ptr()][labelname][value] = numbering;
431: } else {
432: if (this->_debug) {std::cout << "["<<bundle->commRank()<<"]Using old numbering: " << labelname << " value " << value << std::endl;}
433: }
434: return this->_numberings[bundle.ptr()][labelname][value];
435: }
436: template<typename ABundle_, typename Section_>
437: const Obj<order_type>& getGlobalOrder(const Obj<ABundle_>& bundle, const std::string& name, const Obj<Section_>& section) {
438: if ((this->_orders.find(bundle.ptr()) == this->_orders.end()) ||
439: (this->_orders[bundle.ptr()].find(name) == this->_orders[bundle.ptr()].end())) {
440: bundle->constructOverlap();
441: Obj<order_type> order = new order_type(bundle->comm(), bundle->debug());
442: Obj<send_overlap_type> sendOverlap = bundle->getSendOverlap();
443: Obj<recv_overlap_type> recvOverlap = bundle->getRecvOverlap();
445: order->setDefault(&_unknownOrder);
446: if (this->_debug) {std::cout << "["<<bundle->commRank()<<"]Creating new global order: " << name << std::endl;}
447: this->constructOrder(order, sendOverlap, recvOverlap, section->getChart(), section);
448: this->_orders[bundle.ptr()][name] = order;
449: } else {
450: if (this->_debug) {std::cout << "["<<bundle->commRank()<<"]Using old global order: " << name << std::endl;}
451: }
452: return this->_orders[bundle.ptr()][name];
453: }
454: #if 0
455: template<typename ABundle_, typename Section_>
456: const Obj<order_type>& getGlobalOrderWithBC(const Obj<ABundle_>& bundle, const std::string& name, const Obj<Section_>& section) {
457: if ((this->_orders.find(bundle.ptr()) == this->_orders.end()) ||
458: (this->_orders[bundle.ptr()].find(name) == this->_orders[bundle.ptr()].end())) {
459: bundle->constructOverlap();
460: Obj<order_type> order = new order_type(bundle->comm(), bundle->debug());
461: Obj<send_overlap_type> sendOverlap = bundle->getSendOverlap();
462: Obj<recv_overlap_type> recvOverlap = bundle->getRecvOverlap();
464: order->setDefault(&_unknownOrder);
465: if (this->_debug) {std::cout << "["<<bundle->commRank()<<"]Creating new global order: " << name << std::endl;}
466: this->constructOrderWithBC(order, sendOverlap, recvOverlap, section->getChart(), section);
467: this->_orders[bundle.ptr()][name] = order;
468: } else {
469: if (this->_debug) {std::cout << "["<<bundle->commRank()<<"]Using old global order: " << name << std::endl;}
470: }
471: return this->_orders[bundle.ptr()][name];
472: }
473: #endif
474: template<typename ABundle_>
475: void setGlobalOrder(const Obj<ABundle_>& bundle, const std::string& name, const Obj<order_type>& order) {
476: this->_orders[bundle.ptr()][name] = order;
477: }
478: };
479: }
480: #endif