Skip to content

Structured tensors

The compact symmetry-class types. Each stores a handful of scalars instead of components and computes products and inverses in closed form. The algebra behind each is on Isotropic tensors, The Walpole basis, The extended Walpole algebra, Orthotropy and Cubic symmetry.

Storage

TypeStoredOrientationClass
TensISO{2,dim}1 scalar none
TensISO{4,dim}2 scalars none 
TensTI{2,T,2}axis  
TensTI{2,T,3}axis   , the antisymmetric part
TensTI{4,T,5}axis major-symmetric TI
TensTI{4,T,6}axis general TI
TensTI{4,T,8}axis full axially invariant
TensCubic{T,B}3 scalars cube frame B  
TensOrtho{T,B}9 constantsframe Borthotropic
julia
using TensND, LinearAlgebra

iso = TensISO{3}(3 * 20.0, 2 * 8.0)      # 3k 𝕁 + 2μ 𝕂
3×3×3×3 TensISO{4, 3, Float64, 2}:
[:, :, 1, 1] =
 30.6667   0.0      0.0
  0.0     14.6667   0.0
  0.0      0.0     14.6667

[:, :, 2, 1] =
 0.0  8.0  0.0
 8.0  0.0  0.0
 0.0  0.0  0.0

[:, :, 3, 1] =
 0.0  0.0  8.0
 0.0  0.0  0.0
 8.0  0.0  0.0

[:, :, 1, 2] =
 0.0  8.0  0.0
 8.0  0.0  0.0
 0.0  0.0  0.0

[:, :, 2, 2] =
 14.6667   0.0      0.0
  0.0     30.6667   0.0
  0.0      0.0     14.6667

[:, :, 3, 2] =
 0.0  0.0  0.0
 0.0  0.0  8.0
 0.0  8.0  0.0

[:, :, 1, 3] =
 0.0  0.0  8.0
 0.0  0.0  0.0
 8.0  0.0  0.0

[:, :, 2, 3] =
 0.0  0.0  0.0
 0.0  0.0  8.0
 0.0  8.0  0.0

[:, :, 3, 3] =
 14.6667   0.0      0.0
  0.0     14.6667   0.0
  0.0      0.0     30.6667

The show method prints the algebraic form, not 81 numbers:

julia
n = (0.0, 0.0, 1.0)
ti = TensTI{4}(12.0, 13.0, 3.5, 7.0, 4.0, n)
3×3×3×3 TensTI{4, Float64, 5}:
[:, :, 1, 1] =
 10.0  0.0  0.0
  0.0  3.0  0.0
  0.0  0.0  2.47487

[:, :, 2, 1] =
 0.0  3.5  0.0
 3.5  0.0  0.0
 0.0  0.0  0.0

[:, :, 3, 1] =
 0.0  0.0  2.0
 0.0  0.0  0.0
 2.0  0.0  0.0

[:, :, 1, 2] =
 0.0  3.5  0.0
 3.5  0.0  0.0
 0.0  0.0  0.0

[:, :, 2, 2] =
 3.0   0.0  0.0
 0.0  10.0  0.0
 0.0   0.0  2.47487

[:, :, 3, 2] =
 0.0  0.0  0.0
 0.0  0.0  2.0
 0.0  2.0  0.0

[:, :, 1, 3] =
 0.0  0.0  2.0
 0.0  0.0  0.0
 2.0  0.0  0.0

[:, :, 2, 3] =
 0.0  0.0  0.0
 0.0  0.0  2.0
 0.0  2.0  0.0

[:, :, 3, 3] =
 2.47487  0.0       0.0
 0.0      2.47487   0.0
 0.0      0.0      12.0
julia
= CanonicalBasis{3, Float64}()
ort = TensOrtho(10.0, 8.0, 9.0, 3.0, 2.0, 4.0, 2.5, 3.0, 1.5, ℬ)
3×3×3×3 TensOrtho{Float64, CanonicalBasis{3, Float64}}:
[:, :, 1, 1] =
 10.0  0.0  0.0
  0.0  3.0  0.0
  0.0  0.0  2.0

[:, :, 2, 1] =
 0.0  1.5  0.0
 1.5  0.0  0.0
 0.0  0.0  0.0

[:, :, 3, 1] =
 0.0  0.0  3.0
 0.0  0.0  0.0
 3.0  0.0  0.0

[:, :, 1, 2] =
 0.0  1.5  0.0
 1.5  0.0  0.0
 0.0  0.0  0.0

[:, :, 2, 2] =
 3.0  0.0  0.0
 0.0  8.0  0.0
 0.0  0.0  4.0

[:, :, 3, 2] =
 0.0  0.0  0.0
 0.0  0.0  2.5
 0.0  2.5  0.0

[:, :, 1, 3] =
 0.0  0.0  3.0
 0.0  0.0  0.0
 3.0  0.0  0.0

[:, :, 2, 3] =
 0.0  0.0  0.0
 0.0  0.0  2.5
 0.0  2.5  0.0

[:, :, 3, 3] =
 2.0  0.0  0.0
 0.0  4.0  0.0
 0.0  0.0  9.0
julia
cub = tens_cubic(10.0, 4.0, 2.0, ℬ)      # (C₁₁, C₁₂, C₄₄)
3×3×3×3 TensCubic{Float64, CanonicalBasis{3, Float64}}:
[:, :, 1, 1] =
 10.0  0.0  0.0
  0.0  4.0  0.0
  0.0  0.0  4.0

[:, :, 2, 1] =
 0.0  2.0  0.0
 2.0  0.0  0.0
 0.0  0.0  0.0

[:, :, 3, 1] =
 0.0  0.0  2.0
 0.0  0.0  0.0
 2.0  0.0  0.0

[:, :, 1, 2] =
 0.0  2.0  0.0
 2.0  0.0  0.0
 0.0  0.0  0.0

[:, :, 2, 2] =
 4.0   0.0  0.0
 0.0  10.0  0.0
 0.0   0.0  4.0

[:, :, 3, 2] =
 0.0  0.0  0.0
 0.0  0.0  2.0
 0.0  2.0  0.0

[:, :, 1, 3] =
 0.0  0.0  2.0
 0.0  0.0  0.0
 2.0  0.0  0.0

[:, :, 2, 3] =
 0.0  0.0  0.0
 0.0  0.0  2.0
 0.0  2.0  0.0

[:, :, 3, 3] =
 4.0  0.0   0.0
 0.0  4.0   0.0
 0.0  0.0  10.0

Constructors

ClassConstructors
ISOTensISO, tens_Id2, tens_Id4, tens_J4, tens_K4, ISO, iso_projectors
TI order 4TensTI, tens_TI, tens_TI_eng, tens_TI_Hoenig, fromISO, tens_W1tens_W8, walpole_basis, walpole_basis_sym
TI order 2TensTI{2}(a, b, n) and (a, b, c, n)
CUBICTensCubic, tens_cubic, iso_to_cubic
ORTHOTensOrtho, iso_to_ortho, walpole_to_ortho, cubic_to_ortho

Accessors

FunctionApplies toReturns
get_dataallthe stored coefficient tuple
get_ℓTensTI{4}the six classical Walpole coefficients
get_ℓ8TensTI{4}all eight, zero-padded
axisTensTIthe symmetry axis
frameTensOrtho, TensCubicthe material or cube frame
referenceTensTI, TensOrtho, TensCubicaxis or frame, whichever applies
symmetryallthe class as a Symbol
KM_materialTensOrtho, TensCubicthe sparse matrix in the class's own frame
arg_cubicTensCubicthe constants
cubic_anisotropyTensCubicthe Zener-type departure from isotropy
julia
get_ℓ(ti), axis(ti)
((12.0, 13.0, 3.5, 3.5, 7.0, 4.0), (0.0, 0.0, 1.0))
julia
KM_material(ort)
6×6 StaticArraysCore.SMatrix{6, 6, Float64, 36} with indices SOneTo(6)×SOneTo(6):
 10.0  3.0  2.0  0.0  0.0  0.0
  3.0  8.0  4.0  0.0  0.0  0.0
  2.0  4.0  9.0  0.0  0.0  0.0
  0.0  0.0  0.0  5.0  0.0  0.0
  0.0  0.0  0.0  0.0  6.0  0.0
  0.0  0.0  0.0  0.0  0.0  3.0

Closure: what an operation returns

This is the table to know. between structured types stays structured only while the result stays in the class; otherwise it falls back to the generic route, exactly and without warning.

A ⊡ BISOCUBICTITITIORTHO
ISOISOCUBICTITITIgeneric
CUBICCUBICCUBICgenericgenericgenericgeneric
TI{4,5}TIgenericTITITIgeneric
TI{4,6}TIgenericTITITIgeneric
TI{4,8}TIgenericTITITIgeneric
ORTHOgenericgenericgenericgenericgenericgeneric

The CUBIC row and column need the two frames to describe the same cube, and the ISO/TI/ORTHO ones the same axis or frame; otherwise the generic route is taken.

Two widenings deserve an explanation, and both have the same cause: the major-symmetric tensors of a class do not form a subalgebra.

  • TI{4,5} ⊡ TI{4,5} → TI{4,6}. The Walpole product is a   matrix product, and     unless the blocks commute, so the product of two major-symmetric TI tensors generally has  .

  • ORTHO ⊡ ORTHO → generic. The product keeps the block structure but loses major symmetry: twelve independent constants where TensOrtho stores nine. Rather than add a twelve-parameter container, the generic tensor is returned.

CUBIC ⊡ CUBIC → CUBIC is the one entry that does not widen, and it is worth knowing why: each irreducible representation of the octahedral group appears with multiplicity one, so the three projectors are orthogonal, any two cubic tensors about the same cube commute, and the product is cubic and still major-symmetric. Cubic symmetry is the only class here that is a genuine commutative subalgebra. See Cubic symmetry.

CUBIC ⊡ TI is generic for the opposite reason: the two classes are incomparable, their intersection being the isotropic class.

Inversion, by contrast, always stays in the class:

julia
typeof(inv(iso)), typeof(inv(ti)), typeof(inv(ort)), typeof(inv(cub))
(TensISO{4, 3, Float64, 2}, TensTI{4, Float64, 5}, TensOrtho{Float64, CanonicalBasis{3, Float64}}, TensCubic{Float64, CanonicalBasis{3, Float64}})

Exact promotions

Moving up the lattice is exact — an isotropic tensor really is transversely isotropic about every axis:

julia
typeof(fromISO(iso, [0.0, 0.0, 1.0]))
TensTI{4, Float64, 5}
julia
typeof(iso_to_ortho(iso, ℬ)), typeof(walpole_to_ortho(ti, ℬ, 3))
(TensOrtho{Float64, CanonicalBasis{3, Float64}}, TensOrtho{Float64, CanonicalBasis{3, Float64}})
julia
typeof(iso_to_cubic(iso, ℬ)), typeof(cubic_to_ortho(cub))
(TensCubic{Float64, CanonicalBasis{3, Float64}}, TensOrtho{Float64, CanonicalBasis{3, Float64}})

Moving down is approximation, and is Projection.

Same axis, same frame

Addition and subtraction require the two operands to share their orientation — adding two orthotropic tensors expressed in different material frames throws:

julia
julia> ort + TensOrtho(6., 5., 7., 2., 1., 3., 1.2, 2.2, 0.8, Basis(0.3, 0.7, 0.2))
ERROR: AssertionError: TensOrtho operation requires the same material frame

The assertion is deliberate: silently promoting to a generic tensor would hide a modeling error. Convert explicitly if that is what you mean.

TensCubic is the one class where the test is looser than equality, and legitimately so: the three projectors are invariant under the whole octahedral group, so two frames related by a signed permutation of the axes describe the same tensor with the same coefficients and are accepted. Permuting the axes of an orthotropic tensor permutes ; permuting those of a cubic one changes nothing.

When to use which

SituationType
the physics guarantees isotropyTensISO
a stiffness or compliance with an axis of symmetryTensTI{4,T,5}
an object with an axis but no major symmetry (a concentration tensor)TensTI{4,T,6} or {4,T,8}
a cubic crystal, a cubic array, a cube-symmetric shapeTensCubic
nine constants and a material frameTensOrtho
anything elsea plain Tens

The measured cost of each is in Performance of the structured types.