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