Getting Started#
Spaces
are full or partial deformations on which a given material formulation should be projected to, e.g. to the distortional (part of the deformation) space. Generalized Total-Lagrange Frameworks
for isotropic hyperelastic material formulations based on the invariants of the right Cauchy-Green deformation tensor and the principal stretches enable a clean coding of isotropic material formulations.
The Math
-module provides helpers in reduced vector Voigt storage for symmetric three-dimensional second-order tensors along with a matrix storage for (at least minor) symmetric three-dimensional fourth-order tensors.
Material model formulations
have to be created as classes with methods for the evaluation of the gradient (stress) and the hessian (elasticity) of the strain energy function. It depends on the Framework
which derivatives have to be defined, e.g. the derivatives w.r.t. the invariants of the right Cauchy-Green deformation tensor or w.r.t. the principal stretches. An instance of a Framework
has to be finalized by the application on a Space
.
First, let’s import hyperelastic.
import hyperelastic
Available material formulations#
Model Formulation |
Framework |
Parameters |
---|---|---|
\(C_{10}, C_{01}, C_{11}, C_{20}, C_{30}\) |
||
\(\psi(I_1, I_2, I_3)\) |
||
\(\mu, \alpha\) |
An instance of one of these models is then embedded into the corresponding Framework
, which is further applied onto a Space
.
model = hyperelastic.models.invariants.ThirdOrderDeformation(C10=0.5)
framework = hyperelastic.InvariantsFramework(model)
umat = hyperelastic.DistortionalSpace(framework)
Note
Instead of using the implemented models, define your own material model formulation with manual, automatic or symbolic differentiation with the help of your favourite package, e.g. PyTorch, JAX, Tensorflow, TensorTRAX, SymPy, etc.
Invariant-based material formulations#
A minimal template for an invariant-based material formulation applied on the distortional space:
class MyInvariantsModel:
def gradient(self, I1, I2, I3, statevars):
"""The gradient as the partial derivative of the strain energy function w.r.t.
the invariants of the right Cauchy-Green deformation tensor."""
# user code
dWdI1 = None
dWdI2 = None
dWdI3 = None
return dWdI1, dWdI2, dWdI3, statevars
def hessian(self, I1, I2, I3, statevars_old):
"""The hessian as the second partial derivatives of the strain energy function
w.r.t. the invariants of the right Cauchy-Green deformation tensor."""
# user code
d2WdI1I1 = None
d2WdI2I2 = None
d2WdI3I3 = None
d2WdI1I2 = None
d2WdI2I3 = None
d2WdI1I3 = None
return d2WdI1I1, d2WdI2I2, d2WdI3I3, d2WdI1I2, d2WdI2I3, d2WdI1I3
model = MyInvariantsModel()
framework = hyperelastic.InvariantsFramework(model)
umat = hyperelastic.DistortionalSpace(framework)
Principal stretch-based material formulations#
A minimal template for a principal stretch-based material formulation applied on the distortional space:
class MyStretchesModel:
def gradient(self, λ, statevars):
"""The gradient as the partial derivative of the strain energy function w.r.t.
the principal stretches."""
# user code
dWdλ1, dWdλ2, dWdλ3 = 0 * λ
return [dWdλ1, dWdλ2, dWdλ3], statevars
def hessian(self, λ, statevars_old):
"""The hessian as the second partial derivatives of the strain energy function
w.r.t. the principal stretches."""
# user code
d2Wdλ1dλ1 = None
d2Wdλ2dλ2 = None
d2Wdλ3dλ3 = None
d2Wdλ1dλ2 = None
d2Wdλ2dλ3 = None
d2Wdλ1dλ3 = None
return d2Wdλ1dλ1, d2Wdλ2dλ2, d2Wdλ3dλ3, d2Wdλ1dλ2, d2Wdλ2dλ3, d2Wdλ1dλ3
model = MyStretchesModel()
framework = hyperelastic.StretchesFramework(model)
umat = hyperelastic.DistortionalSpace(framework)
Lab#
In the Lab
, Simulations
on homogeneous load cases provide a visualization of the material response behaviour.
import numpy as np
import hyperelastic
stretch = np.linspace(0.7, 2.5, 181)
parameters = {"C10": 0.3, "C01": 0.2}
def material(C10, C01):
tod = hyperelastic.models.invariants.ThirdOrderDeformation(C10=C10, C01=C01)
framework = hyperelastic.InvariantsFramework(tod)
return hyperelastic.DeformationSpace(framework)
ux = hyperelastic.lab.Simulation(
loadcase=hyperelastic.lab.Uniaxial(label="uniaxial"),
stretch=np.linspace(0.7, 2.5),
material=material,
labels=parameters.keys(),
parameters=parameters.values(),
)
ps = hyperelastic.lab.Simulation(
loadcase=hyperelastic.lab.Planar(label="planar"),
stretch=np.linspace(1.0, 2.5),
material=material,
labels=parameters.keys(),
parameters=parameters.values(),
)
bx = hyperelastic.lab.Simulation(
loadcase=hyperelastic.lab.Biaxial(label="biaxial"),
stretch=np.linspace(1.0, 1.75),
material=material,
labels=parameters.keys(),
parameters=parameters.values(),
)
fig, ax = ux.plot_stress_stretch(lw=2)
fig, ax = ps.plot_stress_stretch(ax=ax, lw=2)
fig, ax = bx.plot_stress_stretch(ax=ax, lw=2)
ax.legend()
ax.set_title(rf"Mooney-Rivlin (C10={parameters['C10']}, C01={parameters['C01']})")