Skip to content

Getting started

A guided tour of the library in one page. Each step links to the manual chapter that develops it and to the theory behind it.

The three objects

TensND is built on three things, in this order:

A tensor is not an array: it is an array together with the basis its components refer to and the variance of each index. That is what allows two tensors expressed in different frames to be added, contracted or compared — and what makes comparing raw component arrays a mistake.

A first computation

julia
using TensND, SymPy

Spherical = coorsys_spherical()
θ, ϕ, r = getcoords(Spherical)
𝐞ᶿ, 𝐞ᵠ, 𝐞ʳ = unitvec(Spherical)
@set_coorsys Spherical

DIV(𝐞ʳ)

The radial unit vector has constant components (0,0,1) in the spherical frame, yet its divergence is : the whole answer comes from the frame varying with position, through the Christoffel symbols (Curvilinear differential calculus).

The kernel of the Laplace equation, and the equilibrium operator of a spherically symmetric stress state:

julia
LAPLACE(1 / r)

julia
σʳʳ = SymFunction("σʳʳ", real = true)(r)
σᶿᶿ = SymFunction("σᶿᶿ", real = true)(r)
𝛔 = σʳʳ * 𝐞ʳ  𝐞ʳ + σᶿᶿ * (𝐞ᶿ  𝐞ᶿ + 𝐞ᵠ  𝐞ᵠ)
simplify(DIV(𝛔))

ᶿᶿᶿᶿᶿᶿ

Structured tensors

An isotropic order-4 tensor is stored as two scalars, not 81 components, and its algebra stays closed:

julia
using TensND

= TensISO{3}(3 * 20.0, 2 * 8.0)      # 3k 𝕁 + 2μ 𝕂
inv(ℂ)
3×3×3×3 TensISO{4, 3, Float64, 2}:
[:, :, 1, 1] =
 0.0472222   0.0         0.0
 0.0        -0.0152778   0.0
 0.0         0.0        -0.0152778

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

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

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

[:, :, 2, 2] =
 -0.0152778  0.0         0.0
  0.0        0.0472222   0.0
  0.0        0.0        -0.0152778

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

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

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

[:, :, 3, 3] =
 -0.0152778   0.0        0.0
  0.0        -0.0152778  0.0
  0.0         0.0        0.0472222

Transverse isotropy uses five coefficients on the Walpole basis (The Walpole basis), orthotropy nine plus a material frame:

julia
n = [0.0, 0.0, 1.0]
𝕊 = tens_TI_eng(9.0, 140.0, 0.40, 0.30, 4.6, n)   # a carbon/epoxy ply
arg_TI_Hoenig(𝕊)
(9.0, 0.4000000000000001, 0.019285714285714288, 15.555555555555557, 1.431111111111111)

The dimensionless Hoenig parameters read off the anisotropy directly — see TI parametrizations.

Finding a symmetry

Given an arbitrary tensor, ask what symmetry it has:

julia
C = get_array(tens_TI(10.0, 3.0, 2.5, 12.0, 2.0, [0.0, 0.0, 1.0]))
_, _, drel, sym = best_sym_tens(Tens(C))
(sym, drel)
(:TI, 8.709305949236423e-17)

and project onto a class, with the distance as evidence:

julia
B, d, drel = proj_tens(:ISO, C)
(B, round(drel, digits = 4))
((16.0) 𝕁 + (6.2) 𝕂, 0.2057)

drel is the relative Frobenius distance, so a tolerance on it is dimensionless. See Projection.

Where to go next

If you want toRead
understand what a basis and a variance areBases, Bases and variance
build and manipulate tensorsTensors
use the compact symmetry-class typesStructured tensors
convert between TI parametrizationsParametrizations
find or impose a material symmetryProjection
differentiate fields on a curvilinear chartCoordinate systems
do the same numerically, by ADNumerical coordinate systems
work on an embedded surfaceSubmanifolds
mix symbolic, numeric and AD typesSymbolic and numeric

The Tutorials are runnable versions of all of the above, and the Theory section states the mathematics each rests on.