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

Third Order Deformation

Invariants

\(C_{10}, C_{01}, C_{11}, C_{20}, C_{30}\)

Torch Autograd Hyperelastic

Invariants

\(\psi(I_1, I_2, I_3)\)

Ogden

Stretches

\(\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']})")
../_images/fig_lab-mr.png