Reference documentation for deal.II version 9.0.0
Classes | Functions
TensorAccessors Namespace Reference

Classes

struct  ReturnType
 
struct  ValueType
 

Functions

template<int index, int rank, typename T >
internal::ReorderedIndexView< index, rank, T > reordered_index_view (T &t)
 
template<int rank, typename T , typename ArrayType >
ReturnType< rank, T >::value_type & extract (T &t, const ArrayType &indices)
 
template<int no_contr, int rank_1, int rank_2, int dim, typename T1 , typename T2 , typename T3 >
void contract (T1 &result, const T2 &left, const T3 &right)
 
template<int rank_1, int rank_2, int dim, typename T1 , typename T2 , typename T3 , typename T4 >
T1 contract3 (const T2 &left, const T3 &middle, const T4 &right)
 

Detailed Description

This namespace is a collection of algorithms working on generic tensorial objects (of arbitrary rank).

The rationale to implement such functionality in a generic fashion in a separate namespace is

A tensorial object has the notion of a rank and allows a rank-times recursive application of the index operator, e.g., if t is a tensorial object of rank 4, the following access is valid:

t[1][2][1][4]

deal.II has its own implementation for tensorial objects such as Tensor<rank, dim, Number> and SymmetricTensor<rank, dim, Number>

The methods and algorithms implemented in this namespace, however, are fully generic. More precisely, it can operate on nested c-style arrays, or on class types T with a minimal interface that provides a local typedef value_type and an index operator operator[](unsigned int) that returns a (const or non-const) reference of value_type:

template <...>
class T
{
typedef ... value_type;
value_type & operator[](unsigned int);
const value_type & operator[](unsigned int) const;
};

This namespace provides primitives for access, reordering and contraction of such objects.

Author
Matthias Maier, 2015

Function Documentation

◆ reordered_index_view()

template<int index, int rank, typename T >
internal::ReorderedIndexView<index, rank, T> TensorAccessors::reordered_index_view ( T &  t)
inline

Provide a "tensorial view" to a reference t of a tensor object of rank rank in which the index index is shifted to the end. As an example consider a tensor of 5th order in dim=5 space dimensions that can be accessed through 5 recursive operator[]() invocations:

tensor[0][1][2][3][4] = 42.;

Index 1 (the 2nd index, count starts at 0) can now be shifted to the end via

auto tensor_view = reordered_index_view<1, 5>(tensor);
tensor_view[0][2][3][4][1] == 42.; // is true

The usage of the Tensor type was solely for the sake of an example. The mechanism implemented by this function is available for fairly general tensorial types T.

The purpose of this reordering facility is to be able to contract over an arbitrary index of two (or more) tensors:

  • reorder the indices in mind to the end of the tensors
  • use the contract function below that contracts the last elements of tensors.
Note
This function returns an internal class object consisting of an array subscript operator operator[](unsigned int) and a typedef value_type describing its return value.
Template Parameters
indexThe index to be shifted to the end. Indices are counted from 0, thus the valid range is \(0\le\text{index}<\text{rank}\).
rankRank of the tensorial object t
TA tensorial object of rank rank. T must provide a local typedef value_type and an index operator operator[]() that returns a (const or non-const) reference of value_type.
Author
Matthias Maier, 2015

Definition at line 186 of file tensor_accessors.h.

◆ extract()

template<int rank, typename T , typename ArrayType >
ReturnType<rank, T>::value_type& TensorAccessors::extract ( T &  t,
const ArrayType &  indices 
)

Return a reference (const or non-const) to a subobject of a tensorial object t of type T, as described by an array type ArrayType object indices. For example:

TableIndices<5> indices (0, 1, 2, 3, 4);
TensorAccessors::extract(tensor, indices) = 42;

This is equivalent to tensor[0][1][2][3][4] = 42..

Template Parameters
TA tensorial object of rank rank. T must provide a local typedef value_type and an index operator operator[]() that returns a (const or non-const) reference of value_type. Further, its tensorial rank must be equal or greater than rank.
ArrayTypeAn array like object, such as std::array, or TableIndices that stores at least rank indices that can be accessed via operator[]().
Author
Matthias Maier, 2015

Definition at line 219 of file tensor_accessors.h.

◆ contract()

template<int no_contr, int rank_1, int rank_2, int dim, typename T1 , typename T2 , typename T3 >
void TensorAccessors::contract ( T1 &  result,
const T2 &  left,
const T3 &  right 
)
inline

This function contracts two tensorial objects left and right and stores the result in result. The contraction is done over the last no_contr indices of both tensorial objects:

\[ \text{result}_{i_1,..,i_{r1},j_1,..,j_{r2}} = \sum_{k_1,..,k_{\text{no\_contr}}} \text{left}_{i_1,..,i_{r1},k_1,..,k_{\text{no\_contr}}} \text{right}_{j_1,..,j_{r2},k_1,..,k_{\text{no\_contr}}} \]

Calling this function is equivalent of writing the following low level code:

for(unsigned int i_0 = 0; i_0 < dim; ++i_0)
...
for(unsigned int i_ = 0; i_ < dim; ++i_)
for(unsigned int j_0 = 0; j_0 < dim; ++j_0)
...
for(unsigned int j_ = 0; j_ < dim; ++j_)
{
result[i_0]..[i_][j_0]..[j_] = 0.;
for(unsigned int k_0 = 0; k_0 < dim; ++k_0)
...
for(unsigned int k_ = 0; k_ < dim; ++k_)
result[i_0]..[i_][j_0]..[j_] += left[i_0]..[i_][k_0]..[k_] * right[j_0]..[j_][k_0]..[k_];
}

with r = rank_1 + rank_2 - 2 * no_contr, l = rank_1 - no_contr, l1 = rank_1, and c = no_contr.

Note
The Types T1, T2, and T3 must have rank rank_1 + rank_2 - 2 * no_contr, rank_1, or rank_2, respectively. Obviously, no_contr must be less or equal than rank_1 and rank_2.
Author
Matthias Maier, 2015

Definition at line 265 of file tensor_accessors.h.

◆ contract3()

template<int rank_1, int rank_2, int dim, typename T1 , typename T2 , typename T3 , typename T4 >
T1 TensorAccessors::contract3 ( const T2 &  left,
const T3 &  middle,
const T4 &  right 
)

Full contraction of three tensorial objects:

\[ \sum_{i_1,..,i_{r1},j_1,..,j_{r2}} \text{left}_{i_1,..,i_{r1}} \text{middle}_{i_1,..,i_{r1},j_1,..,j_{r2}} \text{right}_{j_1,..,j_{r2}} \]

Calling this function is equivalent of writing the following low level code:

T1 result = T1();
for(unsigned int i_0 = 0; i_0 < dim; ++i_0)
...
for(unsigned int i_ = 0; i_ < dim; ++i_)
for(unsigned int j_0 = 0; j_0 < dim; ++j_0)
...
for(unsigned int j_ = 0; j_ < dim; ++j_)
result += left[i_0]..[i_] * middle[i_0]..[i_][j_0]..[j_] * right[j_0]..[j_];
Note
The Types T2, T3, and T4 must have rank rank_1, rank_1 + rank_2, and rank_3, respectively. T1 must be a scalar type.
Author
Matthias Maier, 2015

Definition at line 308 of file tensor_accessors.h.