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 }; // class TupleMirror<...>
258
260 template<typename First_>
261 class TupleMirror<First_>
262 {
263 template<typename,typename...>
264 friend class TupleMirror;
265
266 public:
268 static constexpr int num_blocks = 1;
269
270 typedef typename First_::DataType DataType;
271 typedef typename First_::IndexType IndexType;
272
273 template <typename DT2_ = DataType, typename IT2_ = IndexType>
274 using MirrorType = TupleMirror<typename First_::template MirrorType<DT2_, IT2_> >;
275
277 template <typename DataType2_, typename IndexType2_>
278 using MirrorTypeByDI = MirrorType<DataType2_, IndexType2_>;
279
280 protected:
281 First_ _first;
282
283 public:
284 TupleMirror()
285 {
286 }
287
288 explicit TupleMirror(First_&& the_first) :
289 _first(std::forward<First_>(the_first))
290 {
291 }
292
293 TupleMirror(TupleMirror&& other) :
294 _first(std::forward<First_>(other._first))
295 {
296 }
297
298 TupleMirror& operator=(TupleMirror&& other)
299 {
300 if(this != &other)
301 {
302 _first = std::forward<First_>(other._first);
303 }
304 return *this;
305 }
306
307 TupleMirror clone() const
308 {
309 return TupleMirror(_first.clone());
310 }
311
312 TupleMirror clone(CloneMode clone_mode = CloneMode::Weak) const
313 {
314 return TupleMirror(_first.clone(clone_mode));
315 }
316
317 template<typename SubMirror2_>
318 void convert(const TupleMirror<SubMirror2_>& other)
319 {
320 this->_first.convert(other._first);
321 }
322
323 template<typename Tv_>
324 static TupleMirror make_empty(const TupleVector<Tv_>& tmpl_vec)
325 {
326 return TupleMirror(First_::make_empty(tmpl_vec.first()));
327 }
328
330 std::size_t bytes() const
331 {
332 return _first.bytes();
333 }
334 bool empty() const
335 {
336 return _first.empty();
337 }
338
339 First_& first()
340 {
341 return _first;
342 }
343
344 const First_& first() const
345 {
346 return _first;
347 }
348
349 template<typename Tv_>
350 Index buffer_size(const TupleVector<Tv_>& vector) const
351 {
352 return _first.buffer_size(vector.first());
353 }
354
355 template<typename Tv_>
356 DenseVector<DataType, IndexType> create_buffer(const TupleVector<Tv_>& vector) const
357 {
358 return DenseVector<DataType, IndexType>(buffer_size(vector));
359 }
360
361 template<int i_>
362 First_& at()
363 {
364 static_assert(i_ == 0, "invalid sub-mirror index");
365 return _first;
366 }
367
368 template<int i_>
369 const First_& at() const
370 {
371 static_assert(i_ == 0, "invalid sub-mirror index");
372 return _first;
373 }
374
375 template<typename Tv_>
376 void gather(
377 LAFEM::DenseVector<DataType, IndexType>& buffer,
378 const LAFEM::TupleVector<Tv_>& vector,
379 const Index buffer_offset = Index(0)) const
380 {
381 _first.gather(buffer, vector.first(), buffer_offset);
382 }
383
384 template<typename Tv_>
385 void scatter_axpy(
386 LAFEM::TupleVector<Tv_>& vector,
387 const LAFEM::DenseVector<DataType, IndexType>& buffer,
388 const DataType alpha = DataType(1),
389 const Index buffer_offset = Index(0)) const
390 {
391 _first.scatter_axpy(vector.first(), buffer, alpha, buffer_offset);
392 }
393
394 template<Perspective perspective_, typename Tv_>
395 Index mask_scatter(const LAFEM::TupleVector<Tv_>& vector, std::vector<int>& mask,
396 const int value, const Index offset = Index(0)) const
397 {
398 return _first.template mask_scatter<perspective_>(vector.first(), mask, value, offset);
399 }
400 }; // class TupleMirror<First_>
402 } // namespace LAFEM
403} // 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 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.