1#ifndef __DUNE_ACFEM_TENSORS_BINDINGS_DUNE_DENSEVECTORVIEW_HH__
2#define __DUNE_ACFEM_TENSORS_BINDINGS_DUNE_DENSEVECTORVIEW_HH__
4#include <dune/common/densevector.hh>
6#include "../../../common/literals.hh"
7#include "../../tensorbase.hh"
8#include "fieldvectortraits.hh"
17 template<
class Tensor>
20 template<
class T,
class Storage = Expressions::Storage<OperationTraits<IdentityOperation>, T>,
21 std::
size_t N = std::decay_t<T>::rank,
22 std::
size_t Rank = std::decay_t<T>::rank,
24 class DenseVectorView;
26 template<
class T,
class Storage, std::
size_t N, std::
size_t Rank>
27 class DenseVectorViewElement;
30 template<
class T,
class Storage, std::
size_t N, std::
size_t Rank>
33 ,
public Dune::DenseVector<DenseVectorViewElement<T, Storage, N, Rank> >
36 using DenseVectorType = Dune::DenseVector<DenseVectorViewElement<T, Storage, N, Rank> >;
40 using const_iterator = void;
41 using BaseType::lookAt;
43 using IndexType =
typename BaseType::IndexType;
45 static constexpr IndexType rank_ = Rank;
46 static constexpr IndexType fakedRank_ = N;
47 static constexpr IndexType stage_ = std::decay_t<T>::rank - N;
49 template<
class... Args>
52 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value,
int> = 0>
55 static constexpr std::size_t size()
60 const ValueType& operator[](IndexType i)
const
68 template<
class T,
class Storage, std::
size_t Rank>
71 ,
public Dune::DenseVector<DenseVectorViewElement<T, Storage, 1, Rank> >
75 using DenseVectorType = Dune::DenseVector<DenseVectorViewElement<T, Storage, 1, Rank> >;
76 using BaseType::lookAt;
77 using BaseType::value_;
79 using const_iterator = void;
80 using BaseType::operand;
82 using IndexType =
typename BaseType::IndexType;
84 static constexpr IndexType rank_ = Rank;
85 static constexpr IndexType fakedRank_ = 1;
86 static constexpr IndexType stage_ = std::decay_t<T>::rank - fakedRank_;
88 template<
class... Args>
91 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value,
int> = 0>
94 static constexpr std::size_t size()
96 return TensorTraits<T>::template dim<stage_>();
99 const ValueType& operator[](IndexType i)
const
101 lookAt()[stage_] = i;
102 return value_ = tensorValue(operand(0_c), lookAt());
110 template<
class T,
class Storage, std::
size_t N, std::
size_t Rank,
class SFINAE>
114 static_assert(N > 1,
"Recursion bug.");
115 static_assert(TensorTraits<T>::rank > 0,
"This can only work if rank > 0.");
121 using IndexType = unsigned;
123 static constexpr IndexType rank_ = Rank;
124 static constexpr IndexType fakedRank_ = N;
125 static constexpr IndexType stage_ = TensorTraits<T>::rank - N;
127 template<
class StorageArg,
128 std::enable_if_t<(std::is_constructible<Storage, StorageArg>::value
143 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value,
int> = 0>
148 static constexpr std::size_t size()
150 return TensorTraits<T>::template dim<stage_>();
155 return BaseType::lookAt();
163 template<
class T,
class Storage, std::
size_t Rank>
167 static_assert(std::decay_t<T>::rank > 0,
"This can only work if rank > 0.");
171 using ValueType =
typename std::decay_t<T>::FieldType;
172 using IndexType = unsigned;
173 using IndicesType = std::array<IndexType, std::decay_t<T>::rank>;
175 static constexpr IndexType rank_ = Rank;
176 static constexpr IndexType fakedRank_ = 1;
177 static constexpr IndexType stage_ = std::decay_t<T>::rank-fakedRank_;
179 template<
class StorageArg,
180 std::enable_if_t<(std::is_constructible<Storage, StorageArg>::value
184 : Storage(std::forward<StorageArg>(
storage))
188 : Storage(other), value_(other.value_), indices_(other.indices_)
192 : Storage(std::move(other))
193 , value_(std::move(other.value_))
194 , indices_(std::move(other.indices_))
197 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value,
int> = 0>
202 static constexpr std::size_t size()
204 return TensorTraits<T>::template dim<stage_>();
213 mutable ValueType value_;
214 mutable IndicesType indices_;
221 template<
class T,
class Storage, std::
size_t N>
224 ,
public Dune::DenseVector<DenseVectorView<T, Storage, N, N> >
226 static_assert(TensorTraits<T>::rank > 0,
"This can only work if rank > 0.");
231 using DenseVectorType = Dune::DenseVector<DenseVectorView<T, Storage, N, N> >;
233 using const_iterator = void;
235 using IndexType =
typename BaseType::IndexType;
237 static constexpr IndexType rank_ = N;
238 static constexpr IndexType fakedRank_ = N;
239 static constexpr IndexType stage_ = std::decay_t<T>::rank - fakedRank_;
241 template<
class StorageArg,
242 std::enable_if_t<(std::is_constructible<Storage, StorageArg>::value
257 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value,
int> = 0>
262 static constexpr std::size_t size()
264 return TensorTraits<T>::template dim<stage_>();
267 const ValueType& operator[](IndexType i)
const
269 lookAt()[stage_] = i;
275 return BaseType::lookAt();
283 template<
class T,
class Storage>
286 ,
public Dune::DenseVector<DenseVectorView<T, Storage, 1, 1> >
288 static_assert(TensorTraits<T>::rank > 0,
"This can only work if rank > 0.");
291 using ValueType =
typename TensorTraits<T>::FieldType;
292 using DenseVectorType = Dune::DenseVector<DenseVectorView<T, Storage, 1, 1> >;
294 using const_iterator = void;
295 using Storage::operand;
296 using IndexType = unsigned;
297 using IndicesType = std::array<IndexType, std::decay_t<T>::rank>;
299 static constexpr IndexType rank_ = 1;
300 static constexpr IndexType fakedRank_ = 1;
301 static constexpr IndexType stage_ = std::decay_t<T>::rank-fakedRank_;
303 template<
class StorageArg,
304 std::enable_if_t<(std::is_constructible<Storage, StorageArg>::value
308 : Storage(std::forward<StorageArg>(
storage))
312 : Storage(other), value_(other.value_), indices_(other.indices_)
316 : Storage(std::move(other))
317 , value_(std::move(other.value_))
318 , indices_(std::move(other.indices_))
321 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value,
int> = 0>
326 static constexpr std::size_t size()
328 return TensorTraits<T>::template dim<stage_>();
331 const ValueType& operator[](IndexType i)
const
333 lookAt()[stage_] = i;
334 return value_ = tensorValue(operand(0_c), lookAt());
343 mutable ValueType value_;
344 mutable IndicesType indices_;
348 template<
class T,
class Storage>
352 static_assert(std::decay_t<T>::rank == 0,
"This can only work if rank == 0.");
355 using ValueType =
typename std::decay_t<T>::FieldType;
357 using Storage::operand;
358 using IndexType = unsigned;
360 static constexpr IndexType rank_ = 0;
361 static constexpr IndexType fakedRank_ = 0;
363 template<
class StorageArg,
364 std::enable_if_t<(std::is_constructible<Storage, StorageArg>::value
368 : Storage(std::forward<StorageArg>(
storage))
376 : Storage(std::move(other))
379 template<class C, std::enable_if_t<std::is_base_of<ThisType, C>::value,
int> = 0>
384 static constexpr std::size_t size()
392 return operand(0_c)();
401 template<
class DenseMatrix,
class T>
402 static void apply(DenseMatrix& denseMatrix,
const TensorResult<T> &rhs)
404 static_assert(TensorTraits<T>::rank == 2,
"T should be a Tensor of rank 2.");
406 forLoop<TensorTraits<T>::template dim<0>()>([&](
auto i) {
407 using IType =
decltype(i);
408 forLoop<TensorTraits<T>::template dim<1>()>([&](
auto j) {
409 using JType =
decltype(j);
410 using Indices = Seq<IType::value, JType::value>;
411 denseMatrix[IType::value][JType::value] = rhs(Indices{});
416 template<
class DenseMatrix,
class T,
class Storage, std::
size_t Rank>
417 static void apply(DenseMatrix& denseMatrix,
420 using Traits = TensorTraits<T>;
421 constexpr std::size_t rank = Traits::rank;
422 forLoop<Traits::template dim<rank-2>()>([&](
auto i) {
423 using IType =
decltype(i);
424 forLoop<Traits::template dim<rank-1>()>([&](
auto j) {
425 using JType =
decltype(j);
426 denseMatrix[IType::value][JType::value] = rhs[IType::value][JType::value];
431 template<
class DenseMatrix,
class T,
class Storage, std::
size_t Rank>
432 static void apply(DenseMatrix& denseMatrix,
451 template<
class Field,
int Size,
class T>
452 struct PromotionTraits<FieldVector<Field,
Size>, T>
455 template<
class Field,
int Size,
class T>
456 struct PromotionTraits<T, FieldVector<Field,
Size> >
459 template<
class Field,
int Size>
460 struct PromotionTraits<FieldVector<Field,
Size>, FieldVector<Field,
Size> >
462 using PromotedType = FieldVector<Field, Size>;
465 template<
class Field,
int Rows,
int Cols,
class T>
466 struct PromotionTraits<FieldMatrix<Field, Rows, Cols>, T>
469 template<
class Field,
int Rows,
int Cols,
class T>
470 struct PromotionTraits<T, FieldMatrix<Field, Rows, Cols> >
473 template<
class Any,
class T,
class Storage, std::
size_t N, std::
size_t Rank>
474 struct PromotionTraits<Any, ACFem::Tensor::DenseVectorView<T, Storage, N, Rank> >
477 template<
class Any,
class T,
class Storage, std::
size_t N, std::
size_t Rank>
478 struct PromotionTraits<ACFem::Tensor::DenseVectorView<T, Storage, N, Rank>, Any>
481 template<
class T1,
class Storage1, std::size_t N1, std::size_t Rank1,
482 class T2,
class Storage2, std::size_t N2, std::size_t Rank2>
483 struct PromotionTraits<ACFem::Tensor::DenseVectorView<T1, Storage1, N1, Rank1>,
484 ACFem::Tensor::DenseVectorView<T2, Storage2, N2, Rank2> >
487 template<
class T,
class Storage, std::
size_t N, std::
size_t Rank>
488 struct PromotionTraits<ACFem::Tensor::DenseVectorView<T, Storage, N, Rank>,
489 ACFem::Tensor::DenseVectorView<T, Storage, N, Rank> >
492 template<
class Any,
class T,
class Storage, std::
size_t N, std::
size_t Rank>
493 struct PromotionTraits<Any, ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank> >
496 template<
class Any,
class T,
class Storage, std::
size_t N, std::
size_t Rank>
497 struct PromotionTraits<ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank>, Any>
500 template<
class T1,
class Storage1, std::size_t N1, std::size_t Rank1,
501 class T2,
class Storage2, std::size_t N2, std::size_t Rank2>
502 struct PromotionTraits<ACFem::Tensor::DenseVectorViewElement<T1, Storage1, N1, Rank1>,
503 ACFem::Tensor::DenseVectorViewElement<T2, Storage2, N2, Rank2> >
506 template<
class T,
class Storage, std::
size_t N, std::
size_t Rank>
507 struct PromotionTraits<ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank>,
508 ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank> >
513 template<
class T,
class Storage, std::
size_t N, std::
size_t Rank>
514 struct DenseMatVecTraits<
515 ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank> >
517 using derived_type = ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank>;
518 using container_type = derived_type;
519 using value_type = ACFem::Tensor::DenseVectorViewElement<T, Storage, N-1, Rank>;
520 using size_type = std::size_t;
523 template<
class T,
class Storage, std::
size_t Rank>
524 struct DenseMatVecTraits<ACFem::Tensor::DenseVectorViewElement<T, Storage, 1, Rank> >
526 using derived_type = ACFem::Tensor::DenseVectorViewElement<T, Storage, 1, Rank>;
527 using container_type = derived_type;
528 using value_type =
typename std::decay_t<T>::FieldType;
529 using size_type = std::size_t;
532 template<
class T,
class Storage, std::
size_t Rank>
533 struct DenseMatVecTraits<
534 ACFem::Tensor::DenseVectorView<T, Storage, Rank, Rank> >
536 using derived_type = ACFem::Tensor::DenseVectorView<T, Storage, Rank, Rank>;
537 using container_type = derived_type;
538 using value_type = ACFem::Tensor::DenseVectorViewElement<T, Storage, Rank-1, Rank>;
539 using size_type = std::size_t;
542 template<
class T,
class Storage>
543 struct DenseMatVecTraits<
544 ACFem::Tensor::DenseVectorView<T, Storage, 1, 1> >
546 using derived_type = ACFem::Tensor::DenseVectorView<T, Storage, 1, 1>;
547 using container_type = derived_type;
548 using value_type =
typename std::decay_t<T>::FieldType;
549 using size_type = std::size_t;
554 template<
class T,
class Storage, std::
size_t N, std::
size_t Rank>
555 struct FieldTraits<ACFem::Tensor::DenseVectorView<T, Storage, N, Rank> >
559 template<
class T,
class Storage, std::
size_t N, std::
size_t Rank>
560 struct FieldTraits<ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank> >
567 template<
class T,
class Storage, std::
size_t N, std::
size_t Rank>
568 struct FieldTraits<ACFem::Tensor::DenseVectorView<T, Storage, N, Rank> >
571 using Signature = ACFem::TailPart<N, typename ACFem::TensorTraits<T>::Signature>;
573 using field_type = ACFem::Tensor::FieldVectorSeqType<typename ACFem::TensorTraits<T>::FieldType,
575 using real_type = field_type;
579 template<
class T,
class Storage, std::
size_t N, std::
size_t Rank>
580 struct FieldTraits<ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank> >
583 using Signature = ACFem::TailPart<N, typename ACFem::TensorTraits<T>::Signature>;
585 using field_type = ACFem::Tensor::FieldVectorSeqType<typename ACFem::TensorTraits<T>::FieldType,
587 using real_type = field_type;
592 template<
class T,
int SIZE>
593 struct IsFieldVectorSizeCorrect<ACFem::Tensor::TensorResult<T>, SIZE>
597 template<
class T,
class Storage, std::
size_t N, std::
size_t Rank,
int SIZE>
598 struct IsFieldVectorSizeCorrect<ACFem::Tensor::DenseVectorViewElement<T, Storage, N, Rank>, SIZE>
599 :
ACFem::BoolConstant<ACFem::TensorTraits<T>::template dim<ACFem::TensorTraits<T>::rank - N>() == SIZE>
602 template<
class T,
class Storage, std::
size_t N, std::
size_t Rank,
int SIZE>
603 struct IsFieldVectorSizeCorrect<ACFem::Tensor::DenseVectorView<T, Storage, N, Rank>, SIZE>
604 :
ACFem::BoolConstant<ACFem::TensorTraits<T>::template dim<ACFem::TensorTraits<T>::rank - N>() == SIZE>
609 template<
class DenseMatrix,
class T>
610 class DenseMatrixAssigner<
611 DenseMatrix, ACFem::Tensor::TensorResult<T>,
612 std::enable_if_t<std::decay_t<T>::rank == 2> >
613 :
public ACFem::Tensor::DenseMatrixAssigner
616 template<
class DenseMatrix,
class T,
class Storage, std::
size_t Rank>
617 class DenseMatrixAssigner<
618 DenseMatrix, ACFem::Tensor::DenseVectorViewElement<T, Storage, 2, Rank> >
619 :
public ACFem::Tensor::DenseMatrixAssigner
622 template<
class DenseMatrix,
class T,
class Storage, std::
size_t Rank>
623 class DenseMatrixAssigner<
624 DenseMatrix, ACFem::Tensor::DenseVectorView<T, Storage, 2, Rank> >
625 :
public ACFem::Tensor::DenseMatrixAssigner
636 template<
class T,
class Field>
637 struct is_convertible<Dune::ACFem::Tensor::TensorResult<T>, Dune::FieldVector<Field, 1> >
640 typename Dune::ACFem::TensorTraits<T>::Signature,
641 typename Dune::ACFem::TensorTraits<Dune::FieldVector<Field, 1> >::Signature
643 && std::is_convertible<
644 typename Dune::FieldTraits<T>::field_type,
645 typename Dune::FieldTraits<Field>::field_type
652 template<
class Field,
class T>
653 struct is_same<Dune::FieldVector<Field, 1>, Dune::DenseVector<T> >
654 : std::is_base_of<Dune::DenseVector<T>, Dune::FieldVector<Field, 1> >
657 template<
class T,
class Storage, std::
size_t N, std::
size_t Rank,
class Field>
658 struct is_convertible<Dune::ACFem::Tensor::DenseVectorView<T, Storage, N, Rank>, Dune::FieldVector<Field, 1> >
661 Dune::ACFem::TailPart<N, typename Dune::ACFem::TensorTraits<T>::Signature>,
662 typename Dune::ACFem::TensorTraits<Dune::FieldVector<Field, 1> >::Signature
664 && std::is_convertible<
665 typename Dune::FieldTraits<T>::field_type,
666 typename Dune::FieldTraits<Field>::field_type
Definition: densevectorview.hh:34
Definition: densevectorview.hh:113
The wrapper class wrapped around each expression result.
Definition: tensorresult.hh:37
constexpr auto storage(const F &f, T &&... t)
Generate an expression storage container.
Definition: storage.hh:704
typename FloatingPointClosureHelper< T >::Type FloatingPointClosure
Template alias.
Definition: fieldpromotion.hh:74
IndexConstant< SizeV< std::decay_t< T > > > Size
Gives the number of elements in tuple-likes and std::integer_sequence.
Definition: size.hh:65
Constant< bool, V > BoolConstant
Short-cut for integral constant of type bool.
Definition: types.hh:48
Gets the type of the n-th element of a tuple-like or the std::integral_constant corresponding to the ...
Definition: access.hh:42
TrueType if T1 and T2 have the same decay types, otherwise FalseType.
Definition: types.hh:440
Definition: densevectorview.hh:400