Actual source code: Sections.hh

  1: #ifndef included_ALE_Sections_hh
  2: #define included_ALE_Sections_hh

  4: #ifndef  included_ALE_Numbering_hh
  5: #include <Numbering.hh>
  6: #endif

  8: namespace ALE {
  9:   namespace New {
 10:     // This section takes an existing section, and reports instead the fiber dimensions as values
 11:     template<typename Section_>
 12:     class SizeSection : public ALE::ParallelObject {
 13:     public:
 14:       typedef Section_                          section_type;
 15:       typedef typename section_type::point_type point_type;
 16:       typedef int                               value_type;
 17:     protected:
 18:       Obj<section_type> _section;
 19:       value_type        _size;
 20:     public:
 21:       SizeSection(const Obj<section_type>& section) : ParallelObject(MPI_COMM_SELF, section->debug()), _section(section) {};
 22:       virtual ~SizeSection() {};
 23:     public:
 24:       bool hasPoint(const point_type& point) {
 25:         return this->_section->hasPoint(point);
 26:       };
 27:       const value_type *restrict(const point_type& p) {
 28:         this->_size = this->_section->getFiberDimension(p); // Could be size()
 29:         return &this->_size;
 30:       };
 31:       const value_type *restrictPoint(const point_type& p) {
 32:         this->_size = this->_section->getFiberDimension(p);
 33:         return &this->_size;
 34:       };
 35:     public:
 36:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
 37:         this->_section->view(name, comm);
 38:       };
 39:     };

 41:     // This section reports as values the size of the partition associated with the partition point
 42:     template<typename Bundle_, typename Marker_>
 43:     class PartitionSizeSection : public ALE::ParallelObject {
 44:     public:
 45:       typedef Bundle_                          bundle_type;
 46:       typedef typename bundle_type::sieve_type sieve_type;
 47:       typedef typename bundle_type::point_type point_type;
 48:       typedef Marker_                          marker_type;
 49:       typedef int                              value_type;
 50:       typedef std::map<marker_type, int>       sizes_type;
 51:     protected:
 52:       sizes_type _sizes;
 53:       int        _height;
 54:       void _init(const Obj<bundle_type>& bundle, const int numElements, const marker_type partition[]) {
 55:         const Obj<typename bundle_type::label_sequence>& cells      = bundle->heightStratum(this->_height);
 56:         const Obj<typename bundle_type::numbering_type>& cNumbering = bundle->getFactory()->getLocalNumbering(bundle, bundle->depth() - this->_height);
 57:         std::map<marker_type, std::set<point_type> >     points;

 59:         if (numElements != (int) cells->size()) {
 60:           throw ALE::Exception("Partition size does not match the number of elements");
 61:         }
 62:         for(typename bundle_type::label_sequence::iterator e_iter = cells->begin(); e_iter != cells->end(); ++e_iter) {
 63:           typedef ALE::SieveAlg<bundle_type> sieve_alg_type;
 64:           const Obj<typename sieve_alg_type::coneArray>& closure = sieve_alg_type::closure(bundle, *e_iter);
 65:           const int idx = cNumbering->getIndex(*e_iter);

 67:           points[partition[idx]].insert(closure->begin(), closure->end());
 68:           if (this->_height > 0) {
 69:             const Obj<typename sieve_alg_type::supportArray>& star = sieve_alg_type::star(bundle, *e_iter);

 71:             points[partition[idx]].insert(star->begin(), star->end());
 72:           }
 73:         }
 74:         for(typename std::map<marker_type, std::set<point_type> >::const_iterator p_iter = points.begin(); p_iter != points.end(); ++p_iter) {
 75:           this->_sizes[p_iter->first] = p_iter->second.size();
 76:         }
 77:       };
 78:     public:
 79:       PartitionSizeSection(const Obj<bundle_type>& bundle, const int elementHeight, const int numElements, const marker_type *partition) : ParallelObject(MPI_COMM_SELF, bundle->debug()), _height(elementHeight) {
 80:         this->_init(bundle, numElements, partition);
 81:       };
 82:       virtual ~PartitionSizeSection() {};
 83:     public:
 84:       bool hasPoint(const point_type& point) {return true;};
 85:       const value_type *restrictPoint(const point_type& p) {
 86:         return &this->_sizes[p];
 87:       };
 88:     public:
 89:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
 90:         ostringstream txt;
 91:         int rank;

 93:         if (comm == MPI_COMM_NULL) {
 94:           comm = this->comm();
 95:           rank = this->commRank();
 96:         } else {
 97:           MPI_Comm_rank(comm, &rank);
 98:         }
 99:         if (name == "") {
100:           if(rank == 0) {
101:             txt << "viewing a PartitionSizeSection" << std::endl;
102:           }
103:         } else {
104:           if(rank == 0) {
105:             txt << "viewing PartitionSizeSection '" << name << "'" << std::endl;
106:           }
107:         }
108:         for(typename sizes_type::const_iterator s_iter = this->_sizes.begin(); s_iter != this->_sizes.end(); ++s_iter) {
109:           const marker_type& partition = s_iter->first;
110:           const value_type   size      = s_iter->second;

112:           txt << "[" << this->commRank() << "]: Partition " << partition << " size " << size << std::endl;
113:         }
114:         PetscSynchronizedPrintf(comm, txt.str().c_str());
115:         PetscSynchronizedFlush(comm);
116:       };
117:     };

119:     template<typename Point_>
120:     class PartitionDomain {
121:     public:
122:       typedef Point_ point_type;
123:     public:
124:       PartitionDomain() {};
125:       ~PartitionDomain() {};
126:     public:
127:       int count(const point_type& point) const {return 1;};
128:     };

130:     // This section returns the points in each partition
131:     template<typename Bundle_, typename Marker_>
132:     class PartitionSection : public ALE::ParallelObject {
133:     public:
134:       typedef Bundle_                            bundle_type;
135:       typedef typename bundle_type::sieve_type   sieve_type;
136:       typedef typename bundle_type::point_type   point_type;
137:       typedef Marker_                            marker_type;
138:       typedef int                                value_type;
139:       typedef std::map<marker_type, point_type*> points_type;
140:       typedef PartitionDomain<point_type>        chart_type;
141:     protected:
142:       points_type _points;
143:       chart_type  _domain;
144:       int         _height;
145:       void _init(const Obj<bundle_type>& bundle, const int numElements, const marker_type partition[]) {
146:         // Should check for patch 0
147:         const Obj<typename bundle_type::label_sequence>& cells      = bundle->heightStratum(this->_height);
148:         const Obj<typename bundle_type::numbering_type>& cNumbering = bundle->getFactory()->getLocalNumbering(bundle, bundle->depth() - this->_height);
149:         std::map<marker_type, std::set<point_type> >     points;
150:         std::map<marker_type, int>                       offsets;

152:         if (numElements != (int) cells->size()) {
153:           throw ALE::Exception("Partition size does not match the number of elements");
154:         }
155:         for(typename bundle_type::label_sequence::iterator e_iter = cells->begin(); e_iter != cells->end(); ++e_iter) {
156:           typedef ALE::SieveAlg<bundle_type> sieve_alg_type;
157:           const Obj<typename sieve_alg_type::coneArray>& closure = sieve_alg_type::closure(bundle, *e_iter);
158:           const int idx = cNumbering->getIndex(*e_iter);

160:           points[partition[idx]].insert(closure->begin(), closure->end());
161:           if (this->_height > 0) {
162:             const Obj<typename sieve_alg_type::supportArray>& star = sieve_alg_type::star(bundle, *e_iter);

164:             points[partition[idx]].insert(star->begin(), star->end());
165:           }
166:         }
167:         for(typename std::map<marker_type, std::set<point_type> >::const_iterator p_iter = points.begin(); p_iter != points.end(); ++p_iter) {
168:           this->_points[p_iter->first] = new point_type[p_iter->second.size()];
169:           offsets[p_iter->first] = 0;
170:           for(typename std::set<point_type>::const_iterator s_iter = p_iter->second.begin(); s_iter != p_iter->second.end(); ++s_iter) {
171:             this->_points[p_iter->first][offsets[p_iter->first]++] = *s_iter;
172:           }
173:         }
174:         for(typename std::map<marker_type, std::set<point_type> >::const_iterator p_iter = points.begin(); p_iter != points.end(); ++p_iter) {
175:           if (offsets[p_iter->first] != (int) p_iter->second.size()) {
176:             ostringstream txt;
177:             txt << "Invalid offset for partition " << p_iter->first << ": " << offsets[p_iter->first] << " should be " << p_iter->second.size();
178:             throw ALE::Exception(txt.str().c_str());
179:           }
180:         }
181:       };
182:     public:
183:       PartitionSection(const Obj<bundle_type>& bundle, const int elementHeight, const int numElements, const marker_type *partition) : ParallelObject(MPI_COMM_SELF, bundle->debug()), _height(elementHeight) {
184:         this->_init(bundle, numElements, partition);
185:       };
186:       virtual ~PartitionSection() {
187:         for(typename points_type::iterator p_iter = this->_points.begin(); p_iter != this->_points.end(); ++p_iter) {
188:           delete [] p_iter->second;
189:         }
190:       };
191:     public:
192:       const chart_type& getChart() {return this->_domain;};
193:       bool hasPoint(const point_type& point) {return true;};
194:       const value_type *restrictPoint(const point_type& p) {
195:         return this->_points[p];
196:       };
197:     public:
198:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
199:         ostringstream txt;
200:         int rank;

202:         if (comm == MPI_COMM_NULL) {
203:           comm = this->comm();
204:           rank = this->commRank();
205:         } else {
206:           MPI_Comm_rank(comm, &rank);
207:         }
208:         if (name == "") {
209:           if(rank == 0) {
210:             txt << "viewing a PartitionSection" << std::endl;
211:           }
212:         } else {
213:           if(rank == 0) {
214:             txt << "viewing PartitionSection '" << name << "'" << std::endl;
215:           }
216:         }
217:         for(typename points_type::const_iterator p_iter = this->_points.begin(); p_iter != this->_points.end(); ++p_iter) {
218:           const marker_type& partition  = p_iter->first;
219:           //const point_type *points = p_iter->second;

221:           txt << "[" << this->commRank() << "]: Partition " << partition << std::endl;
222:         }
223:         if (this->_points.size() == 0) {
224:           txt << "[" << this->commRank() << "]: empty" << std::endl;
225:         }
226:         PetscSynchronizedPrintf(comm, txt.str().c_str());
227:         PetscSynchronizedFlush(comm);
228:       };
229:     };

231:     template<typename Bundle_, typename Sieve_>
232:     class ConeSizeSection : public ALE::ParallelObject {
233:     public:
234:       typedef ConeSizeSection<Bundle_, Sieve_> section_type;
235:       typedef int                              patch_type;
236:       typedef Bundle_                          bundle_type;
237:       typedef Sieve_                           sieve_type;
238:       typedef typename bundle_type::point_type point_type;
239:       typedef int                              value_type;
240:     protected:
241:       Obj<bundle_type> _bundle;
242:       Obj<sieve_type>  _sieve;
243:       value_type       _size;
244:       int              _minHeight;
245:       Obj<section_type> _section;
246:     public:
247:       ConeSizeSection(const Obj<bundle_type>& bundle, const Obj<sieve_type>& sieve, int minimumHeight = 0) : ParallelObject(MPI_COMM_SELF, sieve->debug()), _bundle(bundle), _sieve(sieve), _minHeight(minimumHeight) {
248:         this->_section = this;
249:         this->_section.addRef();
250:       };
251:       virtual ~ConeSizeSection() {};
252:     public: // Verifiers
253:       bool hasPoint(const point_type& point) {return true;};
254:     public: // Restriction
255:       const value_type *restrictPoint(const point_type& p) {
256:         if ((this->_minHeight == 0) || (this->_bundle->height(p) >= this->_minHeight)) {
257:           this->_size = this->_sieve->cone(p)->size();
258:         } else {
259:           this->_size = 0;
260:         }
261:         return &this->_size;
262:       };
263:     public: // Adapter
264:       const Obj<section_type>& getSection(const patch_type& patch) {
265:         return this->_section;
266:       };
267:     public:
268:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
269:         ostringstream txt;
270:         int rank;

272:         if (comm == MPI_COMM_NULL) {
273:           comm = this->comm();
274:           rank = this->commRank();
275:         } else {
276:           MPI_Comm_rank(comm, &rank);
277:         }
278:         if (name == "") {
279:           if(rank == 0) {
280:             txt << "viewing a ConeSizeSection" << std::endl;
281:           }
282:         } else {
283:           if(rank == 0) {
284:             txt << "viewing ConeSizeSection '" << name << "'" << std::endl;
285:           }
286:         }
287:         PetscSynchronizedPrintf(comm, txt.str().c_str());
288:         PetscSynchronizedFlush(comm);
289:       };
290:     };

292:     template<typename Sieve_>
293:     class ConeSection : public ALE::ParallelObject {
294:     public:
295:       typedef Sieve_                           sieve_type;
296:       typedef typename sieve_type::target_type point_type;
297:       typedef typename sieve_type::source_type value_type;
298:       typedef PartitionDomain<sieve_type>      chart_type;
299:     protected:
300:       Obj<sieve_type> _sieve;
301:       int             _coneSize;
302:       value_type     *_cone;
303:       chart_type      _domain;
304:       void ensureCone(const int size) {
305:         if (size > this->_coneSize) {
306:           if (this->_cone) delete [] this->_cone;
307:           this->_coneSize = size;
308:           this->_cone     = new value_type[this->_coneSize];
309:         }
310:       };
311:     public:
312:       ConeSection(const Obj<sieve_type>& sieve) : ParallelObject(MPI_COMM_SELF, sieve->debug()), _sieve(sieve), _coneSize(-1), _cone(NULL) {};
313:       virtual ~ConeSection() {if (this->_cone) delete [] this->_cone;};
314:     public:
315:       const chart_type& getChart() {return this->_domain;};
316:       bool hasPoint(const point_type& point) {return true;};
317:       const value_type *restrictPoint(const point_type& p) {
318:         const Obj<typename sieve_type::traits::coneSequence>& cone = this->_sieve->cone(p);
319:         int c = 0;

321:         this->ensureCone(cone->size());
322:         for(typename sieve_type::traits::coneSequence::iterator c_iter = cone->begin(); c_iter != cone->end(); ++c_iter) {
323:           this->_cone[c++] = *c_iter;
324:         }
325:         return this->_cone;
326:       };
327:     public:
328:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
329:         ostringstream txt;
330:         int rank;

332:         if (comm == MPI_COMM_NULL) {
333:           comm = this->comm();
334:           rank = this->commRank();
335:         } else {
336:           MPI_Comm_rank(comm, &rank);
337:         }
338:         if (name == "") {
339:           if(rank == 0) {
340:             txt << "viewing a ConeSection" << std::endl;
341:           }
342:         } else {
343:           if(rank == 0) {
344:             txt << "viewing ConeSection '" << name << "'" << std::endl;
345:           }
346:         }
347:         PetscSynchronizedPrintf(comm, txt.str().c_str());
348:         PetscSynchronizedFlush(comm);
349:       };
350:     };

352:     template<typename Bundle_, typename Sieve_>
353:     class SupportSizeSection : public ALE::ParallelObject {
354:     public:
355:       typedef Bundle_                          bundle_type;
356:       typedef Sieve_                           sieve_type;
357:       typedef typename sieve_type::source_type point_type;
358:       typedef typename sieve_type::target_type value_type;
359:     protected:
360:       Obj<bundle_type> _bundle;
361:       Obj<sieve_type>  _sieve;
362:       value_type       _size;
363:       int              _minDepth;
364:     public:
365:       SupportSizeSection(const Obj<bundle_type>& bundle, const Obj<sieve_type>& sieve, int minimumDepth = 0) : ParallelObject(MPI_COMM_SELF, bundle->debug()), _bundle(bundle), _sieve(sieve), _minDepth(minimumDepth) {};
366:       virtual ~SupportSizeSection() {};
367:     public:
368:       bool hasPoint(const point_type& point) {return true;};
369:       const value_type *restrictPoint(const point_type& p) {
370:         if ((this->_minDepth == 0) || (this->_bundle->depth(p) >= this->_minDepth)) {
371:           this->_size = this->_sieve->support(p)->size();
372:         } else {
373:           this->_size = 0;
374:         }
375:         return &this->_size;
376:       };
377:     public:
378:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
379:         ostringstream txt;
380:         int rank;

382:         if (comm == MPI_COMM_NULL) {
383:           comm = this->comm();
384:           rank = this->commRank();
385:         } else {
386:           MPI_Comm_rank(comm, &rank);
387:         }
388:         if (name == "") {
389:           if(rank == 0) {
390:             txt << "viewing a SupportSizeSection" << std::endl;
391:           }
392:         } else {
393:           if(rank == 0) {
394:             txt << "viewing SupportSizeSection '" << name << "'" << std::endl;
395:           }
396:         }
397:         PetscSynchronizedPrintf(comm, txt.str().c_str());
398:         PetscSynchronizedFlush(comm);
399:       };
400:     };

402:     template<typename Sieve_>
403:     class SupportSection : public ALE::ParallelObject {
404:     public:
405:       typedef Sieve_                           sieve_type;
406:       typedef typename sieve_type::source_type point_type;
407:       typedef typename sieve_type::target_type value_type;
408:       typedef PartitionDomain<sieve_type>      chart_type;
409:     protected:
410:       Obj<sieve_type> _sieve;
411:       int             _supportSize;
412:       value_type     *_support;
413:       chart_type      _domain;
414:       void ensureSupport(const int size) {
415:         if (size > this->_supportSize) {
416:           if (this->_support) delete [] this->_support;
417:           this->_supportSize = size;
418:           this->_support     = new value_type[this->_supportSize];
419:         }
420:       };
421:     public:
422:       SupportSection(const Obj<sieve_type>& sieve) : ParallelObject(MPI_COMM_SELF, sieve->debug()), _sieve(sieve), _supportSize(-1), _support(NULL) {};
423:       virtual ~SupportSection() {if (this->_support) delete [] this->_support;};
424:     public:
425:       const chart_type& getChart() {return this->_domain;};
426:       bool hasPoint(const point_type& point) {return true;};
427:       const value_type *restrictPoint(const point_type& p) {
428:         const Obj<typename sieve_type::traits::supportSequence>& support = this->_sieve->support(p);
429:         int s = 0;

431:         this->ensureSupport(support->size());
432:         for(typename sieve_type::traits::supportSequence::iterator s_iter = support->begin(); s_iter != support->end(); ++s_iter) {
433:           this->_support[s++] = *s_iter;
434:         }
435:         return this->_support;
436:       };
437:     public:
438:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
439:         ostringstream txt;
440:         int rank;

442:         if (comm == MPI_COMM_NULL) {
443:           comm = this->comm();
444:           rank = this->commRank();
445:         } else {
446:           MPI_Comm_rank(comm, &rank);
447:         }
448:         if (name == "") {
449:           if(rank == 0) {
450:             txt << "viewing a SupportSection" << std::endl;
451:           }
452:         } else {
453:           if(rank == 0) {
454:             txt << "viewing SupportSection '" << name << "'" << std::endl;
455:           }
456:         }
457:         PetscSynchronizedPrintf(comm, txt.str().c_str());
458:         PetscSynchronizedFlush(comm);
459:       };
460:     };

462:     template<typename Sieve_, typename Section_>
463:     class ArrowSection : public ALE::ParallelObject {
464:     public:
465:       typedef Sieve_                            sieve_type;
466:       typedef Section_                          section_type;
467:       typedef typename sieve_type::target_type  point_type;
468:       typedef typename section_type::point_type arrow_type;
469:       typedef typename section_type::value_type value_type;
470:     protected:
471:       Obj<sieve_type>   _sieve;
472:       Obj<section_type> _section;
473:       int               _coneSize;
474:       value_type       *_cone;
475:       void ensureCone(const int size) {
476:         if (size > this->_coneSize) {
477:           if (this->_cone) delete [] this->_cone;
478:           this->_coneSize = size;
479:           this->_cone     = new value_type[this->_coneSize];
480:         }
481:       };
482:     public:
483:       ArrowSection(const Obj<sieve_type>& sieve, const Obj<section_type>& section) : ParallelObject(MPI_COMM_SELF, sieve->debug()), _sieve(sieve), _section(section), _coneSize(-1), _cone(NULL) {};
484:       virtual ~ArrowSection() {if (this->_cone) delete [] this->_cone;};
485:     public:
486:       bool hasPoint(const point_type& point) {return this->_sieve->baseContains(point);};
487:       const value_type *restrictPoint(const point_type& p) {
488:         const Obj<typename sieve_type::traits::coneSequence>& cone = this->_sieve->cone(p);
489:         int c = -1;

491:         this->ensureCone(cone->size());
492:         for(typename sieve_type::traits::coneSequence::iterator c_iter = cone->begin(); c_iter != cone->end(); ++c_iter) {
493:           this->_cone[++c] = this->_section->restrictPoint(arrow_type(*c_iter, p))[0];
494:         }
495:         return this->_cone;
496:       };
497:     public:
498:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
499:         ostringstream txt;
500:         int rank;

502:         if (comm == MPI_COMM_NULL) {
503:           comm = this->comm();
504:           rank = this->commRank();
505:         } else {
506:           MPI_Comm_rank(comm, &rank);
507:         }
508:         if (name == "") {
509:           if(rank == 0) {
510:             txt << "viewing a ConeSection" << std::endl;
511:           }
512:         } else {
513:           if(rank == 0) {
514:             txt << "viewing ConeSection '" << name << "'" << std::endl;
515:           }
516:         }
517:         PetscSynchronizedPrintf(comm, txt.str().c_str());
518:         PetscSynchronizedFlush(comm);
519:       };
520:     };
521:   }
522: }

524: namespace ALECompat {
525:   namespace New {
526:     // This section takes an existing section, and reports instead the fiber dimensions as values
527:     //   Should not need the _patch variable
528:     template<typename Section_>
529:     class SizeSection : public ALE::ParallelObject {
530:     public:
531:       typedef Section_                          section_type;
532:       typedef typename section_type::patch_type patch_type;
533:       typedef typename section_type::point_type point_type;
534:       typedef int                               value_type;
535:     protected:
536:       Obj<section_type> _section;
537:       const patch_type  _patch;
538:       value_type        _size;
539:     public:
540:       SizeSection(const Obj<section_type>& section, const patch_type& patch) : ParallelObject(MPI_COMM_SELF, section->debug()), _section(section), _patch(patch) {};
541:       virtual ~SizeSection() {};
542:     public:
543:       bool hasPoint(const patch_type& patch, const point_type& point) {
544:         return this->_section->hasPoint(patch, point);
545:       };
546:       const value_type *restrict(const patch_type& patch, const point_type& p) {
547:         this->_size = this->_section->getFiberDimension(this->_patch, p); // Could be size()
548:         return &this->_size;
549:       };
550:       const value_type *restrictPoint(const patch_type& patch, const point_type& p) {
551:         this->_size = this->_section->getFiberDimension(this->_patch, p);
552:         return &this->_size;
553:       };
554:     public:
555:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
556:         this->_section->view(name, comm);
557:       };
558:     };

560:     // This section reports as values the size of the partition associated with the partition point
561:     template<typename Topology_, typename MeshTopology_, typename Marker_>
562:     class PartitionSizeSection : public ALE::ParallelObject {
563:     public:
564:       typedef Topology_                          topology_type;
565:       typedef MeshTopology_                      mesh_topology_type;
566:       typedef typename topology_type::patch_type patch_type;
567:       typedef typename topology_type::sieve_type sieve_type;
568:       typedef typename topology_type::point_type point_type;
569:       typedef typename ALECompat::New::NumberingFactory<mesh_topology_type> NumberingFactory;
570:       typedef Marker_                            marker_type;
571:       typedef int                                value_type;
572:       typedef std::map<patch_type,int>           sizes_type;
573:     protected:
574:       Obj<topology_type> _topology;
575:       sizes_type         _sizes;
576:       int                _height;
577:       void _init(const Obj<mesh_topology_type>& topology, const int numElements, const marker_type partition[]) {
578:         if (topology->depth() > 1) throw ALE::Exception("Compatibility layer is not for interpolated meshes");
579:         // Should check for patch 0
580:         const typename mesh_topology_type::patch_type           patch = 0;
581:         const Obj<typename mesh_topology_type::sieve_type>&     sieve = topology->getPatch(patch);
582:         const Obj<typename mesh_topology_type::label_sequence>& cells = topology->heightStratum(patch, this->_height);
583:         const Obj<typename NumberingFactory::numbering_type>&   cNumbering = NumberingFactory::singleton(topology->debug())->getLocalNumbering(topology, patch, topology->depth(patch) - this->_height);
584:         std::map<patch_type, std::set<point_type> >             points;

586:         if (numElements != (int) cells->size()) {
587:           throw ALE::Exception("Partition size does not match the number of elements");
588:         }
589:         for(typename mesh_topology_type::label_sequence::iterator e_iter = cells->begin(); e_iter != cells->end(); ++e_iter) {
590:           const Obj<typename mesh_topology_type::sieve_type::coneSequence>& closure = sieve->cone(*e_iter);
591:           const int idx = cNumbering->getIndex(*e_iter);

593:           points[partition[idx]].insert(*e_iter);
594:           points[partition[idx]].insert(closure->begin(), closure->end());
595:           if (this->_height > 0) {
596:             const Obj<typename mesh_topology_type::sieve_type::supportSequence>& star = sieve->support(*e_iter);

598:             points[partition[idx]].insert(star->begin(), star->end());
599:           }
600:         }
601:         for(typename std::map<patch_type, std::set<point_type> >::const_iterator p_iter = points.begin(); p_iter != points.end(); ++p_iter) {
602:           this->_sizes[p_iter->first] = p_iter->second.size();
603:         }
604:       };
605:     public:
606:       PartitionSizeSection(const Obj<topology_type>& topology, const Obj<mesh_topology_type>& meshTopology, const int elementHeight, const int numElements, const marker_type *partition) : ParallelObject(MPI_COMM_SELF, topology->debug()), _topology(topology), _height(elementHeight) {
607:         this->_init(meshTopology, numElements, partition);
608:       };
609:       virtual ~PartitionSizeSection() {};
610:     public:
611:       bool hasPoint(const patch_type& patch, const point_type& point) {return true;};
612:       const value_type *restrict(const patch_type& patch, const point_type& p) {return this->restrictPoint(patch, p);};
613:       const value_type *restrictPoint(const patch_type& patch, const point_type& p) {
614:         return &this->_sizes[p];
615:       };
616:     public:
617:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
618:         ostringstream txt;
619:         int rank;

621:         if (comm == MPI_COMM_NULL) {
622:           comm = this->comm();
623:           rank = this->commRank();
624:         } else {
625:           MPI_Comm_rank(comm, &rank);
626:         }
627:         if (name == "") {
628:           if(rank == 0) {
629:             txt << "viewing a PartitionSizeSection" << std::endl;
630:           }
631:         } else {
632:           if(rank == 0) {
633:             txt << "viewing PartitionSizeSection '" << name << "'" << std::endl;
634:           }
635:         }
636:         for(typename sizes_type::const_iterator s_iter = this->_sizes.begin(); s_iter != this->_sizes.end(); ++s_iter) {
637:           const patch_type& patch = s_iter->first;
638:           const value_type  size  = s_iter->second;

640:           txt << "[" << this->commRank() << "]: Patch " << patch << " size " << size << std::endl;
641:         }
642:         PetscSynchronizedPrintf(comm, txt.str().c_str());
643:         PetscSynchronizedFlush(comm);
644:       };
645:     };

647:     template<typename Topology_>
648:     class PartitionDomain {
649:     public:
650:       typedef Topology_                          topology_type;
651:       typedef typename topology_type::patch_type patch_type;
652:       typedef typename topology_type::point_type point_type;
653:     public:
654:       PartitionDomain() {};
655:       ~PartitionDomain() {};
656:     public:
657:       int count(const point_type& point) const {return 1;};
658:     };

660:     // This section returns the points in each partition
661:     template<typename Topology_, typename MeshTopology_, typename Marker_>
662:     class PartitionSection : public ALE::ParallelObject {
663:     public:
664:       typedef Topology_                          topology_type;
665:       typedef MeshTopology_                      mesh_topology_type;
666:       typedef typename topology_type::patch_type patch_type;
667:       typedef typename topology_type::sieve_type sieve_type;
668:       typedef typename topology_type::point_type point_type;
669:       typedef ALECompat::New::NumberingFactory<mesh_topology_type> NumberingFactory;
670:       typedef Marker_                            marker_type;
671:       typedef int                                value_type;
672:       typedef std::map<patch_type,point_type*>   points_type;
673:       typedef PartitionDomain<topology_type>     chart_type;
674:     protected:
675:       Obj<topology_type> _topology;
676:       points_type        _points;
677:       chart_type         _domain;
678:       int                _height;
679:       void _init(const Obj<mesh_topology_type>& topology, const int numElements, const marker_type partition[]) {
680:         if (topology->depth() > 1) throw ALE::Exception("Compatibility layer is not for interpolated meshes");
681:         // Should check for patch 0
682:         const typename mesh_topology_type::patch_type           patch = 0;
683:         const Obj<typename mesh_topology_type::sieve_type>&     sieve = topology->getPatch(patch);
684:         const Obj<typename mesh_topology_type::label_sequence>& cells = topology->heightStratum(patch, this->_height);
685:         const Obj<typename NumberingFactory::numbering_type>&   cNumbering = NumberingFactory::singleton(topology->debug())->getLocalNumbering(topology, patch, topology->depth(patch) - this->_height);
686:         std::map<patch_type, std::set<point_type> >             points;
687:         std::map<patch_type, int>                               offsets;

689:         if (numElements != (int) cells->size()) {
690:           throw ALE::Exception("Partition size does not match the number of elements");
691:         }
692:         for(typename mesh_topology_type::label_sequence::iterator e_iter = cells->begin(); e_iter != cells->end(); ++e_iter) {
693:           const Obj<typename mesh_topology_type::sieve_type::coneSequence>& closure = sieve->cone(*e_iter);
694:           const int idx = cNumbering->getIndex(*e_iter);

696:           points[partition[idx]].insert(*e_iter);
697:           points[partition[idx]].insert(closure->begin(), closure->end());
698:           if (this->_height > 0) {
699:             const Obj<typename mesh_topology_type::sieve_type::supportSequence>& star = sieve->support(*e_iter);

701:             points[partition[idx]].insert(star->begin(), star->end());
702:           }
703:         }
704:         for(typename std::map<patch_type, std::set<point_type> >::const_iterator p_iter = points.begin(); p_iter != points.end(); ++p_iter) {
705:           this->_points[p_iter->first] = new point_type[p_iter->second.size()];
706:           offsets[p_iter->first] = 0;
707:           for(typename std::set<point_type>::const_iterator s_iter = p_iter->second.begin(); s_iter != p_iter->second.end(); ++s_iter) {
708:             this->_points[p_iter->first][offsets[p_iter->first]++] = *s_iter;
709:           }
710:         }
711:         for(typename std::map<patch_type, std::set<point_type> >::const_iterator p_iter = points.begin(); p_iter != points.end(); ++p_iter) {
712:           if (offsets[p_iter->first] != (int) p_iter->second.size()) {
713:             ostringstream txt;
714:             txt << "Invalid offset for partition " << p_iter->first << ": " << offsets[p_iter->first] << " should be " << p_iter->second.size();
715:             throw ALE::Exception(txt.str().c_str());
716:           }
717:         }
718:       };
719:     public:
720:       PartitionSection(const Obj<topology_type>& topology, const Obj<mesh_topology_type>& meshTopology, const int elementHeight, const int numElements, const marker_type *partition) : ParallelObject(MPI_COMM_SELF, topology->debug()), _topology(topology), _height(elementHeight) {
721:         this->_init(meshTopology, numElements, partition);
722:       };
723:       virtual ~PartitionSection() {
724:         for(typename points_type::iterator p_iter = this->_points.begin(); p_iter != this->_points.end(); ++p_iter) {
725:           delete [] p_iter->second;
726:         }
727:       };
728:     public:
729:       const chart_type& getPatch(const patch_type& patch) {return this->_domain;};
730:       bool hasPoint(const patch_type& patch, const point_type& point) {return true;};
731:       const value_type *restrict(const patch_type& patch, const point_type& p) {return this->restrictPoint(patch, p);};
732:       const value_type *restrictPoint(const patch_type& patch, const point_type& p) {
733:         return this->_points[p];
734:       };
735:     public:
736:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
737:         ostringstream txt;
738:         int rank;

740:         if (comm == MPI_COMM_NULL) {
741:           comm = this->comm();
742:           rank = this->commRank();
743:         } else {
744:           MPI_Comm_rank(comm, &rank);
745:         }
746:         if (name == "") {
747:           if(rank == 0) {
748:             txt << "viewing a PartitionSection" << std::endl;
749:           }
750:         } else {
751:           if(rank == 0) {
752:             txt << "viewing PartitionSection '" << name << "'" << std::endl;
753:           }
754:         }
755:         for(typename points_type::const_iterator p_iter = this->_points.begin(); p_iter != this->_points.end(); ++p_iter) {
756:           const patch_type& patch  = p_iter->first;
757:           //const point_type *points = p_iter->second;

759:           txt << "[" << this->commRank() << "]: Patch " << patch << std::endl;
760:         }
761:         if (this->_points.size() == 0) {
762:           txt << "[" << this->commRank() << "]: empty" << std::endl;
763:         }
764:         PetscSynchronizedPrintf(comm, txt.str().c_str());
765:         PetscSynchronizedFlush(comm);
766:       };
767:     };

769:     template<typename Topology_, typename MeshTopology_, typename Sieve_>
770:     class ConeSizeSection : public ALE::ParallelObject {
771:     public:
772:       typedef Topology_                          topology_type;
773:       typedef MeshTopology_                      mesh_topology_type;
774:       typedef typename topology_type::patch_type patch_type;
775:       typedef typename topology_type::sieve_type sieve_type;
776:       typedef typename topology_type::point_type point_type;
777:       typedef Sieve_                             cone_sieve_type;
778:       typedef int                                value_type;
779:       typedef std::map<patch_type,int>           sizes_type;
780:     protected:
781:       Obj<topology_type>      _topology;
782:       Obj<mesh_topology_type> _meshTopology;
783:       Obj<cone_sieve_type>    _sieve;
784:       value_type              _size;
785:       int                     _minHeight;
786:     public:
787:       ConeSizeSection(const Obj<topology_type>& topology, const Obj<mesh_topology_type>& meshTopology, const Obj<cone_sieve_type>& sieve, int minimumHeight = 0) : ParallelObject(MPI_COMM_SELF, topology->debug()), _topology(topology), _meshTopology(meshTopology), _sieve(sieve), _minHeight(minimumHeight) {};
788:       virtual ~ConeSizeSection() {};
789:     public:
790:       bool hasPoint(const patch_type& patch, const point_type& point) {return true;};
791:       const value_type *restrict(const patch_type& patch, const point_type& p) {return this->restrictPoint(patch, p);};
792:       const value_type *restrictPoint(const patch_type& patch, const point_type& p) {
793:         if ((this->_minHeight == 0) || (this->_meshTopology->height(patch, p) >= this->_minHeight)) {
794:           this->_size = this->_sieve->cone(p)->size();
795:         } else {
796:           this->_size = 0;
797:         }
798:         return &this->_size;
799:       };
800:     public:
801:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
802:         ostringstream txt;
803:         int rank;

805:         if (comm == MPI_COMM_NULL) {
806:           comm = this->comm();
807:           rank = this->commRank();
808:         } else {
809:           MPI_Comm_rank(comm, &rank);
810:         }
811:         if (name == "") {
812:           if(rank == 0) {
813:             txt << "viewing a ConeSizeSection" << std::endl;
814:           }
815:         } else {
816:           if(rank == 0) {
817:             txt << "viewing ConeSizeSection '" << name << "'" << std::endl;
818:           }
819:         }
820:         PetscSynchronizedPrintf(comm, txt.str().c_str());
821:         PetscSynchronizedFlush(comm);
822:       };
823:     };

825:     template<typename Topology_, typename Sieve_>
826:     class ConeSection : public ALE::ParallelObject {
827:     public:
828:       typedef Topology_                          topology_type;
829:       typedef typename topology_type::patch_type patch_type;
830:       typedef typename topology_type::sieve_type sieve_type;
831:       typedef typename topology_type::point_type point_type;
832:       typedef Sieve_                             cone_sieve_type;
833:       typedef point_type                         value_type;
834:       typedef std::map<patch_type,int>           sizes_type;
835:       typedef PartitionDomain<topology_type>     chart_type;
836:     protected:
837:       Obj<topology_type>      _topology;
838:       Obj<cone_sieve_type>    _sieve;
839:       int                     _coneSize;
840:       value_type             *_cone;
841:       chart_type              _domain;
842:       void ensureCone(const int size) {
843:         if (size > this->_coneSize) {
844:           if (this->_cone) delete [] this->_cone;
845:           this->_coneSize = size;
846:           this->_cone     = new value_type[this->_coneSize];
847:         }
848:       };
849:     public:
850:       ConeSection(MPI_Comm comm, const Obj<cone_sieve_type>& sieve, const int debug = 0) : ParallelObject(comm, debug), _sieve(sieve), _coneSize(-1), _cone(NULL) {
851:         this->_topology = new topology_type(comm, debug);
852:       };
853:       ConeSection(const Obj<topology_type>& topology, const Obj<cone_sieve_type>& sieve) : ParallelObject(MPI_COMM_SELF, topology->debug()), _topology(topology), _sieve(sieve), _coneSize(-1), _cone(NULL) {};
854:       virtual ~ConeSection() {if (this->_cone) delete [] this->_cone;};
855:     public:
856:       const chart_type& getPatch(const patch_type& patch) {return this->_domain;};
857:       bool hasPoint(const patch_type& patch, const point_type& point) {return true;};
858:       const value_type *restrict(const patch_type& patch, const point_type& p) {return this->restrictPoint(patch, p);};
859:       const value_type *restrictPoint(const patch_type& patch, const point_type& p) {
860:         const Obj<typename cone_sieve_type::traits::coneSequence>& cone = this->_sieve->cone(p);
861:         int c = 0;

863:         this->ensureCone(cone->size());
864:         for(typename cone_sieve_type::traits::coneSequence::iterator c_iter = cone->begin(); c_iter != cone->end(); ++c_iter) {
865:           this->_cone[c++] = *c_iter;
866:         }
867:         return this->_cone;
868:       };
869:     public:
870:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
871:         ostringstream txt;
872:         int rank;

874:         if (comm == MPI_COMM_NULL) {
875:           comm = this->comm();
876:           rank = this->commRank();
877:         } else {
878:           MPI_Comm_rank(comm, &rank);
879:         }
880:         if (name == "") {
881:           if(rank == 0) {
882:             txt << "viewing a ConeSection" << std::endl;
883:           }
884:         } else {
885:           if(rank == 0) {
886:             txt << "viewing ConeSection '" << name << "'" << std::endl;
887:           }
888:         }
889:         PetscSynchronizedPrintf(comm, txt.str().c_str());
890:         PetscSynchronizedFlush(comm);
891:       };
892:     };

894:     template<typename Topology_, typename MeshTopology_, typename Sieve_>
895:     class SupportSizeSection : public ALE::ParallelObject {
896:     public:
897:       typedef Topology_                          topology_type;
898:       typedef MeshTopology_                      mesh_topology_type;
899:       typedef typename topology_type::patch_type patch_type;
900:       typedef typename topology_type::sieve_type sieve_type;
901:       typedef typename topology_type::point_type point_type;
902:       typedef Sieve_                             support_sieve_type;
903:       typedef int                                value_type;
904:       typedef std::map<patch_type,int>           sizes_type;
905:     protected:
906:       Obj<topology_type>      _topology;
907:       Obj<mesh_topology_type> _meshTopology;
908:       Obj<support_sieve_type> _sieve;
909:       value_type              _size;
910:       int                     _minDepth;
911:     public:
912:       SupportSizeSection(const Obj<topology_type>& topology, const Obj<mesh_topology_type>& meshTopology, const Obj<support_sieve_type>& sieve, int minimumDepth = 0) : ParallelObject(MPI_COMM_SELF, topology->debug()), _topology(topology), _meshTopology(meshTopology), _sieve(sieve), _minDepth(minimumDepth) {};
913:       virtual ~SupportSizeSection() {};
914:     public:
915:       bool hasPoint(const patch_type& patch, const point_type& point) {return true;};
916:       const value_type *restrict(const patch_type& patch, const point_type& p) {return this->restrictPoint(patch, p);};
917:       const value_type *restrictPoint(const patch_type& patch, const point_type& p) {
918:         if ((this->_minDepth == 0) || (this->_meshTopology->depth(patch, p) >= this->_minDepth)) {
919:           this->_size = this->_sieve->support(p)->size();
920:         } else {
921:           this->_size = 0;
922:         }
923:         return &this->_size;
924:       };
925:     public:
926:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
927:         ostringstream txt;
928:         int rank;

930:         if (comm == MPI_COMM_NULL) {
931:           comm = this->comm();
932:           rank = this->commRank();
933:         } else {
934:           MPI_Comm_rank(comm, &rank);
935:         }
936:         if (name == "") {
937:           if(rank == 0) {
938:             txt << "viewing a SupportSizeSection" << std::endl;
939:           }
940:         } else {
941:           if(rank == 0) {
942:             txt << "viewing SupportSizeSection '" << name << "'" << std::endl;
943:           }
944:         }
945:         PetscSynchronizedPrintf(comm, txt.str().c_str());
946:         PetscSynchronizedFlush(comm);
947:       };
948:     };

950:     template<typename Topology_, typename Sieve_>
951:     class SupportSection : public ALE::ParallelObject {
952:     public:
953:       typedef Topology_                          topology_type;
954:       typedef typename topology_type::patch_type patch_type;
955:       typedef typename topology_type::sieve_type sieve_type;
956:       typedef typename topology_type::point_type point_type;
957:       typedef Sieve_                             support_sieve_type;
958:       typedef point_type                         value_type;
959:       typedef std::map<patch_type,int>           sizes_type;
960:       typedef PartitionDomain<topology_type>     chart_type;
961:     protected:
962:       Obj<topology_type>      _topology;
963:       Obj<support_sieve_type> _sieve;
964:       int                     _supportSize;
965:       value_type             *_support;
966:       chart_type              _domain;
967:       void ensureSupport(const int size) {
968:         if (size > this->_supportSize) {
969:           if (this->_support) delete [] this->_support;
970:           this->_supportSize = size;
971:           this->_support     = new value_type[this->_supportSize];
972:         }
973:       };
974:     public:
975:       SupportSection(MPI_Comm comm, const Obj<support_sieve_type>& sieve, const int debug = 0) : ParallelObject(comm, debug), _sieve(sieve), _supportSize(-1), _support(NULL) {
976:         this->_topology = new topology_type(comm, debug);
977:       };
978:       SupportSection(const Obj<topology_type>& topology, const Obj<support_sieve_type>& sieve) : ParallelObject(MPI_COMM_SELF, topology->debug()), _topology(topology), _sieve(sieve), _supportSize(-1), _support(NULL) {};
979:       virtual ~SupportSection() {if (this->_support) delete [] this->_support;};
980:     public:
981:       const chart_type& getPatch(const patch_type& patch) {return this->_domain;};
982:       bool hasPoint(const patch_type& patch, const point_type& point) {return true;};
983:       const value_type *restrict(const patch_type& patch, const point_type& p) {return this->restrictPoint(patch, p);};
984:       const value_type *restrictPoint(const patch_type& patch, const point_type& p) {
985:         const Obj<typename support_sieve_type::traits::supportSequence>& support = this->_sieve->support(p);
986:         int s = 0;

988:         this->ensureSupport(support->size());
989:         for(typename support_sieve_type::traits::supportSequence::iterator s_iter = support->begin(); s_iter != support->end(); ++s_iter) {
990:           this->_support[s++] = *s_iter;
991:         }
992:         return this->_support;
993:       };
994:     public:
995:       void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
996:         ostringstream txt;
997:         int rank;

999:         if (comm == MPI_COMM_NULL) {
1000:           comm = this->comm();
1001:           rank = this->commRank();
1002:         } else {
1003:           MPI_Comm_rank(comm, &rank);
1004:         }
1005:         if (name == "") {
1006:           if(rank == 0) {
1007:             txt << "viewing a SupportSection" << std::endl;
1008:           }
1009:         } else {
1010:           if(rank == 0) {
1011:             txt << "viewing SupportSection '" << name << "'" << std::endl;
1012:           }
1013:         }
1014:         PetscSynchronizedPrintf(comm, txt.str().c_str());
1015:         PetscSynchronizedFlush(comm);
1016:       };
1017:     };
1018:   }
1019: }
1020: #endif