Rheolef  7.2
an efficient C++ finite element environment
field_wdof_indirect.h
Go to the documentation of this file.
1 #ifndef _RHEOLEF_FIELD_WDOF_INDIRECT_H
2 #define _RHEOLEF_FIELD_WDOF_INDIRECT_H
23 // proxy class for the trace on subdomains: uh["boundary"], vh["east"]
24 
25 // SUMMARY:
26 // 1. field_indirect_const_iterator
27 // 2. field_indirect_iterator
28 // 3. field_indirect_base
29 // 4. field_rdof_indirect_const
30 // 5. field_wdof_indirect
31 
32 #include "rheolef/field_wdof.h"
33 #include "rheolef/space.h"
34 
35 namespace rheolef { namespace details {
36 // =================================================================================
37 // 1. field_indirect_const_iterator
38 // =================================================================================
39 template <class SizeRandomInputIterator
40  ,class ScalarForwardInputIterator>
42 public:
43 // definitions:
44 
45  using iterator_category = std::forward_iterator_tag;
46  using size_type = std::size_t;
47  using value_type = typename std::iterator_traits<ScalarForwardInputIterator>::value_type;
48  using reference = const value_type&;
49  using pointer = const value_type*;
50  using difference_type = std::ptrdiff_t;
52 
53 // allocator:
54 
56  SizeRandomInputIterator dis_idof_iter,
57  size_type first_dis_idof,
58  ScalarForwardInputIterator val)
59  : _dis_idof_iter(dis_idof_iter),
60  _first_dis_idof(first_dis_idof),
61  _val(val)
62  {}
63 
64 // accessors & modifiers:
65 
66  const value_type& operator* () const { return _val [*_dis_idof_iter - _first_dis_idof]; }
67  self_type& operator++() { ++_dis_idof_iter; return *this; }
69  self_type operator+ (difference_type n) const { self_type tmp = *this; return tmp += n; }
70 
71 // comparators:
72 
73  bool operator== (const self_type& j) const { return _dis_idof_iter == j._dis_idof_iter; }
74  bool operator!= (const self_type& j) const { return ! operator== (j); }
75 protected:
76 // data:
77  SizeRandomInputIterator _dis_idof_iter;
79  ScalarForwardInputIterator _val;
80 };
81 // =================================================================================
82 // 2. field_indirect_iterator
83 // =================================================================================
84 template <class SizeRandomInputIterator
85  ,class ScalarForwardOutputIterator>
87 public field_indirect_const_iterator<SizeRandomInputIterator,ScalarForwardOutputIterator>
88 {
89 public:
90 // definitions:
91 
93  using size_type = typename base::size_type;
94  using value_type = typename base::value_type;
95  using difference_type = std::ptrdiff_t;
97 
98 // allocator:
99 
101  SizeRandomInputIterator dis_idof_iter,
102  size_type first_dis_idof,
103  ScalarForwardOutputIterator val)
104  : base (dis_idof_iter, first_dis_idof, val)
105  {}
106 
107 // accessors & modifiers:
108 
110  self_type& operator++() { ++base::_dis_idof_iter; return *this; }
112  self_type operator+ (difference_type n) const { self_type tmp = *this; return tmp += n; }
113 };
114 // =================================================================================
115 // 3. field_indirect_base
116 // =================================================================================
117 template <class T, class M>
119 public:
120 // definitions:
121 
123  using memory_type = M;
126  using size_type = typename geo_type::size_type;
127 
128 // allocators:
129 
130  field_indirect_base (const space_type& V, const geo_type& dom);
131 
132 // accessors:
133 
134  const distributor& ownership() const { return _W.ownership(); }
135  const communicator& comm() const { return ownership().comm(); }
136  size_type ndof() const { return ownership().size(); }
137  size_type dis_ndof() const { return ownership().dis_size(); }
138  const geo_type& get_geo() const { return _W.get_geo(); }
139  const space_type& get_space() const { return _W; }
140 #ifdef TO_CLEAN
141  bool have_homogeneous_space (space_type& Xh) const { Xh = get_space(); return true; }
142 #endif // TO_CLEAN
143 protected:
144 #ifdef TO_CLEAN
145  std::string _name() const;
146 #endif // TO_CLEAN
147 // data:
153 };
154 // ----------------
155 // inlined
156 // ----------------
157 template <class T, class M>
159  const space_type& V,
160  const geo_type& dom)
161 : _V(V),
162  _W(),
163  _dom(dom),
164  _dom_dis_idof2dis_idof(),
165  _first_dis_idof(V.ownership().first_index())
166 {
167  if ( ! _V.get_basis().option().is_trace_n()
168  || ( _V.get_geo().map_dimension() != _dom.map_dimension() + 1)) {
169  _W = space_type (dom, _V.get_basis().name());
170  } else {
171  // restricted on a subdomain: e.g. Pkd[sides](square) => Pkd(square[interface])
172  // i.e. the basis should remove the "sides" option
173  size_type k = _V.get_basis().degree();
174  _W = space_type (dom, "P"+std::to_string(k)+"d", _V.valued());
175 #ifdef TODO
176  // TODO: more general, by skipping "sides" in option basis: how to do that?
177  // => fatal(../../include/rheolef/smart_pointer.h,330): no_copy functor called (illegal copy)
178  basis b = _V.get_basis();
179  basis_option bopt = b.option();
180  bopt.set_trace (false);
181  b.reset (bopt);
182  _W = space_type (dom, b.name()); // TODO: a cstor space(dom,basis) ?
183 #endif // TODO
184  }
185  _dom_dis_idof2dis_idof = _V.build_dom_dis_idof2bgd_dis_idof (_W, dom);
186 }
187 #ifdef TO_CLEAN
188 template <class T, class M>
189 inline
190 std::string
192 {
193  // e.g. "P1(square[left]", an unique signature for field_expr<Expr> size-like checks
194  std::string dom_name = (_dom.variant() != geo_abstract_base_rep<double>::geo_domain) ?
195  _V.get_geo().name() + "[" + _dom.name() + "]" :
196  _dom.name();
197  return _V.get_basis().name() + "{" + dom_name + "}";
198 }
199 #endif // TO_CLEAN
200 // =================================================================================
201 // 4. field_rdof_indirect_const
202 // =================================================================================
203 // as for:
204 // gh = uh["left"]
205 template <class FieldRdof>
207  public field_rdof_base<field_rdof_indirect_const <FieldRdof>>
208  ,public field_indirect_base<
209  typename FieldRdof::scalar_type
210  ,typename FieldRdof::memory_type
211  >
212 {
213 public:
214 // definitions:
215 
216  using scalar_type = typename FieldRdof::scalar_type;
217  using memory_type = typename FieldRdof::memory_type;
219  using size_type = typename base::size_type;
220  using geo_type = typename base::geo_type;
221  using space_type = typename base::space_type;
224  ,typename FieldRdof::const_iterator>;
225 
226 // allocators:
227 
229 
230  template<class Sfinae
231  = typename std::enable_if<
233  ,void
234  >::type
235  >
236  field_rdof_indirect_const (const FieldRdof& uh, const geo_type& dom);
238 
239 // new accessors:
240 
241  const scalar_type& dis_dof (size_type dis_idof) const;
242  const scalar_type& dof (size_type idof) const
243  { return _uh_const.begin_dof() [base::_dom_dis_idof2dis_idof [idof] - base::_first_dis_idof]; }
244 
245  const_iterator begin_dof() const;
246  const_iterator end_dof() const;
247 protected:
248 // data:
249  const FieldRdof _uh_const;
250 };
251 
252 // concepts:
253 template <class FieldRdof>
254 struct is_field_rdof <field_rdof_indirect_const<FieldRdof>>: std::true_type {};
255 
256 template<class FieldRdof>
258  using size_type = typename FieldRdof::size_type;
259  using scalar_type = typename FieldRdof::scalar_type;
260  using memory_type = typename FieldRdof::memory_type;
261 };
262 // ----------------
263 // inlined
264 // ----------------
265 template<class FieldRdof>
266 template<class Sfinae>
268  const FieldRdof& uh,
269  const geo_type& dom)
270 : base(uh.get_space(), dom),
271  _uh_const(uh)
272 {
273 }
274 template<class FieldRdof>
276  const field_wdof_indirect<FieldRdof>& wdof)
277 : base(wdof),
278  _uh_const(wdof._uh)
279 {
280 }
281 template<class FieldRdof>
282 inline
285 {
286  return const_iterator (base::_dom_dis_idof2dis_idof.begin(), base::_first_dis_idof, _uh_const.begin_dof());
287 }
288 template<class FieldRdof>
289 inline
292 {
293  return const_iterator (base::_dom_dis_idof2dis_idof.end(), base::_first_dis_idof, _uh_const.begin_dof());
294 }
295 template<class FieldRdof>
296 inline
299 {
300  size_type dis_idof = base::_dom_dis_idof2dis_idof.dis_at (dom_dis_idof);
301  return _uh_const.dis_dof (dis_idof);
302 }
303 // =================================================================================
304 // 5. field_wdof_indirect
305 // =================================================================================
306 // as for:
307 // uh["left"] = value
308 // uh["left"] = gh
309 
310 template <class FieldWdof>
312  public field_wdof_base<field_wdof_indirect<FieldWdof>>
313  ,public field_indirect_base<
314  typename FieldWdof::scalar_type
315  ,typename FieldWdof::memory_type
316  >
317 {
318 public:
319 // definitions:
320 
322  using scalar_type = typename FieldWdof::scalar_type;
323  using memory_type = typename FieldWdof::memory_type;
325  using size_type = typename base::size_type;
326  using geo_type = typename base::geo_type;
327  using space_type = typename base::space_type;
330  ,typename FieldWdof::const_iterator>;
333  ,typename FieldWdof::iterator>;
334  using dis_reference = typename FieldWdof::dis_reference;
335 
336 // allocators:
337 
341 
342  template<class Sfinae
343  = typename std::enable_if<
345  ,void
346  >::type
347  >
348  field_wdof_indirect (FieldWdof& uh, const geo_type& dom);
349 
350  template <class Value>
351  typename std::enable_if<
354  >::type
355  operator= (const Value& value) { base0::operator= (value); return *this; }
356 
357  template <class FieldRdof>
358  typename std::enable_if<
361  >::type
362  operator= (const FieldRdof& rdof) { base0::operator= (rdof); return *this; }
363 
364  template<class FieldLazy>
365  typename std::enable_if<
369  >::type
370  operator= (const FieldLazy& lazy) { base0::operator= (lazy); return *this; }
371 
372 // accessors:
373 
374  const scalar_type& dof (size_type idof) const { return _uh.begin_dof() [base::_dom_dis_idof2dis_idof [idof] - base::_first_dis_idof]; }
376  const scalar_type& dis_dof (size_type dis_idof) const;
378  template <class SetOp = details::generic_set_op>
379  void dis_dof_update (const SetOp& set_op = SetOp()) const { _uh.dis_dof_update (set_op); }
380 
381  const_iterator begin_dof() const;
382  const_iterator end_dof() const;
384  iterator end_dof();
385 
386 protected:
387 // data:
389  FieldWdof& _uh; // WARNING for cstor copy & assignt: contains a reference
390 };
391 
392 // concepts:
393 template<class FieldWdof>
395 
396 // avoid some mistakes:
397 template<class FieldWdof>
398 struct is_field_function <field_wdof_indirect<FieldWdof>>: std::false_type {};
399 
400 template<class FieldWdof>
401 struct field_traits<field_wdof_indirect<FieldWdof>> {
402  using size_type = typename FieldWdof::size_type;
403  using scalar_type = typename FieldWdof::scalar_type;
404  using memory_type = typename FieldWdof::memory_type;
405 };
406 
407 template<class FieldWdof>
410 };
411 // ------------------
412 // inlined
413 // ------------------
414 template<class FieldWdof>
415 template<class Sfinae>
417  FieldWdof& uh,
418  const geo_type& dom)
419 : base (uh.get_space(), dom),
420  _uh(uh)
421 {
422 trace_macro("fi(fw,geo)");
423 }
424 template<class FieldWdof>
427 {
428 trace_macro("fi::op=(const fi&)");
429  // WARNING: the class contains a reference
430  // => explicit copy (avoid simple copy of the proxy; see nfem/ptst/field_comp_assign_tst.cc )
431  // call the previous template FieldRdof version of op=
432  return this -> template operator=<field_wdof_indirect<FieldWdof>> (expr);
433 }
434 template<class FieldWdof>
435 inline
438 {
439  return const_iterator (base::_dom_dis_idof2dis_idof.begin(), base::_first_dis_idof, _uh.begin_dof());
440 }
441 template<class FieldWdof>
442 inline
445 {
446  return const_iterator (base::_dom_dis_idof2dis_idof.end(), base::_first_dis_idof, _uh.begin_dof());
447 }
448 template<class FieldWdof>
449 inline
452 {
453  return iterator (base::_dom_dis_idof2dis_idof.begin(), base::_first_dis_idof, _uh.begin_dof());
454 }
455 template<class FieldWdof>
456 inline
459 {
460  return iterator (base::_dom_dis_idof2dis_idof.end(), base::_first_dis_idof, _uh.begin_dof());
461 }
462 template<class FieldWdof>
463 inline
466 {
467  size_type dis_idof = base::_dom_dis_idof2dis_idof.dis_at (dom_dis_idof);
468  return _uh.dis_dof (dis_idof);
469 }
470 template<class FieldWdof>
471 inline
474 {
475  size_type dis_idof = base::_dom_dis_idof2dis_idof.dis_at (dom_dis_idof);
476  return _uh.dis_dof_entry (dis_idof);
477 }
478 
479 }}// namespace rheolef::details
480 # endif /* _RHEOLEF_FIELD_WDOF_INDIRECT_H */
field::size_type size_type
Definition: branch.cc:430
see the basis page for the full documentation
see the basis_option page for the full documentation
Definition: basis_option.h:93
disarray< size_type, memory_type > _dom_dis_idof2dis_idof
typename geo_type::size_type size_type
const distributor & ownership() const
geo_basic< float_type, memory_type > geo_type
typename float_traits< T >::type float_type
field_indirect_base(const space_type &V, const geo_type &dom)
space_basic< float_type, memory_type > space_type
typename std::iterator_traits< ScalarForwardInputIterator >::value_type value_type
field_indirect_const_iterator(SizeRandomInputIterator dis_idof_iter, size_type first_dis_idof, ScalarForwardInputIterator val)
self_type operator+(difference_type n) const
field_indirect_iterator(SizeRandomInputIterator dis_idof_iter, size_type first_dis_idof, ScalarForwardOutputIterator val)
self_type & operator+=(difference_type n)
self_type operator+(difference_type n) const
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 field_traits< Derived >::size_type size_type
Definition: field_rdof.h:45
typename FieldRdof::scalar_type scalar_type
const scalar_type & dof(size_type idof) const
typename FieldRdof::memory_type memory_type
const scalar_type & dis_dof(size_type dis_idof) const
std::enable_if< details::is_rheolef_arithmetic< Value >::value, field_wdof_base< field_wdof_indirect< FieldWdof > > & >::type operator=(const Value &)
Definition: field_wdof.icc:45
void dis_dof_update(const SetOp &set_op=SetOp()) const
const scalar_type & dof(size_type idof) const
const scalar_type & dis_dof(size_type dis_idof) const
typename FieldWdof::scalar_type scalar_type
field_indirect_iterator< typename disarray< size_type, memory_type >::const_iterator,typename FieldWdof::iterator > iterator
typename FieldWdof::dis_reference dis_reference
dis_reference dis_dof_entry(size_type dis_idof)
field_wdof_indirect(const field_wdof_indirect< FieldWdof > &)=delete
field_wdof_indirect< FieldWdof > & operator=(const field_wdof_indirect< FieldWdof > &)
scalar_type & dof(size_type idof)
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
abstract base interface class
Definition: geo.h:248
rheolef::std type
rheolef::std value
#define trace_macro(message)
Definition: dis_macros.h:111
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
Expr1::memory_type M
Definition: vec_expr_v2.h:416