rheolef  6.3
geo_element_v4.h
Go to the documentation of this file.
1 #ifndef _RHEOLEF_GEO_ELEMENT_V4_H
2 #define _RHEOLEF_GEO_ELEMENT_V4_H
3 // => la memoire est contigue globalement, l'acces plus rapide avec
4 // => petit gaspillage de memoire
5 #include "rheolef/reference_element.h"
6 #include "rheolef/geo_element_indirect.h"
7 #include "rheolef/heap_allocator.h"
8 #include "rheolef/array.h"
9 #include <boost/serialization/serialization.hpp>
10 #include <boost/serialization/base_object.hpp>
11 
12 namespace rheolef {
13 
14 template <class A> class geo_element_auto;
15 
59 class geo_element {
60 public:
61 
62 
63  enum {
64  _variant_offset = 0, // i.e. type, as triangle(t) or tetra(T), etc
65  _order_offset = 1, // i.e. k, when Pk curved element
66  _dis_ie_offset = 2, // internal numbering, depend upon partitionand nproc
67  _ios_dis_ie_offset = 3, // i/o numbering, independent of parition and nproc
68  _master_offset = 4, // (d-1)-side has one or two master d-element that contains it
69  _last_offset = 6 // here starts node indexes, face indexes, etc
70  };
71  // => waste a lot of place
74  typedef size_type* iterator;
75  typedef const size_type* const_iterator;
77 
80 
82  typedef geo_element_indirect::shift_type shift_type; // for 0..3 face shift
83  struct parameter_type {
87  : variant(v), order(o) {}
88  };
89 
90 
92  {
93  reset (K.variant(), K.order()); // resize auto, nothing for hack
94  std::copy (K._data_begin(), K._data_begin() + _data_size(), _data_begin());
95  reset (K.variant(), K.order()); // reset order=1 for hack, resize nothing for auto
96  return *this;
97  }
98  virtual ~geo_element() {}
99  virtual void reset (variant_type variant, size_type order) = 0;
100 
101 
102  operator reference_element () const { return reference_element(variant()); }
103 
104 
106  size_type order() const { return *(_data_begin() + _order_offset); }
107  size_type dis_ie() const { return *(_data_begin() + _dis_ie_offset); }
109  size_type master (bool i) const { return *(_data_begin() + _master_offset + i); }
110 
113  char name() const { return reference_element::name (variant()); }
115 
118  void set_master (bool i, size_type dis_ie) const {
119  const_iterator p = _data_begin() + _master_offset + i; // mutable member fct
120  *(const_cast<iterator>(p)) = dis_ie;
121  }
122 
124  const_iterator begin() const { return _data_begin() + _node_offset (variant(), order()); }
125  iterator end() { return begin() + size(); }
126  const_iterator end() const { return begin() + size(); }
127  size_type& operator[] (size_type loc_inod) { return *(begin() + loc_inod); }
128  size_type operator[] (size_type loc_inod) const { return *(begin() + loc_inod); }
129  size_type& node (size_type loc_inod) { return operator[] (loc_inod); }
130  size_type node (size_type loc_inod) const { return operator[] (loc_inod); }
131 
132  iterator begin(size_type node_subgeo_dim) { return begin() + first_inod (node_subgeo_dim); }
133  const_iterator begin(size_type node_subgeo_dim) const { return begin() + first_inod (node_subgeo_dim); }
134  iterator end (size_type node_subgeo_dim) { return begin() + last_inod (node_subgeo_dim); }
135  const_iterator end (size_type node_subgeo_dim) const { return begin() + last_inod (node_subgeo_dim); }
136 
139  return *(reinterpret_cast<const geo_element_indirect*>(p));
140  }
143  return *(reinterpret_cast<const geo_element_indirect*>(p));
144  }
146  iterator p = _data_begin() + _edge_offset (variant(), order()) + i;
147  return *(reinterpret_cast<geo_element_indirect*>(p));
148  }
150  iterator p = _data_begin() + _face_offset (variant(), order()) + i;
151  return *(reinterpret_cast<geo_element_indirect*>(p));
152  }
153  size_type edge (size_type i) const { return (dimension() <= 1) ? dis_ie() : edge_indirect(i).index(); }
154  size_type face (size_type i) const { return (dimension() <= 2) ? dis_ie() : face_indirect(i).index(); }
155 
156  size_type n_subgeo (size_type subgeo_dim) const {
157  return reference_element::n_subgeo (variant(), subgeo_dim); }
158  size_type subgeo_n_node (size_type subgeo_dim, size_type loc_isid) const {
159  return reference_element::subgeo_n_node (variant(), order(), subgeo_dim, loc_isid); }
160  size_type subgeo_local_node (size_type subgeo_dim, size_type loc_isid, size_type loc_jsidnod) const {
161  return reference_element::subgeo_local_node (variant(), order(), subgeo_dim, loc_isid, loc_jsidnod); }
162  size_type subgeo_size (size_type subgeo_dim, size_type loc_isid) const {
163  return reference_element::subgeo_n_node (variant(), 1, subgeo_dim, loc_isid); }
164  size_type subgeo_local_vertex(size_type subgeo_dim, size_type i_subgeo, size_type i_subgeo_vertex) const {
165  return reference_element::subgeo_local_node (variant(), 1, subgeo_dim, i_subgeo, i_subgeo_vertex); }
166  size_type first_inod (size_type subgeo_dim) const {
167  return reference_element::first_inod (variant(), order(), subgeo_dim); }
168  size_type last_inod (size_type subgeo_dim) const {
169  return reference_element::last_inod (variant(), order(), subgeo_dim); }
170 
171  size_type n_edge () const { return n_subgeo (1); }
172  size_type n_face () const { return n_subgeo (2); }
173 
174 
176  const geo_element& S,
177  size_type& loc_isid,
178  size_type& shift) const;
179 
181 
182  bool get_orientation_and_shift (const geo_element& S,
183  orientation_type& orient, shift_type& shift) const;
184  orientation_type get_edge_orientation (size_type dis_iv0, size_type dis_iv1) const;
186  size_type dis_iv0, size_type dis_iv1, size_type dis_iv2,
187  orientation_type& orient,
188  shift_type& shift) const;
190  size_type dis_iv0, size_type dis_iv1, size_type dis_iv2, size_type dis_iv3,
191  orientation_type& orient,
192  shift_type& shift) const;
193 
194 
195  template <class T, class M>
196  bool contains (const array<point_basic<T>,M>& node, const point_basic<T>& x) const;
197 
198 // i/o;
199 
200  friend std::istream& operator>> (std::istream& is, geo_element& K);
201  friend std::ostream& operator<< (std::ostream& os, const geo_element& K);
202 
203 
205  const geo_element& K,
206  size_type loc_iedg,
207  size_type loc_iedg_j,
208  size_type order);
209 
211  orientation_type orient,
213  size_type loc_iedg_j);
214 
215  static void loc_tri_inod2lattice (
216  size_type loc_tri_inod,
218  point_basic<size_type>& ij_lattice);
219 
220  static void loc_qua_inod2lattice (
221  size_type loc_qua_inod,
223  point_basic<size_type>& ij_lattice);
224 
226  const geo_element& K,
227  size_type loc_itri,
228  size_type loc_itri_j,
229  size_type order);
230 
232  orientation_type orient,
233  shift_type shift,
235  size_type loc_itri_j);
236 
238  const geo_element& K,
239  size_type loc_iqua,
240  size_type loc_iqua_j,
241  size_type order);
242 
244  orientation_type orient,
245  shift_type shift,
247  size_type loc_iqua_j);
248 
249 
253  static size_type _data_size (variant_type variant, size_type order) { return _node_offset(variant,order) + reference_element::n_node(variant,order); }
254  static size_type _data_size (const parameter_type& p) { return _data_size (p.variant,p.order); }
255 
256  size_type _data_size() const { return _data_size (variant(),order()); }
257 
258  virtual iterator _data_begin() = 0;
259  virtual iterator _data_end() = 0;
260  virtual const_iterator _data_begin() const = 0;
261  virtual const_iterator _data_end() const = 0;
262 
263  template<class Archive>
264  void serialize (Archive& ar, const unsigned int version) {
265  }
266 #ifdef TO_CLEAN
268 #endif // TO_CLEAN
269 };
272 public:
273 
274 
275  typedef A allocator_type;
283 
284 
285  explicit geo_element_auto (const A& alloc = A())
286  : _data (_last_offset, std::numeric_limits<size_type>::max(), alloc)
287  {
289  _data [_order_offset] = 0;
290  }
291  explicit geo_element_auto (variant_type variant, size_type order = 1, const A& alloc = A())
292  : _data (_data_size(variant,order), std::numeric_limits<size_type>::max(), alloc)
293  {
296  }
297  explicit geo_element_auto (parameter_type p, const A& alloc = A())
298  : _data (_data_size(p), std::numeric_limits<size_type>::max(), alloc)
299  {
301  _data [_order_offset] = p.order;
302  }
304  : _data (K._data_size(), size_type(0), A()) // cree un nouvel allocateur
305  { std::copy (K._data_begin(), K._data_end(), _data.begin()); }
307  : _data (K._data.size(), size_type(0), K._data.get_allocator()) // re-utilise l'allocateur precedent
308  { std::copy (K._data.begin(), K._data.end(), _data.begin()); }
309  template <class A2>
311  : _data (K._data.size(), size_type(0), A()) // cree un nouvel allocateur
312  { std::copy (K._data.begin(), K._data.end(), _data.begin()); }
314  {
315  _data.resize(K._data_size());
316  std::copy (K._data_begin(), K._data_end(), _data.begin());
317  return *this;
318  }
319  void reset (variant_type variant, size_type order) {
320  _data.resize (_data_size(variant,order), std::numeric_limits<size_type>::max());
323  }
324  void reset (const parameter_type& param) { reset (param.variant, param.order); }
325 
326 
327  template<class Archive>
328  void serialize (Archive& ar, const unsigned int version) {
329  ar & boost::serialization::base_object<geo_element>(*this);
330  ar & _data;
331  }
332 
333 
334  iterator _data_begin() { return _data.begin().operator->(); }
335  const_iterator _data_begin() const { return _data.begin().operator->(); }
336  iterator _data_end() { return _data.end().operator->(); }
337  const_iterator _data_end() const { return _data.end().operator->(); }
338 
339  template <class A2> friend class geo_element_auto;
340 
341 
342  std::vector<size_type,A> _data;
343 };
345 public:
346 
347 
348  enum {
349  _vtable_size = 1 /* = sizeof(geo_element_X_hack)/sizeof(size_type) */
350  };
351 
360 
361 
363  template <class A>
365  {
366  check_macro (K.variant() == variant(), "incompatible conversion");
367 #ifdef TO_CLEAN
368  check_macro (K.order() == order(), "incompatible conversion");
369 #endif // TO_CLEAN
370  std::copy (K._data.begin(), K._data.begin() + _data_size(), _data_begin());
371  }
372 
373 
374  void reset (variant_type variant1, size_type order1) {
375  check_macro (variant1 == variant(), "cannot change variant from "<<variant()<<" to "<<variant1<<" in a raw element");
376 #ifdef TO_CLEAN
377  check_macro (order1 == 1, "cannot change order "<<order1<< " > 1 in a raw element");
378 #endif // TO_CLEAN
380  }
381 protected:
382 
383  static size_type _size_of (const parameter_type& p) { return _vtable_size + _data_size(p); }
384 
385  iterator _data_begin() { return reinterpret_cast<iterator> (this) + _vtable_size; }
386  const_iterator _data_begin() const { return reinterpret_cast<const_iterator>(this) + _vtable_size; }
388  const_iterator _data_end() const { return _data_begin() + _data_size(); }
389 
390  size_type _get_data (size_type i) const { return *(_data_begin() + i); }
391  size_type& _get_data_ref(size_type i) { return *(_data_begin() + i); }
392  void _set_data (size_type i, size_type value) { _get_data_ref(i) = value; }
393 
394  void _reset (variant_type variant, size_type order) {
395  check_macro (order == 1, "cannot set order "<<order<< " > 1 in a raw element");
396  _set_data (_variant_offset, variant);
397  _set_data (_order_offset, order);
398  for (size_type i = _order_offset+1, n = _data_size (variant,order); i < n; i++) {
400  }
401  }
402  void _set_parameter (const parameter_type& p) { _reset (p.variant, p.order); }
403 
404  template <class T, class A> friend class hack_array_seq_rep;
405 };
408  geo_element_permuted_put (const std::vector<size_type>& perm1) : perm(perm1) {}
409  std::ostream& operator() (std::ostream& os, const geo_element& K) {
410  static const bool do_verbose = true;
411  if (do_verbose || K.size() > 2 || K.order() > 1) { os << K.name() << "\t"; }
412  if (do_verbose || K.order() > 1) { os << "p" << K.order() << " "; }
413  for (geo_element::size_type iloc = 0; iloc < K.n_node(); iloc++) {
414  os << perm [K[iloc]];
415  if (iloc < K.n_node() - 1) os << " ";
416  }
417  return os;
418  }
419  const std::vector<size_type>& perm;
420 };
421 
422 }// namespace rheolef
423 #endif // _RHEOLEF_GEO_ELEMENT_V4_H
424