Elastic moduli
<!– crosslinks: written by .github/scripts/crosslinks.py from docs/crosslinks.toml; do not edit –>
See also
Theory: Isotropic tensors
Manual: Structured tensors · Symbolic and numeric · Parametrizations and conversions
Tutorials: Elastic Green's functions · The elastic sphere, solved symbolically · Differentiation and interoperability · Performance of the structured types · Differential operators, symbolically
<!– /crosslinks –>
An isotropic linear elastic material has two independent constants, and six of them are in common use: the bulk modulus
| to … | write |
|---|---|
| build a stiffness from two moduli | iso_stiffness_<pair>(a, b), e.g. iso_stiffness_young_poisson(E, ν) or iso_stiffness_E_ν(E, ν) |
| build a compliance from two moduli | iso_compliance_<pair>(a, b), e.g. iso_compliance_young_poisson(E, ν) |
| read one modulus | young_modulus(ℂ), poisson_ratio(ℂ), …, or young_modulus(𝕊; role = :compliance) |
| read two moduli | young_poisson(ℂ) (E_ν(ℂ)), lame_shear(ℂ) (λ_μ(ℂ)), …, with the same role |
| work in 2-D (plane strain) | the same builders with Val(2) first |
| switch between plane strain and plane stress | plane_strain_stiffness, plane_stress_stiffness, plane_stress_to_plane_strain, plane_strain_to_plane_stress |
The stiffness and its moduli
In dimension 3 the stiffness is TensISO{4,3}. The other moduli follow from
Each has its reader, bulk_modulus, young_modulus, lame_lambda, shear_modulus, poisson_ratio and pwave_modulus, and each pair too, named after its two moduli in the order bulk_shear, young_poisson, lame_shear, young_pwave, …
using TensND
ℂ = iso_stiffness_young_poisson(70.0, 0.33) # an aluminum, GPa
(k = bulk_modulus(ℂ), E = young_modulus(ℂ), λ = lame_lambda(ℂ),
μ = shear_modulus(ℂ), ν = poisson_ratio(ℂ), M = pwave_modulus(ℂ))(k = 68.62745098039215, E = 70.0, λ = 51.08359133126935, μ = 26.31578947368421, ν = 0.33, M = 103.71517027863777)Stiffness or compliance
The compliance is role, which says which of the two it is given: :stiffness, the default, or :compliance. Each modulus then has a formula of its own on each, written directly on the two coefficients, never through an inverse:
| modulus | on | on |
|---|---|---|
𝕊 = iso_compliance_young_poisson(70.0, 0.33) # the same aluminum
young_poisson(𝕊; role = :compliance)(70.0, 0.33)The compliance builders write TensISO tells a stiffness from a compliance: the role is the caller's to give, and a compliance read as a stiffness gives the moduli of another material.
Building from any pair
The stiffness of a pair is iso_stiffness_<pair>, and its compliance iso_compliance_<pair> (iso_compliance for
with
The pair
E, ν = young_poisson(iso_stiffness_lame_shear(40.0, 26.0))(67.75757575757575, 0.30303030303030304)young_shear(iso_stiffness_bulk_poisson(70.0, 0.25))(105.0, 42.0)Shorter names
The pairs without the P-wave modulus also have the names of their symbols, in ASCII and with Greek letters, as exact aliases: k_mu and k_μ are bulk_shear, E_nu and E_ν are young_poisson, λ_μ and lambda_mu are lame_shear, and the builders likewise, iso_stiffness_E_nu, iso_stiffness_E_ν, iso_stiffness_λ_μ, … and iso_compliance_E_nu, iso_compliance_E_ν, iso_compliance_λ_μ, …. The pairs with k_M or μ_M name the moduli of a matrix in MeanFieldHomogenization, and the two meanings would be read one for the other.
k, μ = k_μ(iso_stiffness_E_ν(70.0, 0.33))(68.62745098039215, 26.31578947368421)Symbolic moduli
No formula depends on the sign of a value, so the moduli may be symbols. With SymPy, the closed forms come out exactly:
using SymPyPythonCall
λ, μ = symbols("λ μ", positive = true)
ℂ = iso_stiffness_lame_shear(λ, μ)
simplify(young_modulus(ℂ)), simplify(poisson_ratio(ℂ))(μ*(3*λ + 2*μ)/(λ + μ), λ/(2*(λ + μ)))They go through ForwardDiff as well: a derivative of a modulus with respect to another pair is that of the composition.
using ForwardDiff
ForwardDiff.derivative(ν -> shear_modulus(iso_stiffness_young_poisson(70.0, ν)), 0.33)-19.78630787495053Two dimensions
A TensISO{4,2} is the in-plane stiffness of a 3-D material under plane strain, bulk_shear. Every builder takes the dimension as a first argument Val(2) (Val(3) is the default):
ℂ₂ = iso_stiffness_young_poisson(Val(2), 70.0, 0.33)
bulk_shear(ℂ₂), young_poisson(ℂ₂)((77.39938080495357, 26.31578947368421), (70.0, 0.33000000000000007))On a 2-D compliance
and the compliance builders take Val(2) as the stiffness builders do:
𝕊₂ = iso_compliance_young_poisson(Val(2), 70.0, 0.33)
young_poisson(𝕊₂; role = :compliance)(70.0, 0.32999999999999996)The pairs with
Plane strain and plane stress
A 2-D computation on a 3-D material assumes either plane strain, plane_strain_stiffness and plane_stress_stiffness give the in-plane stiffness of each. Plane strain keeps the in-plane block of
ℂ = iso_stiffness_young_poisson(70.0, 0.33)
lame_shear(plane_strain_stiffness(ℂ)), lame_shear(plane_stress_stiffness(ℂ))((51.08359133126936, 26.31578947368421), (25.92301649646505, 26.31578947368421))Both are TensISO{4,2}, so a plane-stress state is computed with the plane-strain formulas of another material. plane_stress_to_plane_strain gives its moduli and plane_strain_to_plane_stress goes back:
E′, ν′ = plane_stress_to_plane_strain(70.0, 0.33)
young_poisson(plane_stress_stiffness(ℂ)) .≈ (E′, ν′)(true, true)