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 static_assert(0 <= index && index < rank,
189 "The specified index must lie within the range [0,rank)");
191 return internal::ReorderedIndexView<index, rank, T>(t);
217 template <
int rank,
typename T,
typename ArrayType>
typename 218 ReturnType<rank, T>::value_type &
221 return internal::ExtractHelper<0, rank>::template extract<T, ArrayType>(t, indices);
263 template <
int no_contr,
int rank_1,
int rank_2,
int dim,
typename T1,
typename T2,
typename T3>
264 inline DEAL_II_ALWAYS_INLINE
265 void contract(T1 &result,
const T2 &left,
const T3 &right)
267 static_assert(rank_1 >= no_contr,
"The rank of the left tensor must be " 268 "equal or greater than the number of " 270 static_assert(rank_2 >= no_contr,
"The rank of the right tensor must be " 271 "equal or greater than the number of " 274 internal::Contract<no_contr, rank_1, rank_2, dim>::template contract<T1, T2, T3>
275 (result, left, right);
307 template <
int rank_1,
int rank_2,
int dim,
typename T1,
typename T2,
typename T3,
typename T4>
308 T1
contract3(
const T2 &left,
const T3 &middle,
const T4 &right)
310 return internal::Contract3<rank_1, rank_2, dim>::template contract3<T1, T2, T3, T4>
311 (left, middle, right);
321 template <
int rank,
typename S>
class StoreIndex;
322 template <
typename T>
class Identity;
323 template <
int no_contr,
int dim>
class Contract2;
334 template <
typename T>
340 template <
int rank,
typename S>
343 typedef StoreIndex<rank, S> type;
346 template <
int index,
int rank,
typename T>
347 struct ReferenceType<ReorderedIndexView<index, rank, T> >
349 typedef ReorderedIndexView<index, rank, T> type;
381 template <
int index,
int rank,
typename T>
382 class ReorderedIndexView
385 ReorderedIndexView(
typename ReferenceType<T>::type t) : t_(t) {}
387 typedef ReorderedIndexView<index - 1, rank - 1,
typename ValueType<T>::value_type>
391 inline DEAL_II_ALWAYS_INLINE
392 value_type operator[](
unsigned int j)
const 394 return value_type(t_[j]);
398 typename ReferenceType<T>::type t_;
412 template <
int rank,
typename T>
413 class ReorderedIndexView<0, rank, T>
416 ReorderedIndexView(
typename ReferenceType<T>::type t) : t_(t) {}
418 typedef StoreIndex<rank - 1, internal::Identity<T> > value_type;
420 inline DEAL_II_ALWAYS_INLINE
421 value_type operator[](
unsigned int j)
const 423 return value_type(Identity<T>(t_), j);
427 typename ReferenceType<T>::type t_;
433 template <
typename T>
434 class ReorderedIndexView<0, 1, T>
437 ReorderedIndexView(
typename ReferenceType<T>::type t) : t_(t) {}
439 typedef typename ReferenceType<typename ValueType<T>::value_type>::type value_type;
441 inline DEAL_II_ALWAYS_INLINE
442 value_type operator[](
unsigned int j)
const 448 typename ReferenceType<T>::type t_;
456 template <
typename T>
460 Identity(
typename ReferenceType<T>::type t) : t_(t) {}
462 typedef typename ValueType<T>::value_type return_type;
464 inline DEAL_II_ALWAYS_INLINE
465 typename ReferenceType<return_type>::type apply(
unsigned int j)
const 471 typename ReferenceType<T>::type t_;
482 template <
int rank,
typename S>
486 StoreIndex(S s,
int i) : s_(s), i_(i) {}
488 typedef StoreIndex<rank - 1, StoreIndex<rank, S> > value_type;
490 inline DEAL_II_ALWAYS_INLINE
491 value_type operator[](
unsigned int j)
const 493 return value_type(*
this, j);
496 typedef typename ValueType<typename S::return_type>::value_type return_type;
499 typename ReferenceType<return_type>::type apply(
unsigned int j)
const 501 return s_.apply(j)[i_];
513 template <
typename S>
514 class StoreIndex<1, S>
517 StoreIndex(S s,
int i) : s_(s), i_(i) {}
519 typedef typename ValueType<typename S::return_type>::value_type return_type;
520 typedef return_type value_type;
522 inline DEAL_II_ALWAYS_INLINE
523 return_type &operator[](
unsigned int j)
const 525 return s_.apply(j)[i_];
541 template <
int position,
int rank>
544 template <
typename T,
typename ArrayType>
547 typename ReturnType<rank - position, T>::value_type &
549 const ArrayType &indices)
551 return ExtractHelper<position + 1, rank>::
552 template extract<typename ValueType<T>::value_type, ArrayType>
553 (t[indices[position]], indices);
560 struct ExtractHelper<rank, rank>
562 template <
typename T,
typename ArrayType>
588 template <
int no_contr,
int rank_1,
int rank_2,
int dim>
592 template <
typename T1,
typename T2,
typename T3>
593 inline DEAL_II_ALWAYS_INLINE
static 594 void contract(T1 &result,
const T2 &left,
const T3 &right)
596 for (
unsigned int i = 0; i < dim; ++i)
597 Contract<no_contr, rank_1 - 1, rank_2, dim>::
598 contract(result[i], left[i], right);
616 template <
int no_contr,
int rank_2,
int dim>
617 class Contract<no_contr, no_contr, rank_2, dim>
620 template <
typename T1,
typename T2,
typename T3>
621 inline DEAL_II_ALWAYS_INLINE
static 622 void contract(T1 &result,
const T2 &left,
const T3 &right)
624 for (
unsigned int i = 0; i < dim; ++i)
625 Contract<no_contr, no_contr, rank_2 - 1, dim>::
626 contract(result[i], left, right[i]);
644 template <
int no_contr,
int dim>
645 class Contract<no_contr, no_contr, no_contr, dim>
648 template <
typename T1,
typename T2,
typename T3>
649 inline DEAL_II_ALWAYS_INLINE
static 650 void contract(T1 &result,
const T2 &left,
const T3 &right)
652 result = Contract2<no_contr, dim>::template contract2<T1>(left, right);
660 template <
int no_contr,
int dim>
664 template <
typename T1,
typename T2,
typename T3>
665 inline DEAL_II_ALWAYS_INLINE
static 666 T1 contract2(
const T2 &left,
const T3 &right)
671 for (
unsigned int i = 0; i < dim; ++i)
672 result += Contract2<no_contr - 1, dim>::template contract2<T1>(left[i], right[i]);
681 class Contract2<0, dim>
684 template <
typename T1,
typename T2,
typename T3>
685 inline DEAL_II_ALWAYS_INLINE
static 686 T1 contract2(
const T2 &left,
const T3 &right)
707 template <
int rank_1,
int rank_2,
int dim>
711 template <
typename T1,
typename T2,
typename T3,
typename T4>
713 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)
746 for (
unsigned int i = 0; i < dim; ++i)
747 result += Contract3<0, rank_2 - 1, dim>::template contract3<T1>(left, middle[i], right[i]);
756 class Contract3<0, 0, dim>
759 template <
typename T1,
typename T2,
typename T3,
typename T4>
761 T1
contract3(
const T2 &left,
const T3 &middle,
const T4 &right)
763 return left * middle * right;
772 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)