API of the TensND library
TensND.Basis — Type
Basis(v::AbstractMatrix{T}, ::Val{:cov})
Basis{dim, T<:Number}()
Basis(θ::T<:Number, ϕ::T<:Number, ψ::T<:Number)Basis built from a square matrix v where columns correspond either to
- primal vectors ie
eᵢ=v[:,i]ifvar=:covas by default - dual vectors ie
eⁱ=v[:,i]ifvar=:cont.
Basis without any argument refers to the canonical basis (CanonicalBasis) in Rᵈⁱᵐ (by default dim=3 and T=Sym)
Basis can also be built from Euler angles (RotatedBasis) θ in 2D and (θ, ϕ, ψ) in 3D
The attributes of this object can be obtained by
vecbasis(ℬ, :cov): square matrix defining the primal basiseᵢ=e[:,i]vecbasis(ℬ, :cont): square matrix defining the dual basiseⁱ=E[:,i]metric(ℬ, :cov): square matrix defining the covariant components of the metric tensorgᵢⱼ=eᵢ⋅eⱼ=g[i,j]metric(ℬ, :cont): square matrix defining the contravariant components of the metric tensorgⁱʲ=eⁱ⋅eʲ=gⁱʲ[i,j]
Examples
julia> v = Sym[1 0 0; 0 1 0; 0 1 1] ; ℬ = Basis(v)
Basis{3, Sym}
# basis: 3×3 Tensor{2, 3, Sym, 9}:
1 0 0
0 1 0
0 1 1
# dual basis: 3×3 Tensor{2, 3, Sym, 9}:
1 0 0
0 1 -1
0 0 1
# covariant metric tensor: 3×3 SymmetricTensor{2, 3, Sym, 6}:
1 0 0
0 2 1
0 1 1
# contravariant metric tensor: 3×3 SymmetricTensor{2, 3, Sym, 6}:
1 0 0
0 1 -1
0 -1 2
julia> θ, ϕ, ψ = symbols("θ, ϕ, ψ", real = true) ; ℬʳ = Basis(θ, ϕ, ψ) ; display(vecbasis(ℬʳ, :cov))
3×3 Tensor{2, 3, Sym, 9}:
-sin(ψ)⋅sin(ϕ) + cos(θ)⋅cos(ψ)⋅cos(ϕ) -sin(ψ)⋅cos(θ)⋅cos(ϕ) - sin(ϕ)⋅cos(ψ) sin(θ)⋅cos(ϕ)
sin(ψ)⋅cos(ϕ) + sin(ϕ)⋅cos(θ)⋅cos(ψ) -sin(ψ)⋅sin(ϕ)⋅cos(θ) + cos(ψ)⋅cos(ϕ) sin(θ)⋅sin(ϕ)
-sin(θ)⋅cos(ψ) sin(θ)⋅sin(ψ) cos(θ)TensND.CanonicalBasis — Type
CanonicalBasis{dim, T}Canonical basis of dimension dim (default: 3) and type T (default: Sym)
The attributes of this object can be obtained by
vecbasis(ℬ, :cov): square matrix defining the primal basiseᵢ=e[:,i]=δᵢⱼvecbasis(ℬ, :cont): square matrix defining the dual basiseⁱ=E[:,i]=δᵢⱼmetric(ℬ, :cov): square matrix defining the covariant components of the metric tensorgᵢⱼ=eᵢ⋅eⱼ=g[i,j]=δᵢⱼmetric(ℬ, :cont): square matrix defining the contravariant components of the metric tensorgⁱʲ=eⁱ⋅eʲ=gⁱʲ[i,j]=δᵢⱼ
Examples
julia> ℬ = CanonicalBasis()
CanonicalBasis{3, Sym}
# basis: 3×3 TensND.LazyIdentity{3, Sym}:
1 0 0
0 1 0
0 0 1
# dual basis: 3×3 TensND.LazyIdentity{3, Sym}:
1 0 0
0 1 0
0 0 1
# covariant metric tensor: 3×3 TensND.LazyIdentity{3, Sym}:
1 0 0
0 1 0
0 0 1
# contravariant metric tensor: 3×3 TensND.LazyIdentity{3, Sym}:
1 0 0
0 1 0
0 0 1
julia> ℬ₂ = CanonicalBasis{2, Float64}()
CanonicalBasis{2, Float64}
# basis: 2×2 TensND.LazyIdentity{2, Float64}:
1.0 0.0
0.0 1.0
# dual basis: 2×2 TensND.LazyIdentity{2, Float64}:
1.0 0.0
0.0 1.0
# covariant metric tensor: 2×2 TensND.LazyIdentity{2, Float64}:
1.0 0.0
0.0 1.0
# contravariant metric tensor: 2×2 TensND.LazyIdentity{2, Float64}:
1.0 0.0
0.0 1.0TensND.CoorSystemNum — Type
CoorSystemNum{dim,T<:Real} <: AbstractCoorSystem{dim,T}Numerical coordinate system for automatic-differentiation-based differential operators.
Stores three point-wise functions:
χ_func(x): Lamé coefficients at pointxR_func(x): rotation matrix (columns = unit vectors of the normalized basis) atxΓ_func(x): Christoffel symbols atx→Array{T,3}withΓ[i,j,k] = Γᵏᵢⱼ
All three functions accept an AbstractVector of coordinates and are called at each evaluation point. Predefined constructors are available:
coorsys_cartesian_num(T=Float64)
coorsys_polar_num(T=Float64)
coorsys_cylindrical_num(T=Float64)
coorsys_spherical_num(T=Float64)A generic constructor from an OM::Function (position vector) is also provided:
CoorSystemNum(OM::Function, dim::Integer, T::Type=Float64)Unlike CoorSystemSym, the normalized basis, natural basis vectors, Lamé coefficients, and Christoffel symbols all depend on the evaluation point x₀ and are accessed via point-wise accessors normalized_basis(CS, x₀), natural_basis(CS, x₀), etc.
TensND.CoorSystemNum — Method
CoorSystemNum(OM_func::Function, dim::Integer, T::Type=Float64)Generic constructor: build a CoorSystemNum from a position-vector function. OM_func(x) must return a Vector of Cartesian components given a coordinate vector x of length dim. Christoffel symbols are computed by nested automatic differentiation of the metric tensor g = J'J where J = ∂OM/∂x.
TensND.RotatedBasis — Type
RotatedBasis(θ::T<:Number, ϕ::T<:Number, ψ::T<:Number)
RotatedBasis(θ::T<:Number)Orthonormal basis of dimension dim (default: 3) and type T (default: Sym) built from Euler angles θ in 2D and (θ, ϕ, ψ) in 3D
Examples
julia> θ, ϕ, ψ = symbols("θ, ϕ, ψ", real = true) ; ℬʳ = RotatedBasis(θ, ϕ, ψ) ; display(vecbasis(ℬʳ, :cov))
3×3 Tensor{2, 3, Sym, 9}:
-sin(ψ)⋅sin(ϕ) + cos(θ)⋅cos(ψ)⋅cos(ϕ) -sin(ψ)⋅cos(θ)⋅cos(ϕ) - sin(ϕ)⋅cos(ψ) sin(θ)⋅cos(ϕ)
sin(ψ)⋅cos(ϕ) + sin(ϕ)⋅cos(θ)⋅cos(ψ) -sin(ψ)⋅sin(ϕ)⋅cos(θ) + cos(ψ)⋅cos(ϕ) sin(θ)⋅sin(ϕ)
-sin(θ)⋅cos(ψ) sin(θ)⋅sin(ψ) cos(θ)TensND.SubManifoldSym — Type
CoorSystemSym(OM::AbstractTens{1,dim,Sym},coords::NTuple{dim,Sym},bnorm::AbstractBasis{dim,Sym},χᵢ::NTuple{dim},
tmp_coords::NTuple = (),params::NTuple = ();rules::Dict = Dict(),tmp_var::Dict = Dict(),to_coords::Dict = Dict()) where {dim}
CoorSystemSym(OM::AbstractTens{1,dim,Sym},coords::NTuple{dim,Sym},
tmp_coords::NTuple = (),params::NTuple = ();rules::Dict = Dict(),tmp_var::Dict = Dict(),to_coords::Dict = Dict()) where {dim}Define a new coordinate system either from
the position vector
OM, the coordinatescoords, the basis of unit vectors (𝐞ᵢ)bnormand the Lamé coefficientsχᵢIn this case the natural basis is formed by the vectors
𝐚ᵢ = χᵢ 𝐞ᵢdirectly calculated from the input data.or the position vector
OMand the coordinatescoordsIn this case the natural basis is formed by the vectors
𝐚ᵢ = ∂ᵢOMi.e. by the derivative of the position vector with respect to theiᵗʰcoordinate
Optional parameters can be provided:
tmp_coordscontains temporary variables depending on coordinates (in order to allow symbolic simplifications)paramscontains possible parameters involved inOMrulescontains aDictwith substitution rules to facilitate the simplification of formulastmp_varcontains aDictwith substitution of coordinates by temporary variablesto_coordsindicates how to eliminate the temporary variables to come back to the actual coordinates before derivation for Examples
Examples
julia> ϕ, p = symbols("ϕ p", real = true) ;
julia> p̄, q, q̄, c = symbols("p̄ q q̄ c", positive = true) ;
julia> coords = (ϕ, p, q) ; tmp_coords = (p̄, q̄) ; params = (c,) ;
julia> OM = Tens(c * [p̄ * q̄ * cos(ϕ), p̄ * q̄ * sin(ϕ), p * q]) ;
julia> Spheroidal = CoorSystemSym(OM, coords, tmp_coords, params; tmp_var = Dict(1-p^2 => p̄^2, q^2-1 => q̄^2), to_coords = Dict(p̄ => √(1-p^2), q̄ => √(q^2-1))) ;TensND.Tens — Type
Tens{order,dim,T,A<:AbstractArray}Tensor type of any order defined by
- a multidata of components (of any type heriting from
AbstractArray, e.g.TensororSymmetricTensor) - a basis of
AbstractBasistype - a tuple of variances (covariant
:covor contravariant:cont) of length equal to theorderof the tensor
Examples
julia> ℬ = Basis(Sym[1 0 0; 0 1 0; 0 1 1]) ;
julia> T = Tens(metric(ℬ,:cov),ℬ,(:cov,:cov))
Tens{2, 3, Sym, SymmetricTensor{2, 3, Sym, 6}}
# data: 3×3 SymmetricTensor{2, 3, Sym, 6}:
1 0 0
0 2 1
0 1 1
# basis: 3×3 Tensor{2, 3, Sym, 9}:
1 0 0
0 1 0
0 1 1
# var: (:cov, :cov)
julia> components(T,(:cont,:cov),b)
3×3 Matrix{Sym}:
1 0 0
0 1 0
0 0 1TensND.TensOrtho — Type
TensOrtho{T} <: AbstractTens{4,3,T}Orthotropic 4th-order tensor with material frame (e₁,e₂,e₃) and 9 independent elastic constants (C₁₁,C₂₂,C₃₃,C₁₂,C₁₃,C₂₃,C₄₄,C₅₅,C₆₆) where C₄₄=C₂₃₂₃, C₅₅=C₁₃₁₃, C₆₆=C₁₂₁₂:
ℂ = C₁₁P₁⊗P₁ + C₂₂P₂⊗P₂ + C₃₃P₃⊗P₃
+ C₁₂(P₁⊗P₂+P₂⊗P₁) + C₁₃(P₁⊗P₃+P₃⊗P₁) + C₂₃(P₂⊗P₃+P₃⊗P₂)
+ 2C₄₄(P₂⊠ˢP₃) + 2C₅₅(P₁⊠ˢP₃) + 2C₆₆(P₁⊠ˢP₂)with Pₘ = eₘ⊗eₘ. The Kelvin-Mandel matrix in the material frame is block-diagonal:
[[C₁₁,C₁₂,C₁₃, 0, 0, 0 ],
[C₁₂,C₂₂,C₂₃, 0, 0, 0 ],
[C₁₃,C₂₃,C₃₃, 0, 0, 0 ],
[ 0, 0, 0, 2C₄₄, 0, 0 ],
[ 0, 0, 0, 0, 2C₅₅, 0 ],
[ 0, 0, 0, 0, 0, 2C₆₆]]TensND.TensOrtho — Method
TensOrtho(KMmat::AbstractMatrix, frame)Build a TensOrtho from a 6×6 Kelvin-Mandel matrix expressed in the material frame. The matrix must have the block-diagonal orthotropic structure: upper-left 3×3 for normal stresses and lower-right 3×3 diagonal for shear.
TensND.TensOrtho — Method
TensOrtho(C11,C22,C33,C12,C13,C23,C44,C55,C66, frame)Orthotropic tensor from the 9 elastic constants in the material frame frame.
TensND.TensTI — Type
TensTI{order, T, N} <: AbstractTens{order, 3, T}Transversely isotropic tensor of order order (always dim=3) with symmetry axis n, parametrised like TensISO{order, dim, T, N}.
Three concrete shapes are supported:
| Parametrization | Role | Stored coefficients |
|---|---|---|
TensTI{2, T, 2} | 2nd-order TI | data = (a, b), n::NTuple{3} |
TensTI{4, T, 5} | 4th-order TI, major-symmetric | data = (ℓ₁,ℓ₂,ℓ₃,ℓ₅,ℓ₆), n |
TensTI{4, T, 6} | 4th-order TI, general | data = (ℓ₁,…,ℓ₆), n |
Order 2 (
N=2):𝐀 = a·nT + b·nₙwherenₙ = n⊗n,nT = 𝟏 − nₙ.ais the transverse coefficient,bthe axial one. Whena = b, the tensor is isotropic and equivalent toTensISO{2,3,T}(a).Order 4: stored in the Walpole basis
{W₁,…,W₆}, withW₁ = nₙ⊗nₙ,W₂ = (nT⊗nT)/2,W₃ = (nₙ⊗nT)/√2,W₄ = (nT⊗nₙ)/√2,W₅ = nT⊠ˢnT − (nT⊗nT)/2,W₆ = nT⊠ˢnₙ + nₙ⊠ˢnT. Major-symmetric tensors haveℓ₃ = ℓ₄and are stored underN=5. Synthetic notation:L ≡ ([[ℓ₁,ℓ₃],[ℓ₄,ℓ₂]], ℓ₅, ℓ₆).
See also tens_TI, tens_TI_eng, tens_TI_Hoenig.
Base.inv — Method
inv(t::TensOrtho) → TensOrthoInverse via the KM matrix in the material frame (block-diagonal, efficiently invertible).
Base.inv — Method
inv(t::TensTI{2,T,2}) → TensTI{2,T,2}Inverse: (a·nT + b·nₙ)⁻¹ = (1/a)·nT + (1/b)·nₙ.
Examples
julia> A = TensTI{2}(5.0, 8.0, [0., 0., 1.]);
julia> inv(A).data
(0.2, 0.125)Base.inv — Method
inv(t::TensTI{4, T, 5}) → TensTI{4, T, 5}
inv(t::TensTI{4, T, 6}) → TensTI{4, T, 6}Inverse via the 2×2 Walpole matrix and scalar inverses for ℓ₅, ℓ₆.
LinearAlgebra.dot — Method
dot(t1::AbstractTens{order1,dim}, t2::AbstractTens{order2,dim})Define a contracted product between two tensors
a ⋅ b = aⁱbⱼ
LinearAlgebra.normalize — Function
normalize(ℬ::AbstractBasis, var = cov)Build a basis after normalization of column vectors of input matrix v where columns define either
- primal vectors ie
eᵢ=v[:,i]/norm(v[:,i])ifvar = :covas by default - dual vector ie
eⁱ=v[:,i]/norm(v[:,i])ifvar = :cont.
LinearAlgebra.tr — Method
tr(t::TensTI{2}) → scalarTrace: tr(a·nT + b·nₙ) = 2a + b.
TensND.DIV — Method
DIV(t::AbstractTens{order,dim,Sym},CS::CoorSystemSym{dim}) where {order,dim,T<:Number}Calculate the divergence of T with respect to the coordinate system CS
TensND.DIV — Method
DIV(f::Function, CS::CoorSystemNum) -> FunctionReturn a function x₀ -> divergence as a scalar (if f is a vector field) or AbstractTens (if f is a tensor field of order ≥ 2).
f may return a plain Array or an AbstractTens (components are extracted via Array).
TensND.DIV — Method
DIV(T::AbstractTens{order,dim,Sym},SM::SubManifoldSym{dim}) where {order,dim}Calculate the divergence of T with respect to the coordinate system SM
TensND.GRAD — Method
GRAD(t::Union{t,AbstractTens{order,dim,T}},CS::CoorSystemSym{dim}) where {order,dim,T<:Number}Calculate the gradient of t with respect to the coordinate system CS
TensND.GRAD — Method
GRAD(f::Function, CS::CoorSystemNum) -> FunctionReturn a function x₀ -> gradient as an AbstractTens in the normalized basis at x₀.
- If
freturns a scalar, the gradient is a rank-1AbstractTens. - If
freturns a rank-nAbstractTensor array, the gradient is a rank-n+1AbstractTens.
TensND.GRAD — Method
GRAD(T::Union{Sym,AbstractTens{order,dim,Sym}},SM::SubManifoldSym{dim}) where {order,dim}Calculate the gradient of T with respect to the coordinate system SM
TensND.HESS — Method
HESS(t::Union{Sym,AbstractTens{order,dim,Sym}},CS::CoorSystemSym{dim}) where {order,dim,T<:Number}Calculate the Hessian of T with respect to the coordinate system CS
TensND.HESS — Method
HESS(f::Function, CS::CoorSystemNum) -> FunctionReturn a function x₀ -> Hessian as an AbstractTens{2} in the normalized basis. Uses the raw (plain-array) double gradient internally.
TensND.HESS — Method
HESS(T::Union{Sym,AbstractTens{order,dim,Sym}},SM::SubManifoldSym{dim}) where {order,dim}Calculate the Hessian of T with respect to the coordinate system SM
TensND.ISO — Method
ISO(args...)Legacy alias of iso_projectors kept for backward compatibility.
TensND.KM — Method
KM(t::TensOrtho)Returns the 6×6 Kelvin-Mandel matrix in the canonical frame. Use KM_material(t) for the block-diagonal form in the material frame.
TensND.KM — Method
KM(t::TensTI{4})Kelvin-Mandel (6×6) matrix of the Walpole tensor.
TensND.KM — Method
KM(t::AbstractTens{order,dim}; kwargs...)
KM(t::AbstractTens{order,dim}, var::NTuple{order,Symbol}, b::AbstractBasis{dim}; kwargs...)Write the components of a second or fourth order tensor in Kelvin-Mandel notation
Examples
julia> σ = Tens(SymmetricTensor{2,3}((i, j) -> symbols("σ$i$j", real = true))) ;
julia> KM(σ)
6-element Vector{Sym}:
σ11
σ22
σ33
√2⋅σ32
√2⋅σ31
√2⋅σ21
julia> C = Tens(SymmetricTensor{4,3}((i, j, k, l) -> symbols("C$i$j$k$l", real = true))) ;
julia> KM(C)
6×6 Matrix{Sym}:
C₁₁₁₁ C₁₁₂₂ C₁₁₃₃ √2⋅C₁₁₃₂ √2⋅C₁₁₃₁ √2⋅C₁₁₂₁
C₂₂₁₁ C₂₂₂₂ C₂₂₃₃ √2⋅C₂₂₃₂ √2⋅C₂₂₃₁ √2⋅C₂₂₂₁
C₃₃₁₁ C₃₃₂₂ C₃₃₃₃ √2⋅C₃₃₃₂ √2⋅C₃₃₃₁ √2⋅C₃₃₂₁
√2⋅C₃₂₁₁ √2⋅C₃₂₂₂ √2⋅C₃₂₃₃ 2⋅C₃₂₃₂ 2⋅C₃₂₃₁ 2⋅C₃₂₂₁
√2⋅C₃₁₁₁ √2⋅C₃₁₂₂ √2⋅C₃₁₃₃ 2⋅C₃₁₃₂ 2⋅C₃₁₃₁ 2⋅C₃₁₂₁
√2⋅C₂₁₁₁ √2⋅C₂₁₂₂ √2⋅C₂₁₃₃ 2⋅C₂₁₃₂ 2⋅C₂₁₃₁ 2⋅C₂₁₂₁TensND.KM — Method
KM(v::AllIsotropic{dim}; kwargs...)Kelvin-Mandel vector or matrix representation
TensND.KM_material — Method
KM_material(t::TensOrtho)Returns the 6×6 Kelvin-Mandel matrix in the material frame (block-diagonal).
TensND.LAPLACE — Method
LAPLACE(t::Union{Sym,AbstractTens{order,dim,Sym}},CS::CoorSystemSym{dim}) where {order,dim,T<:Number}Calculate the Laplace operator of T with respect to the coordinate system CS
TensND.LAPLACE — Method
LAPLACE(f::Function, CS::CoorSystemNum) -> FunctionReturn a function x₀ -> Laplacian (scalar). Uses the raw (plain-array) gradient and divergence internally, so it is fully compatible with ForwardDiff differentiation.
TensND.LAPLACE — Method
LAPLACE(T::Union{Sym,AbstractTens{order,dim,Sym}},SM::SubManifoldSym{dim}) where {order,dim}Calculate the Laplace operator of T with respect to the coordinate system SM
TensND.LeviCivita — Function
LeviCivita(T::Type{<:Number} = Sym)Builds an Array{T,3} of Levi-Civita Symbol ϵᵢⱼₖ = (i-j) (j-k) (k-i) / 2
Examples
julia> ε = LeviCivita(Sym)
3×3×3 Array{Sym, 3}:
[:, :, 1] =
0 0 0
0 0 1
0 -1 0
[:, :, 2] =
0 0 -1
0 0 0
1 0 0
[:, :, 3] =
0 1 0
-1 0 0
0 0 0TensND.SYMGRAD — Method
SYMGRAD(t::Union{T,AbstractTens{order,dim,T}},CS::CoorSystemSym{dim}) where {order,dim,T<:Number}Calculate the symmetrized gradient of T with respect to the coordinate system CS
TensND.SYMGRAD — Method
SYMGRAD(f::Function, CS::CoorSystemNum) -> FunctionReturn a function x₀ -> symmetric gradient as an AbstractTens{2} in the normalized basis at x₀. Applies to vector-valued functions f.
TensND.SYMGRAD — Method
SYMGRAD(T::Union{Sym,AbstractTens{order,dim,Sym}},SM::SubManifoldSym{dim}) where {order,dim}Calculate the symmetrized gradient of T with respect to the coordinate system SM
TensND.Walpole — Method
Walpole(n; sym::Bool = false)Legacy entry point: dispatches to walpole_basis (6-tuple, default) or walpole_basis_sym (5-tuple, sym=true). Kept for backward compatibility with older scripts; new code should prefer the dedicated functions whose return arity is deterministic from the name.
TensND._KM_of_array — Method
_KM_of_array(A::AbstractArray{T,4}) → Matrix{T}Compute the 6×6 Kelvin-Mandel matrix of a 3×3×3×3 array.
TensND._KM_of_array — Method
_KM_of_array(A::AbstractArray{T,2}) → Matrix{T}Compute the 6-vector (or just return the 3×3 matrix) Kelvin-Mandel for a 2nd-order tensor.
TensND._KM_rotation — Method
_KM_rotation(θ, ϕ, ψ) → SMatrix{6,6}6×6 Kelvin-Mandel (Bond) rotation matrix from Euler angles (θ, ϕ, ψ). Compatible with ForwardDiff.
Transforms a 6×6 KM matrix as: C' = Q' · C · Q where Q = _KM_rotation(...).
Uses the standard Bond matrix construction from R = _rot3_raw(θ, ϕ, ψ).
Examples
julia> Q = _KM_rotation(0.3, 0.5, 0.0);
julia> size(Q)
(6, 6)TensND._angles_from_n — Method
_angles_from_n(n) → (θ, ϕ)Extract spherical angles (θ, ϕ) from a unit vector n:
θ = atan(√(n₁² + n₂²), n₃)(polar angle from z-axis)ϕ = atan(n₂, n₁)(azimuthal angle)
Examples
julia> _angles_from_n((0.0, 0.0, 1.0))
(0.0, 0.0)
julia> _angles_from_n((1.0, 0.0, 0.0))
(1.5707963267948966, 0.0)TensND._apply_christoffel — Method
Apply the Christoffel correction to a rank-order tensor in natural contravariant components. t_arr : array of natural contravariant components (size dim^order) Γᵢ : Γ[i,:,:] slice (dim×dim matrix, entry [k,j] = Γᵏᵢₖ ... = Γᵏᵢⱼ)
TensND._axis_on_frame_index — Method
_axis_on_frame_index(n, frame::OrthonormalBasis{3}; atol=1e-10) → IntReturn the index k ∈ {1,2,3} such that n is parallel to the k-th axis of frame (i.e. |n ⋅ eₖ| ≈ 1), or 0 if n is not aligned with any axis.
Used to decide whether a TensTI{4} (TI with axis n) and a TensOrtho (with a material frame) are compatible for symmetry-preserving arithmetic.
Examples
julia> TensND._axis_on_frame_index((0.0, 0.0, 1.0), CanonicalBasis{3,Float64}())
3
julia> TensND._axis_on_frame_index((1.0, 0.0, 0.0), CanonicalBasis{3,Float64}())
1
julia> TensND._axis_on_frame_index((1.0, 1.0, 0.0) ./ √2, CanonicalBasis{3,Float64}())
0TensND._build_ORTHO_KM — Method
_build_ORTHO_KM(C₁₁, C₂₂, C₃₃, C₁₂, C₁₃, C₂₃, C₄₄, C₅₅, C₆₆) → SMatrix{6,6}Build a 6×6 KM matrix in the material frame from 9 orthotropic parameters.
Examples
julia> B = _build_ORTHO_KM(10.0, 8.0, 12.0, 3.0, 2.5, 1.5, 2.0, 3.0, 3.5);
julia> B[4,4] # = 2*C₄₄ = 4
4.0TensND._build_TI_KM — Method
_build_TI_KM(ℓ₁, ℓ₂, ℓ₃, ℓ₅, ℓ₆) → SMatrix{6,6}Build a 6×6 KM matrix (in the frame where e₃ is the TI axis) from 5 major-symmetric Walpole coefficients.
Examples
julia> B = _build_TI_KM(12.0, 13.0, sqrt(2)*2.5, 7.0, 4.0);
julia> B[1,1] # = (ℓ₂ + ℓ₅)/2 = (13+7)/2 = 10
10.0TensND._candidate_ORTHO_frame — Method
_candidate_ORTHO_frame(C::AbstractArray{T,4}) → OrthonormalBasis{3,T}Propose a candidate orthotropic material frame for C by taking the three eigenvectors of its trace tensor dᵢⱼ = Cᵢₖⱼₖ. Returns a RotatedBasis{3,T} (or CanonicalBasis{3,T} if the eigenvectors coincide with the canonical frame).
Only meaningful for numeric element types: for symbolic T, the canonical frame is returned.
TensND._candidate_ORTHO_frame — Method
_candidate_ORTHO_frame(M::AbstractMatrix{T}) → OrthonormalBasis{3,T}For a 2nd-order tensor, the ORTHO frame candidate is directly built from its eigenvectors.
TensND._candidate_TI_axis — Method
_candidate_TI_axis(C::AbstractArray{T,4}; rtol=1e-8) → NTuple{3,T}Propose a candidate TI symmetry axis for a 4th-order tensor C by looking at the eigenvalues of its trace tensor dᵢⱼ = Cᵢₖⱼₖ. If two eigenvalues coincide (relative tolerance rtol), the third one's eigenvector is the candidate axis — this is exact for a genuinely TI tensor. Otherwise falls back to e₃ = (0, 0, 1).
Only meaningful for numeric element types: for symbolic T, the eigendecomposition is skipped and e₃ is returned.
TensND._candidate_TI_axis — Method
_candidate_TI_axis(M::AbstractMatrix{T}; rtol=1e-8) → NTuple{3,T}For a 2nd-order tensor M, propose its unique/isolated eigenvector as the candidate TI axis. Falls back to e₃ when the three eigenvalues are indistinguishable.
TensND._christoffel_from_OM — Method
Compute Christoffel symbols from position vector function OM via nested AD. OM_func(x) returns a vector of Cartesian coordinates.
TensND._christoffel_orthogonal — Method
Compute Christoffel symbols for an orthogonal system from the Jacobian of the Lamé-coefficient function.
Convention: Γ[i,j,k] = Γᵏᵢⱼ.
TensND._lift_walpole_N6 — Method
_lift_walpole_N6(A::TensTI{4, T, 5}) → TensTI{4, T, 6}Lift a major-symmetric N=5 Walpole tensor to the general N=6 form by duplicating the shared coefficient ℓ₃ = ℓ₄.
TensND._n_from_angles — Method
_n_from_angles(θ, ϕ) → NTuple{3}Build a unit vector from spherical angles: n = (sinθ·cosϕ, sinθ·sinϕ, cosθ).
Examples
julia> _n_from_angles(0.0, 0.0)
(0.0, 0.0, 1.0)TensND._project_ORTHO_KM — Method
_project_ORTHO_KM(C::AbstractMatrix) → NTuple{9}Extract 9 orthotropic parameters from a 6×6 KM matrix in the material frame. Returns (C₁₁, C₂₂, C₃₃, C₁₂, C₁₃, C₂₃, C₄₄, C₅₅, C₆₆).
For non-symmetric KM matrices (non-major-symmetric tensors), the off-diagonal entries are averaged: Cᵢⱼ = (C[i,j] + C[j,i]) / 2.
Examples
julia> C = Float64[10 3 2.5 0 0 0; 3 8 1.5 0 0 0; 2.5 1.5 12 0 0 0;
0 0 0 4 0 0; 0 0 0 0 6 0; 0 0 0 0 0 7];
julia> _project_ORTHO_KM(C)
(10.0, 8.0, 12.0, 3.0, 2.5, 1.5, 2.0, 3.0, 3.5)TensND._project_TI_KM — Method
_project_TI_KM(C::AbstractMatrix) → (ℓ₁, ℓ₂, ℓ₃, ℓ₅, ℓ₆)Project a 6×6 KM matrix (assumed to be in a frame where e₃ is the TI symmetry axis) onto the major-symmetric TI subspace. Returns the 5 Walpole coefficients.
Formulas (from ECHOES tensor_ti.h):
c = (C[1,1] + C[2,2]) / 2d = (C[1,2] + C[2,1]) / 2ℓ₁ = C[3,3]ℓ₂ = c + dℓ₃ = (C[1,3] + C[2,3] + C[3,1] + C[3,2]) / (2√2)ℓ₅ = (c − d + C[6,6]) / 2ℓ₆ = (C[4,4] + C[5,5]) / 2
Examples
julia> C = Float64[10 3 2.5 0 0 0; 3 10 2.5 0 0 0; 2.5 2.5 12 0 0 0;
0 0 0 4 0 0; 0 0 0 0 4 0; 0 0 0 0 0 7];
julia> _project_TI_KM(C)
(12.0, 13.0, 3.5355339059327378, 7.0, 4.0)TensND._rot3_raw — Method
_rot3_raw(θ, ϕ, ψ) → SMatrix{3,3}Rotation matrix (RotZYZ convention: R = Rz(ϕ)·Ry(θ)·Rz(ψ)) built from explicit cos/sin, compatible with ForwardDiff Dual numbers.
The third column of the matrix is the direction (sinθ cosϕ, sinθ sinϕ, cosθ).
Examples
julia> R = _rot3_raw(0.3, 0.5, 0.0)
3×3 SMatrix{3, 3, Float64, 9} with indices SOneTo(3)×SOneTo(3):
...TensND._trace_tensor — Method
_trace_tensor(C::AbstractArray{T,4}) → SMatrix{3,3,T,9}Return the 2nd-order "trace" tensor dᵢⱼ = ∑ₖ C[i,k,j,k] — its eigenstructure exposes the principal directions of C cheaply (no optimisation required).
Used to propose candidate TI axes and candidate orthotropic frames when the user asks for symmetry detection without angle optimisation.
TensND._χ_outer — Method
Return an array of shape (dim, dim, ...) (order times) where entry [i₁,…,iₙ] = χᵢ₁ ⋯ χᵢₙ.
TensND.angles — Method
angles(M::AbstractMatrix{T})Determine the Euler angles corresponding to the input matrix supposed to be a rotation matrix or at least a similarity
Examples
julia> θ, ϕ, ψ = symbols("θ, ϕ, ψ", real = true) ; ℬʳ = RotatedBasis(θ, ϕ, ψ) ; display(vecbasis(ℬʳ, :cov))
3×3 Tensor{2, 3, Sym, 9}:
-sin(ψ)⋅sin(ϕ) + cos(θ)⋅cos(ψ)⋅cos(ϕ) -sin(ψ)⋅cos(θ)⋅cos(ϕ) - sin(ϕ)⋅cos(ψ) sin(θ)⋅cos(ϕ)
sin(ψ)⋅cos(ϕ) + sin(ϕ)⋅cos(θ)⋅cos(ψ) -sin(ψ)⋅sin(ϕ)⋅cos(θ) + cos(ψ)⋅cos(ϕ) sin(θ)⋅sin(ϕ)
-sin(θ)⋅cos(ψ) sin(θ)⋅sin(ψ) cos(θ)
julia> angles(ℬʳ)
(θ = θ, ϕ = ϕ, ψ = ψ)TensND.arg_TI — Method
arg_TI(t::TensTI{4}) → (C₁₁₁₁, C₁₁₂₂, C₁₁₃₃, C₃₃₃₃, C₂₃₂₃)Extract the 5 independent TI components from a Walpole tensor, directly from the stored coefficients (no array materialisation).
Inverse of tens_TI:
C₃₃₃₃ = ℓ₁C₁₁₁₁ = (ℓ₂ + ℓ₅)/2C₁₁₂₂ = (ℓ₂ − ℓ₅)/2C₁₁₃₃ = ℓ₃/√2C₂₃₂₃ = ℓ₆/2
See also arg_TI_eng.
TensND.arg_TI_Hoenig — Method
arg_TI_Hoenig(𝕊::TensTI{4}) → (E, ν₁, ν₂, H, Γ)Extract the 5 Hoenig parameters from a TI compliance tensor.
See also tens_TI_Hoenig, arg_TI_eng.
TensND.arg_TI_eng — Method
arg_TI_eng(𝕊::TensTI{4}) → (E₁, E₃, ν₁₂, ν₃₁, G₃₁)Extract engineering constants from a TI compliance tensor.
See also tens_TI_eng, arg_TI.
TensND.axis — Method
axis(t::TensTI)Return the symmetry axis of a transversely isotropic tensor.
TensND.best_sym_tens — Method
best_sym_tens(t; proj=(:ISO, :TI, :ORTHO), ε=1e-6, optimize_angles=false)Find the best (most restrictive) symmetry of tensor t by trying each symmetry class in proj (from most to least symmetric) and accepting the first whose relative projection error is below ε.
optimize_angles=false(default, cheap path, no optimisation): the:ISOprojection is closed-form; for:TIthe symmetry axis is taken fromtitself (if it is a structured TI container) or derived from the Kelvin-Mandel eigenstructure (otherwise); for:ORTHOthe material frame is taken fromtor derived likewise. No external optimiser needed.optimize_angles=true: the:TIaxis and:ORTHOframe are found by nonlinear optimisation (multistart L-BFGS) — requiresusing NLopt.
Returns (projected, d, drel, sym) where sym ∈ {:ISO, :TI, :ORTHO, :ANISO}.
Behaviour change (vs. pre-2026 versions): the default no-argument call no longer throws when NLopt is absent; set optimize_angles=true to restore the previous angle-optimised behaviour.
Examples
julia> n = [0., 0., 1.];
julia> C = tens_TI(10., 3., 2.5, 12., 2., n);
julia> _, _, _, sym = best_sym_tens(C);
julia> sym === :TI
trueSee also best_sym_tens(t, n_or_frame) for fixed-axis/frame use, proj_tens.
TensND.best_sym_tens — Method
best_sym_tens(t; proj=(:ISO, :TI, :ORTHO), ε=1e-6, optimize_angles=false)Find the best (most restrictive) symmetry of tensor t by trying each symmetry class in proj (from most to least symmetric) and accepting the first whose relative projection error is below ε.
optimize_angles=false(default, cheap path, no optimisation): the:ISOprojection is closed-form; for:TIthe symmetry axis is taken fromtitself (if it is a structured TI container) or derived from the Kelvin-Mandel eigenstructure (otherwise); for:ORTHOthe material frame is taken fromtor derived likewise. No external optimiser needed.optimize_angles=true: the:TIaxis and:ORTHOframe are found by nonlinear optimisation (multistart L-BFGS) — requiresusing NLopt.
Returns (projected, d, drel, sym) where sym ∈ {:ISO, :TI, :ORTHO, :ANISO}.
Behaviour change (vs. pre-2026 versions): the default no-argument call no longer throws when NLopt is absent; set optimize_angles=true to restore the previous angle-optimised behaviour.
Examples
julia> n = [0., 0., 1.];
julia> C = tens_TI(10., 3., 2.5, 12., 2., n);
julia> _, _, _, sym = best_sym_tens(C);
julia> sym === :TI
trueSee also best_sym_tens(t, n_or_frame) for fixed-axis/frame use, proj_tens.
TensND.best_sym_tens — Method
best_sym_tens(t, n_or_frame; proj=(:ISO, :TI, :ORTHO), ε=1e-6)Find the best symmetry of tensor t with a fixed symmetry axis n (for TI) or material frame frame (for ORTHO). No rotation optimisation is performed.
n_or_frame: a vector (axis for TI) orOrthonormalBasis{3}(frame for ORTHO). For ISO projection the extra argument is ignored.
Returns (projected, d, drel, sym).
Examples
julia> n = [0., 0., 1.];
julia> C = tens_TI(10., 3., 2.5, 12., 2., n);
julia> _, _, drel, sym = best_sym_tens(C, n);
julia> sym == :TI && drel < 1e-12
trueTensND.best_sym_tens — Method
best_sym_tens(t, n_or_frame; proj=(:ISO, :TI, :ORTHO), ε=1e-6)Find the best symmetry of tensor t with a fixed symmetry axis n (for TI) or material frame frame (for ORTHO). No rotation optimisation is performed.
n_or_frame: a vector (axis for TI) orOrthonormalBasis{3}(frame for ORTHO). For ISO projection the extra argument is ignored.
Returns (projected, d, drel, sym).
Examples
julia> n = [0., 0., 1.];
julia> C = tens_TI(10., 3., 2.5, 12., 2., n);
julia> _, _, drel, sym = best_sym_tens(C, n);
julia> sym == :TI && drel < 1e-12
trueTensND.change_tens — Method
change_tens(t::AbstractTens{order,dim,T},ℬ::AbstractBasis{dim},var::NTuple{order,Symbol})
change_tens(t::AbstractTens{order,dim,T},ℬ::AbstractBasis{dim})
change_tens(t::AbstractTens{order,dim,T},var::NTuple{order,Symbol})Rewrite the same tensor with components corresponding to new variances and/or to a new basis
julia> ℬ = Basis(Sym[0 1 1; 1 0 1; 1 1 0]) ;
julia> TV = Tens(Tensor{1,3}(i->symbols("v$i",real=true)))
TensND.TensCanonical{1, 3, Sym, Vec{3, Sym}}
# data: 3-element Vec{3, Sym}:
v₁
v₂
v₃
# basis: 3×3 TensND.LazyIdentity{3, Sym}:
1 0 0
0 1 0
0 0 1
# var: (:cont,)
julia> factor.(components(TV, ℬ, (:cont,)))
3-element Vector{Sym}:
-(v1 - v2 - v3)/2
(v1 - v2 + v3)/2
(v1 + v2 - v3)/2
julia> ℬ₀ = Basis(Sym[0 1 1; 1 0 1; 1 1 1]) ;
julia> TV0 = change_tens(TV, ℬ₀)
Tens{1, 3, Sym, Vec{3, Sym}}
# data: 3-element Vec{3, Sym}:
-v₁ + v₃
-v₂ + v₃
v₁ + v₂ - v₃
# basis: 3×3 Tensor{2, 3, Sym, 9}:
0 1 1
1 0 1
1 1 1
# var: (:cont,)TensND.change_tens_canon — Method
change_tens_canon(t::AbstractTens{order,dim,T},var::NTuple{order,Symbol})Rewrite the same tensor with components corresponding to the canonical basis
julia> ℬ = Basis(Sym[0 1 1; 1 0 1; 1 1 0]) ;
julia> TV = Tens(Tensor{1,3}(i->symbols("v$i",real=true)), ℬ)
Tens{1, 3, Sym, Vec{3, Sym}}
# data: 3-element Vec{3, Sym}:
v₁
v₂
v₃
# basis: 3×3 Tensor{2, 3, Sym, 9}:
0 1 1
1 0 1
1 1 1
# var: (:cont,)
julia> TV0 = change_tens_canon(TV)
TensND.TensCanonical{1, 3, Sym, Vec{3, Sym}}
# data: 3-element Vec{3, Sym}:
v₂ + v₃
v₁ + v₃
v₁ + v₂ + v₃
# basis: 3×3 TensND.LazyIdentity{3, Sym}:
1 0 0
0 1 0
0 0 1
# var: (:cont,)TensND.components — Method
components(t::AbstractTens{order,dim,T},ℬ::AbstractBasis{dim},var::NTuple{order,Symbol})
components(t::AbstractTens{order,dim,T},ℬ::AbstractBasis{dim})
components(t::AbstractTens{order,dim,T},var::NTuple{order,Symbol})Extract the components of a tensor for new variances and/or in a new basis
Examples
julia> ℬ = Basis(Sym[0 1 1; 1 0 1; 1 1 0]) ;
julia> TV = Tens(Tensor{1,3}(i->symbols("v$i",real=true)))
TensND.TensCanonical{1, 3, Sym, Vec{3, Sym}}
# data: 3-element Vec{3, Sym}:
v₁
v₂
v₃
# basis: 3×3 TensND.LazyIdentity{3, Sym}:
1 0 0
0 1 0
0 0 1
# var: (:cont,)
julia> factor.(components(TV, ℬ, (:cont,)))
3-element Vector{Sym}:
-(v1 - v2 - v3)/2
(v1 - v2 + v3)/2
(v1 + v2 - v3)/2
julia> components(TV, ℬ, (:cov,))
3-element Vector{Sym}:
v₂ + v₃
v₁ + v₃
v₁ + v₂
julia> simplify.(components(TV, normalize(ℬ), (:cov,)))
3-element Vector{Sym}:
sqrt(2)*(v2 + v3)/2
sqrt(2)*(v1 + v3)/2
sqrt(2)*(v1 + v2)/2
julia> TT = Tens(Tensor{2,3}((i,j)->symbols("t$i$j",real=true)))
TensND.TensCanonical{2, 3, Sym, Tensor{2, 3, Sym, 9}}
# data: 3×3 Tensor{2, 3, Sym, 9}:
t₁₁ t₁₂ t₁₃
t₂₁ t₂₂ t₂₃
t₃₁ t₃₂ t₃₃
# basis: 3×3 TensND.LazyIdentity{3, Sym}:
1 0 0
0 1 0
0 0 1
# var: (:cont, :cont)
julia> components(TT, ℬ, (: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.(components(TT, ℬ, (:cont,:cov)))
3×3 Matrix{Sym}:
-(t12 + t13 - t22 - t23 - t32 - t33)/2 … -(t11 + t12 - t21 - t22 - t31 - t32)/2
(t12 + t13 - t22 - t23 + t32 + t33)/2 (t11 + t12 - t21 - t22 + t31 + t32)/2
(t12 + t13 + t22 + t23 - t32 - t33)/2 (t11 + t12 + t21 + t22 - t31 - t32)/2TensND.components_canon — Method
components_canon(t::AbstractTens)Extract the components of a tensor in the canonical basis
TensND.contract — Method
contract(t::AbstractTens{order,dim}, i::Integer, j::Integer)Calculate the tensor obtained after contraction with respect to the indices i and j
TensND.coorsys_cartesian — Method
coorsys_cartesian(coords = symbols("x y z", real = true))Return the cartesian coordinate system
Examples
julia> Cartesian = coorsys_cartesian() ; 𝐗 = getcoords(Cartesian) ; 𝐄 = unitvec(Cartesian) ; ℬ = get_basis(Cartesian)
julia> 𝛔 = Tens(SymmetricTensor{2,3}((i, j) -> SymFunction("σ$i$j", real = true)(𝐗...))) ;
julia> DIV(𝛔, CScar)
Tens.TensCanonical{1, 3, Sym, Vec{3, Sym}}
# data: 3-element Vec{3, Sym}:
Derivative(σ11(x, y, z), x) + Derivative(σ21(x, y, z), y) + Derivative(σ31(x, y, z), z)
Derivative(σ21(x, y, z), x) + Derivative(σ22(x, y, z), y) + Derivative(σ32(x, y, z), z)
Derivative(σ31(x, y, z), x) + Derivative(σ32(x, y, z), y) + Derivative(σ33(x, y, z), z)
# basis: 3×3 Tens.LazyIdentity{3, Sym}:
1 0 0
0 1 0
0 0 1
# var: (:cont,)TensND.coorsys_cartesian_num — Method
coorsys_cartesian_num(T=Float64)Numerical Cartesian coordinate system in 3D. Coordinates: (x, y, z).
TensND.coorsys_cylindrical — Method
coorsys_cylindrical(coords = (symbols("r", positive = true), symbols("θ", real = true), symbols("z", real = true)); canonical = false)Return the cylindrical coordinate system
Examples
julia> Cylindrical = coorsys_cylindrical() ; rθz = getcoords(Cylindrical) ; 𝐞ʳ, 𝐞ᶿ, 𝐞ᶻ = unitvec(Cylindrical) ; ℬᶜ = get_basis(Cylindrical)
julia> 𝐯 = Tens(Vec{3}(i -> SymFunction("v$(rθz[i])", real = true)(rθz...)), ℬᶜ) ;
julia> DIV(𝐯, Cylindrical)
∂
vr(r, θ, z) + ──(vθ(r, θ, z))
∂ ∂ ∂θ
──(vr(r, θ, z)) + ──(vz(r, θ, z)) + ─────────────────────────────
∂r ∂z rTensND.coorsys_cylindrical_num — Method
coorsys_cylindrical_num(T=Float64)Numerical cylindrical coordinate system. Coordinates: (r, θ, z). Lamé coefficients: (1, r, 1).
TensND.coorsys_polar — Method
coorsys_polar(coords = (symbols("r", positive = true), symbols("θ", real = true)); canonical = false)Return the polar coordinate system
Examples
julia> Polar = coorsys_polar() ; r, θ = getcoords(Polar) ; 𝐞ʳ, 𝐞ᶿ = unitvec(Polar) ; ℬᵖ = get_basis(Polar)
julia> f = SymFunction("f", real = true)(r, θ) ;
julia> LAPLACE(f, Polar)
2
∂
───(f(r, θ))
2
∂ ∂θ
2 ──(f(r, θ)) + ────────────
∂ ∂r r
───(f(r, θ)) + ──────────────────────────
2 r
∂rTensND.coorsys_polar_num — Method
coorsys_polar_num(T=Float64)Numerical polar coordinate system. Coordinates: (r, θ). Lamé coefficients: (1, r).
TensND.coorsys_spherical — Method
coorsys_spherical(coords = (symbols("θ", real = true), symbols("ϕ", real = true), symbols("r", positive = true)); canonical = false)Return the spherical coordinate system
Examples
julia> Spherical = coorsys_spherical() ; θ, ϕ, r = getcoords(Spherical) ; 𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ = unitvec(Spherical) ; ℬˢ = get_basis(Spherical)
julia> for σⁱʲ ∈ ("σʳʳ", "σᶿᶿ", "σᵠᵠ") @eval $(Symbol(σⁱʲ)) = SymFunction($σⁱʲ, real = true)($r) end ;
julia> 𝛔 = σʳʳ * 𝐞ʳ ⊗ 𝐞ʳ + σᶿᶿ * 𝐞ᶿ ⊗ 𝐞ᶿ + σᵠᵠ * 𝐞ᵠ ⊗ 𝐞ᵠ ;
julia> div𝛔 = DIV(𝛔, Spherical)
Tens.TensRotated{1, 3, Sym, Vec{3, Sym}}
# data: 3-element Vec{3, Sym}:
(-σᵠᵠ(r) + σᶿᶿ(r))*cos(θ)/(r*sin(θ))
0
Derivative(σʳʳ(r), r) + (σʳʳ(r) - σᵠᵠ(r))/r + (σʳʳ(r) - σᶿᶿ(r))/r
# basis: 3×3 Tensor{2, 3, Sym, 9}:
cos(θ)⋅cos(ϕ) -sin(ϕ) sin(θ)⋅cos(ϕ)
sin(ϕ)⋅cos(θ) cos(ϕ) sin(θ)⋅sin(ϕ)
-sin(θ) 0 cos(θ)
# var: (:cont,)
julia> div𝛔 ⋅ 𝐞ʳ
d σʳʳ(r) - σᵠᵠ(r) σʳʳ(r) - σᶿᶿ(r)
──(σʳʳ(r)) + ─────────────── + ───────────────
dr r rTensND.coorsys_spherical_num — Method
coorsys_spherical_num(T=Float64)Numerical spherical coordinate system. Coordinates: (θ, ϕ, r) — same convention as coorsys_spherical(). Lamé coefficients: (r, r·sin(θ), 1).
TensND.coorsys_spheroidal — Method
coorsys_spheroidal(coords = (symbols("ϕ", real = true),symbols("p", real = true),symbols("q", positive = true),),
c = symbols("c", positive = true),tmp_coords = (symbols("p̄ q̄", positive = true)...,),)Return the spheroidal coordinate system
Examples
julia> Spheroidal = coorsys_spheroidal() ; OM = getOM(Spheroidal)
Tens.TensCanonical{1, 3, Sym, Vec{3, Sym}}
# data: 3-element Vec{3, Sym}:
c⋅p̄⋅q̄⋅cos(ϕ)
c⋅p̄⋅q̄⋅sin(ϕ)
c⋅p⋅q
# basis: 3×3 Tens.LazyIdentity{3, Sym}:
1 0 0
0 1 0
0 0 1
# var: (:cont,)
julia> LAPLACE(OM[1]^2, Spheroidal)
2TensND.frame — Method
frame(t::TensOrtho)Return the material frame of an orthotropic tensor.
TensND.fromISO — Method
fromISO(A::TensISO{4,3}, n) → TensTI{4, T, 5}Convert an isotropic 4th-order tensor αJ + βK into its Walpole representation.
Formulas: ℓ₁=(α+2β)/3, ℓ₂=(2α+β)/3 (note: dim=3 → these are (3k,2μ) related), ℓ₃=ℓ₄=√2(α−β)/3, ℓ₅=ℓ₆=β. Here α = data[1] and β = data[2] in TensISO (coefficients of J and K).
TensND.get_array — Method
get_array(t::TensOrtho{T}) → Array{T,4}Compute the 3×3×3×3 component array in the canonical frame.
TensND.get_array — Method
get_array(t::TensTI{2,T,2}) → Array{T,2}Compute the 3×3 component array: a*(δᵢⱼ − nᵢnⱼ) + b*nᵢnⱼ.
Examples
julia> A = TensTI{2}(5.0, 8.0, [0., 0., 1.]);
julia> get_array(A)
3×3 Matrix{Float64}:
5.0 0.0 0.0
0.0 5.0 0.0
0.0 0.0 8.0TensND.get_array — Method
get_array(t::TensTI{4, T}) → Array{T,4}Compute the 3×3×3×3 component array from the Walpole coefficients and axis.
TensND.get_ℓ — Method
get_ℓ(t::TensTI{4,T,N}) → NTuple{6,T}Always returns a 6-tuple (ℓ₁, ℓ₂, ℓ₃, ℓ₄, ℓ₅, ℓ₆) of Walpole coefficients. For N=5 (major-symmetric), ℓ₃ = ℓ₄ is stored once and duplicated on read.
TensND.init_cartesian — Function
init_cartesian(coords = symbols("x y z", real = true))Returns the coordinates, unit vectors and basis of the cartesian basis
Examples
julia> coords, vectors, ℬ = init_cartesian() ; x, y, z = coords ; 𝐞₁, 𝐞₂, 𝐞₃ = vectors ;TensND.init_cylindrical — Function
init_cylindrical(coords = (symbols("r", positive = true), symbols("θ z", real = true)...); canonical = false)Returns the coordinates, base vectors and basis of the cylindrical basis
Examples
julia> coords, vectors, ℬᶜ = init_cylindrical() ; r, θ, z = coords ; 𝐞ʳ, 𝐞ᶿ, 𝐞ᶻ = vectors ;TensND.init_polar — Function
init_polar(coords = (symbols("r θ", real = true)); canonical = false)Returns the coordinates, base vectors and basis of the polar basis
Examples
julia> coords, vectors, ℬᵖ = init_polar() ; r, θ = coords ; 𝐞ʳ, 𝐞ᶿ = vectors ;TensND.init_rotated — Function
init_rotated(coords = symbols("θ ϕ ψ", real = true); canonical = false)Return the angles, base vectors and basis of the rotated basis. Note that here the coordinates are angles and do not represent a valid parametrization of ℝ³
Examples
julia> angles, vectors, ℬʳ = init_rotated() ; θ, ϕ, ψ = angles ; 𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ = vectors ;TensND.init_spherical — Function
init_spherical(coords = (symbols("θ ϕ", real = true)..., symbols("r", positive = true)); canonical = false)Return the coordinates, base vectors and basis of the spherical basis. Take care that the order of the 3 vectors is 𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ so that the basis coincides with the canonical one when the angles are null and in consistency the coordinates are ordered as θ, ϕ, r.
Examples
julia> coords, vectors, ℬˢ = init_spherical() ; θ, ϕ, r = coords ; 𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ = vectors ;TensND.inv_KM — Method
inv_KM(v::AbstractVecOrMat; kwargs...)Define a tensor from a Kelvin-Mandel vector or matrix representation
TensND.is_ISO — Method
is_ISO(A::AbstractArray; ε=1e-6) → BoolReturn true when the components of A satisfy material isotropy up to relative tolerance ε (closed-form projection: no optimisation).
The value-level predicate complements the type-level is_ISO(::TensISO) = true defined in tens_isotropic.jl: the type version asks whether the container imposes isotropy, this version asks whether the numerical components satisfy it.
Examples
julia> C = [1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0];
julia> is_ISO(C)
true
julia> is_ISO([1.0 2.0 0.0; 2.0 3.0 0.0; 0.0 0.0 1.0])
falseTensND.is_ORTHO — Method
is_ORTHO(A::AbstractArray, frame::OrthonormalBasis{3}; ε=1e-6) → BoolReturn true when A is orthotropic in the given material frame up to relative tolerance ε (closed-form projection on the fixed frame).
TensND.is_ORTHO — Method
is_ORTHO(A::AbstractArray; ε=1e-6, optimize_angles=false) → BoolCheap default: propose a candidate orthotropic frame from the Kelvin-Mandel eigendecomposition and check the residual. With optimize_angles=true, runs the NLopt-backed frame search — requires using NLopt.
TensND.is_TI — Method
is_TI(A::AbstractArray, n; ε=1e-6) → BoolReturn true when A is transversely isotropic about the given axis n up to relative tolerance ε (closed-form projection on the fixed axis).
Examples
julia> n = [0.0, 0.0, 1.0];
julia> C = tens_TI(10., 3., 2.5, 12., 2., n);
julia> is_TI(get_array(C), n)
true
julia> is_TI(get_array(C), [1.0, 0.0, 0.0])
falseTensND.is_TI — Method
is_TI(A::AbstractArray; ε=1e-6, optimize_angles=false) → BoolCheap default: propose a candidate TI axis from the Kelvin-Mandel eigendecomposition of A and check the residual. With optimize_angles=true, runs the NLopt-backed axis search — requires using NLopt.
See also is_TI(A, n), _candidate_TI_axis.
TensND.is_TI — Method
is_TI(A)Return true if A is a TensTI{4}, indicating transverse isotropy.
TensND.iso_projectors — Method
iso_projectors(::Val{dim} = Val(3), ::Val{T} = Val(Sym))Return the three fourth-order isotropic tensors (𝕀, 𝕁, 𝕂) — the symmetric identity, spherical projector, and deviatoric projector. Any isotropic 4th-order tensor can be written as α·𝕁 + β·𝕂.
Examples
julia> 𝕀, 𝕁, 𝕂 = iso_projectors();
julia> 𝕁 + 𝕂 == 𝕀
trueTensND.iso_to_ortho — Method
iso_to_ortho(A::TensISO{4,3,T}, frame::OrthonormalBasis{3}) → TensOrtho{T}Convert an isotropic 4th-order tensor α·𝕁 + β·𝕂 into a TensOrtho stored in the given material frame. An isotropic tensor is orthotropic in any frame; the orthotropic coefficients are
C₁₁ = C₂₂ = C₃₃ = (α + 2β) / 3
C₁₂ = C₁₃ = C₂₃ = (α − β) / 3
C₄₄ = C₅₅ = C₆₆ = β / 2This is the obvious promotion for operations that combine TensISO{4} with a TensOrtho, e.g. TensISO + TensOrtho → TensOrtho.
Examples
julia> I4 = TensISO{3}(2.0, 3.0); # α=2, β=3
julia> O = iso_to_ortho(I4, CanonicalBasis{3,Float64}());
julia> typeof(O) === TensOrtho{Float64}
true
julia> get_data(O)[1], get_data(O)[4], get_data(O)[7]
(2.6666666666666665, -0.3333333333333333, 1.5)See also walpole_to_ortho, fromISO.
TensND.isorthogonal — Method
isorthogonal(ℬ::AbstractBasis)Check whether the basis ℬ is orthogonal
TensND.isorthonormal — Method
isorthonormal(ℬ::AbstractBasis)Check whether the basis ℬ is orthonormal
TensND.metric — Method
metric(ℬ::AbstractBasis, var = :cov)Return the covariant (if var = :cov) or contravariant (if var = :cont) metric matrix
TensND.natural_basis — Method
natural_basis(CS::CoorSystemNum, x₀) → AbstractBasisReturn the natural (non-normalized) basis at point x₀ as an OrthogonalBasis (i.e. a RotatedBasis scaled by the Lamé coefficients).
TensND.natvec — Method
natvec(CS::CoorSystemNum, x₀, i, var=:cov) → AbstractTensReturn the i-th natural basis vector at point x₀, either covariant (var=:cov, proportional to χᵢ) or contravariant (var=:cont, proportional to 1/χᵢ).
TensND.normalized_basis — Method
normalized_basis(CS::CoorSystemNum, x₀) → AbstractBasisReturn the normalized (orthonormal) basis at point x₀ as a RotatedBasis or CanonicalBasis (when the system is Cartesian at that point).
TensND.otimesul — Method
otimesul(t1::AbstractTens{order1,dim}, t2::AbstractTens{order2,dim})Define a special tensor product between two tensors of at least second order
(𝐚 ⊠ˢ 𝐛) ⊡ 𝐩 = (𝐚 ⊠ 𝐛) ⊡ (𝐩 + ᵗ𝐩)/2 = 1/2(aⁱᵏbʲˡ+aⁱˡbʲᵏ) pₖₗ eᵢ⊗eⱼ
TensND.proj_tens — Method
proj_tens(sym::Symbol, A::AbstractArray, arg) → (projected, d, drel)Convenience dispatch: proj_tens(:TI, A, n) calls proj_tens(Val(:TI), A, n).
TensND.proj_tens — Method
proj_tens(::Val{:ORTHO}, A::AbstractArray{T,4}, frame::OrthonormalBasis{3}) → (TensOrtho{T}, d, drel)Project a 4th-order tensor A (3×3×3×3) onto the orthotropic subspace with fixed material frame frame. Returns a TensOrtho{T}.
Examples
julia> frame = CanonicalBasis{3,Float64}();
julia> t = TensOrtho(10., 8., 12., 3., 2.5, 1.5, 2., 3., 3.5, frame);
julia> B, d, drel = proj_tens(:ORTHO, get_array(t), frame);
julia> d < 1e-12
trueTensND.proj_tens — Method
proj_tens(::Val{:ORTHO}, A::AbstractArray{T,4}) where {T<:AbstractFloat}Find the best orthotropic approximation of A by optimizing over all possible material frames. Requires the NLopt package: using NLopt.
TensND.proj_tens — Method
proj_tens(::Val{:ORTHO}, A::AbstractArray{T,2}, frame::OrthonormalBasis{3}) → (Array{T,2}, d, drel)Project a 2nd-order tensor A (3×3) onto the orthotropic subspace with fixed material frame frame. The projection is diag(M₁₁, M₂₂, M₃₃) in the material frame.
Examples
julia> frame = CanonicalBasis{3,Float64}();
julia> A = [5. 1 2; 1 8 3; 2 3 12];
julia> B, d, drel = proj_tens(:ORTHO, A, frame);
julia> B ≈ diagm([5., 8., 12.])
trueTensND.proj_tens — Method
proj_tens(::Val{:ORTHO}, A::AbstractArray{T,2}) where {T<:AbstractFloat}Find the best orthotropic approximation of a 2nd-order tensor A by optimizing the material frame. Requires the NLopt package: using NLopt.
TensND.proj_tens — Method
proj_tens(::Val{:TI}, A::AbstractArray{T,4}, n) → (TensTI{4, T, 5}, d, drel)Project a 4th-order tensor A (3×3×3×3) onto the transversely isotropic subspace with fixed symmetry axis n. Returns a major-symmetric TensTI{4, T, 5}.
The projection minimises the Frobenius distance ‖B − A‖ over all TI tensors B with axis n.
Returns a 3-tuple (B, d, drel):
B: the projectedTensTI{4, T, 5}d: absolute Frobenius distance‖B − A‖drel: relative distanced / ‖A‖
Examples
julia> n = [0., 0., 1.];
julia> C = tens_TI(10., 3., 2.5, 12., 2., n);
julia> B, d, drel = proj_tens(:TI, get_array(C), n);
julia> d < 1e-12
true
julia> arg_TI(B) == arg_TI(C)
trueTensND.proj_tens — Method
proj_tens(::Val{:TI}, A::AbstractArray{T,4}) where {T<:AbstractFloat}Find the best TI approximation of A by optimizing over all possible symmetry axes. Requires the NLopt package: using NLopt.
See also proj_tens(::Val{:TI}, A, n) for fixed-axis projection.
TensND.proj_tens — Method
proj_tens(::Val{:TI}, A::AbstractArray{T,2}, n) → (TensTI{2,T,2}, d, drel)Project a 2nd-order tensor A (3×3) onto the transversely isotropic subspace with fixed symmetry axis n. Returns a TensTI{2,T,2}.
In the rotated frame where e₃ = n:
a = (M[1,1] + M[2,2]) / 2(transverse)b = M[3,3](axial)
Examples
julia> n = [0., 0., 1.];
julia> A = [5. 0 0; 0 5 0; 0 0 8];
julia> B, d, drel = proj_tens(:TI, A, n);
julia> B.data
(5.0, 8.0)TensND.proj_tens — Method
proj_tens(::Val{:TI}, A::AbstractArray{T,2}) where {T<:AbstractFloat}Find the best TI approximation of a 2nd-order tensor A by optimizing the symmetry axis. Requires the NLopt package: using NLopt.
TensND.qcontract — Method
qcontract(t1::AbstractTens{order1,dim}, t2::AbstractTens{order2,dim})Define a quadruple contracted product between two tensors
𝔸 ⊙ 𝔹 = AᵢⱼₖₗBⁱʲᵏˡ
Examples
julia> 𝕀 = t𝕀(Sym) ; 𝕁 = t𝕁(Sym) ; 𝕂 = t𝕂(Sym) ;
julia> 𝕀 ⊙ 𝕀
6
julia> 𝕁 ⊙ 𝕀
1
julia> 𝕂 ⊙ 𝕀
5
julia> 𝕂 ⊙ 𝕁
0TensND.reference — Method
reference(t)Return the geometric reference that parametrises the material symmetry of t: the symmetry axis NTuple{3} for a TensTI, the material frame OrthonormalBasis{3} for a TensOrtho, and nothing for TensISO or any tensor without a structured reference.
Examples
julia> reference(tens_TI(10., 3., 2.5, 12., 2., [0., 0., 1.]))
(0.0, 0.0, 1.0)
julia> reference(TensISO{3}(2.0, 3.0)) === nothing
trueTensND.rot2 — Method
rot2(θ)Return a 2D rotation matrix with respect to the angle θ
Examples
julia> rot2(θ)
2×2 Tensor{2, 2, Sym, 4}:
cos(θ) -sin(θ)
sin(θ) cos(θ)TensND.rot3 — Function
rot3(θ, ϕ = 0, ψ = 0)Return a rotation matrix with respect to the 3 Euler angles θ, ϕ, ψ
Examples
julia> cθ, cϕ, cψ, sθ, sϕ, sψ = symbols("cθ cϕ cψ sθ sϕ sψ", real = true) ;
julia> d = Dict(cos(θ) => cθ, cos(ϕ) => cϕ, cos(ψ) => cψ, sin(θ) => sθ, sin(ϕ) => sϕ, sin(ψ) => sψ) ;
julia> subs.(rot3(θ, ϕ, ψ),d...)
3×3 StaticArrays.SMatrix{3, 3, Sym, 9} with indices SOneTo(3)×SOneTo(3):
cθ⋅cψ⋅cϕ - sψ⋅sϕ -cθ⋅cϕ⋅sψ - cψ⋅sϕ cϕ⋅sθ
cθ⋅cψ⋅sϕ + cϕ⋅sψ -cθ⋅sψ⋅sϕ + cψ⋅cϕ sθ⋅sϕ
-cψ⋅sθ sθ⋅sψ cθTensND.rot6 — Function
rot6(θ, ϕ = 0, ψ = 0)Return a rotation matrix with respect to the 3 Euler angles θ, ϕ, ψ
Examples
julia> cθ, cϕ, cψ, sθ, sϕ, sψ = symbols("cθ cϕ cψ sθ sϕ sψ", real = true) ;
julia> d = Dict(cos(θ) => cθ, cos(ϕ) => cϕ, cos(ψ) => cψ, sin(θ) => sθ, sin(ϕ) => sϕ, sin(ψ) => sψ) ;
julia> R = Tens(subs.(rot3(θ, ϕ, ψ),d...))
Tens.TensCanonical{2, 3, Sym, Tensor{2, 3, Sym, 9}}
# data: 3×3 Tensor{2, 3, Sym, 9}:
cθ⋅cψ⋅cϕ - sψ⋅sϕ -cθ⋅cϕ⋅sψ - cψ⋅sϕ cϕ⋅sθ
cθ⋅cψ⋅sϕ + cϕ⋅sψ -cθ⋅sψ⋅sϕ + cψ⋅cϕ sθ⋅sϕ
-cψ⋅sθ sθ⋅sψ cθ
# var: (:cont, :cont)
# basis: 3×3 Tens.LazyIdentity{3, Sym}:
1 0 0
0 1 0
0 0 1
julia> RR = R ⊠ˢ R
Tens.TensCanonical{4, 3, Sym, SymmetricTensor{4, 3, Sym, 36}}
# data: 6×6 Matrix{Sym}:
(cθ*cψ*cϕ - sψ*sϕ)^2 (-cθ*cϕ*sψ - cψ*sϕ)^2 cϕ^2*sθ^2 √2⋅cϕ⋅sθ⋅(-cθ⋅cϕ⋅sψ - cψ⋅sϕ) √2⋅cϕ⋅sθ⋅(cθ⋅cψ⋅cϕ - sψ⋅sϕ) √2⋅(cθ⋅cψ⋅cϕ - sψ⋅sϕ)⋅(-cθ⋅cϕ⋅sψ - cψ⋅sϕ)
(cθ*cψ*sϕ + cϕ*sψ)^2 (-cθ*sψ*sϕ + cψ*cϕ)^2 sθ^2*sϕ^2 √2⋅sθ⋅sϕ⋅(-cθ⋅sψ⋅sϕ + cψ⋅cϕ) √2⋅sθ⋅sϕ⋅(cθ⋅cψ⋅sϕ + cϕ⋅sψ) √2⋅(cθ⋅cψ⋅sϕ + cϕ⋅sψ)⋅(-cθ⋅sψ⋅sϕ + cψ⋅cϕ)
cψ^2*sθ^2 sθ^2*sψ^2 cθ^2 √2⋅cθ⋅sθ⋅sψ -√2⋅cθ⋅cψ⋅sθ -sqrt(2)*cψ*sθ^2*sψ
-√2⋅cψ⋅sθ⋅(cθ⋅cψ⋅sϕ + cϕ⋅sψ) √2⋅sθ⋅sψ⋅(-cθ⋅sψ⋅sϕ + cψ⋅cϕ) √2⋅cθ⋅sθ⋅sϕ cθ*(-cθ*sψ*sϕ + cψ*cϕ) + sθ^2*sψ*sϕ cθ*(cθ*cψ*sϕ + cϕ*sψ) - cψ*sθ^2*sϕ -cψ⋅sθ⋅(-cθ⋅sψ⋅sϕ + cψ⋅cϕ) + sθ⋅sψ⋅(cθ⋅cψ⋅sϕ + cϕ⋅sψ)
-√2⋅cψ⋅sθ⋅(cθ⋅cψ⋅cϕ - sψ⋅sϕ) √2⋅sθ⋅sψ⋅(-cθ⋅cϕ⋅sψ - cψ⋅sϕ) √2⋅cθ⋅cϕ⋅sθ cθ*(-cθ*cϕ*sψ - cψ*sϕ) + cϕ*sθ^2*sψ cθ*(cθ*cψ*cϕ - sψ*sϕ) - cψ*cϕ*sθ^2 -cψ⋅sθ⋅(-cθ⋅cϕ⋅sψ - cψ⋅sϕ) + sθ⋅sψ⋅(cθ⋅cψ⋅cϕ - sψ⋅sϕ)
√2⋅(cθ⋅cψ⋅cϕ - sψ⋅sϕ)⋅(cθ⋅cψ⋅sϕ + cϕ⋅sψ) √2⋅(-cθ⋅cϕ⋅sψ - cψ⋅sϕ)⋅(-cθ⋅sψ⋅sϕ + cψ⋅cϕ) sqrt(2)*cϕ*sθ^2*sϕ cϕ⋅sθ⋅(-cθ⋅sψ⋅sϕ + cψ⋅cϕ) + sθ⋅sϕ⋅(-cθ⋅cϕ⋅sψ - cψ⋅sϕ) cϕ⋅sθ⋅(cθ⋅cψ⋅sϕ + cϕ⋅sψ) + sθ⋅sϕ⋅(cθ⋅cψ⋅cϕ - sψ⋅sϕ) (cθ*cψ*cϕ - sψ*sϕ)*(-cθ*sψ*sϕ + cψ*cϕ) + (cθ*cψ*sϕ + cϕ*sψ)*(-cθ*cϕ*sψ - cψ*sϕ)
# var: (:cont, :cont, :cont, :cont)
# basis: 3×3 Tens.LazyIdentity{3, Sym}:
1 0 0
0 1 0
0 0 1
julia> R6 = inv_KM(subs.(KM(rot6(θ, ϕ, ψ)),d...))
Tens.TensCanonical{4, 3, Sym, SymmetricTensor{4, 3, Sym, 36}}
# data: 6×6 Matrix{Sym}:
(cθ*cψ*cϕ - sψ*sϕ)^2 (-cθ*cϕ*sψ - cψ*sϕ)^2 cϕ^2*sθ^2 √2⋅cϕ⋅sθ⋅(-cθ⋅cϕ⋅sψ - cψ⋅sϕ) √2⋅cϕ⋅sθ⋅(cθ⋅cψ⋅cϕ - sψ⋅sϕ) √2⋅(cθ⋅cψ⋅cϕ - sψ⋅sϕ)⋅(-cθ⋅cϕ⋅sψ - cψ⋅sϕ)
(cθ*cψ*sϕ + cϕ*sψ)^2 (-cθ*sψ*sϕ + cψ*cϕ)^2 sθ^2*sϕ^2 √2⋅sθ⋅sϕ⋅(-cθ⋅sψ⋅sϕ + cψ⋅cϕ) √2⋅sθ⋅sϕ⋅(cθ⋅cψ⋅sϕ + cϕ⋅sψ) √2⋅(cθ⋅cψ⋅sϕ + cϕ⋅sψ)⋅(-cθ⋅sψ⋅sϕ + cψ⋅cϕ)
cψ^2*sθ^2 sθ^2*sψ^2 cθ^2 √2⋅cθ⋅sθ⋅sψ -√2⋅cθ⋅cψ⋅sθ -sqrt(2)*cψ*sθ^2*sψ
-√2⋅cψ⋅sθ⋅(cθ⋅cψ⋅sϕ + cϕ⋅sψ) √2⋅sθ⋅sψ⋅(-cθ⋅sψ⋅sϕ + cψ⋅cϕ) √2⋅cθ⋅sθ⋅sϕ cθ*(-cθ*sψ*sϕ + cψ*cϕ) + sθ^2*sψ*sϕ cθ*(cθ*cψ*sϕ + cϕ*sψ) - cψ*sθ^2*sϕ -cψ⋅sθ⋅(-cθ⋅sψ⋅sϕ + cψ⋅cϕ) + sθ⋅sψ⋅(cθ⋅cψ⋅sϕ + cϕ⋅sψ)
-√2⋅cψ⋅sθ⋅(cθ⋅cψ⋅cϕ - sψ⋅sϕ) √2⋅sθ⋅sψ⋅(-cθ⋅cϕ⋅sψ - cψ⋅sϕ) √2⋅cθ⋅cϕ⋅sθ cθ*(-cθ*cϕ*sψ - cψ*sϕ) + cϕ*sθ^2*sψ cθ*(cθ*cψ*cϕ - sψ*sϕ) - cψ*cϕ*sθ^2 -cψ⋅sθ⋅(-cθ⋅cϕ⋅sψ - cψ⋅sϕ) + sθ⋅sψ⋅(cθ⋅cψ⋅cϕ - sψ⋅sϕ)
√2⋅(cθ⋅cψ⋅cϕ - sψ⋅sϕ)⋅(cθ⋅cψ⋅sϕ + cϕ⋅sψ) √2⋅(-cθ⋅cϕ⋅sψ - cψ⋅sϕ)⋅(-cθ⋅sψ⋅sϕ + cψ⋅cϕ) sqrt(2)*cde Liv Lehn ϕ*sθ^2*sϕ cϕ⋅sθ⋅(-cθ⋅sψ⋅sϕ + cψ⋅cϕ) + sθ⋅sϕ⋅(-cθ⋅cϕ⋅sψ - cψ⋅sϕ) cϕ⋅sθ⋅(cθ⋅cψ⋅sϕ + cϕ⋅sψ) + sθ⋅sϕ⋅(cθ⋅cψ⋅cϕ - sψ⋅sϕ) (cθ*cψ*cϕ - sψ*sϕ)*(-cθ*sψ*sϕ + cψ*cϕ) + (cθ*cψ*sϕ + cϕ*sψ)*(-cθ*cϕ*sψ - cψ*sϕ)
# var: (:cont, :cont, :cont, :cont)
# basis: 3×3 Tens.LazyIdentity{3, Sym}:
1 0 0
0 1 0
0 0 1
julia> R6 == RR
trueTensND.sotimes — Method
sotimes(t1::AbstractTens{order1,dim}, t2::AbstractTens{order2,dim})Define a symmetric tensor product between two tensors
(aⁱeᵢ) ⊗ˢ (bʲeⱼ) = 1/2(aⁱbʲ + aʲbⁱ) eᵢ⊗eⱼ
TensND.symmetry — Method
symmetry(t) -> SymbolReturn the material symmetry class imposed by the container type of t: :ISO, :TI, :ORTHO, or :ANISO (default for any unstructured tensor).
This is a type-level query — it tells you what symmetry the storage guarantees, not whether the numerical components happen to satisfy a tighter symmetry. For value-level detection use best_sym_tens(t).
Examples
julia> symmetry(TensISO{3}(2.0, 3.0))
:ISO
julia> symmetry(tens_TI(10., 3., 2.5, 12., 2., [0., 0., 1.]))
:TISee also reference, is_ISO, is_TI, is_ORTHO, best_sym_tens.
TensND.tens_Id2 — Method
tens_Id2(::Val{dim}, ::Val{T}) where {dim,T<:Number}Identity tensor of second order 𝟏ᵢⱼ = δᵢⱼ = 1 if i=j otherwise 0
Examples
julia> 𝟏 = t𝟏() ; KM(𝟏)
6-element Vector{Sym}:
1
1
1
0
0
0
julia> 𝟏.data
3×3 SymmetricTensor{2, 3, Sym, 6}:
1 0 0
0 1 0
0 0 1TensND.tens_Id4 — Method
tens_Id4(::Val{dim} = Val(3), ::Val{T} = Val(Sym))Symmetric identity tensor of fourth order 𝕀 = 𝟏 ⊠ˢ 𝟏 i.e. (𝕀)ᵢⱼₖₗ = (δᵢₖδⱼₗ+δᵢₗδⱼₖ)/2
Examples
julia> 𝕀 = t𝕀() ; KM(𝕀)
6×6 Matrix{Sym}:
1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
0 0 0 1 0 0
0 0 0 0 1 0
0 0 0 0 0 1TensND.tens_J4 — Method
tens_J4(::Val{dim} = Val(3), ::Val{T} = Val(Sym))Spherical projector of fourth order 𝕁 = (𝟏 ⊗ 𝟏) / dim i.e. (𝕁)ᵢⱼₖₗ = δᵢⱼδₖₗ/dim
Examples
julia> 𝕁 = t𝕁() ; KM(𝕁)
6×6 Matrix{Sym}:
1/3 1/3 1/3 0 0 0
1/3 1/3 1/3 0 0 0
1/3 1/3 1/3 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0TensND.tens_K4 — Method
tens_K4(::Val{dim} = Val(3), ::Val{T} = Val(Sym))Deviatoric projector of fourth order 𝕂 = 𝕀 - 𝕁 i.e. (𝕂)ᵢⱼₖₗ = (δᵢₖδⱼₗ+δᵢₗδⱼₖ)/2 - δᵢⱼδₖₗ/dim
Examples
julia> 𝕂 = t𝕂() ; KM(𝕂)
6×6 Matrix{Sym}:
2/3 -1/3 -1/3 0 0 0
-1/3 2/3 -1/3 0 0 0
-1/3 -1/3 2/3 0 0 0
0 0 0 1 0 0
0 0 0 0 1 0
0 0 0 0 0 1TensND.tens_TI — Method
tens_TI(C₁₁₁₁, C₁₁₂₂, C₁₁₃₃, C₃₃₃₃, C₂₃₂₃, n) → TensTI{4, T, 5}Construct a major-symmetric TI 4th-order tensor from its 5 independent components and symmetry axis n. Works for both stiffness and compliance tensors (the formula is the same).
Walpole coefficients:
ℓ₁ = C₃₃₃₃ℓ₂ = C₁₁₁₁ + C₁₁₂₂ℓ₃ = √2 C₁₁₃₃ℓ₅ = C₁₁₁₁ − C₁₁₂₂ℓ₆ = 2 C₂₃₂₃
See also arg_TI, tens_TI_eng.
TensND.tens_TI_Hoenig — Method
tens_TI_Hoenig(E, ν₁, ν₂, H, Γ, n) → TensTI{4, T, 5}Construct the TI compliance tensor from 5 Hoenig parameters (Hoenig, 1978) and symmetry axis n.
E: transverse Young's modulus (= 1/S₁₁₁₁)ν₁: in-plane Poisson's ratio (= −E S₁₁₂₂)ν₂: axial-transverse Poisson's ratio (= −E S₁₁₃₃)H: axial-to-transverse modulus ratio (= 1/(E S₃₃₃₃))Γ: shear anisotropy parameter (= (1+ν₁)/(2 E S₂₃₂₃))
Compliance components:
S₁₁₁₁ = 1/ES₁₁₂₂ = −ν₁/ES₁₁₃₃ = −ν₂/ES₃₃₃₃ = 1/(E H)S₂₃₂₃ = (1+ν₁)/(2 E Γ)
To obtain the stiffness tensor, invert the result: inv(tens_TI_Hoenig(…)).
See also arg_TI_Hoenig, tens_TI_eng, tens_TI.
TensND.tens_TI_eng — Method
tens_TI_eng(E₁, E₃, ν₁₂, ν₃₁, G₃₁, n) → TensTI{4, T, 5}Construct the TI compliance tensor from 5 engineering constants and symmetry axis n.
E₁: transverse Young's modulus (isotropic plane)E₃: axial Young's modulus (symmetry axis)ν₁₂: in-plane Poisson's ratioν₃₁: axial-transverse Poisson's ratio (ν₃₁/E₃ = ν₁₃/E₁)G₃₁: axial shear modulus
To obtain the stiffness tensor, invert the result: inv(tens_TI_eng(…)).
See also arg_TI_eng, tens_TI.
TensND.tens_W1 — Method
tens_W1(n) → TensTI{4, T, 6} (W₁ = nₙ⊗nₙ, coeffs (1,0,0,0,0,0))TensND.tens_W2 — Method
tens_W2(n) → TensTI{4, T, 6} (W₂ = (nT⊗nT)/2, coeffs (0,1,0,0,0,0))TensND.tens_W3 — Method
tens_W3(n) → TensTI{4, T, 6} (W₃ = (nₙ⊗nT)/√2, coeffs (0,0,1,0,0,0))TensND.tens_W4 — Method
tens_W4(n) → TensTI{4, T, 6} (W₄ = (nT⊗nₙ)/√2, coeffs (0,0,0,1,0,0))TensND.tens_W5 — Method
tens_W5(n) → TensTI{4, T, 6} (W₅ = nT⊠ˢnT − (nT⊗nT)/2, coeffs (0,0,0,0,1,0))TensND.tens_W6 — Method
tens_W6(n) → TensTI{4, T, 6} (W₆ = nT⊠ˢnₙ + nₙ⊠ˢnT, coeffs (0,0,0,0,0,1))TensND.unitvec — Method
unitvec(CS::CoorSystemNum, x₀, i) → AbstractTensReturn the i-th unit vector of the normalized basis at point x₀.
TensND.vecbasis — Method
vecbasis(ℬ::AbstractBasis, var = :cov)Return the primal (if var = :cov) or dual (if var = :cont) basis
TensND.walpole_basis — Method
walpole_basis(n) → (W₁, W₂, W₃, W₄, W₅, W₆)Return the six general (N=6) Walpole basis tensors for the symmetry axis n. These span the full TI 4th-order tensor space, including the non-major-symmetric components W₃ ≠ W₄.
TensND.walpole_basis_sym — Method
walpole_basis_sym(n) → (W₁ˢ, W₂ˢ, W₃ˢ, W₄ˢ, W₅ˢ)Return the five major-symmetric (N=5) Walpole basis tensors for the symmetry axis n, where W₃ˢ = W₃ + W₄. Use this for building stiffness / compliance TI tensors, which are always major-symmetric.
TensND.walpole_to_ortho — Method
walpole_to_ortho(A::TensTI{4, T, 5}, frame::OrthonormalBasis{3}, axis_idx::Int) → TensOrtho{T}Convert a major-symmetric TensTI{4, T, 5} into a TensOrtho stored in the given material frame, assuming the Walpole axis A.n is aligned with axis axis_idx ∈ {1,2,3} of the frame. A TI tensor is a special case of an orthotropic tensor (with the 1–2 equivalence about the TI axis).
Mapping in the rotated material frame (TI axis = axis k):
Ctrtr = (ℓ₂ + ℓ₅) / 2 (transverse–transverse C in KM)
Cmix = (ℓ₂ − ℓ₅) / 2 (between the two transverse axes)
Cax_tr = ℓ₃ / √2 (axial ↔ transverse)
Cax = ℓ₁ (axial–axial)
Cshear_ax = ℓ₆ / 2 (shear involving the axial axis)
Cshear_tr = ℓ₅ / 2 (shear in the transverse plane)The 9 orthotropic coefficients are then permuted according to axis_idx.
Restricted to N=5 (major-symmetric Walpole): a non-major-symmetric TI (N=6) has no orthotropic counterpart in TensOrtho (which carries only 9 major-symmetric constants).
See also iso_to_ortho, _axis_on_frame_index.
TensND.∂ — Method
∂(f::Function, i::Integer, CS::CoorSystemNum, x₀)Covariant derivative of f with respect to the i-th coordinate, evaluated at x₀.
f must accept an AbstractVector of length dim and return either a scalar or a plain Array of physical (normalized-frame) components of the tensor field. Returns a plain scalar or plain Array (suitable for further ForwardDiff differentiation).
See also GRAD, DIV, LAPLACE, HESS, SYMGRAD for high-level operators that wrap results in AbstractTens.
TensND.∂ — Method
∂(t::AbstractTens{order,dim,T,A},xᵢ::T)Return the derivative of the tensor t with respect to the variable x_i
Examples
julia> (θ, ϕ, r), (𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ), ℬˢ = init_spherical() ;
julia> ∂(𝐞ʳ, ϕ) == sin(θ) * 𝐞ᵠ
true
julia> ∂(𝐞ʳ ⊗ 𝐞ʳ,θ)
Tens.TensRotated{2, 3, Sym, SymmetricTensor{2, 3, Sym, 6}}
# data: 3×3 SymmetricTensor{2, 3, Sym, 6}:
0 0 1
0 0 0
1 0 0
# basis: 3×3 Tensor{2, 3, Sym, 9}:
cos(θ)⋅cos(ϕ) -sin(ϕ) sin(θ)⋅cos(ϕ)
sin(ϕ)⋅cos(θ) cos(ϕ) sin(θ)⋅sin(ϕ)
-sin(θ) 0 cos(θ)
# var: (:cont, :cont)TensND.𝐞 — Method
𝐞(i::Integer, dim::Int = 3, T::Type{<:Number} = Sym)Vector of the canonical basis
Examples
julia> 𝐞(1)
Tens{1, 3, Sym, Sym, Vec{3, Sym}, CanonicalBasis{3, Sym}}
# data: 3-element Vec{3, Sym}:
1
0
0
# var: (:cont,)
# basis: 3×3 Tensor{2, 3, Sym, 9}:
1 0 0
0 1 0
0 0 1TensND.𝐞ˢ — Method
𝐞ˢ(i::Integer, θ::T = zero(Sym), ϕ::T = zero(Sym), ψ::T = zero(Sym); canonical = false)Vector of the basis rotated with the 3 Euler angles θ, ϕ, ψ (spherical if ψ=0)
Examples
julia> θ, ϕ, ψ = symbols("θ, ϕ, ψ", real = true) ;
Tens{1, 3, Sym, Sym, Vec{3, Sym}, RotatedBasis{3, Sym}}
# data: 3-element Vec{3, Sym}:
1
0
0
# var: (:cont,)
# basis: 3×3 Tensor{2, 3, Sym, 9}:
-sin(ψ)⋅sin(ϕ) + cos(θ)⋅cos(ψ)⋅cos(ϕ) -sin(ψ)⋅cos(θ)⋅cos(ϕ) - sin(ϕ)⋅cos(ψ) sin(θ)⋅cos(ϕ)
sin(ψ)⋅cos(ϕ) + sin(ϕ)⋅cos(θ)⋅cos(ψ) -sin(ψ)⋅sin(ϕ)⋅cos(θ) + cos(ψ)⋅cos(ϕ) sin(θ)⋅sin(ϕ)
-sin(θ)⋅cos(ψ) sin(θ)⋅sin(ψ) cos(θ)TensND.𝐞ᵖ — Method
𝐞ᵖ(i::Integer, θ::T = zero(Sym); canonical = false)Vector of the polar basis
Examples
julia> θ = symbols("θ", real = true) ;
julia> 𝐞ᵖ(1, θ)
Tens{1, 2, Sym, Sym, Vec{2, Sym}, RotatedBasis{2, Sym}}
# data: 2-element Vec{2, Sym}:
1
0
# var: (:cont,)
# basis: 2×2 Tensor{2, 2, Sym, 4}:
cos(θ) -sin(θ)
sin(θ) cos(θ)TensND.𝐞ᶜ — Method
𝐞ᶜ(i::Integer, θ::T = zero(Sym); canonical = false)Vector of the cylindrical basis
Examples
julia> θ = symbols("θ", real = true) ;
julia> 𝐞ᶜ(1, θ)
Tens{1, 3, Sym, Sym, Vec{3, Sym}, RotatedBasis{3, Sym}}
# data: 3-element Vec{3, Sym}:
1
0
0
# var: (:cont,)
# basis: 3×3 Tensor{2, 3, Sym, 9}:
cos(θ) -sin(θ) 0
sin(θ) cos(θ) 0
0 0 1Tensors.dcontract — Method
dcontract(A::TensTI{4}, B::TensISO{4,3}) → TensTI{4, T, 6}
dcontract(A::TensISO{4,3}, B::TensTI{4}) → TensTI{4, T, 6}Tensors.dcontract — Method
dcontract(A::TensTI{4}, B::TensTI{4}) → TensTI{4, T, 6}Product rule via 2×2 matrix product + scalar products for ℓ₅, ℓ₆. Always returns N=6 since the product of two symmetric tensors need not be symmetric.
Tensors.dcontract — Method
dcontract(t1::AbstractTens{order1,dim}, t2::AbstractTens{order2,dim})Define a double contracted product between two tensors
𝛔 ⊡ 𝛆 = σⁱʲεᵢⱼ 𝛔 = ℂ ⊡ 𝛆
Examples
julia> 𝛆 = Tens(SymmetricTensor{2,3}((i, j) -> symbols("ε$i$j", real = true))) ;
julia> k, μ = symbols("k μ", real =true) ;
julia> ℂ = 3k * t𝕁() + 2μ * t𝕂() ;
julia> 𝛔 = ℂ ⊡ 𝛆
Tens{2, 3, Sym, Sym, SymmetricTensor{2, 3, Sym, 6}, CanonicalBasis{3, Sym}}
# data: 3×3 SymmetricTensor{2, 3, Sym, 6}:
ε11*(k + 4*μ/3) + ε22*(k - 2*μ/3) + ε33*(k - 2*μ/3) 2⋅ε21⋅μ 2⋅ε31⋅μ
2⋅ε21⋅μ ε11*(k - 2*μ/3) + ε22*(k + 4*μ/3) + ε33*(k - 2*μ/3) 2⋅ε32⋅μ
2⋅ε31⋅μ 2⋅ε32⋅μ ε11*(k - 2*μ/3) + ε22*(k - 2*μ/3) + ε33*(k + 4*μ/3)
# var: (:cont, :cont)
# basis: 3×3 Tensor{2, 3, Sym, 9}:
1 0 0
0 1 0
0 0 1Tensors.dotdot — Method
dotdot(v1::AbstractTens{order1,dim}, S::AbstractTens{orderS,dim}, v2::AbstractTens{order2,dim})Define a bilinear operator 𝐯₁⋅𝕊⋅𝐯₂
Examples
julia> n = Tens(Sym[0, 0, 1]) ;
julia> k, μ = symbols("k μ", real =true) ;
julia> ℂ = 3k * t𝕁() + 2μ * t𝕂() ;
julia> dotdot(n,ℂ,n) # Acoustic tensor
3×3 Tens{2, 3, Sym, Sym, Tensor{2, 3, Sym, 9}, CanonicalBasis{3, Sym}}:
μ 0 0
0 μ 0
0 0 k + 4*μ/3Tensors.otimes — Method
otimes(A::TensTI{2}, B::TensISO{2,3}) → TensTI{4, T, 6}Tensor product of a TI 2nd-order tensor with a 3D isotropic 2nd-order tensor. The isotropic tensor λ·𝟏 is treated as TensTI{2}(λ,λ,n) with the axis of A.
Tensors.otimes — Method
otimes(A::TensTI{2}, B::TensTI{2}) → TensTI{4, T, 6}Tensor product of two TI 2nd-order tensors with the same axis. Falls back to generic otimes if axes differ.
(a₁·nT + b₁·nₙ) ⊗ (a₂·nT + b₂·nₙ)
= b₁b₂·W₁ + 2a₁a₂·W₂ + √2·b₁a₂·W₃ + √2·a₁b₂·W₄Tensors.otimes — Method
otimes(A::TensISO{2,3}, B::TensTI{2}) → TensTI{4, T, 6}Tensor product of a 3D isotropic 2nd-order tensor with a TI 2nd-order tensor. The isotropic tensor λ·𝟏 is treated as TensTI{2}(λ,λ,n) with the axis of B.
Tensors.otimes — Method
otimes(A::TensTI{2}) → TensTI{4, T, 5}Self tensor product of a TI 2nd-order tensor. The result is always major-symmetric (ℓ₃ = ℓ₄) and lives in the Walpole basis with N=5.
(a·nT + b·nₙ) ⊗ (a·nT + b·nₙ)
= b²W₁ + 2a²W₂ + √2·ab·(W₃+W₄)Tensors.otimes — Method
otimes(t1::AbstractTens{order1,dim}, t2::AbstractTens{order2,dim})Define a tensor product between two tensors
(aⁱeᵢ) ⊗ (bʲeⱼ) = aⁱbʲ eᵢ⊗eⱼ
Tensors.otimesu — Method
otimesu(t1::AbstractTens{order1,dim}, t2::AbstractTens{order2,dim})Define a special tensor product between two tensors of at least second order
(𝐚 ⊠ 𝐛) ⊡ 𝐩 = 𝐚⋅𝐩⋅𝐛 = aⁱᵏbʲˡpₖₗ eᵢ⊗eⱼ
TensND.@set_coorsys — Macro
@set_coorsys CS
@set_coorsys(CS)Set a coordinate system in order to avoid precising it in differential operators
Examples
julia> Spherical = coorsys_spherical() ; θ, ϕ, r = getcoords(Spherical) ; 𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ = unitvec(Spherical) ; vec = ("𝐞ᶿ", "𝐞ᵠ", "𝐞ʳ") ;
julia> @set_coorsys Spherical
julia> intrinsic(GRAD(𝐞ʳ),vec)
(1/r)𝐞ᶿ⊗𝐞ᶿ + (1/r)𝐞ᵠ⊗𝐞ᵠ
julia> intrinsic(DIV(𝐞ʳ ⊗ 𝐞ʳ),vec)
(2/r)𝐞ʳ
julia> LAPLACE(1/r)
0Index
TensND.BasisTensND.CanonicalBasisTensND.CoorSystemNumTensND.CoorSystemNumTensND.RotatedBasisTensND.SubManifoldSymTensND.TensTensND.TensOrthoTensND.TensOrthoTensND.TensOrthoTensND.TensTIBase.invBase.invBase.invLinearAlgebra.dotLinearAlgebra.normalizeLinearAlgebra.trTensND.DIVTensND.DIVTensND.DIVTensND.GRADTensND.GRADTensND.GRADTensND.HESSTensND.HESSTensND.HESSTensND.ISOTensND.KMTensND.KMTensND.KMTensND.KMTensND.KM_materialTensND.LAPLACETensND.LAPLACETensND.LAPLACETensND.LeviCivitaTensND.SYMGRADTensND.SYMGRADTensND.SYMGRADTensND.WalpoleTensND._KM_of_arrayTensND._KM_of_arrayTensND._KM_rotationTensND._angles_from_nTensND._apply_christoffelTensND._axis_on_frame_indexTensND._build_ORTHO_KMTensND._build_TI_KMTensND._candidate_ORTHO_frameTensND._candidate_ORTHO_frameTensND._candidate_TI_axisTensND._candidate_TI_axisTensND._christoffel_from_OMTensND._christoffel_orthogonalTensND._lift_walpole_N6TensND._n_from_anglesTensND._project_ORTHO_KMTensND._project_TI_KMTensND._rot3_rawTensND._trace_tensorTensND._χ_outerTensND.anglesTensND.arg_TITensND.arg_TI_HoenigTensND.arg_TI_engTensND.axisTensND.best_sym_tensTensND.best_sym_tensTensND.best_sym_tensTensND.best_sym_tensTensND.change_tensTensND.change_tens_canonTensND.componentsTensND.components_canonTensND.contractTensND.coorsys_cartesianTensND.coorsys_cartesian_numTensND.coorsys_cylindricalTensND.coorsys_cylindrical_numTensND.coorsys_polarTensND.coorsys_polar_numTensND.coorsys_sphericalTensND.coorsys_spherical_numTensND.coorsys_spheroidalTensND.frameTensND.fromISOTensND.get_arrayTensND.get_arrayTensND.get_arrayTensND.get_ℓTensND.init_cartesianTensND.init_cylindricalTensND.init_polarTensND.init_rotatedTensND.init_sphericalTensND.inv_KMTensND.is_ISOTensND.is_ORTHOTensND.is_ORTHOTensND.is_TITensND.is_TITensND.is_TITensND.iso_projectorsTensND.iso_to_orthoTensND.isorthogonalTensND.isorthonormalTensND.metricTensND.natural_basisTensND.natvecTensND.normalized_basisTensND.otimesulTensND.proj_tensTensND.proj_tensTensND.proj_tensTensND.proj_tensTensND.proj_tensTensND.proj_tensTensND.proj_tensTensND.proj_tensTensND.proj_tensTensND.qcontractTensND.referenceTensND.rot2TensND.rot3TensND.rot6TensND.sotimesTensND.symmetryTensND.tens_Id2TensND.tens_Id4TensND.tens_J4TensND.tens_K4TensND.tens_TITensND.tens_TI_HoenigTensND.tens_TI_engTensND.tens_W1TensND.tens_W2TensND.tens_W3TensND.tens_W4TensND.tens_W5TensND.tens_W6TensND.unitvecTensND.vecbasisTensND.walpole_basisTensND.walpole_basis_symTensND.walpole_to_orthoTensND.∂TensND.∂TensND.𝐞TensND.𝐞ˢTensND.𝐞ᵖTensND.𝐞ᶜTensors.dcontractTensors.dcontractTensors.dcontractTensors.dotdotTensors.otimesTensors.otimesTensors.otimesTensors.otimesTensors.otimesTensors.otimesuTensND.@set_coorsys