Tensors
A tensor, parametrized by an order and a dimension, is in general defined by
- an array or a set of condensed parameters (e.g. isotropic tensors),
- a basis,
- a set of variances (covariant
:cov
or contravariant:cont
) useful if the basis is not orthonormal.
In practice, the type of basis conditions the type of tensor (TensCanonical
, TensRotated
, TensOrthogonal
, Tens
or even TensISO
in case of isotropic tensor).
julia> ℬ = Basis(Sym[0 1 1; 1 0 1; 1 1 0])
Basis{3, Sym}
→ basis: 3×3 Matrix{Sym}:
0 1 1
1 0 1
1 1 0
→ dual basis: 3×3 Matrix{Sym}:
-1/2 1/2 1/2
1/2 -1/2 1/2
1/2 1/2 -1/2
→ covariant metric tensor: 3×3 Symmetric{Sym, Matrix{Sym}}:
2 1 1
1 2 1
1 1 2
→ contravariant metric tensor: 3×3 Symmetric{Sym, Matrix{Sym}}:
3/4 -1/4 -1/4
-1/4 3/4 -1/4
-1/4 -1/4 3/4
julia> V = Tens(Tensor{1,3}(i -> symbols("v$i", real = true)))
(v1)𝐞¹ + (v2)𝐞² + (v3)𝐞³
julia> components(V, ℬ, (:cont,))
3-element Vector{Sym}:
-v1/2 + v2/2 + v3/2
v1/2 - v2/2 + v3/2
v1/2 + v2/2 - v3/2
julia> components(V, ℬ, (:cov,))
3-element Vector{Sym}:
v₂ + v₃
v₁ + v₃
v₁ + v₂
julia> ℬ̄ = normalize(ℬ)
Basis{3, Sym}
→ basis: 3×3 Matrix{Sym}:
0 sqrt(2)/2 sqrt(2)/2
sqrt(2)/2 0 sqrt(2)/2
sqrt(2)/2 sqrt(2)/2 0
→ dual basis: 3×3 Matrix{Sym}:
-sqrt(2)/2 sqrt(2)/2 sqrt(2)/2
sqrt(2)/2 -sqrt(2)/2 sqrt(2)/2
sqrt(2)/2 sqrt(2)/2 -sqrt(2)/2
→ covariant metric tensor: 3×3 Symmetric{Sym, Matrix{Sym}}:
1 1/2 1/2
1/2 1 1/2
1/2 1/2 1
→ contravariant metric tensor: 3×3 Symmetric{Sym, Matrix{Sym}}:
3/2 -1/2 -1/2
-1/2 3/2 -1/2
-1/2 -1/2 3/2
julia> components(V, ℬ̄, (:cov,))
3-element Vector{Sym}:
sqrt(2)*v2/2 + sqrt(2)*v3/2
sqrt(2)*v1/2 + sqrt(2)*v3/2
sqrt(2)*v1/2 + sqrt(2)*v2/2
julia> T = Tens(Tensor{2,3}((i, j) -> symbols("t$i$j", real = true)))
(t11)𝐞¹⊗𝐞¹ + (t21)𝐞²⊗𝐞¹ + (t31)𝐞³⊗𝐞¹ + (t12)𝐞¹⊗𝐞² + (t22)𝐞²⊗𝐞² + (t32)𝐞³⊗𝐞² + (t13)𝐞¹⊗𝐞³ + (t23)𝐞²⊗𝐞³ + (t33)𝐞³⊗𝐞³
julia> components(T, ℬ, (:cov, :cov))
3×3 Matrix{Sym}:
t₂₂ + t₂₃ + t₃₂ + t₃₃ t₂₁ + t₂₃ + t₃₁ + t₃₃ t₂₁ + t₂₂ + t₃₁ + t₃₂
t₁₂ + t₁₃ + t₃₂ + t₃₃ t₁₁ + t₁₃ + t₃₁ + t₃₃ t₁₁ + t₁₂ + t₃₁ + t₃₂
t₁₂ + t₁₃ + t₂₂ + t₂₃ t₁₁ + t₁₃ + t₂₁ + t₂₃ t₁₁ + t₁₂ + t₂₁ + t₂₂
julia> factor(simplify(components(T, ℬ, (:cont, :cov))))
3×3 Matrix{Sym}:
-(t12 + t13 - t22 - t23 - t32 - t33)/2 -(t11 + t13 - t21 - t23 - t31 - t33)/2 -(t11 + t12 - t21 - t22 - t31 - t32)/2
(t12 + t13 - t22 - t23 + t32 + t33)/2 (t11 + t13 - t21 - t23 + t31 + t33)/2 (t11 + t12 - t21 - t22 + t31 + t32)/2
(t12 + t13 + t22 + t23 - t32 - t33)/2 (t11 + t13 + t21 + t23 - t31 - t33)/2 (t11 + t12 + t21 + t22 - t31 - t32)/2
Special tensors are available
tensId2(::Val{dim} = Val(3), ::Val{T} = Val(Sym)) where {dim,T<:Number}
: second-order identity (𝟏ᵢⱼ = δᵢⱼ = 1 if i=j otherwise 0
)tensId4(::Val{dim} = Val(3), ::Val{T} = Val(Sym)) where {dim,T<:Number}
: fourth-order identity with minor symmetries (𝕀 = 𝟏 ⊠ˢ 𝟏
i.e.(𝕀)ᵢⱼₖₗ = (δᵢₖδⱼₗ+δᵢₗδⱼₖ)/2
)tensJ4(::Val{dim} = Val(3), ::Val{T} = Val(Sym)) where {dim,T<:Number}
: fourth-order spherical projector (𝕁 = (𝟏 ⊗ 𝟏) / dim
i.e.(𝕁)ᵢⱼₖₗ = δᵢⱼδₖₗ/dim
)tensK4(::Val{dim} = Val(3), ::Val{T} = Val(Sym)) where {dim,T<:Number}
: fourth-order deviatoric projector (𝕂 = 𝕀 - 𝕁
i.e.(𝕂)ᵢⱼₖₗ = (δᵢₖδⱼₗ+δᵢₗδⱼₖ)/2 - δᵢⱼδₖₗ/dim
)ISO(::Val{dim} = Val(3), ::Val{T} = Val(Sym)) where {dim,T<:Number}
: returns𝕀, 𝕁, 𝕂
The useful tensor products are the following:
⊗
tensor product⊗ˢ
symmetrized tensor product⊠
modified tensor product⊠ˢ
symmetrized modified tensor product⋅
contracted product⊡
double contracted product⊙
quadruple contracted product
NOTE: more information about modified tensor products can be found in Sébastien Brisard's blog.
julia> 𝟏 = tensId2(3, Sym)
(1) 𝟏
julia> 𝕀, 𝕁, 𝕂 = ISO(3, Sym) ;
julia> 𝕀 == 𝟏 ⊠ˢ 𝟏
true
julia> 𝕁 == (𝟏 ⊗ 𝟏)/3
true
julia> a = Tens(Vec{3}((i,) -> symbols("a$i", real = true))) ;
julia> b = Tens(Vec{3}((i,) -> symbols("b$i", real = true))) ;
julia> a ⊗ b
(a1*b1)𝐞¹⊗𝐞¹ + (a2*b1)𝐞²⊗𝐞¹ + (a3*b1)𝐞³⊗𝐞¹ + (a1*b2)𝐞¹⊗𝐞² + (a2*b2)𝐞²⊗𝐞² + (a3*b2)𝐞³⊗𝐞² + (a1*b3)𝐞¹⊗𝐞³ + (a2*b3)𝐞²⊗𝐞³ + (a3*b3)𝐞³⊗𝐞³
julia> a ⊗ˢ b
(a1*b1)𝐞¹⊗𝐞¹ + (a1*b2/2 + a2*b1/2)𝐞²⊗𝐞¹ + (a1*b3/2 + a3*b1/2)𝐞³⊗𝐞¹ + (a1*b2/2 + a2*b1/2)𝐞¹⊗𝐞² + (a2*b2)𝐞²⊗𝐞² + (a2*b3/2 + a3*b2/2)𝐞³⊗𝐞² + (a1*b3/2 + a3*b1/2)𝐞¹⊗𝐞³
+ (a2*b3/2 + a3*b2/2)𝐞²⊗𝐞³ + (a3*b3)𝐞³⊗𝐞³
julia> (θ, ϕ, r), (𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ), ℬˢ = init_spherical()
((θ, ϕ, r), (Sym[1, 0, 0], Sym[0, 1, 0], Sym[0, 0, 1]), Sym[cos(θ)*cos(ϕ) -sin(ϕ) sin(θ)*cos(ϕ); sin(ϕ)*cos(θ) cos(ϕ) sin(θ)*sin(ϕ); -sin(θ) 0 cos(θ)])
julia> R = rot3(θ, ϕ)
3×3 RotZYZ{Sym} with indices SOneTo(3)×SOneTo(3)(ϕ, θ, 0):
cos(θ)⋅cos(ϕ) -sin(ϕ) sin(θ)⋅cos(ϕ)
sin(ϕ)⋅cos(θ) cos(ϕ) sin(θ)⋅sin(ϕ)
-sin(θ) 0 cos(θ)
julia> A = Tens(R * a)
(a1*cos(θ)*cos(ϕ) - a2*sin(ϕ) + a3*sin(θ)*cos(ϕ))𝐞¹ + (a1*sin(ϕ)*cos(θ) + a2*cos(ϕ) + a3*sin(θ)*sin(ϕ))𝐞² + (-a1*sin(θ) + a3*cos(θ))𝐞³
julia> simplify(change_tens(A, ℬˢ))
(a1)𝐞¹ + (a2)𝐞² + (a3)𝐞³