Structured tensors
The compact symmetry-class types. Each stores a handful of scalars instead of
Storage
| Type | Stored | Orientation | Class |
|---|---|---|---|
TensISO{2,dim} | 1 scalar | none | |
TensISO{4,dim} | 2 scalars | none | |
TensTI{2,T,2} | axis | ||
TensTI{2,T,3} | axis | ||
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 constants | frame B | orthotropic |
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.6667The show method prints the algebraic form, not 81 numbers:
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ℬ = 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.0cub = 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.0Constructors
| Class | Constructors |
|---|---|
| ISO | TensISO, tens_Id2, tens_Id4, tens_J4, tens_K4, ISO, iso_projectors |
| TI order 4 | TensTI, tens_TI, tens_TI_eng, tens_TI_Hoenig, fromISO, tens_W1…tens_W8, walpole_basis, walpole_basis_sym |
| TI order 2 | TensTI{2}(a, b, n) and (a, b, c, n) |
| CUBIC | TensCubic, tens_cubic, iso_to_cubic |
| ORTHO | TensOrtho, iso_to_ortho, walpole_to_ortho, cubic_to_ortho |
Accessors
| Function | Applies to | Returns |
|---|---|---|
get_data | all | the stored coefficient tuple |
get_ℓ | TensTI{4} | the six classical Walpole coefficients |
get_ℓ8 | TensTI{4} | all eight, zero-padded |
axis | TensTI | the symmetry axis |
frame | TensOrtho, TensCubic | the material or cube frame |
reference | TensTI, TensOrtho, TensCubic | axis or frame, whichever applies |
symmetry | all | the class as a Symbol |
KM_material | TensOrtho, TensCubic | the sparse matrix in the class's own frame |
arg_cubic | TensCubic | the constants |
cubic_anisotropy | TensCubic | the Zener-type departure from isotropy |
get_ℓ(ti), axis(ti)((12.0, 13.0, 3.5, 3.5, 7.0, 4.0), (0.0, 0.0, 1.0))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.0Closure: 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 ⊡ B | ISO | CUBIC | TI | TI | TI | ORTHO |
|---|---|---|---|---|---|---|
| ISO | ISO | CUBIC | TI | TI | TI | generic |
| CUBIC | CUBIC | CUBIC | generic | generic | generic | generic |
| TI{4,5} | TI | generic | TI | TI | TI | generic |
| TI{4,6} | TI | generic | TI | TI | TI | generic |
| TI{4,8} | TI | generic | TI | TI | TI | generic |
| ORTHO | generic | generic | generic | generic | generic | generic |
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 whereTensOrthostores 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:
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:
typeof(fromISO(iso, [0.0, 0.0, 1.0]))TensTI{4, Float64, 5}typeof(iso_to_ortho(iso, ℬ)), typeof(walpole_to_ortho(ti, ℬ, 3))(TensOrtho{Float64, CanonicalBasis{3, Float64}}, TensOrtho{Float64, CanonicalBasis{3, Float64}})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> 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 frameThe 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
When to use which
| Situation | Type |
|---|---|
| the physics guarantees isotropy | TensISO |
| a stiffness or compliance with an axis of symmetry | TensTI{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 shape | TensCubic |
| nine constants and a material frame | TensOrtho |
| anything else | a plain Tens |
The measured cost of each is in Performance of the structured types.