Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
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
35namespace rheolef { namespace details {
36// =================================================================================
37// 1. field_indirect_const_iterator
38// =================================================================================
39template <class SizeRandomInputIterator
40 ,class ScalarForwardInputIterator>
42public:
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
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); }
75protected:
76// data:
77 SizeRandomInputIterator _dis_idof_iter;
79 ScalarForwardInputIterator _val;
80};
81// =================================================================================
82// 2. field_indirect_iterator
83// =================================================================================
84template <class SizeRandomInputIterator
85 ,class ScalarForwardOutputIterator>
87public field_indirect_const_iterator<SizeRandomInputIterator,ScalarForwardOutputIterator>
88{
89public:
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
112 self_type operator+ (difference_type n) const { self_type tmp = *this; return tmp += n; }
113};
114// =================================================================================
115// 3. field_indirect_base
116// =================================================================================
117template <class T, class M>
119public:
120// definitions:
121
123 using memory_type = M;
124 using geo_type = geo_basic <float_type,memory_type>;
126 using size_type = typename geo_type::size_type;
127
128// allocators:
129
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
143protected:
144#ifdef TO_CLEAN
145 std::string _name() const;
146#endif // TO_CLEAN
147// data:
153};
154// ----------------
155// inlined
156// ----------------
157template <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
188template <class T, class M>
189inline
190std::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"]
205template <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{
213public:
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
246 const_iterator end_dof() const;
247protected:
248// data:
249 const FieldRdof _uh_const;
250};
251
252// concepts:
253template <class FieldRdof>
254struct is_field_rdof <field_rdof_indirect_const<FieldRdof>>: std::true_type {};
255
256template<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// ----------------
265template<class FieldRdof>
266template<class Sfinae>
268 const FieldRdof& uh,
269 const geo_type& dom)
270: base(uh.get_space(), dom),
271 _uh_const(uh)
272{
273}
274template<class FieldRdof>
277: base(wdof),
278 _uh_const(wdof._uh)
279{
280}
281template<class FieldRdof>
282inline
285{
286 return const_iterator (base::_dom_dis_idof2dis_idof.begin(), base::_first_dis_idof, _uh_const.begin_dof());
287}
288template<class FieldRdof>
289inline
292{
293 return const_iterator (base::_dom_dis_idof2dis_idof.end(), base::_first_dis_idof, _uh_const.begin_dof());
294}
295template<class FieldRdof>
296inline
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
310template <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{
318public:
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
382 const_iterator end_dof() const;
385
386protected:
387// data:
389 FieldWdof& _uh; // WARNING for cstor copy & assignt: contains a reference
390};
391
392// concepts:
393template<class FieldWdof>
394struct is_field_wdof <field_wdof_indirect<FieldWdof>>: std::true_type {};
395
396// avoid some mistakes:
397template<class FieldWdof>
398struct is_field_function <field_wdof_indirect<FieldWdof>>: std::false_type {};
399
400template<class 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
407template<class FieldWdof>
411// ------------------
412// inlined
413// ------------------
414template<class FieldWdof>
415template<class Sfinae>
417 FieldWdof& uh,
418 const geo_type& dom)
419: base (uh.get_space(), dom),
420 _uh(uh)
421{
422trace_macro("fi(fw,geo)");
423}
424template<class FieldWdof>
427{
428trace_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}
434template<class FieldWdof>
435inline
438{
439 return const_iterator (base::_dom_dis_idof2dis_idof.begin(), base::_first_dis_idof, _uh.begin_dof());
440}
441template<class FieldWdof>
442inline
445{
446 return const_iterator (base::_dom_dis_idof2dis_idof.end(), base::_first_dis_idof, _uh.begin_dof());
447}
448template<class FieldWdof>
449inline
452{
453 return iterator (base::_dom_dis_idof2dis_idof.begin(), base::_first_dis_idof, _uh.begin_dof());
454}
455template<class FieldWdof>
456inline
459{
460 return iterator (base::_dom_dis_idof2dis_idof.end(), base::_first_dis_idof, _uh.begin_dof());
461}
462template<class FieldWdof>
463inline
466{
467 size_type dis_idof = base::_dom_dis_idof2dis_idof.dis_at (dom_dis_idof);
468 return _uh.dis_dof (dis_idof);
469}
470template<class FieldWdof>
471inline
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
disarray< size_type, memory_type > _dom_dis_idof2dis_idof
typename geo_type::size_type size_type
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, ScalarForwardInputIterator > self_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)
field_indirect_iterator< SizeRandomInputIterator, ScalarForwardOutputIterator > self_type
self_type operator+(difference_type n) const
typename FieldRdof::scalar_type scalar_type
const scalar_type & dof(size_type idof) const
field_indirect_const_iterator< typename disarray< size_type, memory_type >::const_iterator,typename FieldRdof::const_iterator > const_iterator
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 &)
void dis_dof_update(const SetOp &set_op=SetOp()) const
const scalar_type & dis_dof(size_type dis_idof) const
field_indirect_const_iterator< typename disarray< size_type, memory_type >::const_iterator,typename FieldWdof::const_iterator > const_iterator
const scalar_type & dof(size_type 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 > &)
typename FieldWdof::memory_type memory_type
see the disarray page for the full documentation
Definition disarray.h:497
rep::base::const_iterator const_iterator
Definition disarray.h:503
see the distributor page for the full documentation
Definition distributor.h:69
size_type dis_size() const
global and local sizes
size_type size(size_type iproc) const
const communicator_type & comm() const
abstract base interface class
Definition geo.h:248
#define trace_macro(message)
Definition dis_macros.h:111
This file is part of Rheolef.
bool have_homogeneous_space(space_basic< scalar_type, memory_type > &Vh) const
Expr1::memory_type M