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_>
 15:     class SectionCompletion {
 16:     public:
 17:       typedef int                                                                     point_type;
 18:       typedef Value_                                                                  value_type;
 19:       typedef Topology_                                                               mesh_topology_type;
 20:       typedef typename mesh_topology_type::sieve_type                                 sieve_type;
 21:       typedef typename ALE::DiscreteSieve<point_type>                                 dsieve_type;
 22:       typedef typename ALE::Topology<int, dsieve_type>                                topology_type;
 23:       typedef typename ALE::Sifter<int, point_type, point_type>                       send_overlap_type;
 24:       typedef typename ALE::Sifter<point_type, int, point_type>                       recv_overlap_type;
 25:       typedef typename ALE::Field<send_overlap_type, int, ALE::ConstantSection<point_type, int> > constant_sizer;
 26:       typedef typename ALE::New::SectionCompletion<mesh_topology_type, int>           int_completion;
 27:       typedef typename ALE::New::SectionCompletion<mesh_topology_type, value_type>    completion;
 28:     public:
 29:       // Creates a DiscreteTopology with the overlap information
 30:       static Obj<topology_type> createSendTopology(const Obj<send_overlap_type>& sendOverlap) {
 31:         const Obj<send_overlap_type::traits::baseSequence> ranks = sendOverlap->base();
 32:         Obj<topology_type> topology = new topology_type(sendOverlap->comm(), sendOverlap->debug());

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

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

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

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

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

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

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

 96:             section->setFiberDimension(point, 1);
 97:           }
 98:         }
 99:         recvSection->construct(recvSizer);
100:         recvSection->allocate();
101:         recvSection->constructCommunication(Section::RECEIVE);
102:       };
103:       template<typename SizerFiller, typename Filler, typename SendSection, typename RecvSection>
104:       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) {
105:         typedef typename ALE::Field<send_overlap_type, int, ALE::Section<point_type, int> > send_sizer_type;
106:         typedef typename ALE::Field<recv_overlap_type, int, ALE::Section<point_type, int> > recv_sizer_type;
107:         Obj<send_sizer_type> sendSizer      = new send_sizer_type(sendSection->comm(), sendSection->debug());
108:         Obj<recv_sizer_type> recvSizer      = new recv_sizer_type(recvSection->comm(), sendSizer->getTag(), recvSection->debug());
109:         Obj<constant_sizer>  constSendSizer = new constant_sizer(sendSection->comm(), sendSection->debug());
110:         Obj<constant_sizer>  constRecvSizer = new constant_sizer(recvSection->comm(), recvSection->debug());
111:         Obj<topology_type>   sendChart      = completion::createSendTopology(sendOverlap);
112:         Obj<topology_type>   recvChart      = completion::createRecvTopology(recvOverlap);

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

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

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

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

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

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

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

227:             recvSieve->addPoint(point);
228:           }
229:           recvSection->getTopology()->setPatch(*r_iter, recvSieve);
230:         }
231:         recvSection->getTopology()->stratify();
232:         recvSection->construct(recvSizer);
233:         recvSection->allocate();
234:         recvSection->constructCommunication(Section::RECEIVE);
235:       };
236:       template<typename SizerFiller, typename Filler, typename SendSection, typename RecvSection>
237:       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) {
238:         Obj<send_sizer_type> sendSizer     = new send_sizer_type(sendSection->comm(), sendSection->debug());
239:         Obj<recv_sizer_type> recvSizer     = new recv_sizer_type(recvSection->comm(), sendSizer->getTag(), recvSection->debug());
240:         Obj<constant_sizer>  constantSizer = new constant_sizer(recvSection->comm(), 1, sendSection->debug());

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