FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
tuple_mirror.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8#include <kernel/lafem/dense_vector.hpp>
9#include <kernel/lafem/tuple_vector.hpp>
10#include <kernel/lafem/meta_element.hpp>
11
12namespace FEAT
13{
14 namespace LAFEM
15 {
27 template<
28 typename First_,
29 typename... Rest_>
31 {
32 template<typename,typename...>
33 friend class TupleMirror;
34
35 typedef TupleMirror<Rest_...> RestClass;
36
37 public:
39 static constexpr int num_blocks = RestClass::num_blocks + 1;
40
42 typedef typename First_::DataType DataType;
44 typedef typename First_::IndexType IndexType;
45
46 // ensure that all sub-vector have the same data-type
47 static_assert(std::is_same<DataType, typename RestClass::DataType>::value, "sub-mirrors have different data-types");
48 static_assert(std::is_same<IndexType, typename RestClass::IndexType>::value, "sub-mirrors have different index-types");
49
51 template <typename DT2_ = DataType, typename IT2_ = IndexType>
53 typename First_::template MirrorType<DT2_, IT2_>,
54 typename Rest_::template MirrorType<DT2_, IT2_>...>;
55
57 template <typename DataType2_, typename IndexType2_>
59
60 protected:
62 First_ _first;
65
67 TupleMirror(First_&& the_first, RestClass&& the_rest) :
68 _first(std::forward<First_>(the_first)),
69 _rest(std::forward<RestClass>(the_rest))
70 {
71 }
72
73 public:
76 {
77 }
78
80 explicit TupleMirror(First_&& the_first, Rest_&&... the_rest) :
81 _first(std::forward<First_>(the_first)),
82 _rest(std::forward<Rest_>(the_rest)...)
83 {
84 }
85
88 _first(std::forward<First_>(other._first)),
89 _rest(std::forward<RestClass>(other._rest))
90 {
91 }
92
95 {
96 if(this != &other)
97 {
98 _first = std::forward<First_>(other._first);
99 _rest = std::forward<RestClass>(other._rest);
100 }
101 return *this;
102 }
103
110 {
111 return TupleMirror(_first.clone(clone_mode), _rest.clone(clone_mode));
112 }
113
120 template<typename... SubMirror2_>
122 {
123 this->_first.convert(other._first);
124 this->_rest.convert(other._rest);
125 }
126
135 template<typename Tv_, typename... Tw_>
137 {
138 return TupleMirror(First_::make_empty(tmpl_vec.first()), RestClass::make_empty(tmpl_vec.rest()));
139 }
140
142 std::size_t bytes() const
143 {
144 return _first.bytes() + _rest.bytes();
145 }
146
152 bool empty() const
153 {
154 return _first.empty() && _rest.empty();
155 }
156
158 First_& first()
159 {
160 return _first;
161 }
162
163 const First_& first() const
164 {
165 return _first;
166 }
167
168 RestClass& rest()
169 {
170 return _rest;
171 }
172
173 const RestClass& rest() const
174 {
175 return _rest;
176 }
178
185 template<typename Tv_, typename... Tw_>
187 {
188 return _first.buffer_size(vector.first()) + _rest.buffer_size(vector.rest());
189 }
190
197 template<typename Tv_, typename... Tw_>
199 {
201 }
202
212 template<int i_>
213 typename TupleElement<i_, First_, Rest_...>::Type& at()
214 {
216 }
217
219 template<int i_>
220 typename TupleElement<i_, First_, Rest_...>::Type const& at() const
221 {
223 }
224
226 template<typename Tv_, typename... Tw_>
227 void gather(
230 const Index buffer_offset = Index(0)) const
231 {
232 _first.gather(buffer, vector.first(), buffer_offset);
233 _rest.gather(buffer, vector.rest(), buffer_offset + _first.buffer_size(vector.first()));
234 }
235
237 template<typename Tv_, typename... Tw_>
241 const DataType alpha = DataType(1),
242 const Index buffer_offset = Index(0)) const
243 {
244 _first.scatter_axpy(vector.first(), buffer, alpha, buffer_offset);
245 _rest.scatter_axpy(vector.rest(), buffer, alpha, buffer_offset + _first.buffer_size(vector.first()));
246 }
247
249 template<Perspective perspective_, typename Tv_, typename... Tw_>
250 Index mask_scatter(const LAFEM::TupleVector<Tv_, Tw_...>& vector, std::vector<int>& mask,
251 const int value, const Index offset = Index(0)) const
252 {
253 Index nf = _first.template mask_scatter<perspective_>(vector.first(), mask, value, offset);
254 Index nr = _rest.template mask_scatter<perspective_>(vector.rest(), mask, value, offset + nf);
255 return nf + nr;
256 }
257
259 void dump(std::ostream& os) const
260 {
261 os << this->first() << ",";
262 this->rest().dump(os);
263 }
264 }; // class TupleMirror<...>
265
267 template<typename First_>
268 class TupleMirror<First_>
269 {
270 template<typename,typename...>
271 friend class TupleMirror;
272
273 public:
275 static constexpr int num_blocks = 1;
276
277 typedef typename First_::DataType DataType;
278 typedef typename First_::IndexType IndexType;
279
280 template <typename DT2_ = DataType, typename IT2_ = IndexType>
281 using MirrorType = TupleMirror<typename First_::template MirrorType<DT2_, IT2_> >;
282
284 template <typename DataType2_, typename IndexType2_>
285 using MirrorTypeByDI = MirrorType<DataType2_, IndexType2_>;
286
287 protected:
288 First_ _first;
289
290 public:
291 TupleMirror()
292 {
293 }
294
295 explicit TupleMirror(First_&& the_first) :
296 _first(std::forward<First_>(the_first))
297 {
298 }
299
300 TupleMirror(TupleMirror&& other) :
301 _first(std::forward<First_>(other._first))
302 {
303 }
304
305 TupleMirror& operator=(TupleMirror&& other)
306 {
307 if(this != &other)
308 {
309 _first = std::forward<First_>(other._first);
310 }
311 return *this;
312 }
313
314 TupleMirror clone() const
315 {
316 return TupleMirror(_first.clone());
317 }
318
319 TupleMirror clone(CloneMode clone_mode = CloneMode::Weak) const
320 {
321 return TupleMirror(_first.clone(clone_mode));
322 }
323
324 template<typename SubMirror2_>
325 void convert(const TupleMirror<SubMirror2_>& other)
326 {
327 this->_first.convert(other._first);
328 }
329
330 template<typename Tv_>
331 static TupleMirror make_empty(const TupleVector<Tv_>& tmpl_vec)
332 {
333 return TupleMirror(First_::make_empty(tmpl_vec.first()));
334 }
335
337 std::size_t bytes() const
338 {
339 return _first.bytes();
340 }
341 bool empty() const
342 {
343 return _first.empty();
344 }
345
346 First_& first()
347 {
348 return _first;
349 }
350
351 const First_& first() const
352 {
353 return _first;
354 }
355
356 template<typename Tv_>
357 Index buffer_size(const TupleVector<Tv_>& vector) const
358 {
359 return _first.buffer_size(vector.first());
360 }
361
362 template<typename Tv_>
363 DenseVector<DataType, IndexType> create_buffer(const TupleVector<Tv_>& vector) const
364 {
365 return DenseVector<DataType, IndexType>(buffer_size(vector));
366 }
367
368 template<int i_>
369 First_& at()
370 {
371 static_assert(i_ == 0, "invalid sub-mirror index");
372 return _first;
373 }
374
375 template<int i_>
376 const First_& at() const
377 {
378 static_assert(i_ == 0, "invalid sub-mirror index");
379 return _first;
380 }
381
382 template<typename Tv_>
383 void gather(
384 LAFEM::DenseVector<DataType, IndexType>& buffer,
385 const LAFEM::TupleVector<Tv_>& vector,
386 const Index buffer_offset = Index(0)) const
387 {
388 _first.gather(buffer, vector.first(), buffer_offset);
389 }
390
391 template<typename Tv_>
392 void scatter_axpy(
393 LAFEM::TupleVector<Tv_>& vector,
394 const LAFEM::DenseVector<DataType, IndexType>& buffer,
395 const DataType alpha = DataType(1),
396 const Index buffer_offset = Index(0)) const
397 {
398 _first.scatter_axpy(vector.first(), buffer, alpha, buffer_offset);
399 }
400
401 template<Perspective perspective_, typename Tv_>
402 Index mask_scatter(const LAFEM::TupleVector<Tv_>& vector, std::vector<int>& mask,
403 const int value, const Index offset = Index(0)) const
404 {
405 return _first.template mask_scatter<perspective_>(vector.first(), mask, value, offset);
406 }
407
409 void dump(std::ostream& os) const
410 {
411 os << this->first();
412 }
413 }; // class TupleMirror<First_>
414
415 template <typename First_, typename... Rest_>
416 inline std::ostream& operator<< (std::ostream & os, const TupleMirror<First_, Rest_...>& x)
417 {
418 os << "[";
419 x.dump(os);
420 os << "]";
421 return os;
422 }
424 } // namespace LAFEM
425} // namespace FEAT
Dense data vector class template.
TupleVector meta-mirror class template.
bool empty() const
Checks whether the mirror is empty.
TupleMirror(TupleMirror &&other)
move-ctor
TupleMirror(First_ &&the_first, Rest_ &&... the_rest)
sub-mirror emplacement ctor
First_::DataType DataType
sub-mirror data-type
static constexpr int num_blocks
number of mirror blocks
TupleMirror< typename First_::template MirrorType< DT2_, IT2_ >, typename Rest_::template MirrorType< DT2_, IT2_ >... > MirrorType
Our 'base' class type.
TupleElement< i_, First_, Rest_... >::Type & at()
Returns a sub-mirror block.
DenseVector< DataType, IndexType > create_buffer(const TupleVector< Tv_, Tw_... > &vector) const
Creates a new buffer vector for a TupleVector.
std::size_t bytes() const
Returns the total amount of bytes allocated.
void scatter_axpy(LAFEM::TupleVector< Tv_, Tw_... > &vector, const LAFEM::DenseVector< DataType, IndexType > &buffer, const DataType alpha=DataType(1), const Index buffer_offset=Index(0)) const
Scatters the buffer entries onto a DenseVector.
TupleMirror & operator=(TupleMirror &&other)
move-assign operator
Index mask_scatter(const LAFEM::TupleVector< Tv_, Tw_... > &vector, std::vector< int > &mask, const int value, const Index offset=Index(0)) const
Updates a scatter mask vector for this mirror.
TupleElement< i_, First_, Rest_... >::Type const & at() const
Returns a sub-mirror block.
void gather(LAFEM::DenseVector< DataType, IndexType > &buffer, const LAFEM::TupleVector< Tv_, Tw_... > &vector, const Index buffer_offset=Index(0)) const
Gathers the buffer entries from a DenseVector.
static TupleMirror make_empty(const TupleVector< Tv_, Tw_... > &tmpl_vec)
Creates and returns an empty mirror.
void dump(std::ostream &os) const
auxiliary function for operator<< implementation
void convert(const TupleMirror< SubMirror2_... > &other)
Conversion method.
First_::IndexType IndexType
sub-mirror index-type
MirrorType< DataType2_, IndexType2_ > MirrorTypeByDI
this typedef lets you create a mirror with new Data and Index types
TupleMirror(First_ &&the_first, RestClass &&the_rest)
data-move ctor; this one is protected for a reason
First_ _first
the first sub-mirror
RestClass _rest
all remaining sub-mirrors
TupleMirror clone(CloneMode clone_mode=CloneMode::Weak) const
Clone operation.
Index buffer_size(const TupleVector< Tv_, Tw_... > &vector) const
Computes the required buffer size for a TupleVector.
Variadic TupleVector class template.
@ other
generic/other permutation strategy
@ rest
restriction (multigrid)
FEAT namespace.
Definition: adjactor.hpp:12
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.
Tuple container element helper class template.