deal.II version GIT relicensing-2289-g1e5549a87a 2024-12-21 21:30:00+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
Namespaces | Classes | Functions
TensorAccessors Namespace Reference

Namespaces

namespace  internal
 

Classes

struct  ReturnType
 
struct  ReturnType< 0, T >
 
struct  ValueType
 
struct  ValueType< const T >
 
struct  ValueType< const T[N]>
 
struct  ValueType< T[N]>
 

Functions

template<int index, int rank, typename T >
constexpr internal::ReorderedIndexView< index, rank, T > reordered_index_view (T &t)
 
template<int rank, typename T , typename ArrayType >
constexpr 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 >
constexpr 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 >
constexpr 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 and SymmetricTensor

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 alias value_type and an index operator operator[](unsigned int) that returns a (const or non-const) reference of value_type:

template <...>
class T
{
using 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.

Function Documentation

◆ reordered_index_view()

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

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 an alias 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 alias value_type and an index operator operator[]() that returns a (const or non-const) reference of value_type.

Definition at line 186 of file tensor_accessors.h.

◆ extract()

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

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;
constexpr ReturnType< rank, T >::value_type & extract(T &t, const ArrayType &indices)

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

Template Parameters
TA tensorial object of rank rank. T must provide a local alias 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[]().

Definition at line 218 of file tensor_accessors.h.

◆ contract()

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

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_{\mathrm{no\_contr}}} \mathrm{left}_{i_1,..,i_{r1},k_1,..,k_{\mathrm{no\_contr}}} \mathrm{right}_{j_1,..,j_{r2},k_1,..,k_{\mathrm{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.

Definition at line 271 of file tensor_accessors.h.

◆ contract3()

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

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.

Definition at line 323 of file tensor_accessors.h.