8#include <kernel/lafem/dense_vector.hpp>
9#include <kernel/lafem/tuple_vector.hpp>
10#include <kernel/lafem/meta_element.hpp>
32 template<
typename,
typename...>
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");
51 template <
typename DT2_ = DataType,
typename IT2_ = IndexType>
57 template <
typename DataType2_,
typename IndexType2_>
68 _first(std::forward<First_>(the_first)),
80 explicit TupleMirror(First_&& the_first, Rest_&&... the_rest) :
81 _first(std::forward<First_>(the_first)),
82 _rest(std::forward<Rest_>(the_rest)...)
98 _first = std::forward<First_>(other._first);
99 _rest = std::forward<RestClass>(other._rest);
120 template<
typename... SubMirror2_>
123 this->_first.convert(other._first);
124 this->_rest.
convert(other._rest);
135 template<
typename Tv_,
typename... Tw_>
163 const First_& first()
const
173 const RestClass&
rest()
const
185 template<
typename Tv_,
typename... Tw_>
197 template<
typename Tv_,
typename... Tw_>
226 template<
typename Tv_,
typename... Tw_>
232 _first.gather(buffer, vector.first(), buffer_offset);
233 _rest.
gather(buffer, vector.rest(), buffer_offset +
_first.buffer_size(vector.first()));
237 template<
typename Tv_,
typename... Tw_>
244 _first.scatter_axpy(vector.first(), buffer, alpha, buffer_offset);
249 template<
Perspective perspective_,
typename Tv_,
typename... Tw_>
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);
259 void dump(std::ostream& os)
const
261 os << this->first() <<
",";
262 this->rest().dump(os);
267 template<
typename First_>
268 class TupleMirror<First_>
270 template<
typename,
typename...>
271 friend class TupleMirror;
277 typedef typename First_::DataType
DataType;
278 typedef typename First_::IndexType
IndexType;
280 template <
typename DT2_ = DataType,
typename IT2_ = IndexType>
281 using MirrorType = TupleMirror<typename First_::template MirrorType<DT2_, IT2_> >;
284 template <
typename DataType2_,
typename IndexType2_>
295 explicit TupleMirror(First_&& the_first) :
296 _first(std::forward<First_>(the_first))
300 TupleMirror(TupleMirror&& other) :
305 TupleMirror&
operator=(TupleMirror&& other)
314 TupleMirror
clone()
const
316 return TupleMirror(
_first.clone());
321 return TupleMirror(
_first.clone(clone_mode));
324 template<
typename SubMirror2_>
325 void convert(
const TupleMirror<SubMirror2_>& other)
327 this->_first.convert(
other._first);
330 template<
typename Tv_>
331 static TupleMirror
make_empty(
const TupleVector<Tv_>& tmpl_vec)
333 return TupleMirror(First_::make_empty(tmpl_vec.first()));
337 std::size_t
bytes()
const
351 const First_& first()
const
356 template<
typename Tv_>
359 return _first.buffer_size(vector.first());
362 template<
typename Tv_>
363 DenseVector<DataType, IndexType>
create_buffer(
const TupleVector<Tv_>& vector)
const
365 return DenseVector<DataType, IndexType>(
buffer_size(vector));
371 static_assert(i_ == 0,
"invalid sub-mirror index");
376 const First_&
at()
const
378 static_assert(i_ == 0,
"invalid sub-mirror index");
382 template<
typename Tv_>
384 LAFEM::DenseVector<DataType, IndexType>& buffer,
385 const LAFEM::TupleVector<Tv_>& vector,
388 _first.gather(buffer, vector.first(), buffer_offset);
391 template<
typename Tv_>
393 LAFEM::TupleVector<Tv_>& vector,
394 const LAFEM::DenseVector<DataType, IndexType>& buffer,
398 _first.scatter_axpy(vector.first(), buffer, alpha, buffer_offset);
401 template<Perspective perspective_,
typename Tv_>
402 Index mask_scatter(
const LAFEM::TupleVector<Tv_>& vector, std::vector<int>& mask,
405 return _first.template mask_scatter<perspective_>(vector.first(), mask,
value, offset);
409 void dump(std::ostream& os)
const
415 template <
typename First_,
typename... Rest_>
416 inline std::ostream& operator<< (std::ostream & os,
const TupleMirror<First_, Rest_...>& x)
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.
TupleMirror()
default ctor
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)
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.
Tuple container element helper class template.