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