Other operators
Base.invBase.sqrtBase.transposeLinearAlgebra.crossLinearAlgebra.detLinearAlgebra.eigenLinearAlgebra.eigvalsLinearAlgebra.eigvecsLinearAlgebra.normLinearAlgebra.trTensors.devTensors.dotdotTensors.dottTensors.fromvoigtTensors.majorsymmetricTensors.majortransposeTensors.minorsymmetricTensors.minortransposeTensors.rotateTensors.rotation_tensorTensors.skewTensors.symmetricTensors.tdotTensors.tovoigtTensors.tovoigt!Tensors.vol
Transpose-dot
The dot product between the transpose of a tensor with itself. Results in a symmetric tensor.
\[\mathbf{A} = \mathbf{B}^\text{T} \cdot \mathbf{B} \Leftrightarrow A_{ij} = B_{ki}^\text{T} B_{kj} = B_{ik} B_{kj}\]
\[\mathbf{A} = \mathbf{B} \cdot \mathbf{B}^\text{T} \Leftrightarrow A_{ij} = B_{ik} B_{jk}^\text{T} = B_{ik} B_{kj}\]
Tensors.tdot — Function
tdot(A::SecondOrderTensor)Compute the transpose-dot product of A with itself, i.e. dot(A', A). Return a SymmetricTensor.
Examples
julia> A = rand(Tensor{2,3})
3×3 Tensor{2, 3, Float64, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> tdot(A)
3×3 SymmetricTensor{2, 3, Float64, 6}:
0.455498 0.571559 0.855529
0.571559 1.0798 1.3281
0.855529 1.3281 1.78562sourceTensors.dott — Function
dott(A::SecondOrderTensor)Compute the dot-transpose product of A with itself, i.e. dot(A, A'). Return a SymmetricTensor.
Examples
julia> A = rand(Tensor{2,3})
3×3 Tensor{2, 3, Float64, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> dott(A)
3×3 SymmetricTensor{2, 3, Float64, 6}:
1.81438 1.253 0.894897
1.253 1.05904 0.65243
0.894897 0.65243 0.4475sourceNorm
The (2)-norm of a tensor is defined for a vector, second order tensor and fourth order tensor as
\[\|\mathbf{a}\| = \sqrt{\mathbf{a} \cdot \mathbf{a}} \Leftrightarrow \|a_i\| = \sqrt{a_i a_i},\]
\[\|\mathbf{A}\| = \sqrt{\mathbf{A} : \mathbf{A}} \Leftrightarrow \|A_{ij}\| = \sqrt{A_{ij} A_{ij}},\]
\[\|\mathsf{A}\| = \sqrt{\mathsf{A} :: \mathsf{A}} \Leftrightarrow \|A_{ijkl}\| = \sqrt{A_{ijkl} A_{ijkl}}.\]
LinearAlgebra.norm — Function
norm(::Vec)
norm(::SecondOrderTensor)
norm(::FourthOrderTensor)Computes the norm of a tensor.
Examples
julia> A = rand(Tensor{2,3})
3×3 Tensor{2, 3, Float64, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> norm(A)
1.8223398556552728sourceTrace
The trace for a second order tensor is defined as the sum of the diagonal elements. This can be written as
\[\text{tr}(\mathbf{A}) = \mathbf{I} : \mathbf{A} \Leftrightarrow \text{tr}(A_{ij}) = A_{ii}.\]
LinearAlgebra.tr — Function
tr(::SecondOrderTensor)Computes the trace of a second order tensor.
Examples
julia> A = rand(SymmetricTensor{2,3})
3×3 SymmetricTensor{2, 3, Float64, 6}:
0.325977 0.549051 0.218587
0.549051 0.894245 0.353112
0.218587 0.353112 0.394255
julia> tr(A)
1.6144775244804341sourceDeterminant
Determinant for a second order tensor.
LinearAlgebra.det — Function
det(::SecondOrderTensor)Computes the determinant of a second order tensor.
Examples
julia> A = rand(SymmetricTensor{2,3})
3×3 SymmetricTensor{2, 3, Float64, 6}:
0.325977 0.549051 0.218587
0.549051 0.894245 0.353112
0.218587 0.353112 0.394255
julia> det(A)
-0.002539324113350679sourceInverse
Inverse of a second order tensor such that
\[\mathbf{A}^{-1} \cdot \mathbf{A} = \mathbf{I}\]
where $\mathbf{I}$ is the second order identity tensor.
Base.inv — Function
inv(::SecondOrderTensor)Computes the inverse of a second order tensor.
Examples
julia> A = rand(Tensor{2,3})
3×3 Tensor{2, 3, Float64, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> inv(A)
3×3 Tensor{2, 3, Float64, 9}:
-587.685 -279.668 1583.46
-411.743 -199.494 1115.12
588.35 282.819 -1587.79sourceTranspose
Transpose of tensors is defined by changing the order of the tensor's "legs". The transpose of a vector/symmetric tensor is the vector/tensor itself. The transpose of a second order tensor can be written as:
\[A_{ij}^\text{T} = A_{ji}\]
and for a fourth order tensor the minor transpose can be written as
\[A_{ijkl}^\text{t} = A_{jilk}\]
and the major transpose as
\[A_{ijkl}^\text{T} = A_{klij}.\]
Base.transpose — Function
transpose(::Vec)
transpose(::SecondOrderTensor)
transpose(::FourthOrderTensor)Compute the transpose of a tensor. For a fourth order tensor, the transpose is the minor transpose.
Examples
julia> A = rand(Tensor{2,2})
2×2 Tensor{2, 2, Float64, 4}:
0.325977 0.218587
0.549051 0.894245
julia> A'
2×2 Tensor{2, 2, Float64, 4}:
0.325977 0.549051
0.218587 0.894245sourceTensors.minortranspose — Function
Tensors.majortranspose — Function
Symmetric
The symmetric part of a second order tensor is defined by:
\[\mathbf{A}^\text{sym} = \frac{1}{2}(\mathbf{A} + \mathbf{A}^\text{T}) \Leftrightarrow A_{ij}^\text{sym} = \frac{1}{2}(A_{ij} + A_{ji}),\]
The major symmetric part of a fourth order tensor is defined by
\[\mathsf{A}^\text{majsym} = \frac{1}{2}(\mathsf{A} + \mathsf{A}^\text{T}) \Leftrightarrow A_{ijkl}^\text{majsym} = \frac{1}{2}(A_{ijkl} + A_{klij}).\]
The minor symmetric part of a fourth order tensor is defined by
\[A_{ijkl}^\text{minsym} = \frac{1}{4}(A_{ijkl} + A_{ijlk} + A_{jikl} + A_{jilk}).\]
Tensors.symmetric — Function
symmetric(::SecondOrderTensor)
symmetric(::FourthOrderTensor)Computes the (minor) symmetric part of a second or fourth order tensor. Return a SymmetricTensor.
Examples
julia> A = rand(Tensor{2,2})
2×2 Tensor{2, 2, Float64, 4}:
0.325977 0.218587
0.549051 0.894245
julia> symmetric(A)
2×2 SymmetricTensor{2, 2, Float64, 3}:
0.325977 0.383819
0.383819 0.894245sourceTensors.minorsymmetric — Function
minorsymmetric(::FourthOrderTensor)Compute the minor symmetric part of a fourth order tensor, return a SymmetricTensor{4}.
Tensors.majorsymmetric — Function
Skew symmetric
The skew symmetric part of a second order tensor is defined by
\[\mathbf{A}^\text{skw} = \frac{1}{2}(\mathbf{A} - \mathbf{A}^\text{T}) \Leftrightarrow A^\text{skw}_{ij} = \frac{1}{2}(A_{ij} - A_{ji}).\]
The skew symmetric part of a symmetric tensor is zero.
Tensors.skew — Function
skew(::SecondOrderTensor)Computes the skew-symmetric (anti-symmetric) part of a second order tensor, returns a Tensor{2}.
Deviatoric tensor
The deviatoric part of a second order tensor is defined by
\[\mathbf{A}^\text{dev} = \mathbf{A} - \frac{1}{3} \mathrm{tr}[\mathbf{A}] \mathbf{I} \Leftrightarrow A_{ij}^\text{dev} = A_{ij} - \frac{1}{3}A_{kk}\delta_{ij}.\]
Tensors.dev — Function
dev(::SecondOrderTensor)Computes the deviatoric part of a second order tensor.
Examples
julia> A = rand(Tensor{2, 3});
julia> dev(A)
3×3 Tensor{2, 3, Float64, 9}:
-0.065136 0.894245 0.953125
0.549051 -0.0380011 0.795547
0.218587 0.394255 0.103137
julia> tr(dev(A))
5.551115123125783e-17sourceVolumetric tensor
The volumetric part of a second order tensor is defined by
\[\mathbf{A}^\text{vol} = \frac{1}{3} \mathrm{tr}[\mathbf{A}] \mathbf{I} \Leftrightarrow A_{ij}^\text{vol} = \frac{1}{3}A_{kk}\delta_{ij}.\]
Tensors.vol — Function
vol(::SecondOrderTensor)Computes the volumetric part of a second order tensor based on the additive decomposition.
Examples
julia> A = rand(SymmetricTensor{2,3})
3×3 SymmetricTensor{2, 3, Float64, 6}:
0.325977 0.549051 0.218587
0.549051 0.894245 0.353112
0.218587 0.353112 0.394255
julia> vol(A)
3×3 SymmetricTensor{2, 3, Float64, 6}:
0.538159 0.0 0.0
0.0 0.538159 0.0
0.0 0.0 0.538159
julia> vol(A) + dev(A) ≈ A
truesourceCross product
The cross product between two vectors is defined as
\[\mathbf{a} = \mathbf{b} \times \mathbf{c} \Leftrightarrow a_i = \epsilon_{ijk} b_j c_k\]
LinearAlgebra.cross — Function
cross(::Vec, ::Vec)Computes the cross product between two Vec vectors, returns a Vec{3}. For dimensions 1 and 2 the Vec's are expanded to 3D first. The infix operator × (written \times) can also be used.
Examples
julia> a = rand(Vec{3})
3-element Vec{3, Float64}:
0.32597672886359486
0.5490511363155669
0.21858665481883066
julia> b = rand(Vec{3})
3-element Vec{3, Float64}:
0.8942454282009883
0.35311164439921205
0.39425536741585077
julia> a × b
3-element Vec{3, Float64}:
0.13928086435138393
0.0669520417303531
-0.37588028973385323sourceEigenvalues and eigenvectors
The eigenvalues and eigenvectors of a (symmetric) second order tensor, $\mathbf{A}$ can be solved from the eigenvalue problem
\[\mathbf{A} \cdot \mathbf{v}_i = \lambda_i \mathbf{v}_i \qquad i = 1, \dots, \text{dim}\]
where $\lambda_i$ are the eigenvalues and $\mathbf{v}_i$ are the corresponding eigenvectors. For a symmetric fourth order tensor, $\mathsf{A}$ the second order eigentensors and eigenvalues can be solved from
\[\mathsf{A} : \mathbf{V}_i = \lambda_i \mathbf{V}_i \qquad i = 1, \dots, \text{dim}\]
where $\lambda_i$ are the eigenvalues and $\mathbf{V}_i$ the corresponding eigentensors.
LinearAlgebra.eigen — Function
eigen(A::SymmetricTensor{2})Compute the eigenvalues and eigenvectors of a symmetric second order tensor and return an Eigen object. The eigenvalues are stored in a Vec, sorted in ascending order. The corresponding eigenvectors are stored as the columns of a Tensor.
Examples
julia> A = rand(SymmetricTensor{2, 2});
julia> E = eigen(A);
julia> E.values
2-element Vec{2, Float64}:
-0.27938877799585415
0.8239521616782797
julia> E.vectors
2×2 Tensor{2, 2, Float64, 4}:
-0.671814 0.74072
0.74072 0.671814sourceLinearAlgebra.eigvals — Function
LinearAlgebra.eigvecs — Function
Tensor square root
Square root of a symmetric positive definite second order tensor $S$, defined such that
\[\sqrt{\mathbf{S}} \cdot \sqrt{\mathbf{S}} = S.\]
Base.sqrt — Function
sqrt(S::SymmetricTensor{2})Calculate the square root of the positive definite symmetric second order tensor S, such that √S ⋅ √S == S.
Examples
julia> S = rand(SymmetricTensor{2,2}); S = tdot(S)
2×2 SymmetricTensor{2, 2, Float64, 3}:
0.407718 0.298993
0.298993 0.349237
julia> sqrt(S)
2×2 SymmetricTensor{2, 2, Float64, 3}:
0.578172 0.270989
0.270989 0.525169
julia> √S ⋅ √S ≈ S
truesourceRotations
Tensors.rotate — Function
rotate(x::AbstractTensor{3}, u::Vec{3}, θ::Number)Rotate a three dimensional tensor x around the vector u a total of θ radians.
Examples
julia> x = Vec{3}((0.0, 0.0, 1.0));
julia> u = Vec{3}((0.0, 1.0, 0.0));
julia> rotate(x, u, π/2)
3-element Vec{3, Float64}:
1.0
0.0
6.123233995736766e-17sourcerotate(x::AbstractTensor{2}, θ::Number)Rotate a two dimensional tensor x θ radians around the out-of-plane axis.
Examples
julia> x = Vec{2}((0.0, 1.0));
julia> rotate(x, π/4)
2-element Vec{2, Float64}:
-0.7071067811865475
0.7071067811865476sourceTensors.rotation_tensor — Function
rotation_tensor(θ::Number)Return the two-dimensional rotation matrix corresponding to rotation of θ radians around the out-of-plane axis (i.e. around (0, 0, 1)).
rotation_tensor(ψ::Number, θ::Number, ϕ::Number)Return the three-dimensional rotation matrix corresponding to the rotation described by the three Euler angles $ψ$, $θ$, $ϕ$.
\[R(ψ,θ,ϕ) = R_x(ψ)R_y(θ)R_z(ϕ)\]
see e.g. http://eecs.qmul.ac.uk/~gslabaugh/publications/euler.pdf for a complete description.
Note that the gimbal lock phenomena can occur when using this rotation tensor parametrization.
sourcerotation_tensor(u::Vec{3}, θ::Number)Return the three-dimensional rotation matrix corresponding to rotation of θ radians around the vector u.
Special operations
For computing a special dot product between two vectors $\mathbf{a}$ and $\mathbf{b}$ with a fourth order symmetric tensor $\mathbf{C}$ such that $a_k C_{ikjl} b_l$ there is dotdot(a, C, b). This function is useful because it is the expression for the tangent matrix in continuum mechanics when the displacements are approximated by scalar shape functions.
Tensors.dotdot — Function
dotdot(::Vec, ::SymmetricFourthOrderTensor, ::Vec)Computes a special dot product between two vectors and a symmetric fourth order tensor such that $a_k C_{ikjl} b_l$.
sourceVoigt format
For some operations it is convenient to easily switch to the so called "Voigt"-format. For example when solving a local problem in a plasticity model. To simplify the conversion between tensors and Voigt format, see tovoigt, tovoigt! and fromvoigt documented below. Care must be exercised when combined with differentiation, see Differentiation of Voigt format further down.
Tensors.tovoigt — Function
tovoigt([type::Type{<:AbstractArray}, ]A::Union{SecondOrderTensor, FourthOrderTensor}; kwargs...)Converts a tensor to "Voigt"-format.
Optional argument:
type: determines the returned Array type. Possible types areArrayandSArray(seeStaticArrays).
Keyword arguments:
offdiagscale: determines the scaling factor for the offdiagonal elements. This argument is only applicable forSymmetricTensors.tomandelcan also be used for the "Mandel"-format which setsoffdiagscale = √2forSymmetricTensors, and is equivalent totovoigtforTensors.order: matrix of the linear indices determining the Voigt order. The default index order is[11, 22, 33, 23, 13, 12, 32, 31, 21], corresponding toorder = [1 6 5; 9 2 4; 8 7 3].
See also tovoigt! and fromvoigt.
julia> tovoigt(Tensor{2,3}(1:9))
9-element Vector{Int64}:
1
5
9
8
7
4
6
3
2
julia> tovoigt(SymmetricTensor{2,3}(1:6); offdiagscale = 2)
6-element Vector{Int64}:
1
4
6
10
6
4
julia> tovoigt(Tensor{4,2}(1:16))
4×4 Matrix{Int64}:
1 13 9 5
4 16 12 8
3 15 11 7
2 14 10 6
julia> using StaticArrays: SMatrix
julia> tovoigt(SMatrix, Tensor{4,2}(1:16))
4×4 SMatrix{4, 4, Int64, 16} with indices SOneTo(4)×SOneTo(4):
1 13 9 5
4 16 12 8
3 15 11 7
2 14 10 6sourceTensors.tovoigt! — Function
tovoigt!(v::AbstractArray, A::Union{SecondOrderTensor, FourthOrderTensor}; kwargs...)Converts a tensor to "Voigt"-format using the following index order: [11, 22, 33, 23, 13, 12, 32, 31, 21].
Keyword arguments:
offset: offset index for where in the arrayAthe tensor should be stored. For 4th order tensors the keyword arguments areoffset_iandoffset_j, respectively. Defaults to0.offdiagscale: determines the scaling factor for the offdiagonal elements. This argument is only applicable forSymmetricTensors.frommandel!can also be used for the "Mandel"-format which setsoffdiagscale = √2forSymmetricTensors, and is equivalent tofromvoigt!forTensors.order: matrix of the linear indices determining the Voigt order. The default index order is[11, 22, 33, 23, 13, 12, 32, 31, 21].
See also tovoigt and fromvoigt.
julia> T = rand(Tensor{2,2})
2×2 Tensor{2, 2, Float64, 4}:
0.325977 0.218587
0.549051 0.894245
julia> x = zeros(4);
julia> tovoigt!(x, T)
4-element Vector{Float64}:
0.32597672886359486
0.8942454282009883
0.21858665481883066
0.5490511363155669
julia> x = zeros(5);
julia> tovoigt!(x, T; offset=1)
5-element Vector{Float64}:
0.0
0.32597672886359486
0.8942454282009883
0.21858665481883066
0.5490511363155669sourceTensors.fromvoigt — Function
fromvoigt(S::Type{<:AbstractTensor}, A::AbstractArray{T}; kwargs...)Converts an array A stored in Voigt format to a Tensor of type S.
Keyword arguments:
offset: offset index for where in the arrayAthe tensor starts. For 4th order tensors the keyword arguments areoffset_iandoffset_j, respectively. Defaults to0.offdiagscale: determines the scaling factor for the offdiagonal elements. This argument is only applicable forSymmetricTensors.frommandelcan also be used for the "Mandel"-format which setsoffdiagscale = √2forSymmetricTensors, and is equivalent tofromvoigtforTensors.order: matrix of the linear indices determining the Voigt order. The default index order is[11, 22, 33, 23, 13, 12, 32, 31, 21], corresponding toorder = [1 6 5; 9 2 4; 8 7 3].
See also tovoigt.
julia> fromvoigt(Tensor{2,3}, 1.0:1.0:9.0)
3×3 Tensor{2, 3, Float64, 9}:
1.0 6.0 5.0
9.0 2.0 4.0
8.0 7.0 3.0sourceDifferentiation of Voigt format
Differentiating with a Voigt representation of a symmetric tensor may lead to incorrect results when converted back to tensors. The tomandel, tomandel!, and frommandel versions of tovoigt, tovoigt!, and fromvoigt can then be used. As illustrated by the following example, this will give the correct result. In general, however, direct differentiation of Tensors is faster (see Automatic Differentiation).
julia> using Tensors, ForwardDiff
julia> fun(X::SymmetricTensor{2}) = X;
julia> A = rand(SymmetricTensor{2,2});Differentiation of a tensor directly (correct):
julia> tovoigt(gradient(fun, A))
3×3 Matrix{Float64}:
1.0 0.0 0.0
0.0 1.0 0.0
0.0 0.0 0.5Converting to Voigt format, perform differentiation, convert back (WRONG!):
julia> ForwardDiff.jacobian(
v -> tovoigt(fun(fromvoigt(SymmetricTensor{2,2}, v))),
tovoigt(A)
)
3×3 Matrix{Float64}:
1.0 0.0 0.0
0.0 1.0 0.0
0.0 0.0 1.0Converting to Mandel format, perform differentiation, convert back (correct)
julia> tovoigt(
frommandel(SymmetricTensor{4,2},
ForwardDiff.jacobian(
v -> tomandel(fun(frommandel(SymmetricTensor{2,2}, v))),
tomandel(A)
)
)
)
3×3 Matrix{Float64}:
1.0 0.0 0.0
0.0 1.0 0.0
0.0 0.0 0.5