Skip to content

Parametrizations and conversions ​

<!– crosslinks: written by .github/scripts/crosslinks.py from docs/crosslinks.toml; do not edit –>

<!– /crosslinks –>

Which five numbers describe a transversely isotropic material, how to move between the conventions, and how to go in and out of the Kelvin–Mandel matrix. The matrices themselves are on TI parametrizations.

Isotropic moduli ​

A 3-D isotropic stiffness is     : iso_stiffness builds it from the bulk and shear moduli, and iso_stiffness_young_poisson from Young's modulus and Poisson's ratio; bulk_shear and young_poisson read them back. A compliance is the inverse, exact in the class, so its moduli are those of inv(𝕊). Every other pair of the six isotropic moduli, the two dimensions, and plane strain and plane stress are on Elastic moduli.

julia
using TensND, LinearAlgebra

ℂ = iso_stiffness_young_poisson(70.0, 0.33)   # an aluminum, GPa
bulk_shear(ℂ), young_poisson(ℂ)
((68.62745098039215, 26.31578947368421), (70.0, 0.33))

The three TI conventions ​

formParametersBuilds
:components (default)stiffness or compliance
:engineeringcompliance
:hoenigcompliance

ti_from_constants(c₁, …, c₅, n; form) builds the tensor, with the symmetry axis as its last argument, and returns a TensTI{4,T,5}; ti_constants(t; form) reads the five constants back.

julia
n = [0.0, 0.0, 1.0]
𝕊 = ti_from_constants(9.0, 140.0, 0.40, 0.30, 4.6, n; form = :engineering)   # a carbon/epoxy ply, GPa
ℂ = inv(𝕊)
ti_constants(𝕊; form = :engineering)
(9.0, 140.0, 0.4000000000000001, 0.3, 4.6)

Converting between them ​

Conversion is a round trip through the tensor: build with one constructor, read with another extractor. Because all three produce the same object, the conversion is exact rather than fitted.

julia
ti_constants(𝕊)          # the same compliance, in component form
(0.1111111111111111, -0.04444444444444445, -0.002142857142857143, 0.007142857142857143, 0.05434782608695653)
julia
ti_constants(𝕊; form = :hoenig)   # and in dimensionless Hoenig ratios
(9.0, 0.4000000000000001, 0.019285714285714288, 15.555555555555557, 1.431111111111111)

is the axial-to-transverse modulus ratio and the shear anisotropy; an isotropic material sits at    with  .

Stiffness or compliance: role ​

The engineering and Hoenig constants are defined on the compliance: ti_from_constants(…; form = :engineering) and form = :hoenig build , and ti_constants(t; form) reads t as one. The keyword role = :stiffness makes them build, or read, the stiffness of the same material instead. It is never computed through an inverse: each constant has its closed form on the stiffness components, with   ,

and the stiffness has its closed form in the constants, with    :

Hoenig's parameters are those of  ,  ,  ,   and   .

julia
ℂ = ti_from_constants(9.0, 140.0, 0.40, 0.30, 4.6, n; form = :engineering, role = :stiffness)
ℂ ≈ inv(𝕊), ti_constants(ℂ; form = :engineering, role = :stiffness)
(true, (9.000000000000004, 140.0, 0.4, 0.29999999999999993, 4.6))

role is :compliance by default, as these forms have always been read, and has no effect on form = :components, whose five numbers are those of the tensor given, whatever it is.

A role is the caller's to give

Nothing in a TensTI tells a stiffness from a compliance. Read with the wrong role, a tensor gives the constants of another material.

Walpole coefficients ​

walpole_coeffs(t) reads the six classical coefficients, walpole_coeffs(t, Val(8)) all eight. Stiffness and compliance are inverse in the synthetic algebra, so their   blocks are inverse matrices and their reciprocal:

julia
ℓC, ℓS = walpole_coeffs(ℂ), walpole_coeffs(𝕊)
LC = [ℓC[1] ℓC[3]; ℓC[4] ℓC[2]]
LS = [ℓS[1] ℓS[3]; ℓS[4] ℓS[2]]
round.(LC * LS, digits = 12)
2×2 Matrix{Float64}:
  1.0  -0.0
 -0.0   1.0
julia
round(ℓC[5] * ℓS[5], digits = 12), round(ℓC[6] * ℓS[6], digits = 12)
(1.0, 1.0)

Kelvin–Mandel round trips ​

FunctionDirection
mandeltensor → matrix, canonical frame
mandel_materialTensOrtho → matrix, material frame
from_mandelmatrix → tensor
julia
mandel(ℂ)
6×6 Matrix{Float64}:
 10.8618    4.4332     4.58849  0.0  0.0  0.0
  4.4332   10.8618     4.58849  0.0  0.0  0.0
  4.58849   4.58849  142.753    0.0  0.0  0.0
  0.0       0.0        0.0      9.2  0.0  0.0
  0.0       0.0        0.0      0.0  9.2  0.0
  0.0       0.0        0.0      0.0  0.0  6.42857
julia
norm(get_array(from_mandel(mandel(ℂ))) - get_array(ℂ))
0.0

Parameters from a matrix, and back ​

Four exported aliases give direct access to the projection kernels, for when a   matrix is the natural input — coming from a file, an experiment or another library:

FunctionDoes
ti_params_from_mandel(C)  →
mandel_from_ti_params(ℓ…)the five coefficients →  
ortho_params_from_mandel(C)  → the nine
mandel_from_ortho_params(C…)the nine constants →  

They assume the matrix is expressed in the frame where the symmetry axis is (respectively the material frame), and they project: given a matrix that is not exactly of the class, they return the closest one.

julia
ti_params_from_mandel(mandel(ℂ))
(142.75309541150764, 15.294974508375823, 6.489108115768753, 6.4285714285714315, 9.200000000000001)
julia
norm(mandel_from_ti_params(ti_params_from_mandel(mandel(ℂ))...) - mandel(ℂ))
1.9860273225978185e-15

For a matrix in an arbitrary frame, use project instead — it handles the rotation. See Projection.