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

      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