rheolef  6.3
field_indirect.h
Go to the documentation of this file.
1 # ifndef _RHEOLEF_FIELD_INDIRECT_H
2 # define _RHEOLEF_FIELD_INDIRECT_H
3 
4 #include "rheolef/field.h"
5 
6 namespace rheolef {
7 
8 template <class T, class M>
9 class field_indirect_const;
10 
11 template <class T, class M = rheo_default_memory_model>
13 public:
14 
15 
17  typedef T scalar_type;
18  typedef T value_type; // TO_CLEAN !
19  class iterator;
20  class const_iterator;
21 
22 
24  : _V(uh.get_space()),
25  _W(dom, _V.get_numbering().name(), _V.valued()),
26  _dom(dom),
27  _indirect(_V.build_indirect_array (_W, dom)),
28  _val(uh.begin_dof())
29  {
30  }
31 
33 
34 public:
35 
36  const T& operator= (const T& alpha);
40 
41  const distributor& ownership() const { return _indirect.ownership(); }
42  const communicator& comm() const { return ownership().comm(); }
43  size_type ndof() const { return ownership().size(); }
44  size_type dis_ndof() const { return ownership().dis_size(); }
45  std::string stamp() const;
46  const space_basic<T,M>& get_space() const { return _W; }
47  T& dof (size_type idof) { return _val [_indirect [idof]]; }
48  const T& dof (size_type idof) const { return _val [_indirect [idof]]; }
49 
50  iterator begin_dof();
51  iterator end_dof();
52  const_iterator begin_dof() const;
53  const_iterator end_dof() const;
54 protected:
55  friend class field_basic<T,M>;
56  friend class field_indirect_const<T,M>;
60  array<size_type,M> _indirect; // temporary
61  typename field_basic<T,M>::iterator _val; // iterator = reference on an external variable uh
62  // => cstor is protected : prevent copy outside the field class
63 };
64 template<class T, class M>
65 inline
66 const T&
68 {
69  std::fill (begin_dof(), end_dof(), alpha);
70  return alpha;
71 }
72 template<class T, class M>
73 inline
76 {
77  check_macro (_V.valued_tag() == space_constant::scalar, "field[domain]: unsupported non-scalar field");
78  check_macro (stamp() == expr.stamp(), "field[domain] = field : incompatible spaces "
79  << stamp() << " and " << expr.stamp());
80  algo::copy_n (expr.begin_dof(), expr.ndof(), begin_dof());
81  return *this;
82 }
83 template<class T, class M>
84 inline
87 {
88  check_macro (_V.valued_tag() == space_constant::scalar, "field[domain]: unsupported non-scalar field");
89  check_macro (stamp() == expr.stamp(), "field[domain] = field[domain]: incompatible spaces "
90  << stamp() << " and " << expr.stamp());
91  algo::copy_n (expr.begin_dof(), expr.ndof(), begin_dof());
92  return *this;
93 }
94 template<class T, class M>
95 inline
96 std::string
98 {
99  // e.g. "P1(square.left)", an unique signature for field_expr<Expr> size-like checks
100  return _V.get_numbering().name() + "(" + _V.get_geo().name() + "[" + _dom.name() + "])";
101 }
102 template<class T, class M>
103 inline
106 {
107  dis_dof_update_needed();
108  return field_indirect<T,M> (*this, dom);
109 }
110 template<class T, class M>
111 inline
113 field_basic<T,M>::operator[] (std::string dom_name)
114 {
115  dis_dof_update_needed();
116  return operator[] (get_space().get_geo().operator[] (dom_name));
117 }
118 template<class T, class M>
119 inline
122 {
123  if (stamp() == "") {
124  resize (expr.get_space());
125  } else {
126  check_macro (stamp() == expr.stamp(), "incompatible spaces "
127  << stamp() << " and " << expr.stamp()
128  << " in field = field[domain]");
129  }
130  dis_dof_update_needed();
131  algo::copy_n (expr.begin_dof(), expr.ndof(), begin_dof());
132  return *this;
133 }
134 template<class T, class M>
135 inline
137  : _V(),
138  _u(),
139  _b(),
140  _dis_dof_update_needed(true)
141 {
142  operator= (expr);
143 }
144 template <class T, class M>
146 public:
147  typedef std::forward_iterator_tag iterator_category; // TODO: not fully random yet
148  typedef typename vec<T,M>::size_type size_type;
149  typedef T value_type;
150  typedef T& reference;
151  typedef T* pointer;
152  typedef std::ptrdiff_t difference_type;
153  iterator (typename array<size_type,M>::const_iterator idof_iter, typename field_basic<T,M>::iterator val)
154  : _idof_iter(idof_iter), _val(val) {}
155 
156  T& operator* () { return _val [*_idof_iter]; }
157  const T& operator* () const { return _val [*_idof_iter]; }
158  iterator& operator++() { ++_idof_iter; return *this; }
159 
160 
161  bool operator== (const iterator& j) const { return _idof_iter == j._idof_iter; }
162  bool operator!= (const iterator& j) const { return ! operator== (j); }
163 protected:
164  typename array<size_type,M>::const_iterator _idof_iter;
166 };
167 template<class T, class M>
168 inline
171 {
172  return iterator (_indirect.begin(), _val);
173 }
174 template<class T, class M>
175 inline
178 {
179  return iterator (_indirect.end(), _val);
180 }
181 template <class T, class M>
183 public:
184  typedef std::forward_iterator_tag iterator_category; // TODO: not fully random yet
185  typedef typename vec<T,M>::size_type size_type;
186  typedef T value_type;
187  typedef const T& reference;
188  typedef const T* pointer;
189  typedef std::ptrdiff_t difference_type;
190  const_iterator (typename array<size_type,M>::const_iterator idof_iter, typename field_basic<T,M>::const_iterator val)
191  : _idof_iter(idof_iter), _val(val) {}
192 
193  const T& operator* () const { return _val [*_idof_iter]; }
194  const_iterator& operator++() { ++_idof_iter; return *this; }
195 
196 
197  bool operator== (const const_iterator& j) const { return _idof_iter == j._idof_iter; }
198  bool operator!= (const const_iterator& j) const { return ! operator== (j); }
199 protected:
200  typename array<size_type,M>::const_iterator _idof_iter;
202 };
203 template<class T, class M>
204 inline
207 {
208  return const_iterator (_indirect.begin(), _val);
209 }
210 template<class T, class M>
211 inline
214 {
215  return const_iterator (_indirect.end(), _val);
216 }
217 template <class T, class M = rheo_default_memory_model>
219 public:
220 
221 
223  typedef T scalar_type;
224  typedef T value_type; // TO_CLEAN !
225  class const_iterator;
226 
227 
229  : _V(uh.get_space()),
230  _W(dom, _V.get_numbering().name(), _V.valued()),
231  _dom(dom),
232  _indirect(_V.build_indirect_array (_W, dom)),
233  _val(uh.begin_dof())
234  {
235  }
236 
238  : _V(gh._V),
239  _W(gh._W),
240  _dom(gh._dom),
241  _indirect(gh._indirect),
242  _val(gh._val)
243  {}
244 
245 
246  const distributor& ownership() const { return _indirect.ownership(); }
247  const communicator& comm() const { return ownership().comm(); }
248  size_type ndof() const { return ownership().size(); }
249  size_type dis_ndof() const { return ownership().dis_size(); }
250  std::string stamp() const;
251  space_basic<T,M> get_space() const { return _W; }
252 
253  const T& dof(size_type idof) const { return _val [_indirect [idof]]; }
254 
255  const_iterator begin_dof() const;
256  const_iterator end_dof() const;
257  friend class field_basic<T,M>;
258 protected:
262  array<size_type,M> _indirect; // temporary
263  typename field_basic<T,M>::const_iterator _val; // iterator = reference on an external variable uh
264 };
265 template<class T, class M>
266 inline
267 std::string
269 {
270  // e.g. "P1(square.left)", an unique signature for field_expr<Expr> size-like checks
271  return _V.get_numbering().name() + "(" + _V.get_geo().name() + "[" + _dom.name() + "])";
272 }
273 template<class T, class M>
274 inline
277 {
278  return field_indirect_const<T,M> (*this, dom);
279 }
280 template<class T, class M>
281 inline
283 field_basic<T,M>::operator[] (std::string dom_name) const
284 {
285  return operator[] (get_space().get_geo().operator[] (dom_name));
286 }
287 template<class T, class M>
288 inline
290  : _V(),
291  _u(),
292  _b(),
293  _dis_dof_update_needed(true)
294 {
295  operator= (expr);
296 }
297 template<class T, class M>
298 inline
301 {
302  if (stamp() == "") {
303  resize (expr.get_space());
304  } else {
305  check_macro (stamp() == expr.stamp(), "incompatible spaces "
306  << stamp() << " and " << expr.stamp()
307  << " in field = field[domain]");
308  }
309  dis_dof_update_needed();
310  algo::copy_n (expr.begin_dof(), expr.ndof(), begin_dof());
311  return *this;
312 }
313 template<class T, class M>
314 inline
317 {
318  check_macro (_V.valued_tag() == space_constant::scalar, "field[domain]: unsupported non-scalar field");
319  check_macro (stamp() == expr.stamp(), "field[domain] = field[domain]: incompatible spaces "
320  << stamp() << " and " << expr.stamp());
321  algo::copy_n (expr.begin_dof(), expr.ndof(), begin_dof());
322  return *this;
323 }
324 template <class T, class M>
326 public:
327 
328  typedef std::forward_iterator_tag iterator_category; // TODO: not fully random yet
329  typedef typename vec<T,M>::size_type size_type;
330  typedef T value_type;
331  typedef const T& reference;
332  typedef const T* pointer;
333  typedef std::ptrdiff_t difference_type;
334 
335  const_iterator (typename array<size_type,M>::const_iterator idof_iter, typename field_basic<T,M>::const_iterator val)
336  : _idof_iter(idof_iter), _val(val) {}
337 
338  const T& operator* () const { return _val [*_idof_iter]; }
339  const_iterator& operator++() { ++_idof_iter; return *this; }
340 
341 
342  bool operator== (const const_iterator& j) const { return _idof_iter == j._idof_iter; }
343  bool operator!= (const const_iterator& j) const { return ! operator== (j); }
344 protected:
345  typename array<size_type,M>::const_iterator _idof_iter;
347 };
348 template<class T, class M>
349 inline
352 {
353  return const_iterator (_indirect.begin(), _val);
354 }
355 template<class T, class M>
356 inline
359 {
360  return const_iterator (_indirect.end(), _val);
361 }
362 template <class T, class M>
363 inline
365 operator << (odiststream& ops, const field_indirect<T,M>& uh)
366 {
367  field_basic<T,M> tmp = uh;
368  return tmp.put (ops);
369 }
370 template <class T, class M>
371 inline
372 odiststream&
373 operator << (odiststream& ops, const field_indirect_const<T,M>& uh)
374 {
375  field_basic<T,M> tmp = uh;
376  return tmp.put (ops);
377 }
378 
379 }// namespace rheolef
380 # endif /* _RHEOLEF_FIELD_INDIRECT_H */
381