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