Rheolef  7.1
an efficient C++ finite element environment
domain_indirect_mpi.cc
Go to the documentation of this file.
1 
22 #include "rheolef/config.h"
23 
24 #ifdef _RHEOLEF_HAVE_MPI
25 #include "rheolef/domain_indirect.h"
26 #include "rheolef/geo.h"
27 
28 namespace rheolef {
29 
30 // ----------------------------------------------------------------------------
31 // @brief init domain ios from the whole mesh ios data
32 // ----------------------------------------------------------------------------
33 template <class T>
34 void
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 // ----------------------------------------------------------------------------
191 template<class U>
192 idiststream&
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 }
294 template<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 // ----------------------------------------------------------------------------
322 template
323 idiststream&
325  idiststream& ips,
326  const geo_rep<Float,distributed>& omega);
327 
328 template
331  odiststream& ops,
332  const geo_rep<Float,distributed>& omega) const;
333 
334 #define _RHEOLEF_instanciation(T,M) \
335 template \
336 void \
337 domain_indirect_rep<M>::init_ios (const geo_abstract_rep<T,M>&); \
338 
340 
341 } // namespace rheolef
342 #endif // _RHEOLEF_HAVE_MPI
void put(idiststream &in, odiststream &out, bool do_proj, bool do_lumped_mass, bool def_fill_opt, size_type extract_id, const Float &scale_value, const std::pair< Float, Float > &u_range, render_type render)
Definition: branch.cc:500
see the Float page for the full documentation
see the disarray page for the full documentation
Definition: disarray.h:459
rep::base::size_type size_type
Definition: disarray.h:463
see the distributor page for the full documentation
Definition: distributor.h:62
size_type find_owner(size_type dis_i) const
find iproc associated to a global index dis_i: CPU=log(nproc)
Definition: distributor.cc:106
size_type size(size_type iproc) const
Definition: distributor.h:163
size_type first_index(size_type iproc) const
global index range and local size owned by ip-th process
Definition: distributor.h:151
static const size_type decide
Definition: distributor.h:76
base::const_iterator_ioige const_iterator_ioige
virtual const geo_size & ios_sizes() const =0
virtual size_type ige2ios_dis_ige(size_type dim, size_type ige) const =0
sequential mesh representation
Definition: geo.h:778
odiststream: see the diststream page for the full documentation
Definition: diststream.h:126
distributed
Definition: asr.cc:228
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:43
_RHEOLEF_instanciation(Float, sequential, std::allocator< Float >) _RHEOLEF_instanciation(Float
distributor ownership_by_dimension[4]
Definition: geo_size.h:63