Rheolef  7.2
an efficient C++ finite element environment
field_wdof_sliced.h
Go to the documentation of this file.
1 #ifndef _RHEOLEF_FIELD_WDOF_SLICED_H
2 #define _RHEOLEF_FIELD_WDOF_SLICED_H
23 // proxy class for indexations: uh[0], sigma_h(0,1), etc
24 // => progress with shift and increment >= 1
25 
26 // SUMMARY:
27 // 1) field_sliced_const_iterator
28 // 2) field_sliced_iterator
29 // 3) field_rdof_sliced_base
30 // 4) field_rdof_sliced_const
31 // 5) field_wdof_sliced
32 
33 #include "rheolef/field_wdof.h"
34 #include "rheolef/space_component.h"
35 
36 namespace rheolef { namespace details {
37 // =================================================================================
38 // 1) field_sliced_const_iterator: progress with increment >= 1
39 // =================================================================================
40 template <class OutputIterator> class field_sliced_iterator; // forward decl
41 
42 template <class InputIterator>
44 public:
45 
46 // definitions:
47 
48  using iterator_category = std::forward_iterator_tag;
49  using size_type = std::size_t;
50  using value_type = typename std::iterator_traits<InputIterator>::value_type;
51  using reference = const value_type&;
52  using pointer = const value_type*;
53  using difference_type = std::ptrdiff_t;
55 
56 // allocators:
57 
59  field_sliced_const_iterator(InputIterator iter, size_type incr) : _iter(iter), _incr(incr) {}
60  template<class OutputIterator>
62 
63 // accessors & modifiers:
64 
65  reference operator* () const { return *_iter; }
66  reference operator[] (size_type n) const { return *(_iter + n*_incr); }
67 
68  self_type& operator++ () { _iter += _incr; return *this; }
69  self_type operator++ (int) { self_type tmp = *this; operator++(); return tmp; }
71  self_type operator+ (difference_type n) const { self_type tmp = *this; return tmp += n; }
72 
73 // comparators:
74 
75  bool operator== (const self_type& j) const { return _iter == j._iter; }
76  bool operator!= (const self_type& j) const { return ! operator== (j); }
77 // protected:
78 // data:
79  InputIterator _iter;
81 };
82 // =================================================================================
83 // 2) field_sliced_iterator
84 // =================================================================================
85 template <class OutputIterator>
86 class field_sliced_iterator : public field_sliced_const_iterator<OutputIterator> {
87 public:
88 // definitions:
89 
91  using size_type = typename base::size_type;
92  using value_type = typename base::value_type;
93  using difference_type = std::ptrdiff_t;
95 
96 // allocators:
97 
98  field_sliced_iterator () = delete;
99  field_sliced_iterator(OutputIterator iter, size_type incr) : base(iter,incr) {}
100 
101 // accessors & modifiers:
102 
105 
106  self_type& operator++ () { base::_iter += base::_incr; return *this; }
107  self_type operator++ (int) { self_type tmp = *this; operator++(); return tmp; }
109  self_type operator+ (difference_type n) const { self_type tmp = *this; return tmp += n; }
110 };
111 // =========================================================================
112 // 3) field_wdof_sliced_base
113 // =========================================================================
114 template<class FieldRdof>
116 public:
117 // definitions:
118 
119  using size_type = typename FieldRdof::size_type;
120  using scalar_type = typename FieldRdof::scalar_type;
121  using memory_type = typename FieldRdof::memory_type;
123  using geo_type = typename FieldRdof::geo_type;
124  using space_type = typename FieldRdof::space_type;
126 
127 // allocators:
128 
130  field_rdof_sliced_base (const FieldRdof& uh, size_type i_comp);
131 
132 // accessors:
133 
134  const space_constitution_type& get_constitution() const { return _Vi.get_constitution(); }
135 #ifdef TO_CLEAN
136  std::string name() const { return _Vi.name(); }
137  bool have_homogeneous_space (space_type& Xh) const { Xh = get_space(); return true; }
138 #endif // TO_CLEAN
139  const distributor& ownership() const { return _Vi.ownership(); }
140  const communicator& comm() const { return ownership().comm(); }
141  const geo_type& get_geo() const { return _Vi.get_geo(); }
142  const space_type& get_space() const { return _Vi; }
143  size_type ndof() const { return ownership().size(); }
144  size_type dis_ndof() const { return ownership().dis_size(); }
145 
146  size_type _shift (const FieldRdof& uh) const;
147  size_type _increment (const FieldRdof& uh) const;
148 
149 protected:
150 // data:
153 };
154 template<class FieldRdof>
156 : _Vi(),
157  _i_comp (i_comp)
158 {
159  if (! uh.get_space().get_constitution().is_hierarchical()) {
160  _Vi = space_type (uh.get_geo(), uh.get_space().get_constitution().get_basis()[_i_comp].name());
161  size_type n_comp = uh.get_space().get_constitution().get_basis().size();
162  check_macro (_i_comp < n_comp,
163  "field sliced index "<<_i_comp<<" is out of range [0:"<<n_comp<<"[");
164  } else {
165  _Vi = space_type (uh.get_space() [_i_comp]);
166  size_type n_comp = uh.get_space().get_constitution().size();
167  check_macro (_i_comp < n_comp,
168  "field sliced index "<<_i_comp<<" is out of range [0:"<<n_comp<<"[");
169  }
170 }
171 template<class FieldRdof>
173 field_rdof_sliced_base<FieldRdof>::_shift (const FieldRdof& uh) const
174 {
175  if (! uh.get_space().get_constitution().is_hierarchical()) {
176  return _i_comp;
177  } else {
178  size_type s = 0;
179  for (size_type j_comp = 0; j_comp < _i_comp; j_comp++) {
180  s += uh.get_space().get_constitution()[j_comp].ndof();
181  }
182  return s;
183  }
184 }
185 template<class FieldRdof>
188 {
189  if (! uh.get_space().get_constitution().is_hierarchical()) {
190  return uh.get_space().get_constitution().get_basis().size();
191  } else {
192  return 1;
193  }
194 }
195 // =========================================================================
196 // 4) field_rdof_sliced_const
197 // =========================================================================
198 template<class FieldWdof> class field_wdof_sliced; // forward
199 
200 template<class FieldRdof>
202  public field_wdof_base<field_rdof_sliced_const<FieldRdof>>
203  ,public field_rdof_sliced_base<FieldRdof>
204 {
205 public:
206 
207 // definitions:
208 
210  using size_type = typename FieldRdof::size_type;
211  using scalar_type = typename FieldRdof::scalar_type;
212  using memory_type = typename FieldRdof::memory_type;
213  using geo_type = typename FieldRdof::geo_type;
214  using space_type = typename FieldRdof::space_type;
218 
219 // allocators:
220 
222  field_rdof_sliced_const (const FieldRdof& uh, size_type i_comp);
225  const scalar_type& dof (size_type idof) const { return _start [idof]; }
226  const_iterator begin_dof() const { return _start; }
227  const_iterator end_dof() const { return _start + base::ndof(); }
228 
229 protected:
230 // data:
231  const FieldRdof _uh;
233 };
234 // concept:
235 template<class FieldRdof>
236 struct is_field_wdof<field_rdof_sliced_const<FieldRdof>>: std::true_type {};
237 
238 template<class FieldRdof>
240  using size_type = typename FieldRdof::size_type;
241  using scalar_type = typename FieldRdof::scalar_type;
242  using memory_type = typename FieldRdof::memory_type;
243 };
244 // -------------------
245 // inlined
246 // -------------------
247 template<class FieldRdof>
249  : base(uh, i_comp),
250  _uh(uh),
251  _start(uh.begin_dof() + base::_shift(uh), base::_increment(uh))
252 {
253 }
254 template<class FieldRdof>
256  : base(uh_comp),
257  _uh(uh_comp._uh),
258  _start(uh_comp.begin_dof())
259 {
260 }
261 // =========================================================================
262 // 5) field_wdof_sliced
263 // =========================================================================
264 template<class FieldWdof>
266  public field_wdof_base<field_wdof_sliced<FieldWdof>>
267  ,public field_rdof_sliced_base<FieldWdof>
268 {
269 public:
270 
271 // definitions:
272 
275  using size_type = typename FieldWdof::size_type;
276  using scalar_type = typename FieldWdof::scalar_type;
277  using memory_type = typename FieldWdof::memory_type;
278  using geo_type = typename FieldWdof::geo_type;
279  using space_type = typename FieldWdof::space_type;
282  using dis_reference = typename FieldWdof::dis_reference;
286 
287 // allocators:
288 
289  field_wdof_sliced() = delete;
292 
293  template<class Sfinae
294  = typename std::enable_if<
296  ,void
297  >::type
298  >
299  field_wdof_sliced(FieldWdof& uh, size_type i_comp);
300 
301  template <class Value>
302  typename std::enable_if<
305  >::type
306  operator= (const Value& value) { base0::operator= (value); return *this; }
307 
308  template <class FieldRdof>
309  typename std::enable_if<
312  >::type
313  operator= (const FieldRdof& rdof) { base0::operator= (rdof); return *this; }
314 
315  template<class FieldLazy>
316  typename std::enable_if<
320  >::type
321  operator= (const FieldLazy& lazy) { base0::operator= (lazy); return *this; }
322 
323 // accessors & modifiers:
324 
325  scalar_type& dof (size_type idof) { return _start [idof]; }
326  const scalar_type& dof (size_type idof) const { return _start [idof]; }
327  const scalar_type& dis_dof (size_type dis_idof) const;
329  template <class SetOp = details::generic_set_op>
330  void dis_dof_update (const SetOp& set_op = SetOp()) const;
331 
332  iterator begin_dof() { return _start; }
333  iterator end_dof() { return _start + base::ndof(); }
336 
337 // internals:
339  template<class Iterator>
340  static void _initialize (
341  const space_constitution_type& sup_constit,
342  size_type i_comp,
343  space_constitution_type& constit,
344  Iterator& start,
345  Iterator& last);
346 protected:
347 // data:
348  FieldWdof& _uh; // WARNING for cstor copy & assignt: contains a reference
350 };
351 // concept:
352 template<class FieldWdof>
354 
355 template<class FieldWdof>
356 struct field_traits<field_wdof_sliced<FieldWdof>> {
357  using size_type = typename FieldWdof::size_type;
358  using scalar_type = typename FieldWdof::scalar_type;
359  using memory_type = typename FieldWdof::memory_type;
360 };
361 
362 template<class FieldWdof>
365 };
366 
367 // -------------------
368 // inlined
369 // -------------------
370 template<class FieldWdof>
371 template<class Sfinae>
373  : base(uh,i_comp),
374  _uh(uh),
375  _start(uh.begin_dof() + base::_shift(uh), base::_increment(uh))
376 {
377 }
378 template<class FieldWdof>
381 {
382  // explicit copy cstor (avoid simple copy of the proxy; see nfem/ptst/field_comp_assign_tst.cc )
383  return this -> template operator=<field_wdof_sliced<FieldWdof>> (expr);
384 }
385 template<class FieldWdof>
386 inline
389 {
390  size_type dis_dof = _uh.get_space().get_constitution().comp_dis_idof2dis_idof (base::_i_comp, comp_dis_idof);
391  return _uh.dis_dof (dis_dof);
392 }
393 template<class FieldWdof>
394 inline
397 {
398  size_type dis_dof = _uh.get_space().get_constitution().comp_dis_idof2dis_idof (base::_i_comp, comp_dis_idof);
399  return _uh.dis_dof_entry (dis_dof);
400 }
401 template<class FieldWdof>
402 template <class SetOp>
403 void
405 {
406  _uh.dis_dof_update (set_op);
407 }
408 
409 }} // namespace rheolef::details
410 #endif // _RHEOLEF_FIELD_WDOF_SLICED_H
field::size_type size_type
Definition: branch.cc:430
typename field_traits< Derived >::scalar_type scalar_type
Definition: field_rdof.h:46
typename field_traits< Derived >::memory_type memory_type
Definition: field_rdof.h:47
typename float_traits< scalar_type >::type float_type
Definition: field_rdof.h:48
typename field_traits< Derived >::size_type size_type
Definition: field_rdof.h:45
typename FieldRdof::scalar_type scalar_type
typename FieldRdof::geo_type geo_type
const space_constitution_type & get_constitution() const
size_type _increment(const FieldRdof &uh) const
typename FieldRdof::size_type size_type
typename float_traits< scalar_type >::type float_type
typename FieldRdof::memory_type memory_type
typename FieldRdof::space_type space_type
size_type _shift(const FieldRdof &uh) const
field_rdof_sliced_base(const FieldRdof &uh, size_type i_comp)
const scalar_type & dof(size_type idof) const
field_rdof_sliced_const< FieldRdof > & operator=(const field_rdof_sliced_const< FieldRdof > &uh_comp)=delete
field_sliced_const_iterator(InputIterator iter, size_type incr)
self_type & operator+=(difference_type n)
typename std::iterator_traits< InputIterator >::value_type value_type
bool operator==(const self_type &j) const
bool operator!=(const self_type &j) const
field_sliced_const_iterator(field_sliced_iterator< OutputIterator > i)
self_type operator+(difference_type n) const
self_type & operator+=(difference_type n)
field_sliced_iterator(OutputIterator iter, size_type incr)
self_type operator+(difference_type n) const
std::enable_if< details::is_rheolef_arithmetic< Value >::value, field_wdof_base< field_wdof_sliced< FieldWdof > > & >::type operator=(const Value &)
Definition: field_wdof.icc:45
field_wdof_sliced(const field_wdof_sliced< FieldWdof > &)=delete
void dis_dof_update(const SetOp &set_op=SetOp()) const
field_sliced_const_iterator< typename FieldWdof::const_iterator > const_iterator
const scalar_type & dof(size_type idof) const
typename FieldWdof::scalar_type scalar_type
typename FieldWdof::dis_reference dis_reference
dis_reference dis_dof_entry(size_type dis_idof)
static void _initialize(const space_constitution_type &sup_constit, size_type i_comp, space_constitution_type &constit, Iterator &start, Iterator &last)
scalar_type & dof(size_type idof)
const scalar_type & dis_dof(size_type dis_idof) const
field_wdof_sliced< FieldWdof > & operator=(const field_wdof_sliced< FieldWdof > &expr)
see the distributor page for the full documentation
Definition: distributor.h:69
size_type dis_size() const
global and local sizes
Definition: distributor.h:214
size_type size(size_type iproc) const
Definition: distributor.h:170
const communicator_type & comm() const
Definition: distributor.h:152
rheolef::std type
rheolef::std value
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
void dis_idof(const basis_basic< T > &b, const geo_size &gs, const geo_element &K, typename std::vector< size_type >::iterator dis_idof_tab)
This file is part of Rheolef.
bool have_homogeneous_space(space_basic< scalar_type, memory_type > &Vh) const
const_iterator begin_dof() const