16 #ifndef dealii__tensor_accessors_h 17 #define dealii__tensor_accessors_h 19 #include <deal.II/base/config.h> 20 #include <deal.II/base/template_constraints.h> 21 #include <deal.II/base/table_indices.h> 24 DEAL_II_NAMESPACE_OPEN
76 template <
int index,
int rank,
typename T>
class ReorderedIndexView;
77 template <
int position,
int rank>
struct ExtractHelper;
78 template <
int no_contr,
int rank_1,
int rank_2,
int dim>
class Contract;
79 template <
int rank_1,
int rank_2,
int dim>
class Contract3;
102 typedef typename T::value_type value_type;
105 template <
typename T>
108 typedef const typename T::value_type value_type;
111 template <
typename T, std::
size_t N>
112 struct ValueType<T[N]>
114 typedef T value_type;
117 template <
typename T, std::
size_t N>
118 struct ValueType<const T[N]>
120 typedef const T value_type;
131 template <
int deref_steps,
typename T>
134 typedef typename ReturnType<deref_steps - 1,
typename ValueType<T>::value_type>::value_type value_type;
137 template <
typename T>
140 typedef T value_type;
183 template <
int index,
int rank,
typename T>
184 inline DEAL_II_ALWAYS_INLINE
185 internal::ReorderedIndexView<index, rank, T>
188 #ifdef DEAL_II_WITH_CXX11 189 static_assert(0 <= index && index < rank,
190 "The specified index must lie within the range [0,rank)");
193 return internal::ReorderedIndexView<index, rank, T>(t);
219 template<
int rank,
typename T,
typename ArrayType>
typename 220 ReturnType<rank, T>::value_type &
223 return internal::ExtractHelper<0, rank>::template extract<T, ArrayType>(t, indices);
265 template <
int no_contr,
int rank_1,
int rank_2,
int dim,
typename T1,
typename T2,
typename T3>
266 inline DEAL_II_ALWAYS_INLINE
267 void contract(T1 &result,
const T2 &left,
const T3 &right)
269 #ifdef DEAL_II_WITH_CXX11 270 static_assert(rank_1 >= no_contr,
"The rank of the left tensor must be " 271 "equal or greater than the number of " 273 static_assert(rank_2 >= no_contr,
"The rank of the right tensor must be " 274 "equal or greater than the number of " 278 internal::Contract<no_contr, rank_1, rank_2, dim>::template contract<T1, T2, T3>
279 (result, left, right);
311 template <
int rank_1,
int rank_2,
int dim,
typename T1,
typename T2,
typename T3,
typename T4>
312 T1
contract3(
const T2 &left,
const T3 &middle,
const T4 &right)
314 return internal::Contract3<rank_1, rank_2, dim>::template contract3<T1, T2, T3, T4>
315 (left, middle, right);
325 template <
int rank,
typename S>
class StoreIndex;
326 template <
typename T>
class Identity;
327 template <
int no_contr,
int dim>
class Contract2;
344 template <
int rank,
typename S>
347 typedef StoreIndex<rank, S> type;
350 template <
int index,
int rank,
typename T>
351 struct ReferenceType<ReorderedIndexView<index, rank, T> >
353 typedef ReorderedIndexView<index, rank, T> type;
385 template <
int index,
int rank,
typename T>
386 class ReorderedIndexView
389 ReorderedIndexView(
typename ReferenceType<T>::type t) : t_(t) {}
391 typedef ReorderedIndexView<index - 1, rank - 1,
typename ValueType<T>::value_type>
395 inline DEAL_II_ALWAYS_INLINE
396 value_type operator[](
unsigned int j)
const 398 return value_type(t_[j]);
402 typename ReferenceType<T>::type t_;
416 template <
int rank,
typename T>
417 class ReorderedIndexView<0, rank, T>
420 ReorderedIndexView(
typename ReferenceType<T>::type t) : t_(t) {}
422 typedef StoreIndex<rank - 1, internal::Identity<T> > value_type;
424 inline DEAL_II_ALWAYS_INLINE
425 value_type operator[](
unsigned int j)
const 427 return value_type(Identity<T>(t_), j);
431 typename ReferenceType<T>::type t_;
437 template <
typename T>
438 class ReorderedIndexView<0, 1, T>
441 ReorderedIndexView(
typename ReferenceType<T>::type t) : t_(t) {}
443 typedef typename ReferenceType<typename ValueType<T>::value_type>::type value_type;
445 inline DEAL_II_ALWAYS_INLINE
446 value_type operator[](
unsigned int j)
const 452 typename ReferenceType<T>::type t_;
460 template <
typename T>
464 Identity(
typename ReferenceType<T>::type t) : t_(t) {}
466 typedef typename ValueType<T>::value_type return_type;
468 inline DEAL_II_ALWAYS_INLINE
469 typename ReferenceType<return_type>::type apply(
unsigned int j)
const 475 typename ReferenceType<T>::type t_;
486 template <
int rank,
typename S>
490 StoreIndex(S s,
int i) : s_(s), i_(i) {}
492 typedef StoreIndex<rank - 1, StoreIndex<rank, S> > value_type;
494 inline DEAL_II_ALWAYS_INLINE
495 value_type operator[](
unsigned int j)
const 497 return value_type(*
this, j);
500 typedef typename ValueType<typename S::return_type>::value_type return_type;
503 typename ReferenceType<return_type>::type apply(
unsigned int j)
const 505 return s_.apply(j)[i_];
517 template <
typename S>
518 class StoreIndex<1, S>
521 StoreIndex(S s,
int i) : s_(s), i_(i) {}
523 typedef typename ValueType<typename S::return_type>::value_type return_type;
524 typedef return_type value_type;
526 inline DEAL_II_ALWAYS_INLINE
527 return_type &operator[](
unsigned int j)
const 529 return s_.apply(j)[i_];
545 template<
int position,
int rank>
548 template<
typename T,
typename ArrayType>
551 typename ReturnType<rank - position, T>::value_type &
553 const ArrayType &indices)
555 return ExtractHelper<position + 1, rank>::
556 template extract<typename ValueType<T>::value_type, ArrayType>
557 (t[indices[position]], indices);
564 struct ExtractHelper<rank, rank>
566 template<
typename T,
typename ArrayType>
592 template <
int no_contr,
int rank_1,
int rank_2,
int dim>
596 template<
typename T1,
typename T2,
typename T3>
597 inline DEAL_II_ALWAYS_INLINE
static 598 void contract(T1 &result,
const T2 &left,
const T3 &right)
600 for (
unsigned int i = 0; i < dim; ++i)
601 Contract<no_contr, rank_1 - 1, rank_2, dim>::
602 contract(result[i], left[i], right);
620 template <
int no_contr,
int rank_2,
int dim>
621 class Contract<no_contr, no_contr, rank_2, dim>
624 template<
typename T1,
typename T2,
typename T3>
625 inline DEAL_II_ALWAYS_INLINE
static 626 void contract(T1 &result,
const T2 &left,
const T3 &right)
628 for (
unsigned int i = 0; i < dim; ++i)
629 Contract<no_contr, no_contr, rank_2 - 1, dim>::
630 contract(result[i], left, right[i]);
648 template <
int no_contr,
int dim>
649 class Contract<no_contr, no_contr, no_contr, dim>
652 template<
typename T1,
typename T2,
typename T3>
653 inline DEAL_II_ALWAYS_INLINE
static 654 void contract(T1 &result,
const T2 &left,
const T3 &right)
656 result = Contract2<no_contr, dim>::template contract2<T1>(left, right);
664 template <
int no_contr,
int dim>
668 template<
typename T1,
typename T2,
typename T3>
669 inline DEAL_II_ALWAYS_INLINE
static 670 T1 contract2(
const T2 &left,
const T3 &right)
673 for (
unsigned int i = 0; i < dim; ++i)
674 result += Contract2<no_contr - 1, dim>::template contract2<T1>(left[i], right[i]);
683 class Contract2<0, dim>
686 template<
typename T1,
typename T2,
typename T3>
687 inline DEAL_II_ALWAYS_INLINE
static 688 T1 contract2(
const T2 &left,
const T3 &right)
709 template <
int rank_1,
int rank_2,
int dim>
713 template<
typename T1,
typename T2,
typename T3,
typename T4>
715 T1
contract3(
const T2 &left,
const T3 &middle,
const T4 &right)
718 for (
unsigned int i = 0; i < dim; ++i)
719 result += Contract3<rank_1 - 1, rank_2, dim>::template contract3<T1>(left[i], middle[i], right);
735 template <
int rank_2,
int dim>
736 class Contract3<0, rank_2, dim>
739 template<
typename T1,
typename T2,
typename T3,
typename T4>
741 T1
contract3(
const T2 &left,
const T3 &middle,
const T4 &right)
744 for (
unsigned int i = 0; i < dim; ++i)
745 result += Contract3<0, rank_2 - 1, dim>::template contract3<T1>(left, middle[i], right[i]);
754 class Contract3<0, 0, dim>
757 template<
typename T1,
typename T2,
typename T3,
typename T4>
759 T1
contract3(
const T2 &left,
const T3 &middle,
const T4 &right)
761 return left * middle * right;
770 DEAL_II_NAMESPACE_CLOSE
DEAL_II_ALWAYS_INLINE internal::ReorderedIndexView< index, rank, T > reordered_index_view(T &t)
ReturnType< rank, T >::value_type & extract(T &t, const ArrayType &indices)
DEAL_II_ALWAYS_INLINE void contract(T1 &result, const T2 &left, const T3 &right)
T1 contract3(const T2 &left, const T3 &middle, const T4 &right)