Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
domain_indirect_mpi.cc
Go to the documentation of this file.
1
21
22#include "rheolef/config.h"
23
24#ifdef _RHEOLEF_HAVE_MPI
25#include "rheolef/domain_indirect.h"
26#include "rheolef/geo.h"
27
28namespace rheolef {
29
30// ----------------------------------------------------------------------------
31// @brief init domain ios from the whole mesh ios data
32// ----------------------------------------------------------------------------
33template <class T>
34void
37{
38 // compute i/o _ioige2ini_dis_ioige & _ioige2ini_dis_ioige numbering tables
39 // --------------------------------------------
40 // 1) mark used elements in omega ios numbering
41 // --------------------------------------------
42 const size_type unset = std::numeric_limits<size_type>::max();
43 distributor ios_ownership = omega.ios_sizes().ownership_by_dimension [base::_map_dim];
44 disarray<size_type,distributed> ios_mark (ios_ownership, unset);
45 distributor dom_ownership = base::ownership();
46 size_type first_dom_dis_ie = dom_ownership.first_index();
47 size_type dom_ie = 0;
48 for (const_iterator_ioige iter = base::ioige_begin(), last = base::ioige_end();
49 iter != last; iter++, dom_ie++) {
50 size_type ie = (*iter).index();
51 size_type ios_dis_ie = omega.ige2ios_dis_ige (base::_map_dim, ie);
52 size_type dom_dis_ie = first_dom_dis_ie + dom_ie;
53 ios_mark.dis_entry (ios_dis_ie) = dom_dis_ie;
54 }
55 ios_mark.dis_entry_assembly();
56 // --------------------------------------------
57 // 2) count used elements in omega ios numbering
58 // --------------------------------------------
59 size_type dom_ini_size = 0;
60 for (size_type ios_ie = 0, ios_ne = ios_mark.size(); ios_ie < ios_ne; ios_ie++) {
61 if (ios_mark [ios_ie] != unset) dom_ini_size++;
62 }
63 // --------------------------------------------
64 // 3) set _ini_ioige2dis_ioige
65 // --------------------------------------------
66 distributor dom_ini_ownership (distributor::decide, base::comm(), dom_ini_size);
67 _ini_ioige2dis_ioige.resize (dom_ini_ownership, unset);
68 size_type dom_ini_ie = 0;
69 for (size_type ios_ie = 0, ios_ne = ios_mark.size(); ios_ie < ios_ne; ios_ie++) {
70 if (ios_mark [ios_ie] == unset) continue;
71 _ini_ioige2dis_ioige [dom_ini_ie] = ios_mark [ios_ie];
72 dom_ini_ie++;
73 }
74 // --------------------------------------------
75 // 4) set _ioige2ini_dis_ioige
76 // --------------------------------------------
77 _ioige2ini_dis_ioige.resize (dom_ownership, unset);
78 _ini_ioige2dis_ioige.reverse_permutation (_ioige2ini_dis_ioige);
79}
80// ----------------------------------------------------------------------------
82// ----------------------------------------------------------------------------
191template<class U>
194 idiststream& ips,
195 const geo_rep<U,distributed>& omega)
196{
197 const size_type unset = std::numeric_limits<size_type>::max();
198 // -----------------------
199 // 1) get initial disarray
200 // -----------------------
201 // 1.1) get header
202 communicator comm = omega.comm();
203 if ( ! dis_scatch (ips, comm, "\ndomain")) {
204 ips.is().setstate (std::ios::badbit);
205 return ips;
206 }
207 size_type version, dis_noige;
208 ips >> base::_name
209 >> version
210 >> base::_map_dim
211 >> dis_noige;
212 check_macro (version == 2, "unsupported version="<<version<<" domain format");
213
214 // 1.2) get data
215 distributor ini_ioige_ownership (dis_noige, comm);
216 disarray<geo_element_indirect,distributed> ini_oige (ini_ioige_ownership);
217 ini_oige.get_values (ips);
218 // ---------------------------
219 // 2) first renumbering (ios)
220 // ---------------------------
221 // 2.1) compute ios_owner for each oriented-side
222 distributor ios_ige_ownership = omega.geo_element_ios_ownership (base::_map_dim);
223 disarray<size_type> ios_owner (ini_ioige_ownership, unset);
224 for (size_type ini_ioige = 0, ini_noige = ini_oige.size();
225 ini_ioige < ini_noige; ini_ioige++) {
226 size_type ios_ige = ini_oige [ini_ioige].index();
227 ios_owner [ini_ioige] = ios_ige_ownership.find_owner (ios_ige);
228 }
229 // 2.2) ios repartition
231 disarray<size_type> ini_ioige2ios_dis_ioige;
232 disarray<size_type> ios_ioige2ini_dis_ioige;
233 ini_oige.repartition (
234 ios_owner,
235 ios_oige,
236 ios_ioige2ini_dis_ioige,
237 ini_ioige2ios_dis_ioige);
238
239 // ---------------------
240 // 3) first renumbering
241 // ---------------------
242 // 3.1) geo_element renumbering
243 distributor ios_ioige_ownership = ios_oige.ownership();
244 disarray<geo_element_indirect> tmp_oige (ios_ioige_ownership);
245 for (size_type ios_ioige = 0, ios_noige = ios_ioige_ownership.size();
246 ios_ioige < ios_noige; ios_ioige++) {
247 orientation_type orient = ios_oige [ios_ioige].orientation();
248 size_type ios_dis_ige = ios_oige [ios_ioige].index();
249 size_type ios_ige = ios_dis_ige - ios_ige_ownership.first_index();
250 size_type dis_ige = omega.ios_ige2dis_ige (base::_map_dim, ios_ige);
251 tmp_oige [ios_ioige].set (orient, dis_ige);
252 }
253 // 3.2) compute ownership for each oriented-side
254 distributor ige_ownership = omega.geo_element_ownership (base::_map_dim);
255 disarray<size_type> partition (ios_ioige_ownership, unset);
256 for (size_type ios_ioige = 0, ios_noige = ios_ioige_ownership.size();
257 ios_ioige < ios_noige; ios_ioige++) {
258 size_type ige = tmp_oige [ios_ioige].index();
259 partition [ios_ioige] = ige_ownership.find_owner (ige);
260 }
261 // 3.3) repartition
262 disarray<size_type> ios_ioige2dis_ioige;
263 disarray<size_type> ioige2ios_dis_ioige;
264 tmp_oige.repartition (
265 partition,
266 *this,
267 ioige2ios_dis_ioige,
268 ios_ioige2dis_ioige);
269
270 // 3.4) shift from "dis_ioige" to a "ioige" numbering local to each process:
272 for (size_type ioige = 0, noige = ioige_ownership.size(); ioige < noige; ioige++) {
273 size_type dis_ige = operator[] (ioige).index();
274 size_type ige = dis_ige - ige_ownership.first_index();
275 operator[] (ioige).set_index (ige);
276 }
277 // ----------------------------------------------
278 // 4) Back to "ini" renumbering: set permutations
279 // ----------------------------------------------
280 _ini_ioige2dis_ioige.resize (ini_ioige_ownership, unset);
281 _ioige2ini_dis_ioige.resize ( ioige_ownership, unset);
282 for (size_type ios_ioige = 0, ios_noige = ios_ioige_ownership.size();
283 ios_ioige < ios_noige; ios_ioige++) {
284 size_type ini_dis_ioige = ios_ioige2ini_dis_ioige [ios_ioige];
285 size_type dis_ioige = ios_ioige2dis_ioige [ios_ioige];
286 _ini_ioige2dis_ioige.dis_entry (ini_dis_ioige) = dis_ioige;
287 _ioige2ini_dis_ioige.dis_entry (dis_ioige) = ini_dis_ioige;
288 }
289 _ioige2ini_dis_ioige.dis_entry_assembly();
290 _ini_ioige2dis_ioige.dis_entry_assembly();
291
292 return ips;
293}
294template<class U>
297 odiststream& ops,
298 const geo_rep<U,distributed>& omega) const
299{
300 using namespace std;
301 ops << "domain" << endl
302 << base::_name << endl
303 << "2 " << base::_map_dim << " " << dis_size() << endl;
305 distributor ini_ioige_ownership = _ini_ioige2dis_ioige.ownership();
306 distributor ige_ownership = omega.geo_element_ownership (base::_map_dim);
307 disarray<geo_element_indirect> ini_oige (ini_ioige_ownership);
308 for (size_type ioige = 0, noige = ioige_ownership.size(); ioige < noige; ioige++) {
309 size_type ini_dis_ioige = _ioige2ini_dis_ioige [ioige];
310 orientation_type orient = operator[] (ioige).orientation();
311 size_type ige = operator[] (ioige).index();
312 size_type ios_dis_ige = omega.ige2ios_dis_ige (base::_map_dim, ige);
313 ini_oige.dis_entry (ini_dis_ioige) = geo_element_indirect (orient, ios_dis_ige);
314 }
315 ini_oige.dis_entry_assembly();
316 ini_oige.put_values (ops);
317 return ops;
318}
319// ----------------------------------------------------------------------------
320// instanciation in library
321// ----------------------------------------------------------------------------
322template
325 idiststream& ips,
326 const geo_rep<Float,distributed>& omega);
327
328template
331 odiststream& ops,
332 const geo_rep<Float,distributed>& omega) const;
333
334#define _RHEOLEF_instanciation(T,M) \
335template \
336void \
337domain_indirect_rep<M>::init_ios (const geo_abstract_rep<T,M>&); \
338
339_RHEOLEF_instanciation(Float,distributed)
340
341} // namespace rheolef
342#endif // _RHEOLEF_HAVE_MPI
#define _RHEOLEF_instanciation(T, M, A)
Definition asr.cc:223
see the Float page for the full documentation
see the disarray page for the full documentation
Definition disarray.h:497
see the distributor page for the full documentation
Definition distributor.h:69
size_type find_owner(size_type dis_i) const
find iproc associated to a global index dis_i: CPU=log(nproc)
size_type size(size_type iproc) const
size_type first_index(size_type iproc) const
global index range and local size owned by ip-th process
static const size_type decide
Definition distributor.h:83
base::const_iterator_ioige const_iterator_ioige
abstract interface class
Definition geo.h:401
sequential mesh representation
Definition geo.h:778
idiststream: see the diststream page for the full documentation
Definition diststream.h:336
std::istream & is()
Definition diststream.h:400
odiststream: see the diststream page for the full documentation
Definition diststream.h:137
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
This file is part of Rheolef.
bool dis_scatch(idiststream &ips, const communicator &comm, std::string ch)
distributed version of scatch(istream&,string)
Definition diststream.cc:44
STL namespace.