template<int rank_, int dim, typename Number>
class Tensor< rank_, dim, Number >
A general tensor class with an arbitrary rank, i.e. with an arbitrary number of indices. The Tensor class provides an indexing operator and a bit of infrastructure, but most functionality is recursively handed down to tensors of rank 1 or put into external templated functions, e.g. the contract family.
The rank of a tensor specifies which types of physical quantities it can represent:
A rank-0 tensor is a scalar that can store quantities such as temperature or pressure. These scalar quantities are shown in this documentation as simple lower-case Latin letters e.g. .
A rank-1 tensor is a vector with dim components and it can represent vector quantities such as velocity, displacement, electric field, etc. They can also describe the gradient of a scalar field. The notation used for rank-1 tensors is bold-faced lower-case Latin letters e.g. . The components of a rank-1 tensor such as are represented as where is an index between 0 and dim-1.
A rank-2 tensor is a linear operator that can transform a vector into another vector. These tensors are similar to matrices with components. There is a related class SymmetricTensor<2,dim> for tensors of rank 2 whose elements are symmetric. Rank-2 tensors are usually denoted by bold-faced upper-case Latin letters such as or bold-faced Greek letters for example . The components of a rank 2 tensor such as are shown with two indices as . These tensors usually describe the gradients of vector fields (deformation gradient, velocity gradient, etc.) or Hessians of scalar fields. Additionally, mechanical stress tensors are rank-2 tensors that map the unit normal vectors of internal surfaces into local traction (force per unit area) vectors.
Tensors with ranks higher than 2 are similarly defined in a consistent manner. They have components and the number of indices required to identify a component equals rank. For rank-4 tensors, a symmetric variant called SymmetricTensor<4,dim> exists.
Using this tensor class for objects of rank 2 has advantages over matrices in many cases since the dimension is known to the compiler as well as the location of the data. It is therefore possible to produce far more efficient code than for matrices with runtime-dependent dimension. It also makes the code easier to read because of the semantic difference between a tensor (an object that relates to a coordinate system and has transformation properties with regard to coordinate rotations and transforms) and matrices (which we consider as operators on arbitrary vector spaces related to linear algebra things).
Template Parameters
rank_
An integer that denotes the rank of this tensor. A specialization of this class exists for rank-0 tensors.
dim
An integer that denotes the dimension of the space in which this tensor operates. This of course equals the number of coordinates that identify a point and rank-1 tensor.
Number
The data type in which the tensor elements are to be stored. This will, in almost all cases, simply be the default double, but there are cases where one may want to store elements in a different (and always scalar) type. It can be used to base tensors on float or complex numbers or any other data type that implements basic arithmetic operations. Another example would be a type that allows for Automatic Differentiation (see, for example, the Sacado type used in step-33) and thereby can generate analytic (spatial) derivatives of a function that takes a tensor as argument.
using Tensor< rank_, dim, Number >::value_type = typename Tensor<rank_ - 1, dim, Number>::tensor_type
Type of objects encapsulated by this container and returned by operator[](). This is a tensor of lower rank for a general tensor, and a scalar number type for Tensor<1,dim,Number>.
A constructor where the data is copied from an ArrayView object. Obviously, the ArrayView object must represent a stretch of data of size dimrank. The sequentially ordered elements of the argument initializer are interpreted as described by unrolled_to_component_indices().
This constructor obviously requires that the ElementType type is either equal to Number, or is convertible to Number.
constexpr Tensor & Tensor< rank_, dim, Number >::operator=
(
const Number &
d
)
&
constexpr
This operator assigns a scalar to a tensor. To avoid confusion with what exactly it means to assign a scalar value to a tensor, zero is the only value allowed for d, allowing the intuitive notation t=0 to reset all elements of the tensor to zero.
constexpr Tensor & Tensor< rank_, dim, Number >::operator=
(
const Number &
d
)
&&
constexprdelete
Assign a scalar to the current object. This overload is used for rvalue references; because it does not make sense to assign something to a temporary, the function is deleted.
constexpr void Tensor< rank_, dim, Number >::clear
(
)
constexpr
Reset all values to zero.
Note that this is partly inconsistent with the semantics of the clear() member functions of the standard library containers and of several other classes within deal.II, which not only reset the values of stored elements to zero, but release all memory and return the object into a virginial state. However, since the size of objects of the present type is determined by its template parameters, resizing is not an option, and indeed the state where all elements have a zero value is the state right after construction of such an object.
Return the Frobenius-norm of a tensor, i.e. the square root of the sum of the absolute squares of all entries. For the present case of rank-1 tensors, this equals the usual l2 norm of the vector.
This function unrolls all tensor entries into a single, linearly numbered sequence. The order of the elements is the one given by component_to_unrolled_index().
The template type Number must be convertible to the type of *begin.
Output operator for tensors. Print the elements consecutively, with a space in between, two spaces between rank 1 subtensors, three between rank 2 and so on.
This function unwraps the underlying objects of type Number and OtherNumber that are stored within the Tensor and multiplies them. It returns an unwrapped number of product type.
Multiplication of a tensor of general rank with a scalar number from the right.
Only multiplication with a scalar number type (i.e., a floating point number, a complex floating point number, etc.) is allowed, see the documentation of EnableIfScalar for details.
Multiplication of a tensor of general rank with a scalar number from the left.
Only multiplication with a scalar number type (i.e., a floating point number, a complex floating point number, etc.) is allowed, see the documentation of EnableIfScalar for details.
Division of a tensor of general rank with a scalar number. See the discussion on operator*() above for more information about template arguments and the return type.
The dot product (single contraction) for tensors. This function return a tensor of rank that is the contraction of the last index of a tensor src1 of rank rank_1 with the first index of a tensor src2 of rank rank_2:
Note
For the Tensor class, the multiplication operator only performs a contraction over a single pair of indices. This is in contrast to the multiplication operator for SymmetricTensor, for which the corresponding operator*() performs a double contraction. The origin of the difference in how operator*() is implemented between Tensor and SymmetricTensor is that for the former, the product between two Tensor objects of same rank and dimension results in another Tensor object – that it, operator*() corresponds to the multiplicative group action within the group of tensors. On the other hand, there is no corresponding multiplicative group action with the set of symmetric tensors because, in general, the product of two symmetric tensors is a nonsymmetric tensor. As a consequence, for a mathematician, it is clear that operator*() for symmetric tensors must have a different meaning: namely the dot or scalar product that maps two symmetric tensors of rank 2 to a scalar. This corresponds to the double-dot (colon) operator whose meaning is then extended to the product of any two even-ranked symmetric tensors.
In case the contraction yields a tensor of rank 0, that is, if rank_1==rank_2==1, then a scalar number is returned as an unwrapped number type. Return the norm of the given rank-2 tensor, where (maximum of the sums over columns).
constexpr unsigned intTensor< rank_, dim, Number >::dimension = dim
staticconstexpr
Provide a way to get the dimension of an object without explicit knowledge of it's data type. Implementation is this way instead of providing a function dimension() because now it is possible to get the dimension at compile time without the expansion and preevaluation of an inlined function; the compiler may therefore produce more efficient code and you may use this value to declare other data types.