Operations
Basic operations
LinearAlgebra.cross
— Functioncross(x::Vec, y::Vec)
x × y
Compute the cross product between two vectors. The infix operation x × y
(where ×
can be typed by \times<tab>
) is a synonym for cross(x, y)
.
Examples
julia> x = rand(Vec{3})
3-element Vec{3, Float64}:
0.32597672886359486
0.5490511363155669
0.21858665481883066
julia> y = rand(Vec{3})
3-element Vec{3, Float64}:
0.8942454282009883
0.35311164439921205
0.39425536741585077
julia> x × y
3-element Vec{3, Float64}:
0.13928086435138393
0.0669520417303531
-0.37588028973385323
LinearAlgebra.norm
— Functionnorm(::AbstractTensor)
Compute norm of a tensor.
Examples
julia> x = rand(Mat{3, 3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> norm(x)
1.8223398556552728
LinearAlgebra.normalize
— Functionnormalize(x)
Compute x / norm(x)
.
LinearAlgebra.tr
— Functiontr(A)
Compute the trace of a square tensor A
.
Examples
julia> A = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> tr(A)
1.1733382401532275
Base.inv
— Functioninv(A)
Compute the inverse of a tensor A
.
Examples
julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> inv(x) * x ≈ one(x)
true
julia> A = rand(SymmetricFourthOrderTensor{3});
julia> A ⊡₂ inv(A) ≈ one(A)
true
Tensor operations
Tensorial.contract
— Functioncontract(x, y, ::Val{N})
Conduct contraction of N
inner indices. For example, N=2
contraction for third-order tensors $A_{ij} = B_{ikl} C_{klj}$ can be computed as follows:
Examples
julia> B = rand(Tensor{Tuple{3,3,3}});
julia> C = rand(Tensor{Tuple{3,3,3}});
julia> A = contract(B, C, Val(2))
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
3.70978 2.47156 3.91807
2.90966 2.30881 3.25965
1.78391 1.38714 2.2079
The following infix operators are also available for specific contractions:
x ⊡ y
(where⊡
can be typed by\boxdot<tab>
):contract(x, y, Val(1))
x ⊡₂ y
(where⊡₂
can be typed by\boxdot<tab>\_2<tab>
):contract(x, y, Val(2))
x ⊗ y
(where⊗
can be typed by\otimes<tab>
):contract(x, y, Val(0))
contract(x, y, Val(xdims), Val(ydims))
Perform contraction over the given dimensions.
Examples
julia> A = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> B = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.748415 0.00744801 0.682533
0.578232 0.199377 0.956741
0.727935 0.439243 0.647855
julia> contract(A, B, Val(1), Val(2)) ≈ @einsum C[i,j] := A[k,i] * B[j,k]
true
julia> contract(A, B, Val((1,2)), Val((2,1))) ≈ @einsum c := A[i,j] * B[j,i]
true
TensorCore.tensor
— Functiontensor(x::AbstractTensor, y::AbstractTensor)
x ⊗ y
Compute tensor product such as $A_{ij} = x_i y_j$. x ⊗ y
(where ⊗
can be typed by \otimes<tab>
) is a synonym for tensor(x, y)
.
Examples
julia> x = rand(Vec{3})
3-element Vec{3, Float64}:
0.32597672886359486
0.5490511363155669
0.21858665481883066
julia> y = rand(Vec{3})
3-element Vec{3, Float64}:
0.8942454282009883
0.35311164439921205
0.39425536741585077
julia> A = x ⊗ y
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.291503 0.115106 0.128518
0.490986 0.193876 0.216466
0.19547 0.0771855 0.086179
Base.:^
— Functionx^⊗(n)
n
-fold tensor product of a tensor x
.
Examples
julia> x = rand(Vec{2})
2-element Vec{2, Float64}:
0.32597672886359486
0.5490511363155669
julia> x^⊗(3)
2×2×2 Tensor{Tuple{Symmetry{Tuple{2, 2, 2}}}, Float64, 3, 4}:
[:, :, 1] =
0.0346386 0.0583426
0.0583426 0.098268
[:, :, 2] =
0.0583426 0.098268
0.098268 0.165515
Tensorial.@einsum
— Macro@einsum [TensorType] expr
Performs tensor computations using the Einstein summation convention. Since @einsum
cannot fully infer tensor symmetries, it is possible to annotate the returned tensor type (though this is not checked for correctness). This can help eliminate the computation of the symmetric part, improving performance.
Examples
julia> A = rand(Mat{3,3});
julia> B = rand(Mat{3,3});
julia> (@einsum C[i,j] := A[j,k] * B[k,i]) ≈ (A * B)'
true
julia> (@einsum c := A[i,j] * A[i,j]) ≈ A ⋅ A
true
julia> (@einsum SymmetricSecondOrderTensor{3} D[i,j] := A[k,i] * A[k,j]) ≈ A' * A
true
Symmetry
Tensorial.symmetric
— Functionsymmetric(::AbstractSecondOrderTensor)
symmetric(::AbstractSecondOrderTensor, uplo)
Compute the symmetric part of a second order tensor.
Examples
julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> symmetric(x)
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
0.325977 0.721648 0.585856
0.721648 0.353112 0.594901
0.585856 0.594901 0.49425
julia> symmetric(x, :U)
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
0.325977 0.894245 0.953125
0.894245 0.353112 0.795547
0.953125 0.795547 0.49425
Tensorial.skew
— Functionskew(A)
Compute skew-symmetric (anti-symmetric) part of a second order tensor.
Examples
julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> symmetric(x) + skew(x) ≈ x
true
skew(ω::Vec{3})
Construct a skew-symmetric (anti-symmetric) tensor W
from a vector ω
as
\[\bm{\omega} = \begin{Bmatrix} \omega_1 \\ \omega_2 \\ \omega_3 \end{Bmatrix}, \quad \bm{W} = \begin{bmatrix} 0 & -\omega_3 & \omega_2 \\ \omega_3 & 0 & -\omega_1 \\ -\omega_2 & \omega_1 & 0 \end{bmatrix}\]
Examples
julia> skew(Vec(1,2,3))
3×3 Tensor{Tuple{3, 3}, Int64, 2, 9}:
0 -3 2
3 0 -1
-2 1 0
Tensorial.minorsymmetric
— Functionminorsymmetric(::AbstractFourthOrderTensor) -> SymmetricFourthOrderTensor
Compute the minor symmetric part of a fourth order tensor.
Examples
julia> x = rand(Tensor{Tuple{3,3,3,3}});
julia> minorsymmetric(x) ≈ @einsum y[i,j,k,l] := (x[i,j,k,l] + x[j,i,k,l] + x[i,j,l,k] + x[j,i,l,k]) / 4
true
Rotation
Tensorial.rotmatx
— Functionrotmatx(θ::Number)
Construct rotation matrix around x
axis.
\[\bm{R}_x = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos{\theta} & -\sin{\theta} \\ 0 & \sin{\theta} & \cos{\theta} \end{bmatrix}\]
Tensorial.rotmaty
— Functionrotmaty(θ::Number)
Construct rotation matrix around y
axis.
\[\bm{R}_y = \begin{bmatrix} \cos{\theta} & 0 & \sin{\theta} \\ 0 & 1 & 0 \\ -\sin{\theta} & 0 & \cos{\theta} \end{bmatrix}\]
Tensorial.rotmatz
— Functionrotmatz(θ::Number)
Construct rotation matrix around z
axis.
\[\bm{R}_z = \begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0 \\ \sin{\theta} & \cos{\theta} & 0 \\ 0 & 0 & 1 \end{bmatrix}\]
Tensorial.rotmat
— Functionrotmat(θ::Number)
Construct 2D rotation matrix.
\[\bm{R} = \begin{bmatrix} \cos{\theta} & -\sin{\theta} \\ \sin{\theta} & \cos{\theta} \end{bmatrix}\]
Examples
julia> rotmat(deg2rad(30))
2×2 Tensor{Tuple{2, 2}, Float64, 2, 4}:
0.866025 -0.5
0.5 0.866025
rotmat(θ::Vec{3}; sequence::Symbol)
Convert Euler angles to rotation matrix. Use 3 characters belonging to the set (X, Y, Z) for intrinsic rotations, or (x, y, z) for extrinsic rotations.
Examples
julia> α, β, γ = map(deg2rad, rand(3));
julia> rotmat(Vec(α,β,γ), sequence = :XYZ) ≈ rotmatx(α) * rotmaty(β) * rotmatz(γ)
true
julia> rotmat(Vec(α,β,γ), sequence = :xyz) ≈ rotmatz(γ) * rotmaty(β) * rotmatx(α)
true
julia> rotmat(Vec(α,β,γ), sequence = :XYZ) ≈ rotmat(Vec(γ,β,α), sequence = :zyx)
true
rotmat(a => b)
Construct rotation matrix rotating vector a
to b
. The norms of two vectors must be the same.
Examples
julia> a = normalize(rand(Vec{3}))
3-element Vec{3, Float64}:
0.4829957515506539
0.8135223859352438
0.3238771859304809
julia> b = normalize(rand(Vec{3}))
3-element Vec{3, Float64}:
0.8605677447967596
0.3398133016944055
0.3794075336718636
julia> R = rotmat(a => b)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
-0.00540771 0.853773 0.520617
0.853773 -0.267108 0.446905
0.520617 0.446905 -0.727485
julia> R * a ≈ b
true
rotmat(θ, n::Vec)
Construct rotation matrix from angle θ
and axis n
.
Examples
julia> x = Vec(1.0, 0.0, 0.0)
3-element Vec{3, Float64}:
1.0
0.0
0.0
julia> n = Vec(0.0, 0.0, 1.0)
3-element Vec{3, Float64}:
0.0
0.0
1.0
julia> rotmat(π/2, n) * x
3-element Vec{3, Float64}:
6.123233995736766e-17
1.0
0.0
rotmat(::Quaternion)
Construct rotation matrix from quaternion.
Examples
julia> q = quaternion(π/4, Vec(0,0,1))
0.9238795325112867 + 0.0𝙞 + 0.0𝙟 + 0.3826834323650898𝙠
julia> rotmat(q)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.707107 -0.707107 0.0
0.707107 0.707107 0.0
0.0 0.0 1.0
Tensorial.rotate
— Functionrotate(x, R::SecondOrderTensor)
Rotate x
using the rotation matrix R
. This function preserves the symmetry of the matrix.
Examples
julia> R = rotmatz(π/4)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.707107 -0.707107 0.0
0.707107 0.707107 0.0
0.0 0.0 1.0
julia> rotate(Vec(1,0,0), R)
3-element Vec{3, Float64}:
0.7071067811865476
0.7071067811865475
0.0
julia> A = rand(SymmetricSecondOrderTensor{3})
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
0.325977 0.549051 0.218587
0.549051 0.894245 0.353112
0.218587 0.353112 0.394255
julia> rotate(A, R) ≈ R * A * R'
true
rotate(x::Vec, q::Quaternion)
Rotate x
by quaternion q
.
Examples
julia> v = Vec(1.0, 0.0, 0.0)
3-element Vec{3, Float64}:
1.0
0.0
0.0
julia> rotate(v, quaternion(π/4, Vec(0,0,1)))
3-element Vec{3, Float64}:
0.7071067811865475
0.7071067811865476
0.0
Continuum mechanics
Tensorial.vol
— Methodvol(A)
Compute the volumetric part of a square tensor A
. This is only available in 3D.
Examples
julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> vol(x)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.391113 0.0 0.0
0.0 0.391113 0.0
0.0 0.0 0.391113
julia> vol(x) + dev(x) ≈ x
true
Tensorial.dev
— Methoddev(::AbstractSecondOrderTensor{3})
dev(::AbstractSymmetricSecondOrderTensor{3})
Compute the deviatoric part of a square tensor. This is only available in 3D.
Examples
julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> dev(x)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
-0.065136 0.894245 0.953125
0.549051 -0.0380011 0.795547
0.218587 0.394255 0.103137
julia> tr(dev(x))
5.551115123125783e-17
Tensorial.vonmises
— Functionvonmises(::AbstractSymmetricSecondOrderTensor{3})
Compute the von Mises stress.
\[q = \sqrt{\frac{3}{2} \mathrm{dev}(\bm{\sigma}) : \mathrm{dev}(\bm{\sigma})} = \sqrt{3J_2}\]
Examples
julia> σ = rand(SymmetricSecondOrderTensor{3})
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
0.325977 0.549051 0.218587
0.549051 0.894245 0.353112
0.218587 0.353112 0.394255
julia> vonmises(σ)
1.3078860814690232
Tensorial.stress_invariants
— Functionstress_invariants(::AbstractSecondOrderTensor{3})
stress_invariants(::AbstractSymmetricSecondOrderTensor{3})
stress_invariants(::Vec{3})
Return a tuple storing stress invariants.
\[\begin{aligned} I_1(\bm{\sigma}) &= \mathrm{tr}(\bm{\sigma}) \\ I_2(\bm{\sigma}) &= \frac{1}{2} (\mathrm{tr}(\bm{\sigma})^2 - \mathrm{tr}(\bm{\sigma}^2)) \\ I_3(\bm{\sigma}) &= \det(\bm{\sigma}) \end{aligned}\]
Examples
julia> σ = rand(SymmetricSecondOrderTensor{3})
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
0.325977 0.549051 0.218587
0.549051 0.894245 0.353112
0.218587 0.353112 0.394255
julia> I₁, I₂, I₃ = stress_invariants(σ)
(1.6144775244804341, 0.2986572249840249, -0.0025393241133506677)
Tensorial.deviatoric_stress_invariants
— Functiondeviatoric_stress_invariants(::AbstractSecondOrderTensor{3})
deviatoric_stress_invariants(::AbstractSymmetricSecondOrderTensor{3})
deviatoric_stress_invariants(::Vec{3})
Return a tuple storing deviatoric stress invariants.
\[\begin{aligned} J_1(\bm{\sigma}) &= \mathrm{tr}(\mathrm{dev}(\bm{\sigma})) = 0 \\ J_2(\bm{\sigma}) &= \frac{1}{2} \mathrm{tr}(\mathrm{dev}(\bm{\sigma})^2) \\ J_3(\bm{\sigma}) &= \frac{1}{3} \mathrm{tr}(\mathrm{dev}(\bm{\sigma})^3) \end{aligned}\]
Examples
julia> σ = rand(SymmetricSecondOrderTensor{3})
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
0.325977 0.549051 0.218587
0.549051 0.894245 0.353112
0.218587 0.353112 0.394255
julia> J₁, J₂, J₃ = deviatoric_stress_invariants(σ)
(0.0, 0.5701886673667987, 0.14845380911930367)