Tensor Description
To be able to construct reshaped views of the test functions and their derivates, we can describe the shape of the view through a TensorDescription{R,D} where R is the rank of the tensor and D is the dimension or extent of the tensor in each of the R directions. That means a real valued R-tensor is an element of $\underbrace{\mathbb{R}^D\times\cdots\times\mathbb{R}^D}_{R \text{ times}}$. Specifically, we can identify the following mathematical objects with tensors of different ranks:
| math. object | R-Tensor |
|---|---|
| scalar $\in\mathbb{R}$ | 0-Tensor |
| vector $\in\mathbb{R}^D$ | 1-Tensor |
| matrix $\in\mathbb{R}^D\times\mathbb{R}^D$ | 2-Tensor |
For finite elements, D usually matches the spatial dimension of the problem we want to solve, i.e. D=2 for 2D and D=3 for 3D.
Tensor Types
ExtendableFEM.TensorDescription — TypeTensorDescription{R,D}General type for an R-tensor of dimension/extent D. Mathematically, this describes the shape of an element in $\underbrace{\mathbb{R}^D\times\cdots\times\mathbb{R}^D}_{R} \text{ times}$.
See also: TDScalar{D}, TDVector{D}, TDMatrix{D}, TDRank3{D}, TDRank4{D}
ExtendableFEM.TDScalar — TypeTDScalar{D}Specification for a 0-tensor or scalar, i.e. TensorDescription{0,D}, to improve readability.
Note that in this case D has no greater effect and is only provided to have a matching interface between all the specifications.
ExtendableFEM.TDVector — TypeTDVector{D}Specification for a 1-tensor or vector, i.e. TensorDescription{1,D}, to improve readability.
ExtendableFEM.TDMatrix — TypeTDMatrix{D}Specification for a 2-tensor or matrix, i.e. TensorDescription{2,D}, to improve readability.
ExtendableFEM.TDRank3 — TypeTDRank3{D}Specification for a 3-tensor, i.e. TensorDescription{3,D}, to improve readability.
ExtendableFEM.TDRank4 — TypeTDRank4{D}Specification for a 4-tensor, i.e. TensorDescription{4,D}, to improve readability.
Reshaped views
ExtendableFEM.tensor_view — Methodfunction tensor_view(input,i::Int,::TensorDescription{2,dim})Returns a view of input[i:i+dim^2-1] reshaped as a (dim,dim) matrix.
ExtendableFEM.tensor_view — Methodfunction tensor_view(input,i::Int,::TensorDescription{3,dim})Returns a view of input[i:i+dim^3-1] reshaped as a (dim,dim,dim) 3-tensor.
ExtendableFEM.tensor_view — Methodfunction tensor_view(input,i::Int,::TensorDescription{4,dim})Returns a view of input[i:i+dim^4-1] reshaped as (dim,dim,dim,dim) 4-tensor.
ExtendableFEM.tensor_view — Methodfunction tensor_view(input,i::Int,::TensorDescription{0,dim})Returns a view of input[i] reshaped as a vector of length 1.
ExtendableFEM.tensor_view — Methodfunction tensor_view(input,i::Int,::TensorDescription{1,dim})Returns a view of input[i:i+dim-1] reshaped as a vector of length dim.
ExtendableFEM.tensor_view — Methodfunction tensor_view(input,i::Int,::TensorDescription{rank,dim})Returns a view of input[i] and subsequent entries, reshaped as a rank-tensor of dimension dim.
Note that this general implementation is a fallback for rank>4 that will likely produce allocations and slow assembly times if used in a kernel function.
Which tensor for which unknown?
For an unknown variable u of tensor rank r a derivative of order n has rank r+n, i.e. the hessian (n=2) of a scalar unknown (rank 0) and the gradient (n=1) of a vector valued (rank 1) variable are both matrices (rank 2).
For a more comprehensive list see the following table
| derivative order | scalar-valued | vector-valued | matrix-valued |
|---|---|---|---|
0 (value/id) | TDScalar(D) | TDVector(D) | TDMatrix(D) |
1 (grad) | TDVector(D) | TDMatrix(D) | TDRank3(D) |
2 (hessian) | TDMatrix(D) | TDRank3(D) | TDRank4(D) |
| 3 | TDRank3(D) | TDRank4(D) | TensorDescription(5,D) |
| 4 | TDRank4(D) | TensorDescription(5,D) | TensorDescription(6,D) |
| $\vdots$ | $\vdots$ | $\vdots$ | $\vdots$ |
Helpers
ExtendableFEM.tmul! — Functionfunction tmul!(y,A,x,α=1.0,β=0.0)Combined inplace matrix-vector multiply-add $A^T x α + y β$. The result is stored in y by overwriting it. Note that y must not be aliased with either A or x.
function tmul!(y::AbstractVector{T}, A::AbstractMatrix{T}, x::AbstractVector{T}, α=1.0, β=0.0) where {T<:AbstractFloat}Overload of the generic function for types supported by LinearAlgebra.BLAS.gemv! to avoid slow run times for large inputs.