Actual source code: SectionCompletion.hh

  1: #ifndef included_ALE_SectionCompletion_hh
  2: #define included_ALE_SectionCompletion_hh

  4: #ifndef  included_ALE_Topology_hh
  5: #include <Topology.hh>
  6: #endif

  8: #ifndef  included_ALE_Field_hh
  9: #include <Field.hh>
 10: #endif

 12: namespace ALE {
 13:   namespace New {
 14:     template<typename Topology_, typename Value_, typename Alloc_ = typename Topology_::alloc_type>
 15:     class SectionCompletion {
 16:     public:
 17:       typedef int                                                                     point_type;
 18:       typedef Topology_                                                               mesh_topology_type;
 19:       typedef Value_                                                                  value_type;
 20:       typedef Alloc_                                                                  alloc_type;
 21:       typedef typename alloc_type::template rebind<point_type>::other                 point_alloc_type;
 22:       typedef typename mesh_topology_type::sieve_type                                 sieve_type;
 23:       typedef typename ALE::DiscreteSieve<point_type, point_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::ConstantSection<point_type, int> > constant_sizer;
 28:       typedef typename ALE::New::SectionCompletion<mesh_topology_type, int, alloc_type>           int_completion;
 29:       typedef typename ALE::New::SectionCompletion<mesh_topology_type, value_type, alloc_type>    completion;
 30:     public:
 31:       // Creates a DiscreteTopology with the overlap information
 32:       static Obj<topology_type> createSendTopology(const Obj<send_overlap_type>& sendOverlap) {
 33:         const Obj<send_overlap_type::traits::baseSequence> ranks = sendOverlap->base();
 34:         Obj<topology_type> topology = new topology_type(sendOverlap->comm(), sendOverlap->debug());

 36:         for(send_overlap_type::traits::baseSequence::iterator r_iter = ranks->begin(); r_iter != ranks->end(); ++r_iter) {
 37:           Obj<dsieve_type> sendSieve = new dsieve_type(sendOverlap->cone(*r_iter));
 38:           topology->setPatch(*r_iter, sendSieve);
 39:         }
 40:         //CAN ELIMINATE
 41:         //topology->stratify();
 42:         return topology;
 43:       };
 44:       static Obj<topology_type> createRecvTopology(const Obj<send_overlap_type>& recvOverlap) {
 45:         const Obj<recv_overlap_type::traits::capSequence> ranks = recvOverlap->cap();
 46:         Obj<topology_type> topology = new topology_type(recvOverlap->comm(), recvOverlap->debug());

 48:         for(recv_overlap_type::traits::capSequence::iterator r_iter = ranks->begin(); r_iter != ranks->end(); ++r_iter) {
 49:           Obj<dsieve_type> recvSieve = new dsieve_type();
 50:           const Obj<recv_overlap_type::supportSequence>& points  = recvOverlap->support(*r_iter);

 52:           for(recv_overlap_type::supportSequence::iterator p_iter = points->begin(); p_iter != points->end(); ++p_iter) {
 53:             recvSieve->addPoint(p_iter.color());
 54:           }
 55:           topology->setPatch(*r_iter, recvSieve);
 56:         }
 57:         //CAN ELIMINATE
 58:         //topology->stratify();
 59:         return topology;
 60:       };
 61:       template<typename Sizer, typename Section>
 62:       static void setupSend(const Obj<topology_type>& sendChart, const Obj<Sizer>& sendSizer, const Obj<Section>& sendSection) {
 63:         // Here we should just use the overlap as the topology (once it is a new-style sieve)
 64:         sendSection->clear();
 65:         sendSection->setTopology(sendChart);
 66:         sendSection->construct(sendSizer);
 67:         sendSection->allocate();
 68:         if (sendSection->debug() > 10) {sendSection->view("Send section after setup", MPI_COMM_SELF);}
 69:         sendSection->constructCommunication(Section::SEND);
 70:       };
 71:       template<typename Filler, typename Section>
 72:       static void fillSend(const Filler& sendFiller, const Obj<Section>& sendSection) {
 73:         const typename Section::sheaf_type& patches = sendSection->getPatches();

 75:         for(typename Section::sheaf_type::const_iterator p_iter = patches.begin(); p_iter != patches.end(); ++p_iter) {
 76:           const Obj<typename Section::section_type>&        section = p_iter->second;
 77:           const typename Section::section_type::chart_type& chart   = section->getChart();

 79:           for(typename Section::section_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
 80:             if (sendFiller->hasPoint(*c_iter)) {
 81:               section->updatePoint(*c_iter, sendFiller->restrictPoint(*c_iter));
 82:             }
 83:           }
 84:         }
 85:       };
 86:       template<typename Sizer, typename Section>
 87:       static void setupReceive(const Obj<recv_overlap_type>& recvOverlap, const Obj<Sizer>& recvSizer, const Obj<Section>& recvSection) {
 88:         // Create section
 89:         const Obj<recv_overlap_type::traits::capSequence> ranks = recvOverlap->cap();

 91:         recvSection->clear();
 92:         for(recv_overlap_type::traits::capSequence::iterator r_iter = ranks->begin(); r_iter != ranks->end(); ++r_iter) {
 93:           const Obj<recv_overlap_type::supportSequence>& points  = recvOverlap->support(*r_iter);
 94:           const Obj<typename Section::section_type>&     section = recvSection->getSection(*r_iter);

 96:           // Want to replace this loop with a slice through color
 97:           for(recv_overlap_type::supportSequence::iterator p_iter = points->begin(); p_iter != points->end(); ++p_iter) {
 98:             const typename dsieve_type::point_type& point = p_iter.color();

100:             section->setFiberDimension(point, 1);
101:           }
102:         }
103:         recvSection->construct(recvSizer);
104:         recvSection->allocate();
105:         recvSection->constructCommunication(Section::RECEIVE);
106:       };
107:       template<typename SizerFiller, typename Filler, typename SendSection, typename RecvSection>
108:       static void completeSection(const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, const Obj<SizerFiller>& sizerFiller, const Filler& filler, const Obj<SendSection>& sendSection, const Obj<RecvSection>& recvSection) {
109:         typedef typename alloc_type::template rebind<int>::other int_alloc_type;
110:         typedef typename ALE::Field<send_overlap_type, int, ALE::Section<point_type, int, int_alloc_type> > send_sizer_type;
111:         typedef typename ALE::Field<recv_overlap_type, int, ALE::Section<point_type, int, int_alloc_type> > recv_sizer_type;
112:         Obj<send_sizer_type> sendSizer      = new send_sizer_type(sendSection->comm(), sendSection->debug());
113:         Obj<recv_sizer_type> recvSizer      = new recv_sizer_type(recvSection->comm(), sendSizer->getTag(), recvSection->debug());
114:         Obj<constant_sizer>  constSendSizer = new constant_sizer(sendSection->comm(), sendSection->debug());
115:         Obj<constant_sizer>  constRecvSizer = new constant_sizer(recvSection->comm(), recvSection->debug());
116:         Obj<topology_type>   sendChart      = completion::createSendTopology(sendOverlap);
117:         Obj<topology_type>   recvChart      = completion::createRecvTopology(recvOverlap);

119:         // 1) Create the sizer sections
120:         constSendSizer->setTopology(sendChart);
121:         const typename topology_type::sheaf_type& sendRanks = sendChart->getPatches();
122:         for(typename topology_type::sheaf_type::const_iterator r_iter = sendRanks.begin(); r_iter != sendRanks.end(); ++r_iter) {
123:           const int rank = r_iter->first;
124:           const int one  = 1;
125:           constSendSizer->getSection(rank)->updatePoint(*r_iter->second->base()->begin(), &one);
126:         }
127:         constRecvSizer->setTopology(recvChart);
128:         const typename topology_type::sheaf_type& recvRanks = recvChart->getPatches();
129:         for(typename topology_type::sheaf_type::const_iterator r_iter = recvRanks.begin(); r_iter != recvRanks.end(); ++r_iter) {
130:           const int rank = r_iter->first;
131:           const int one  = 1;
132:           constRecvSizer->getSection(rank)->updatePoint(*r_iter->second->base()->begin(), &one);
133:         }
134:         int_completion::setupSend(sendChart, constSendSizer, sendSizer);
135:         int_completion::setupReceive(recvOverlap, constRecvSizer, recvSizer);
136:         // 2) Fill the sizer section and communicate
137:         int_completion::fillSend(sizerFiller, sendSizer);
138:         if (sendSizer->debug()) {sendSizer->view("Send Sizer in Completion", MPI_COMM_SELF);}
139:         sendSizer->startCommunication();
140:         recvSizer->startCommunication();
141:         sendSizer->endCommunication();
142:         recvSizer->endCommunication();
143:         if (recvSizer->debug()) {recvSizer->view("Receive Sizer in Completion", MPI_COMM_SELF);}
144:         // No need to update a global section since the receive sizes are all on the interface
145:         // 3) Create the send and receive sections
146:         completion::setupSend(sendChart, sendSizer, sendSection);
147:         completion::setupReceive(recvOverlap, recvSizer, recvSection);
148:         // 4) Fill up send section and communicate
149:         completion::fillSend(filler, sendSection);
150:         if (sendSection->debug()) {sendSection->view("Send Section in Completion", MPI_COMM_SELF);}
151:         sendSection->startCommunication();
152:         recvSection->startCommunication();
153:         sendSection->endCommunication();
154:         recvSection->endCommunication();
155:         if (recvSection->debug()) {recvSection->view("Receive Section in Completion", MPI_COMM_SELF);}
156:       };
157:     };
158:   }
159: }

161: namespace ALECompat {
162:   namespace New {
163:     template<typename Topology_, typename Value_>
164:     class SectionCompletion {
165:     public:
166:       typedef int                                                                     point_type;
167:       typedef Value_                                                                  value_type;
168:       typedef Topology_                                                               mesh_topology_type;
169:       typedef typename mesh_topology_type::sieve_type                                 sieve_type;
170:       typedef typename ALE::DiscreteSieve<point_type>                                 dsieve_type;
171:       typedef typename ALE::Topology<int, dsieve_type>                                topology_type;
172:       typedef typename ALE::Sifter<int, point_type, point_type>                       send_overlap_type;
173:       typedef typename ALECompat::New::OverlapValues<send_overlap_type, topology_type, int> send_sizer_type;
174:       typedef typename ALE::Sifter<point_type, int, point_type>                       recv_overlap_type;
175:       typedef typename ALECompat::New::OverlapValues<recv_overlap_type, topology_type, int> recv_sizer_type;
176:       typedef typename ALECompat::New::OldConstantSection<topology_type, int>               constant_sizer;
177:       typedef typename ALECompat::New::SectionCompletion<mesh_topology_type, int>           int_completion;
178:       typedef typename ALECompat::New::SectionCompletion<mesh_topology_type, value_type>    completion;
179:     public:
180:       // Creates a DiscreteTopology with the overlap information
181:       static Obj<topology_type> createSendTopology(const Obj<send_overlap_type>& sendOverlap) {
182:         const Obj<send_overlap_type::traits::baseSequence> ranks = sendOverlap->base();
183:         Obj<topology_type> topology = new topology_type(sendOverlap->comm(), sendOverlap->debug());

185:         for(send_overlap_type::traits::baseSequence::iterator r_iter = ranks->begin(); r_iter != ranks->end(); ++r_iter) {
186:           Obj<dsieve_type> sendSieve = new dsieve_type(sendOverlap->cone(*r_iter));
187:           topology->setPatch(*r_iter, sendSieve);
188:         }
189:         topology->stratify();
190:         return topology;
191:       };
192:       template<typename Sizer, typename Section>
193:       static void setupSend(const Obj<send_overlap_type>& sendOverlap, const Obj<Sizer>& sendSizer, const Obj<Section>& sendSection) {
194:         // Here we should just use the overlap as the topology (once it is a new-style sieve)
195:         sendSection->clear();
196:         sendSection->setTopology(completion::createSendTopology(sendOverlap));
197:         if (sendSection->debug() > 10) {sendSection->getTopology()->view("Send topology after setup", MPI_COMM_SELF);}
198:         sendSection->construct(sendSizer);
199:         sendSection->allocate();
200:         sendSection->constructCommunication(Section::SEND);
201:       };
202:       template<typename Filler, typename Section>
203:       static void fillSend(const Filler& sendFiller, const Obj<Section>& sendSection) {
204:         const topology_type::sheaf_type& ranks = sendSection->getTopology()->getPatches();
205:         const topology_type::patch_type  patch = 0; // FIX: patch should come from overlap

207:         for(topology_type::sheaf_type::const_iterator p_iter = ranks.begin(); p_iter != ranks.end(); ++p_iter) {
208:           const int&                                          rank = p_iter->first;
209:           const Obj<topology_type::sieve_type::baseSequence>& base = p_iter->second->base();

211:           for(topology_type::sieve_type::baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
212:             if (sendFiller->hasPoint(patch, *b_iter)) {
213:               sendSection->updatePoint(rank, *b_iter, sendFiller->restrictPoint(patch, *b_iter));
214:             }
215:           }
216:         }
217:       };
218:       template<typename Sizer, typename Section>
219:       static void setupReceive(const Obj<recv_overlap_type>& recvOverlap, const Obj<Sizer>& recvSizer, const Obj<Section>& recvSection) {
220:         // Create section
221:         const Obj<recv_overlap_type::traits::capSequence> ranks = recvOverlap->cap();

223:         recvSection->clear();
224:         for(recv_overlap_type::traits::capSequence::iterator r_iter = ranks->begin(); r_iter != ranks->end(); ++r_iter) {
225:           Obj<dsieve_type> recvSieve = new dsieve_type();
226:           const Obj<recv_overlap_type::supportSequence>& points = recvOverlap->support(*r_iter);

228:           // Want to replace this loop with a slice through color
229:           for(recv_overlap_type::supportSequence::iterator p_iter = points->begin(); p_iter != points->end(); ++p_iter) {
230:             const dsieve_type::point_type& point = p_iter.color();

232:             recvSieve->addPoint(point);
233:           }
234:           recvSection->getTopology()->setPatch(*r_iter, recvSieve);
235:         }
236:         recvSection->getTopology()->stratify();
237:         recvSection->construct(recvSizer);
238:         recvSection->allocate();
239:         recvSection->constructCommunication(Section::RECEIVE);
240:       };
241:       template<typename SizerFiller, typename Filler, typename SendSection, typename RecvSection>
242:       static void completeSection(const Obj<send_overlap_type>& sendOverlap, const Obj<recv_overlap_type>& recvOverlap, const Obj<SizerFiller>& sizerFiller, const Filler& filler, const Obj<SendSection>& sendSection, const Obj<RecvSection>& recvSection) {
243:         Obj<send_sizer_type> sendSizer     = new send_sizer_type(sendSection->comm(), sendSection->debug());
244:         Obj<recv_sizer_type> recvSizer     = new recv_sizer_type(recvSection->comm(), sendSizer->getTag(), recvSection->debug());
245:         Obj<constant_sizer>  constantSizer = new constant_sizer(recvSection->comm(), 1, sendSection->debug());

247:         // 1) Create the sizer sections
248:         int_completion::setupSend(sendOverlap, constantSizer, sendSizer);
249:         int_completion::setupReceive(recvOverlap, constantSizer, recvSizer);
250:         // 2) Fill the sizer section and communicate
251:         int_completion::fillSend(sizerFiller, sendSizer);
252:         if (sendSizer->debug()) {sendSizer->view("Send Sizer in Completion", MPI_COMM_SELF);}
253:         sendSizer->startCommunication();
254:         recvSizer->startCommunication();
255:         sendSizer->endCommunication();
256:         recvSizer->endCommunication();
257:         if (recvSizer->debug()) {recvSizer->view("Receive Sizer in Completion", MPI_COMM_SELF);}
258:         // No need to update a global section since the receive sizes are all on the interface
259:         // 3) Create the send and receive sections
260:         completion::setupSend(sendOverlap, sendSizer, sendSection);
261:         completion::setupReceive(recvOverlap, recvSizer, recvSection);
262:         // 4) Fill up send section and communicate
263:         completion::fillSend(filler, sendSection);
264:         if (sendSection->debug()) {sendSection->view("Send Section in Completion", MPI_COMM_SELF);}
265:         sendSection->startCommunication();
266:         recvSection->startCommunication();
267:         sendSection->endCommunication();
268:         recvSection->endCommunication();
269:         if (recvSection->debug()) {recvSection->view("Receive Section in Completion", MPI_COMM_SELF);}
270:       };
271:     };
272:   }
273: }
274: #endif