Actual source code: Completion.hh
1: #ifndef included_ALE_Completion_hh
2: #define included_ALE_Completion_hh
4: #ifndef included_ALE_Sections_hh
5: #include <Sections.hh>
6: #endif
8: #include <iostream>
9: #include <fstream>
11: namespace ALE {
12: namespace New {
13: template<typename Bundle_, typename Value_, typename Alloc_ = std::allocator<typename Bundle_::point_type> >
14: class Completion {
15: public:
16: typedef int point_type;
17: typedef Value_ value_type;
18: typedef Bundle_ bundle_type;
19: typedef Alloc_ alloc_type;
20: typedef typename alloc_type::template rebind<int>::other int_alloc_type;
21: typedef typename alloc_type::template rebind<value_type>::other value_alloc_type;
22: typedef typename bundle_type::sieve_type sieve_type;
23: typedef typename ALE::DiscreteSieve<point_type, alloc_type> dsieve_type;
24: typedef typename ALE::Topology<int, dsieve_type, alloc_type> topology_type;
25: typedef typename ALE::Sifter<int, point_type, point_type> send_overlap_type;
26: typedef typename ALE::Sifter<point_type, int, point_type> recv_overlap_type;
27: typedef typename ALE::Field<send_overlap_type, int, ALE::Section<point_type, int, int_alloc_type> > send_sizer_type;
28: typedef typename ALE::Field<recv_overlap_type, int, ALE::Section<point_type, int, int_alloc_type> > recv_sizer_type;
29: typedef typename ALE::New::ConeSizeSection<bundle_type, sieve_type> cone_size_section;
30: typedef typename ALE::New::ConeSection<sieve_type> cone_section;
31: typedef typename ALE::New::SectionCompletion<bundle_type, value_type, alloc_type> completion;
32: public:
33: template<typename PartitionType>
34: static void scatterSieve(const Obj<bundle_type>& bundle, const Obj<sieve_type>& sieve, const int dim, const Obj<sieve_type>& sieveNew, const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, const int height, const int numCells, const PartitionType assignment[]) {
35: typedef typename ALE::Field<send_overlap_type, int, ALE::Section<point_type, value_type, value_alloc_type> > send_section_type;
36: typedef typename ALE::Field<recv_overlap_type, int, ALE::Section<point_type, value_type, value_alloc_type> > recv_section_type;
37: int rank = sieve->commRank();
38: int debug = sieve->debug();
40: // Create local sieve
41: const Obj<typename bundle_type::label_sequence>& cells = bundle->heightStratum(height);
42: int e = 0;
44: if (sieve->debug()) {
45: int e2 = 0;
46: for(typename bundle_type::label_sequence::iterator e_iter = cells->begin(); e_iter != cells->end(); ++e_iter) {
47: std::cout << "assignment["<<*e_iter<<"]" << assignment[e2++] << std::endl;
48: }
49: }
50: PetscTruth flg;
51: PetscOptionsHasName(PETSC_NULL, "-output_partition", &flg);
52: if (flg) {
53: ostringstream fname;
54: fname << "part." << sieve->commSize() << ".dat";
55: std::ofstream f(fname.str().c_str());
56: int e2 = 0;
57: f << sieve->commSize() << std::endl;
58: for(typename bundle_type::label_sequence::iterator e_iter = cells->begin(); e_iter != cells->end(); ++e_iter) {
59: f << assignment[e2++] << std::endl;
60: }
61: }
62: for(typename bundle_type::label_sequence::iterator e_iter = cells->begin(); e_iter != cells->end(); ++e_iter) {
63: if (assignment[e] == rank) {
64: Obj<typename sieve_type::coneSet> current = new typename sieve_type::coneSet();
65: Obj<typename sieve_type::coneSet> next = new typename sieve_type::coneSet();
66: Obj<typename sieve_type::coneSet> tmp;
68: current->insert(*e_iter);
69: while(current->size()) {
70: for(typename sieve_type::coneSet::const_iterator p_iter = current->begin(); p_iter != current->end(); ++p_iter) {
71: const Obj<typename sieve_type::traits::coneSequence>& cone = sieve->cone(*p_iter);
72:
73: for(typename sieve_type::traits::coneSequence::iterator c_iter = cone->begin(); c_iter != cone->end(); ++c_iter) {
74: sieveNew->addArrow(*c_iter, *p_iter, c_iter.color());
75: next->insert(*c_iter);
76: }
77: }
78: tmp = current; current = next; next = tmp;
79: next->clear();
80: }
81: if (height) {
82: current->insert(*e_iter);
83: while(current->size()) {
84: for(typename sieve_type::coneSet::const_iterator p_iter = current->begin(); p_iter != current->end(); ++p_iter) {
85: const Obj<typename sieve_type::traits::supportSequence>& support = sieve->support(*p_iter);
86:
87: for(typename sieve_type::traits::supportSequence::iterator s_iter = support->begin(); s_iter != support->end(); ++s_iter) {
88: sieveNew->addArrow(*p_iter, *s_iter, s_iter.color());
89: next->insert(*s_iter);
90: }
91: }
92: tmp = current; current = next; next = tmp;
93: next->clear();
94: }
95: }
96: }
97: e++;
98: }
99: // Complete sizer section
100: typedef typename ALE::New::PartitionSizeSection<bundle_type, PartitionType> partition_size_section;
101: typedef typename ALE::New::PartitionSection<bundle_type, PartitionType> partition_section;
102: Obj<topology_type> secTopology = completion::createSendTopology(sendOverlap);
103: Obj<partition_size_section> partitionSizeSection = new partition_size_section(bundle, height, numCells, assignment);
104: Obj<partition_section> partitionSection = new partition_section(bundle, height, numCells, assignment);
105: Obj<send_section_type> sendSection = new send_section_type(sieve->comm(), sieve->debug());
106: Obj<recv_section_type> recvSection = new recv_section_type(sieve->comm(), sendSection->getTag(), sieve->debug());
108: completion::completeSection(sendOverlap, recvOverlap, partitionSizeSection, partitionSection, sendSection, recvSection);
109: // Unpack the section into the overlap
110: sendOverlap->clear();
111: recvOverlap->clear();
112: const typename send_section_type::sheaf_type& sendPatches = sendSection->getPatches();
114: for(typename send_section_type::sheaf_type::const_iterator p_iter = sendPatches.begin(); p_iter != sendPatches.end(); ++p_iter) {
115: const typename send_section_type::patch_type rank = p_iter->first;
116: const Obj<typename send_section_type::section_type>& section = p_iter->second;
117: const typename send_section_type::section_type::chart_type chart = section->getChart();
119: for(typename send_section_type::section_type::chart_type::iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
120: const typename send_section_type::value_type *points = section->restrictPoint(*c_iter);
121: int size = section->getFiberDimension(*c_iter);
123: for(int p = 0; p < size; p++) {
124: sendOverlap->addArrow(points[p], rank, points[p]);
125: }
126: }
127: }
128: const typename recv_section_type::sheaf_type& recvPatches = recvSection->getPatches();
130: for(typename recv_section_type::sheaf_type::const_iterator p_iter = recvPatches.begin(); p_iter != recvPatches.end(); ++p_iter) {
131: const typename send_section_type::patch_type rank = p_iter->first;
132: const Obj<typename send_section_type::section_type>& section = p_iter->second;
133: const typename send_section_type::section_type::chart_type chart = section->getChart();
135: for(typename recv_section_type::section_type::chart_type::iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
136: const typename recv_section_type::value_type *points = section->restrictPoint(*c_iter);
137: int size = section->getFiberDimension(*c_iter);
139: for(int p = 0; p < size; p++) {
140: recvOverlap->addArrow(rank, points[p], points[p]);
141: }
142: }
143: }
144: if (debug) {
145: sendOverlap->view(std::cout, "Send overlap for points");
146: recvOverlap->view(std::cout, "Receive overlap for points");
147: }
148: // Receive the point section
149: ALE::New::Completion<bundle_type, value_type>::scatterCones(sieve, sieveNew, sendOverlap, recvOverlap, bundle, height);
150: if (height) {
151: ALE::New::Completion<bundle_type, value_type>::scatterSupports(sieve, sieveNew, sendOverlap, recvOverlap, bundle, bundle->depth()-height);
152: }
153: };
154: template<typename SifterType>
155: static void scatterCones(const Obj<SifterType>& sifter, const Obj<SifterType>& sifterNew, const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, const Obj<bundle_type>& bundle = NULL, const int minimumHeight = 0) {
156: typedef typename ALE::New::ConeSizeSection<bundle_type, SifterType> cone_size_section;
157: typedef typename ALE::New::ConeSection<SifterType> cone_section;
158: typedef typename ALE::Field<send_overlap_type, int, ALE::Section<point_type, value_type, value_alloc_type> > send_section_type;
159: typedef typename ALE::Field<recv_overlap_type, int, ALE::Section<point_type, value_type, value_alloc_type> > recv_section_type;
160: Obj<topology_type> secTopology = completion::createSendTopology(sendOverlap);
161: Obj<cone_size_section> coneSizeSection = new cone_size_section(bundle, sifter, minimumHeight);
162: Obj<cone_section> coneSection = new cone_section(sifter);
163: Obj<send_section_type> sendSection = new send_section_type(sifter->comm(), sifter->debug());
164: Obj<recv_section_type> recvSection = new recv_section_type(sifter->comm(), sendSection->getTag(), sifter->debug());
166: completion::completeSection(sendOverlap, recvOverlap, coneSizeSection, coneSection, sendSection, recvSection);
167: // Unpack the section into the sieve
168: const typename recv_section_type::sheaf_type& patches = recvSection->getPatches();
170: for(typename recv_section_type::sheaf_type::const_iterator p_iter = patches.begin(); p_iter != patches.end(); ++p_iter) {
171: const Obj<typename recv_section_type::section_type>& section = p_iter->second;
172: const typename recv_section_type::section_type::chart_type& chart = section->getChart();
174: for(typename recv_section_type::section_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
175: const typename recv_section_type::value_type *points = section->restrictPoint(*c_iter);
176: int size = section->getFiberDimension(*c_iter);
177: int c = 0;
179: for(int p = 0; p < size; p++) {
180: sifterNew->addArrow(points[p], *c_iter, c++);
181: }
182: }
183: }
184: };
185: template<typename SifterType>
186: static void scatterSupports(const Obj<SifterType>& sifter, const Obj<SifterType>& sifterNew, const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, const Obj<bundle_type>& bundle = NULL, const int minimumDepth = 0) {
187: typedef typename ALE::New::SupportSizeSection<bundle_type, SifterType> support_size_section;
188: typedef typename ALE::New::SupportSection<SifterType> support_section;
189: typedef typename ALE::Field<send_overlap_type, int, ALE::Section<point_type, value_type, value_alloc_type> > send_section_type;
190: typedef typename ALE::Field<recv_overlap_type, int, ALE::Section<point_type, value_type, value_alloc_type> > recv_section_type;
191: Obj<topology_type> secTopology = completion::createSendTopology(sendOverlap);
192: Obj<support_size_section> supportSizeSection = new support_size_section(bundle, sifter, minimumDepth);
193: Obj<support_section> supportSection = new support_section(sifter);
194: Obj<send_section_type> sendSection = new send_section_type(sifter->comm(), sifter->debug());
195: Obj<recv_section_type> recvSection = new recv_section_type(sifter->comm(), sendSection->getTag(), sifter->debug());
197: completion::completeSection(sendOverlap, recvOverlap, supportSizeSection, supportSection, sendSection, recvSection);
198: // Unpack the section into the sieve
199: const typename recv_section_type::sheaf_type& recvPatches = recvSection->getPatches();
201: for(typename recv_section_type::sheaf_type::const_iterator p_iter = recvPatches.begin(); p_iter != recvPatches.end(); ++p_iter) {
202: const Obj<typename send_section_type::section_type>& section = p_iter->second;
203: const typename send_section_type::section_type::chart_type chart = section->getChart();
205: for(typename recv_section_type::section_type::chart_type::iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
206: const typename recv_section_type::value_type *points = section->restrictPoint(*c_iter);
207: int size = section->getFiberDimension(*c_iter);
208: int c = 0;
210: for(int p = 0; p < size; p++) {
211: sifterNew->addArrow(*c_iter, points[p], c++);
212: }
213: }
214: }
215: };
216: };
218: template<typename Value_>
219: class ParallelFactory {
220: public:
221: typedef Value_ value_type;
222: protected:
223: int _debug;
224: MPI_Datatype _mpiType;
225: protected:
226: MPI_Datatype constructMPIType() {
227: if (sizeof(value_type) == 4) {
228: return MPI_INT;
229: } else if (sizeof(value_type) == 8) {
230: return MPI_DOUBLE;
231: } else if (sizeof(value_type) == 28) {
232: int blen[2];
233: MPI_Aint indices[2];
234: MPI_Datatype oldtypes[2], newtype;
235: blen[0] = 1; indices[0] = 0; oldtypes[0] = MPI_INT;
236: blen[1] = 3; indices[1] = sizeof(int); oldtypes[1] = MPI_DOUBLE;
237: MPI_Type_struct(2, blen, indices, oldtypes, &newtype);
238: MPI_Type_commit(&newtype);
239: return newtype;
240: } else if (sizeof(value_type) == 32) {
241: int blen[2];
242: MPI_Aint indices[2];
243: MPI_Datatype oldtypes[2], newtype;
244: blen[0] = 1; indices[0] = 0; oldtypes[0] = MPI_DOUBLE;
245: blen[1] = 3; indices[1] = sizeof(int); oldtypes[1] = MPI_DOUBLE;
246: MPI_Type_struct(2, blen, indices, oldtypes, &newtype);
247: MPI_Type_commit(&newtype);
248: return newtype;
249: }
250: throw ALE::Exception("Cannot determine MPI type for value type");
251: };
252: ParallelFactory(const int debug) : _debug(debug) {
253: this->_mpiType = this->constructMPIType();
254: };
255: public:
256: ~ParallelFactory() {};
257: public:
258: static const Obj<ParallelFactory>& singleton(const int debug, bool cleanup = false) {
259: static Obj<ParallelFactory> *_singleton = NULL;
261: if (cleanup) {
262: if (debug) {std::cout << "Destroying ParallelFactory" << std::endl;}
263: if (_singleton) {delete _singleton;}
264: _singleton = NULL;
265: } else if (_singleton == NULL) {
266: if (debug) {std::cout << "Creating new ParallelFactory" << std::endl;}
267: _singleton = new Obj<ParallelFactory>();
268: *_singleton = new ParallelFactory(debug);
269: }
270: return *_singleton;
271: };
272: public: // Accessors
273: int debug() const {return this->_debug;};
274: MPI_Datatype getMPIType() const {return this->_mpiType;};
275: };
276: }
277: }
279: namespace ALECompat {
280: namespace New {
281: template<typename Section_>
282: class PatchlessSection : public ALE::ParallelObject {
283: public:
284: typedef Section_ section_type;
285: typedef typename section_type::patch_type patch_type;
286: typedef typename section_type::sieve_type sieve_type;
287: typedef typename section_type::point_type point_type;
288: typedef typename section_type::value_type value_type;
289: typedef typename section_type::chart_type chart_type;
290: protected:
291: Obj<section_type> _section;
292: const patch_type _patch;
293: public:
294: PatchlessSection(const Obj<section_type>& section, const patch_type& patch) : ParallelObject(MPI_COMM_SELF, section->debug()), _section(section), _patch(patch) {};
295: virtual ~PatchlessSection() {};
296: public:
297: const chart_type& getPatch(const patch_type& patch) {
298: return this->_section->getAtlas()->getPatch(this->_patch);
299: };
300: bool hasPoint(const patch_type& patch, const point_type& point) {
301: return this->_section->hasPoint(patch, point);
302: };
303: const value_type *restrict(const patch_type& patch) {
304: return this->_section->restrict(this->_patch);
305: };
306: const value_type *restrict(const patch_type& patch, const point_type& p) {
307: return this->_section->restrict(this->_patch, p);
308: };
309: const value_type *restrictPoint(const patch_type& patch, const point_type& p) {
310: return this->_section->restrictPoint(this->_patch, p);
311: };
312: void update(const patch_type& patch, const point_type& p, const value_type v[]) {
313: this->_section->update(this->_patch, p, v);
314: };
315: void updateAdd(const patch_type& patch, const point_type& p, const value_type v[]) {
316: this->_section->updateAdd(this->_patch, p, v);
317: };
318: void updatePoint(const patch_type& patch, const point_type& p, const value_type v[]) {
319: this->_section->updatePoint(this->_patch, p, v);
320: };
321: template<typename Input>
322: void update(const patch_type& patch, const point_type& p, const Obj<Input>& v) {
323: this->_section->update(this->_patch, p, v);
324: };
325: public:
326: void view(const std::string& name, MPI_Comm comm = MPI_COMM_NULL) const {
327: this->_section->view(name, comm);
328: };
329: };
331: template<typename Topology_, typename Value_>
332: class Completion {
333: public:
334: typedef int point_type;
335: typedef Value_ value_type;
336: typedef Topology_ mesh_topology_type;
337: typedef typename mesh_topology_type::sieve_type sieve_type;
338: typedef typename ALE::DiscreteSieve<point_type> dsieve_type;
339: typedef typename ALE::Topology<int, dsieve_type> topology_type;
340: typedef typename ALE::Sifter<int, point_type, point_type> send_overlap_type;
341: typedef typename ALECompat::New::OverlapValues<send_overlap_type, topology_type, int> send_sizer_type;
342: typedef typename ALE::Sifter<point_type, int, point_type> recv_overlap_type;
343: typedef typename ALECompat::New::OverlapValues<recv_overlap_type, topology_type, int> recv_sizer_type;
344: typedef typename ALECompat::New::OldConstantSection<topology_type, int> constant_sizer;
345: typedef typename ALECompat::New::OldConstantSection<topology_type, value_type> constant_section;
346: typedef typename ALECompat::New::ConeSizeSection<topology_type, mesh_topology_type, sieve_type> cone_size_section;
347: typedef typename ALECompat::New::ConeSection<topology_type, sieve_type> cone_section;
348: typedef typename ALECompat::New::SectionCompletion<mesh_topology_type,value_type> completion;
349: public:
350: template<typename PartitionType>
351: static void scatterSieve(const Obj<mesh_topology_type>& topology, const Obj<sieve_type>& sieve, const int dim, const Obj<sieve_type>& sieveNew, const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, const int numCells, const PartitionType assignment[]) {
352: typedef typename ALECompat::New::OverlapValues<send_overlap_type, topology_type, value_type> send_section_type;
353: typedef typename ALECompat::New::OverlapValues<recv_overlap_type, topology_type, value_type> recv_section_type;
354: int rank = sieve->commRank();
355: int debug = sieve->debug();
357: // Create local sieve
358: const Obj<topology_type::label_sequence>& cells = topology->heightStratum(0, 0);
359: int e = 0;
361: if (topology->debug()) {
362: int e2 = 0;
363: for(topology_type::label_sequence::iterator e_iter = cells->begin(); e_iter != cells->end(); ++e_iter) {
364: std::cout << "assignment["<<*e_iter<<"]" << assignment[e2++] << std::endl;
365: }
366: }
367: PetscTruth flg;
368: PetscOptionsHasName(PETSC_NULL, "-output_partition", &flg);
369: if (flg) {
370: ostringstream fname;
371: fname << "part." << sieve->commSize() << ".dat";
372: std::ofstream f(fname.str().c_str());
373: int e2 = 0;
374: f << sieve->commSize() << std::endl;
375: for(topology_type::label_sequence::iterator e_iter = cells->begin(); e_iter != cells->end(); ++e_iter) {
376: f << assignment[e2++] << std::endl;
377: }
378: }
379: for(topology_type::label_sequence::iterator e_iter = cells->begin(); e_iter != cells->end(); ++e_iter) {
380: if (assignment[e] == rank) {
381: Obj<typename sieve_type::coneSet> current = new typename sieve_type::coneSet();
382: Obj<typename sieve_type::coneSet> next = new typename sieve_type::coneSet();
383: Obj<typename sieve_type::coneSet> tmp;
385: current->insert(*e_iter);
386: while(current->size()) {
387: for(typename sieve_type::coneSet::const_iterator p_iter = current->begin(); p_iter != current->end(); ++p_iter) {
388: const Obj<typename sieve_type::traits::coneSequence>& cone = sieve->cone(*p_iter);
389:
390: for(typename sieve_type::traits::coneSequence::iterator c_iter = cone->begin(); c_iter != cone->end(); ++c_iter) {
391: sieveNew->addArrow(*c_iter, *p_iter, c_iter.color());
392: next->insert(*c_iter);
393: }
394: }
395: tmp = current; current = next; next = tmp;
396: next->clear();
397: }
398: }
399: e++;
400: }
401: sieveNew->stratify();
402: // Complete sizer section
403: typedef typename ALECompat::New::PartitionSizeSection<topology_type, mesh_topology_type, PartitionType> partition_size_section;
404: typedef typename ALECompat::New::PartitionSection<topology_type, mesh_topology_type, PartitionType> partition_section;
405: Obj<topology_type> secTopology = completion::createSendTopology(sendOverlap);
406: Obj<partition_size_section> partitionSizeSection = new partition_size_section(secTopology, topology, 0, numCells, assignment);
407: Obj<partition_section> partitionSection = new partition_section(secTopology, topology, 0, numCells, assignment);
408: Obj<send_section_type> sendSection = new send_section_type(sieve->comm(), sieve->debug());
409: Obj<recv_section_type> recvSection = new recv_section_type(sieve->comm(), sendSection->getTag(), sieve->debug());
411: completion::completeSection(sendOverlap, recvOverlap, partitionSizeSection, partitionSection, sendSection, recvSection);
412: // Unpack the section into the overlap
413: sendOverlap->clear();
414: recvOverlap->clear();
415: const topology_type::sheaf_type& sendPatches = sendSection->getTopology()->getPatches();
417: for(topology_type::sheaf_type::const_iterator p_iter = sendPatches.begin(); p_iter != sendPatches.end(); ++p_iter) {
418: const Obj<topology_type::sieve_type::baseSequence>& base = p_iter->second->base();
420: for(topology_type::sieve_type::baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
421: const typename send_section_type::value_type *points = sendSection->restrict(p_iter->first, *b_iter);
422: int size = sendSection->size(p_iter->first, *b_iter);
424: for(int p = 0; p < size; p++) {
425: sendOverlap->addArrow(points[p], p_iter->first, points[p]);
426: }
427: }
428: }
429: const topology_type::sheaf_type& recvPatches = recvSection->getTopology()->getPatches();
431: for(topology_type::sheaf_type::const_iterator p_iter = recvPatches.begin(); p_iter != recvPatches.end(); ++p_iter) {
432: const Obj<topology_type::sieve_type::baseSequence>& base = p_iter->second->base();
433: int rank = p_iter->first;
435: for(topology_type::sieve_type::baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
436: const typename recv_section_type::value_type *points = recvSection->restrict(rank, *b_iter);
437: int size = recvSection->getFiberDimension(rank, *b_iter);
439: for(int p = 0; p < size; p++) {
440: recvOverlap->addArrow(rank, points[p], points[p]);
441: }
442: }
443: }
444: if (debug) {
445: sendOverlap->view(std::cout, "Send overlap for points");
446: recvOverlap->view(std::cout, "Receive overlap for points");
447: }
448: // Receive the point section
449: ALECompat::New::Completion<mesh_topology_type,value_type>::scatterCones(sieve, sieveNew, sendOverlap, recvOverlap);
450: sieveNew->stratify();
451: };
452: template<typename PartitionType>
453: static void scatterSieveByFace(const Obj<mesh_topology_type>& topology, const Obj<sieve_type>& sieve, const int dim, const Obj<sieve_type>& sieveNew, const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, const int numFaces, const PartitionType assignment[]) {
454: typedef typename ALECompat::New::OverlapValues<send_overlap_type, topology_type, value_type> send_section_type;
455: typedef typename ALECompat::New::OverlapValues<recv_overlap_type, topology_type, value_type> recv_section_type;
456: const typename topology_type::patch_type patch = 0;
457: int rank = sieve->commRank();
458: int debug = sieve->debug();
460: // Create local sieve
461: const Obj<topology_type::label_sequence>& faces = topology->heightStratum(patch, 1);
462: int f = 0;
464: for(topology_type::label_sequence::iterator f_iter = faces->begin(); f_iter != faces->end(); ++f_iter) {
465: if (assignment[f] == rank) {
466: Obj<typename sieve_type::coneSet> current = new typename sieve_type::coneSet();
467: Obj<typename sieve_type::coneSet> next = new typename sieve_type::coneSet();
468: Obj<typename sieve_type::coneSet> tmp;
470: current->insert(*f_iter);
471: while(current->size()) {
472: for(typename sieve_type::coneSet::const_iterator p_iter = current->begin(); p_iter != current->end(); ++p_iter) {
473: const Obj<typename sieve_type::traits::coneSequence>& cone = sieve->cone(*p_iter);
474:
475: for(typename sieve_type::traits::coneSequence::iterator c_iter = cone->begin(); c_iter != cone->end(); ++c_iter) {
476: sieveNew->addArrow(*c_iter, *p_iter, c_iter.color());
477: next->insert(*c_iter);
478: }
479: }
480: tmp = current; current = next; next = tmp;
481: next->clear();
482: }
483: const Obj<typename sieve_type::traits::supportSequence>& support = sieve->support(*f_iter);
485: for(typename sieve_type::traits::supportSequence::iterator s_iter = support->begin(); s_iter != support->end(); ++s_iter) {
486: sieveNew->addArrow(*f_iter, *s_iter, s_iter.color());
487: }
488: }
489: f++;
490: }
491: sieveNew->stratify();
492: // Complete sizer section
493: typedef typename ALECompat::New::PartitionSizeSection<topology_type, mesh_topology_type, PartitionType> partition_size_section;
494: typedef typename ALECompat::New::PartitionSection<topology_type, mesh_topology_type, PartitionType> partition_section;
495: Obj<topology_type> secTopology = completion::createSendTopology(sendOverlap);
496: Obj<partition_size_section> partitionSizeSection = new partition_size_section(secTopology, topology, 1, numFaces, assignment);
497: Obj<partition_section> partitionSection = new partition_section(secTopology, topology, 1, numFaces, assignment);
498: Obj<send_section_type> sendSection = new send_section_type(sieve->comm(), sieve->debug());
499: Obj<recv_section_type> recvSection = new recv_section_type(sieve->comm(), sendSection->getTag(), sieve->debug());
501: completion::completeSection(sendOverlap, recvOverlap, partitionSizeSection, partitionSection, sendSection, recvSection);
502: // Unpack the section into the overlap
503: sendOverlap->clear();
504: recvOverlap->clear();
505: const topology_type::sheaf_type& sendPatches = sendSection->getTopology()->getPatches();
507: for(topology_type::sheaf_type::const_iterator p_iter = sendPatches.begin(); p_iter != sendPatches.end(); ++p_iter) {
508: const Obj<topology_type::sieve_type::baseSequence>& base = p_iter->second->base();
510: for(topology_type::sieve_type::baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
511: const typename send_section_type::value_type *points = sendSection->restrict(p_iter->first, *b_iter);
512: int size = sendSection->size(p_iter->first, *b_iter);
514: for(int p = 0; p < size; p++) {
515: sendOverlap->addArrow(points[p], p_iter->first, points[p]);
516: }
517: }
518: }
519: const topology_type::sheaf_type& recvPatches = recvSection->getTopology()->getPatches();
521: for(topology_type::sheaf_type::const_iterator p_iter = recvPatches.begin(); p_iter != recvPatches.end(); ++p_iter) {
522: const Obj<topology_type::sieve_type::baseSequence>& base = p_iter->second->base();
523: int rank = p_iter->first;
525: for(topology_type::sieve_type::baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
526: const typename recv_section_type::value_type *points = recvSection->restrict(rank, *b_iter);
527: int size = recvSection->getFiberDimension(rank, *b_iter);
529: for(int p = 0; p < size; p++) {
530: recvOverlap->addArrow(rank, points[p], points[p]);
531: }
532: }
533: }
534: if (debug) {
535: sendOverlap->view(std::cout, "Send overlap for points");
536: recvOverlap->view(std::cout, "Receive overlap for points");
537: }
538: // Receive the point section
539: ALECompat::New::Completion<mesh_topology_type,value_type>::scatterCones(sieve, sieveNew, sendOverlap, recvOverlap, topology, 1);
540: ALECompat::New::Completion<mesh_topology_type,value_type>::scatterSupports(sieve, sieveNew, sendOverlap, recvOverlap, topology, topology->depth()-1);
541: sieveNew->stratify();
542: };
543: template<typename SifterType>
544: static void scatterCones(const Obj<SifterType>& sifter, const Obj<SifterType>& sifterNew, const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, const Obj<mesh_topology_type>& topology = NULL, const int minimumHeight = 0) {
545: typedef typename ALECompat::New::ConeSizeSection<topology_type, mesh_topology_type, SifterType> cone_size_section;
546: typedef typename ALECompat::New::ConeSection<topology_type, SifterType> cone_section;
547: typedef typename ALECompat::New::OverlapValues<send_overlap_type, topology_type, value_type> send_section_type;
548: typedef typename ALECompat::New::OverlapValues<recv_overlap_type, topology_type, value_type> recv_section_type;
549: Obj<topology_type> secTopology = completion::createSendTopology(sendOverlap);
550: Obj<cone_size_section> coneSizeSection = new cone_size_section(secTopology, topology, sifter, minimumHeight);
551: Obj<cone_section> coneSection = new cone_section(secTopology, sifter);
552: Obj<send_section_type> sendSection = new send_section_type(sifter->comm(), sifter->debug());
553: Obj<recv_section_type> recvSection = new recv_section_type(sifter->comm(), sendSection->getTag(), sifter->debug());
555: completion::completeSection(sendOverlap, recvOverlap, coneSizeSection, coneSection, sendSection, recvSection);
556: // Unpack the section into the sieve
557: const topology_type::sheaf_type& patches = recvSection->getTopology()->getPatches();
559: for(topology_type::sheaf_type::const_iterator p_iter = patches.begin(); p_iter != patches.end(); ++p_iter) {
560: const Obj<topology_type::sieve_type::baseSequence>& base = p_iter->second->base();
561: int rank = p_iter->first;
563: for(topology_type::sieve_type::baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
564: const typename recv_section_type::value_type *points = recvSection->restrict(rank, *b_iter);
565: int size = recvSection->getFiberDimension(rank, *b_iter);
566: int c = 0;
568: for(int p = 0; p < size; p++) {
569: sifterNew->addArrow(points[p], *b_iter, c++);
570: }
571: }
572: }
573: };
574: template<typename SifterType>
575: static void scatterSupports(const Obj<SifterType>& sifter, const Obj<SifterType>& sifterNew, const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, const Obj<mesh_topology_type>& topology = NULL, const int minimumDepth = 0) {
576: typedef typename ALECompat::New::SupportSizeSection<topology_type, mesh_topology_type, SifterType> support_size_section;
577: typedef typename ALECompat::New::SupportSection<topology_type, SifterType> support_section;
578: typedef typename ALECompat::New::OverlapValues<send_overlap_type, topology_type, value_type> send_section_type;
579: typedef typename ALECompat::New::OverlapValues<recv_overlap_type, topology_type, value_type> recv_section_type;
580: Obj<topology_type> secTopology = completion::createSendTopology(sendOverlap);
581: Obj<support_size_section> supportSizeSection = new support_size_section(secTopology, topology, sifter, minimumDepth);
582: Obj<support_section> supportSection = new support_section(secTopology, sifter);
583: Obj<send_section_type> sendSection = new send_section_type(sifter->comm(), sifter->debug());
584: Obj<recv_section_type> recvSection = new recv_section_type(sifter->comm(), sendSection->getTag(), sifter->debug());
586: completion::completeSection(sendOverlap, recvOverlap, supportSizeSection, supportSection, sendSection, recvSection);
587: // Unpack the section into the sieve
588: const topology_type::sheaf_type& patches = recvSection->getTopology()->getPatches();
590: for(topology_type::sheaf_type::const_iterator p_iter = patches.begin(); p_iter != patches.end(); ++p_iter) {
591: const Obj<topology_type::sieve_type::baseSequence>& base = p_iter->second->base();
592: int rank = p_iter->first;
594: for(topology_type::sieve_type::baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
595: const typename recv_section_type::value_type *points = recvSection->restrict(rank, *b_iter);
596: int size = recvSection->getFiberDimension(rank, *b_iter);
597: int c = 0;
599: for(int p = 0; p < size; p++) {
600: sifterNew->addArrow(*b_iter, points[p], c++);
601: }
602: }
603: }
604: };
605: };
607: template<typename Value_>
608: class ParallelFactory {
609: public:
610: typedef Value_ value_type;
611: protected:
612: int _debug;
613: MPI_Datatype _mpiType;
614: protected:
615: MPI_Datatype constructMPIType() {
616: if (sizeof(value_type) == 4) {
617: return MPI_INT;
618: } else if (sizeof(value_type) == 8) {
619: return MPI_DOUBLE;
620: } else if (sizeof(value_type) == 28) {
621: int blen[2];
622: MPI_Aint indices[2];
623: MPI_Datatype oldtypes[2], newtype;
624: blen[0] = 1; indices[0] = 0; oldtypes[0] = MPI_INT;
625: blen[1] = 3; indices[1] = sizeof(int); oldtypes[1] = MPI_DOUBLE;
626: MPI_Type_struct(2, blen, indices, oldtypes, &newtype);
627: MPI_Type_commit(&newtype);
628: return newtype;
629: } else if (sizeof(value_type) == 32) {
630: int blen[2];
631: MPI_Aint indices[2];
632: MPI_Datatype oldtypes[2], newtype;
633: blen[0] = 1; indices[0] = 0; oldtypes[0] = MPI_DOUBLE;
634: blen[1] = 3; indices[1] = sizeof(int); oldtypes[1] = MPI_DOUBLE;
635: MPI_Type_struct(2, blen, indices, oldtypes, &newtype);
636: MPI_Type_commit(&newtype);
637: return newtype;
638: }
639: throw ALE::Exception("Cannot determine MPI type for value type");
640: };
641: ParallelFactory(const int debug) : _debug(debug) {
642: this->_mpiType = this->constructMPIType();
643: };
644: public:
645: ~ParallelFactory() {};
646: public:
647: static const Obj<ParallelFactory>& singleton(const int debug, bool cleanup = false) {
648: static Obj<ParallelFactory> *_singleton = NULL;
650: if (cleanup) {
651: if (debug) {std::cout << "Destroying ParallelFactory" << std::endl;}
652: if (_singleton) {delete _singleton;}
653: _singleton = NULL;
654: } else if (_singleton == NULL) {
655: if (debug) {std::cout << "Creating new ParallelFactory" << std::endl;}
656: _singleton = new Obj<ParallelFactory>();
657: *_singleton = new ParallelFactory(debug);
658: }
659: return *_singleton;
660: };
661: public: // Accessors
662: int debug() const {return this->_debug;};
663: MPI_Datatype getMPIType() const {return this->_mpiType;};
664: };
665: }
666: }
667: #endif