rheolef  7.0
geo_mpi_put.cc
Go to the documentation of this file.
1 #include "rheolef/config.h"
2 #ifdef _RHEOLEF_HAVE_MPI
3 #include "rheolef/geo.h"
4 #include "rheolef/geo_domain.h"
5 #include "rheolef/dis_macros.h"
6 #include "rheolef/rheostream.h"
7 #include "rheolef/iorheo.h"
8 #include "rheolef/index_set.h"
9 
10 namespace rheolef {
11 
12 struct permutation_proxy {
14  permutation_proxy (const hack_array<geo_element_hack>& elts, size_type first_dis_v = 0)
15  : _elts(elts), _first_dis_v(first_dis_v) {}
16  size_type size() const { return _elts.size(); }
17  size_type operator[] (size_type ie) const {
18  const geo_element& K = _elts [ie];
19  return K.ios_dis_ie() - _first_dis_v;
20  }
21  const permutation_proxy& data() const { return *this; }
22  const hack_array<geo_element_hack>& _elts;
23  size_type _first_dis_v;
24 };
25 template <class T>
26 odiststream&
27 geo_rep<T,distributed>::put (odiststream& ops) const
28 {
29  using namespace std;
31  check_macro (format[iorheo::rheo], "geo distributed: unsupported geo output file format=" << format);
32 
33  communicator comm = base::_geo_element[reference_element::p].ownership().comm();
34  size_type io_proc = odiststream::io_proc();
35  size_type my_proc = comm.rank();
36  size_type nproc = comm.size();
37  size_type dis_nnod = base::_node.dis_size ();
38  size_type dis_nv = base::_geo_element[reference_element::p].dis_size ();
39  ops << setprecision(numeric_limits<Float>::digits10)
40  << "#!geo" << endl
41  << endl
42  << "mesh" << endl
43  << base::_version;
44 
45  geo_header h;
46  h.dimension = base::_dimension;
47  h.sys_coord = base::_sys_coord;
48  h.order = base::order();
49  h.dis_size_by_variant [0] = base::_node.dis_size();
50  for (size_type variant = 1; variant < reference_element::max_variant; variant++) {
51  h.dis_size_by_variant [variant] = base::_geo_element [variant].dis_size();
52  }
53  ops << endl << h << endl;
54  if (base::_dimension > 0) {
55  T rounding_prec = iorheo::getrounding_precision(ops.os());
56  if (rounding_prec == 0) {
57  base::_node.permuted_put_values (ops,
58  _inod2ios_dis_inod,
59  _point_put<T>(base::_dimension));
60  } else {
61  base::_node.permuted_put_values (ops,
62  _inod2ios_dis_inod,
63  _round_point_put<T>(base::_dimension, rounding_prec));
64  }
65  ops << endl;
66  }
67  std::vector<size_type> node_perm ((my_proc == io_proc) ? dis_nnod : 0);
68  size_type tag_gather = distributor::get_new_tag();
69  if (my_proc == io_proc) {
70  size_type i_start = _inod2ios_dis_inod.ownership().first_index(my_proc);
71  size_type i_size = _inod2ios_dis_inod.ownership().size (my_proc);
72  for (size_type i = 0; i < i_size; i++) {
73  node_perm [i_start + i] = _inod2ios_dis_inod [i];
74  }
75  for (size_type iproc = 0; iproc < nproc; iproc++) {
76  if (iproc == my_proc) continue;
77  size_type i_start = _inod2ios_dis_inod.ownership().first_index(iproc);
78  size_type i_size = _inod2ios_dis_inod.ownership().size (iproc);
79  comm.recv (iproc, tag_gather, node_perm.begin().operator->() + i_start, i_size);
80  }
81  } else {
82  comm.send (0, tag_gather, _inod2ios_dis_inod.begin().operator->(), _inod2ios_dis_inod.size());
83  }
84  geo_element_permuted_put put_element (node_perm);
85  for (size_type dim = base::_map_dimension; dim > 0; dim--) {
86  size_type first_dis_v = 0;
87  for (size_type variant = reference_element::first_variant_by_dimension(dim);
88  variant < reference_element:: last_variant_by_dimension(dim); variant++) {
89 
90  if (base::_gs.ownership_by_variant[variant].dis_size() == 0) continue;
91  permutation_proxy perm (base::_geo_element [variant], first_dis_v);
92  base::_geo_element [variant].permuted_put_values (ops, perm, put_element);
93  first_dis_v += base::_gs.ownership_by_variant[variant].dis_size();
94  }
95  ops << endl;
96  }
97  for (typename std::vector<domain_indirect_basic<distributed> >::const_iterator
98  iter = base::_domains.begin(),
99  last = base::_domains.end();
100  iter != last; ++iter) {
101  ops << endl;
102  (*iter).put (ops, *this);
103  }
104  return ops;
105 }
106 template <class T>
107 void
108 geo_rep<T,distributed>::dump (std::string name) const
109 {
110  fatal_macro ("dump: not yet");
111 #ifdef TODO
112  base::_node.dump (name + "-node");
113  base::_geo_element[variant].dump(name + "-elem-"+ref::name(variant));
114 #endif // TODO
115 }
116 template class geo_rep<Float,distributed>;
117 
118 } // namespace rheolef
119 #endif // _RHEOLEF_HAVE_MPI
#define fatal_macro(message)
Definition: compiler.h:98
static const variant_type max_variant
void put(std::ostream &out, std::string name, const tiny_matrix< T > &a)
Definition: tiny_lu.h:106
static variant_type last_variant_by_dimension(size_type dim)
static size_type io_proc()
Definition: diststream.cc:43
static flag_type format_field
Definition: iorheo.h:338
static tag_type get_new_tag()
returns a new tag
Definition: distributor.cc:103
static const variant_type p
STL namespace.
flag_type flags() const
Definition: iorheo.cc:148
reference_element::size_type size_type
irheostream, orheostream - large data streams
Definition: compiler.h:7
std::bitset< last > flag_type
Definition: iorheo.h:333
#define check_macro(ok_condition, message)
Definition: compiler.h:104
static variant_type first_variant_by_dimension(size_type dim)
void dump(size_t order, int orient, size_t shift)