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