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