Gridap.TensorValues
This module provides the abstract interface MultiValue
representing tensors that are also Number
s, along with concrete implementations for the following tensors:
- 1st order
VectorValue
, - 2nd order
TensorValue
, - 2nd order and symmetric
SymTensorValue
, - 2nd order, symmetric and traceless
SymTracelessTensorValue
, - 3rd order
ThirdOrderTensorValue
, - 4th order and symmetric
SymFourthOrderTensorValue
.
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)
MultiValue
s 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.VectorValue
— TypeVectorValue{D,T} <: MultiValue{Tuple{D},T,1,D}
Type representing a first-order tensor, that is a vector, of length D
.
Gridap.TensorValues.TensorValue
— TypeTensorValue{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.
Gridap.TensorValues.SymTensorValue
— TypeSymTensorValue{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
.
Gridap.TensorValues.SymTracelessTensorValue
— TypeSymTracelessTensorValue{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
.
Gridap.TensorValues.ThirdOrderTensorValue
— TypeThirdOrderTensorValue{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.
Gridap.TensorValues.SymFourthOrderTensorValue
— TypeSymFourthOrderTensorValue{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
.
Abstract tensor types
Gridap.TensorValues.MultiValue
— TypeMultiValue{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 ofNumber
,N
is the order of the tensor, the length ofS
,L
is the number of components stored internally.
MultiValue
s are immutable.
Gridap.TensorValues.AbstractSymTensorValue
— TypeAbstractSymTensorValue{D,T,L} <: MultiValue{Tuple{D,D},T,2,L}
Abstract type representing any symmetric second-order D
×D
tensor, with symmetry ij↔ji.
See also SymTensorValue
, SymTracelessTensorValue
.
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_components
— Functionnum_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
.
Gridap.TensorValues.mutable
— Functionmutable(a::MultiValue)
Converts a
into a mutable array of type MArray
defined by StaticArrays.jl
.
See also Mutable
.
Gridap.TensorValues.Mutable
— FunctionMutable(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
.
Gridap.TensorValues.num_indep_components
— Functionnum_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.
Gridap.TensorValues.indep_comp_getindex
— Functionindep_comp_getindex(a::Number,i)
Get the i
th independent component of a
. It only differs from getindex(a,i)
when the components of a
are interdependant, see num_indep_components
. i
should be in 1:num_indep_components(a)
.
Gridap.TensorValues.indep_components_names
— Functionindep_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".
Gridap.TensorValues.change_eltype
— Functionchange_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.
Gridap.TensorValues.inner
— Functioninner(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.
LinearAlgebra.dot
— Functiondot(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.
∇⋅f
Equivalent to
divergence(f)
Gridap.TensorValues.double_contraction
— Functiondouble_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).
Gridap.TensorValues.outer
— Functionouter(a,b)
a ⊗ b
Outer product (or tensor-product) of two Number
s and/or MultiValue
s, 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.
outer(∇,f)
Equivalent to
gradient(f)
outer(f,∇)
Equivalent to
transpose(gradient(f))
Other type specific interfaces
For square second order tensors
LinearAlgebra.det
— Functiondet(a::MultiValue{Tuple{D,D},T})
Determinent of square second order tensors.
Base.inv
— Functioninv(a::MultiValue{Tuple{D,D}})
Inverse of a second order tensor.
Gridap.TensorValues.symmetric_part
— Functionsymmetric_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
.
For first order tensors
Gridap.TensorValues.diagonal_tensor
— Functiondiagonal_tensor(v::VectorValue{D,T}) -> ::TensorValue{D,D,T}
Return a diagonal D
×D
tensor with diagonal containing the elements of v
.
For second and third order tensors
LinearAlgebra.tr
— Functiontr(v::MultiValue{Tuple{D1,D2}})
Return the trace of a second order tensor, defined by 0
if D1
≠D2
, and Σᵢ vᵢᵢ
else.
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ᵢᵢⱼ
.
For first and second order tensors
LinearAlgebra.norm
— Functionnorm(u::MultiValue{Tuple{D}})
norm(u::MultiValue{Tuple{D1,D2}})
Euclidean (2-)norm of u
, namely sqrt(inner(u,u))
.
Gridap.TensorValues.meas
— Functionmeas(a::MultiValue{Tuple{D}})
meas(a::MultiValue{Tuple{1,D2}})
Euclidean norm of a vector.
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.
For VectorValue
of length 2 and 3
LinearAlgebra.cross
— Functioncross(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.
cross(∇,f)
Equivalent to
curl(f)
For second order non-traceless and symmetric fourth order tensors
Base.one
— Functionone(::SymFourthOrderTensorValue{D,T}})
Returns the tensor resᵢⱼₖₗ = δᵢₖδⱼₗ(δᵢⱼ + (1-δᵢⱼ)/2)
.
The scalar type T2
of the result is typeof(one(T)/2)
.