Gridap.TensorValues

This module provides the abstract interface MultiValue representing tensors that are also Numbers, along with concrete implementations for the following tensors:

Generalities

The main feature of this module is that the provided types do not extend from AbstractArray, but from Number!

This allows one to work with them as if they were scalar values in broadcasted operations on arrays of VectorValue objects (also for TensorValue or MultiValue objects). For instance, one can perform the following manipulations:

# Assign a VectorValue to all the entries of an Array of VectorValues
A = zeros(VectorValue{2,Int}, (4,5))
v = VectorValue(12,31)
A .= v # This is possible since  VectorValue <: Number

# Broadcasting of tensor operations in arrays of TensorValues
t = TensorValue(13,41,53,17) # creates a 2x2 TensorValue
g = TensorValue(32,41,3,14) # creates another 2x2 TensorValue
B = fill(t,(1,5))
C = inner.(g,B) # inner product of g against all TensorValues in the array B
@show C
# C = [2494 2494 2494 2494 2494]

To create a ::MultiValue tensor from components, these should be given as separate arguments or all gathered in a tuple. The order of the arguments is the order of the linearized Cartesian indices of the corresponding array (order of the Base.LinearIndices indices):

using StaticArrays
t = TensorValue( (1, 2, 3, 4) )
ts= convert(SMatrix{2,2,Int}, t)
@show ts
# 2×2 SMatrix{2, 2, Int64, 4} with indices SOneTo(2)×SOneTo(2):
#  1  3
#  2  4
t2[1,2] == t[1,2] == 3 # true

For symmetric tensor types, only the independent components should be given, see SymTensorValue, SymTracelessTensorValue and SymFourthOrderTensorValue.

A MultiValue can be created from an AbstractArray of the same size. If the MultiValue type has internal constraints (e.g. symmetries), ONLY the required components are picked from the array WITHOUT CHECKING if the given array did respect the constraints:

SymTensorValue( [1 2; 3 4] )          # -> SymTensorValue{2, Int64, 3}(1, 2, 4)
SymTensorValue( SMatrix{2}(1,2,3,4) ) # -> SymTensorValue{2, Int64, 3}(1, 3, 4)

MultiValues can be converted to static and mutable arrays types from StaticArrays.jl using convert and mutable, respectively.

Tensor types

The following concrete tensor types are currently implemented:

Gridap.TensorValues.TensorValueType
TensorValue{D1,D2,T,L} <: MultiValue{Tuple{D1,D2},T,2,L}

Type representing a second-order D1×D2 tensor. It must hold L = D1*D2.

If only D1 or no dimension parameter is given to the constructor, D1=D2 is assumed.

source
Gridap.TensorValues.SymTensorValueType
SymTensorValue{D,T,L} <: AbstractSymTensorValue{D,T,L}

Type representing a symmetric second-order D×D tensor. It must hold L = D(D+1)/2.

It is constructed by providing the components of index (i,j) for 1 ≤ i ≤ j ≤ D.

source
Gridap.TensorValues.SymTracelessTensorValueType
SymTracelessTensorValue{D,T,L} <: AbstractSymTensorValue{D,T,L}
QTensorValue{D,T,L}

Type representing a symetric second-order D×D tensor with zero trace. It must hold L = D(D+1)/2. This type is used to model the Q-tensor order parameter in nematic liquid cristals.

The constructor determines the value of index (D,D) as minus the sum of the other diagonal values, so it value musn't be provided. The constructor thus expects the L-1 components of indices (i,j) for 1 ≤ i ≤ D-1 and i ≤ j ≤ D.

source
Gridap.TensorValues.ThirdOrderTensorValueType
ThirdOrderTensorValue{D1,D2,D3,T,L} <: MultiValue{Tuple{D1,D2,D3},T,3,L}

Type representing a third-order D1×D2×D3 tensor. It must hold L = D1*D2*D3.

If only D1 or no dimension parameter is given to the constructor, D1=D2=D3 is assumed.

source
Gridap.TensorValues.SymFourthOrderTensorValueType
SymFourthOrderTensorValue{D,T,L} <: MultiValue{Tuple{D,D,D,D},T,4,L}

Type representing a symmetric second-order D×D×D×D tensor, with symmetries ijkl↔jikl and ijkl↔ijlk. It must hold L = (D(D+1)/2)^2.

It is constructed by providing the components of index (i,j,k,l) for 1 ≤ i ≤ j ≤ D and 1 ≤ k ≤ l ≤ D.

source

Abstract tensor types

Gridap.TensorValues.MultiValueType
MultiValue{S,T,N,L} <: Number

Abstract type representing a multi-dimensional number value. The parameters are analog to that of StaticArrays.jl:

  • S is a Tuple type holding the size of the tensor, e.g. Tuple{3} for a 3d vector or Tuple{2,4} for a 2 rows and 4 columns tensor,
  • T is the type of the scalar components, should be subtype of Number,
  • N is the order of the tensor, the length of S,
  • L is the number of components stored internally.

MultiValues are immutable.

source

Interface

The tensor types implement methods for the following Base functions: getindex, length, size, rand, zero, real, imag and conj.

one is also implemented in particular cases: it is defined for second and fourth order tensors. For second order, it returns the identity tensor δij, except SymTracelessTensorValue that does not implement one. For fourth order symmetric tensors, see one.

Additionally, the tensor types expose the following interface:

Gridap.TensorValues.num_componentsFunction
num_components(::Type{<:Number})
num_components(a::Number)

Total number of components of a Number or MultiValue, that is 1 for scalars and the product of the size dimensions for a MultiValue. This is the same as length.

source
Gridap.TensorValues.MutableFunction
Mutable(T::Type{<:MultiValue}) -> ::Type{<:MArray}
Mutable(a::MultiValue)

Return the concrete mutable MArray type (defined by StaticArrays.jl) corresponding to the MultiValue type T or array size and type of a.

See also mutable.

source
Gridap.TensorValues.num_indep_componentsFunction
num_indep_components(::Type{<:Number})
num_indep_components(a::Number)

Number of independant components of a Number, that is num_components minus the number of components determined from others by symmetries or constraints.

For example, a TensorValue{3,3} has 9 independant components, a SymTensorValue{3} has 6 and a SymTracelessTensorValue{3} has 5. But they all have 9 (non independant) components.

source
Gridap.TensorValues.indep_components_namesFunction
indep_components_names(::MultiValue)

Return an array of strings containing the component labels in the order they are exported in VTK file.

If all dimensions of the tensor shape S are smaller than 3, the components are named with letters "X","Y" and "Z" similarly to the automatic naming of Paraview. Else, if max(S)>3, they are labeled by integers starting from "1".

source
Gridap.TensorValues.change_eltypeFunction
change_eltype(m::Number,::Type{T2})
change_eltype(M::Type{<:Number},::Type{T2})

For multivalues, returns M or typeof(m) but with the component type (MultiValue's parametric type T) changed to T2.

For scalars (or any non MultiValue number), change_eltype returns T2.

source
Gridap.TensorValues.innerFunction
inner(a::MultiValue{S}, b::MultiValue{S}) -> scalar
a ⊙ b

Inner product of two tensors, that is the full contraction along each indices. The size S of a and b must match.

source
LinearAlgebra.dotFunction
dot(a::MultiValue{Tuple{...,D}}, b::MultiValue{Tuple{D,...}})
a ⋅¹ b
a ⋅ b

Inner product of two tensors a and b, that is the single contraction of the last index of a with the first index of b. The corresponding dimensions D must match. No symmetry is preserved.

source
∇⋅f

Equivalent to

divergence(f)
source
Gridap.TensorValues.double_contractionFunction
double_contraction(a::MultiValue{Tuple{...,D,E}}, b::MultiValue{Tuple{D,E,...})
a ⋅² b

Double contraction of two tensors a and b, along the two last indices of a and two first of b. The corresponding dimensions D and E must match, the contraction order is chosen to be consistent with the inner product of second order tensors.

The double_contraction between second- and/or fourth-order symmetric tensors preserves the symmetry (returns a symmetric tensor type).

source
Gridap.TensorValues.outerFunction
outer(a,b)
a ⊗ b

Outer product (or tensor-product) of two Numbers and/or MultiValues, that is (a⊗b)[i₁,...,iₙ,j₁,...,jₙ] = a[i₁,...,iₙ]*b[j₁,...,jₙ]. This falls back to standard multiplication if a or b is a scalar.

source
outer(∇,f)

Equivalent to

gradient(f)
source
outer(f,∇)

Equivalent to

transpose(gradient(f))
source

Other type specific interfaces

For square second order tensors

Base.invFunction
inv(a::MultiValue{Tuple{D,D}})

Inverse of a second order tensor.

source
Gridap.TensorValues.symmetric_partFunction
symmetric_part(v::MultiValue{Tuple{D,D}})::AbstractSymTensorValue

Return the symmetric part of second order tensor, that is ½(v + vᵀ). Return v if v isa AbstractSymTensorValue.

source

For first order tensors

For second and third order tensors

LinearAlgebra.trFunction
tr(v::MultiValue{Tuple{D1,D2}})

Return the trace of a second order tensor, defined by 0 if D1D2, and Σᵢ vᵢᵢ else.

source
tr(v::MultiValue{Tuple{D1,D1,D2}}) -> ::VectorValue{D2}

Return a vector of length D2 of traces computed on the first two indices: resⱼ = Σᵢ vᵢᵢⱼ.

source

For first and second order tensors

LinearAlgebra.normFunction
norm(u::MultiValue{Tuple{D}})
norm(u::MultiValue{Tuple{D1,D2}})

Euclidean (2-)norm of u, namely sqrt(inner(u,u)).

source
Gridap.TensorValues.measFunction
meas(a::MultiValue{Tuple{D}})
meas(a::MultiValue{Tuple{1,D2}})

Euclidean norm of a vector.

source
meas(J::MultiValue{Tuple{D1,D2}})

Returns the absolute D1-dimensional volume of the parallelepiped formed by the rows of J, that is sqrt(det(J⋅Jᵀ)), or abs(det(J)) if D1=D2. This is used to compute the contribution of the Jacobian matrix J of a changes of variables in integrals.

source

For VectorValue of length 2 and 3

LinearAlgebra.crossFunction
cross(a::VectorValue{3}, b::VectorValue{3}) -> VectorValue{3}
cross(a::VectorValue{2}, b::VectorValue{2}) -> Scalar
a × b

Cross product of 2D and 3D vector.

source
cross(∇,f)

Equivalent to

curl(f)
source

For second order non-traceless and symmetric fourth order tensors

Base.oneFunction
one(::SymFourthOrderTensorValue{D,T}})

Returns the tensor resᵢⱼₖₗ = δᵢₖδⱼₗ(δᵢⱼ + (1-δᵢⱼ)/2).

The scalar type T2 of the result is typeof(one(T)/2).

source