16 #ifndef dealii_tensor_accessors_h 17 #define dealii_tensor_accessors_h 19 #include <deal.II/base/config.h> 21 #include <deal.II/base/table_indices.h> 22 #include <deal.II/base/template_constraints.h> 25 DEAL_II_NAMESPACE_OPEN
77 template <
int index,
int rank,
typename T>
78 class ReorderedIndexView;
79 template <
int position,
int rank>
81 template <
int no_contr,
int rank_1,
int rank_2,
int dim>
83 template <
int rank_1,
int rank_2,
int dim>
104 template <
typename T>
107 using value_type =
typename T::value_type;
110 template <
typename T>
113 using value_type =
const typename T::value_type;
116 template <
typename T, std::
size_t N>
117 struct ValueType<T[N]>
119 using value_type = T;
122 template <
typename T, std::
size_t N>
123 struct ValueType<const T[N]>
125 using value_type =
const T;
136 template <
int deref_steps,
typename T>
141 typename ValueType<T>::value_type>::value_type;
144 template <
typename T>
147 using value_type = T;
190 template <
int index,
int rank,
typename T>
191 inline DEAL_II_ALWAYS_INLINE internal::ReorderedIndexView<index, rank, T>
194 static_assert(0 <= index && index < rank,
195 "The specified index must lie within the range [0,rank)");
197 return internal::ReorderedIndexView<index, rank, T>(t);
224 template <
int rank,
typename T,
typename ArrayType>
225 typename ReturnType<rank, T>::value_type &
228 return internal::ExtractHelper<0, rank>::template extract<T, ArrayType>(
273 template <
int no_contr,
280 inline DEAL_II_ALWAYS_INLINE
void 281 contract(T1 &result,
const T2 &left,
const T3 &right)
283 static_assert(rank_1 >= no_contr,
284 "The rank of the left tensor must be " 285 "equal or greater than the number of " 287 static_assert(rank_2 >= no_contr,
288 "The rank of the right tensor must be " 289 "equal or greater than the number of " 292 internal::Contract<no_contr, rank_1, rank_2, dim>::
293 template contract<T1, T2, T3>(result, left, right);
327 template <
int rank_1,
335 contract3(
const T2 &left,
const T3 &middle,
const T4 &right)
337 return internal::Contract3<rank_1, rank_2, dim>::
338 template contract3<T1, T2, T3, T4>(left, middle, right);
348 template <
int rank,
typename S>
350 template <
typename T>
352 template <
int no_contr,
int dim>
364 template <
typename T>
370 template <
int rank,
typename S>
373 using type = StoreIndex<rank, S>;
376 template <
int index,
int rank,
typename T>
377 struct ReferenceType<ReorderedIndexView<index, rank, T>>
379 using type = ReorderedIndexView<index, rank, T>;
411 template <
int index,
int rank,
typename T>
412 class ReorderedIndexView
415 ReorderedIndexView(
typename ReferenceType<T>::type t)
419 using value_type = ReorderedIndexView<index - 1,
421 typename ValueType<T>::value_type>;
424 inline DEAL_II_ALWAYS_INLINE value_type operator[](
unsigned int j)
const 426 return value_type(t_[j]);
430 typename ReferenceType<T>::type t_;
444 template <
int rank,
typename T>
445 class ReorderedIndexView<0, rank, T>
448 ReorderedIndexView(
typename ReferenceType<T>::type t)
452 using value_type = StoreIndex<rank - 1, internal::Identity<T>>;
454 inline DEAL_II_ALWAYS_INLINE value_type operator[](
unsigned int j)
const 456 return value_type(Identity<T>(t_), j);
460 typename ReferenceType<T>::type t_;
466 template <
typename T>
467 class ReorderedIndexView<0, 1, T>
470 ReorderedIndexView(
typename ReferenceType<T>::type t)
475 typename ReferenceType<typename ValueType<T>::value_type>::type;
477 inline DEAL_II_ALWAYS_INLINE value_type operator[](
unsigned int j)
const 483 typename ReferenceType<T>::type t_;
491 template <
typename T>
495 Identity(
typename ReferenceType<T>::type t)
499 using return_type =
typename ValueType<T>::value_type;
501 inline DEAL_II_ALWAYS_INLINE
typename ReferenceType<return_type>::type
502 apply(
unsigned int j)
const 508 typename ReferenceType<T>::type t_;
519 template <
int rank,
typename S>
523 StoreIndex(S s,
int i)
528 using value_type = StoreIndex<rank - 1, StoreIndex<rank, S>>;
530 inline DEAL_II_ALWAYS_INLINE value_type operator[](
unsigned int j)
const 532 return value_type(*
this, j);
536 typename ValueType<typename S::return_type>::value_type;
538 inline typename ReferenceType<return_type>::type
539 apply(
unsigned int j)
const 541 return s_.apply(j)[i_];
553 template <
typename S>
554 class StoreIndex<1, S>
557 StoreIndex(S s,
int i)
563 typename ValueType<typename S::return_type>::value_type;
564 using value_type = return_type;
566 inline DEAL_II_ALWAYS_INLINE return_type &operator[](
unsigned int j)
const 568 return s_.apply(j)[i_];
584 template <
int position,
int rank>
587 template <
typename T,
typename ArrayType>
588 inline static typename ReturnType<rank - position, T>::value_type &
589 extract(T &t,
const ArrayType &indices)
591 return ExtractHelper<position + 1, rank>::template
extract<
592 typename ValueType<T>::value_type,
593 ArrayType>(t[indices[position]], indices);
600 struct ExtractHelper<rank, rank>
602 template <
typename T,
typename ArrayType>
604 extract(T &t,
const ArrayType &)
626 template <
int no_contr,
int rank_1,
int rank_2,
int dim>
630 template <
typename T1,
typename T2,
typename T3>
631 inline DEAL_II_ALWAYS_INLINE
static void 632 contract(T1 &result,
const T2 &left,
const T3 &right)
634 for (
unsigned int i = 0; i < dim; ++i)
656 template <
int no_contr,
int rank_2,
int dim>
657 class Contract<no_contr, no_contr, rank_2, dim>
660 template <
typename T1,
typename T2,
typename T3>
661 inline DEAL_II_ALWAYS_INLINE
static void 662 contract(T1 &result,
const T2 &left,
const T3 &right)
664 for (
unsigned int i = 0; i < dim; ++i)
686 template <
int no_contr,
int dim>
687 class Contract<no_contr, no_contr, no_contr, dim>
690 template <
typename T1,
typename T2,
typename T3>
691 inline DEAL_II_ALWAYS_INLINE
static void 692 contract(T1 &result,
const T2 &left,
const T3 &right)
694 result = Contract2<no_contr, dim>::template contract2<T1>(left, right);
702 template <
int no_contr,
int dim>
706 template <
typename T1,
typename T2,
typename T3>
707 inline DEAL_II_ALWAYS_INLINE
static T1
708 contract2(
const T2 &left,
const T3 &right)
713 for (
unsigned int i = 0; i < dim; ++i)
715 Contract2<no_contr - 1, dim>::template contract2<T1>(left[i],
725 class Contract2<0, dim>
728 template <
typename T1,
typename T2,
typename T3>
729 inline DEAL_II_ALWAYS_INLINE
static T1
730 contract2(
const T2 &left,
const T3 &right)
751 template <
int rank_1,
int rank_2,
int dim>
755 template <
typename T1,
typename T2,
typename T3,
typename T4>
757 contract3(
const T2 &left,
const T3 &middle,
const T4 &right)
762 for (
unsigned int i = 0; i < dim; ++i)
763 result += Contract3<rank_1 - 1, rank_2, dim>::template contract3<T1>(
764 left[i], middle[i], right);
781 template <
int rank_2,
int dim>
782 class Contract3<0, rank_2, dim>
785 template <
typename T1,
typename T2,
typename T3,
typename T4>
787 contract3(
const T2 &left,
const T3 &middle,
const T4 &right)
792 for (
unsigned int i = 0; i < dim; ++i)
794 Contract3<0, rank_2 - 1, dim>::template contract3<T1>(left,
805 class Contract3<0, 0, dim>
808 template <
typename T1,
typename T2,
typename T3,
typename T4>
810 contract3(
const T2 &left,
const T3 &middle,
const T4 &right)
812 return left * middle * right;
821 DEAL_II_NAMESPACE_CLOSE
internal::ReorderedIndexView< index, rank, T > reordered_index_view(T &t)
ReturnType< rank, T >::value_type & extract(T &t, const ArrayType &indices)
T1 contract3(const T2 &left, const T3 &middle, const T4 &right)
void contract(T1 &result, const T2 &left, const T3 &right)
void contract(Tensor< 2, dim, Number > &dest, const Tensor< 2, dim, Number > &src1, const unsigned int index1, const Tensor< 2, dim, Number > &src2, const unsigned int index3)