Skip to content

Commit

Permalink
Add the MORPH material model formulation
Browse files Browse the repository at this point in the history
  • Loading branch information
adtzlr committed May 13, 2024
1 parent 09092e5 commit e066834
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. The format
- Add an optional relative-residuals argument to `ConstitutiveMaterial.optimize(relative=False)`.
- Add a class-decorator `constitutive_material(Msterial, name=None)`.
- Add the MORPH material formulation implemented by the concept of representative directions `morph_representative_directions(p)` to be used in `Hyperelastic()`.
- Add the MORPH material formulation `morph(p)` to be used in `Hyperelastic()`.

### Changed
- Recfactor the `constitution` module.
Expand Down
3 changes: 3 additions & 0 deletions docs/felupe/constitution.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ There are many different pre-defined constitutive material formulations availabl
finite_strain_viscoelastic
miehe_goektepe_lulei
mooney_rivlin
morph
morph_representative_directions
neo_hooke
ogden
Expand Down Expand Up @@ -229,6 +230,8 @@ There are many different pre-defined constitutive material formulations availabl

.. autofunction:: felupe.mooney_rivlin

.. autofunction:: felupe.morph

.. autofunction:: felupe.morph_representative_directions

.. autofunction:: felupe.neo_hooke
Expand Down
2 changes: 2 additions & 0 deletions src/felupe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
linear_elastic_plastic_isotropic_hardening,
miehe_goektepe_lulei,
mooney_rivlin,
morph,
morph_representative_directions,
neo_hooke,
ogden,
Expand Down Expand Up @@ -188,6 +189,7 @@
"isochoric_volumetric_split",
"miehe_goektepe_lulei",
"mooney_rivlin",
"morph",
"morph_representative_directions",
"neo_hooke",
"ogden",
Expand Down
2 changes: 2 additions & 0 deletions src/felupe/constitution/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
isochoric_volumetric_split,
miehe_goektepe_lulei,
mooney_rivlin,
morph,
morph_representative_directions,
neo_hooke,
ogden,
Expand Down Expand Up @@ -52,6 +53,7 @@
"isochoric_volumetric_split",
"miehe_goektepe_lulei",
"mooney_rivlin",
"morph",
"morph_representative_directions",
"neo_hooke",
"ogden",
Expand Down
3 changes: 2 additions & 1 deletion src/felupe/constitution/hyperelasticity/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from ._helpers import isochoric_volumetric_split
from ._miehe_goektepe_lulei import miehe_goektepe_lulei
from ._mooney_rivlin import mooney_rivlin
from ._morph import morph_representative_directions
from ._morph import morph, morph_representative_directions
from ._neo_hooke import neo_hooke
from ._ogden import ogden
from ._ogden_roxburgh import ogden_roxburgh
Expand All @@ -33,6 +33,7 @@
"isochoric_volumetric_split",
"miehe_goektepe_lulei",
"mooney_rivlin",
"morph",
"morph_representative_directions",
"neo_hooke",
"ogden",
Expand Down
106 changes: 104 additions & 2 deletions src/felupe/constitution/hyperelasticity/models/_morph.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,110 @@
along with FElupe. If not, see <http://www.gnu.org/licenses/>.
"""
from .microsphere import affine_stretch_statevars
from tensortrax.math import array, abs as tensor_abs, maximum, sqrt, exp
from tensortrax.math.special import try_stack
from tensortrax.math import array, abs as tensor_abs, maximum, sqrt, exp, if_else, real_to_dual
from tensortrax.math.special import try_stack, from_triu_1d, triu_1d, sym, dev
from tensortrax.math.linalg import det, inv, eigvalsh, expm


def morph(C, statevars, p):
"""Strain energy function of the
`MORPH <https://doi.org/10.1016/s0749-6419(02)00091-8>`_ model formulation [1]_.
Parameters
----------
C : tensortrax.Tensor
Right Cauchy-Green deformation tensor.
statevars : array
Vector of stacked state variables (CTS, C, SA).
p : list of float
A list which contains the 8 material parameters.
Examples
--------
.. pyvista-plot::
:context:
>>> import felupe as fem
>>>
>>> umat = fem.Hyperelastic(
... fem.morph,
... p=[0.039, 0.371, 0.174, 2.41, 0.0094, 6.84, 5.65, 0.244],
... nstatevars=13,
... )
>>> ax = umat.plot(
... incompressible=True,
... ux=fem.math.linsteps(
... [1, 2, 1, 2.75, 1, 3.5, 1, 4.2, 1, 4.8, 1, 4.8, 1],
... num=50,
... ),
... ps=None,
... bx=None,
... )
.. pyvista-plot::
:include-source: False
:context:
:force_static:
>>> import pyvista as pv
>>>
>>> fig = ax.get_figure()
>>> chart = pv.ChartMPL(fig)
>>> chart.show()
References
----------
.. [1] D. Besdo and J. Ihlemann, "A phenomenological constitutive model for
rubberlike materials and its numerical applications", International Journal
of Plasticity, vol. 19, no. 7. Elsevier BV, pp. 1019–1036, Jul. 2003. doi:
`10.1016/s0749-6419(02)00091-8 <https://doi.org/10.1016/s0749-6419(02)00091-8>`_.
"""

# extract old state variables
CTSn = array(statevars[0], like=C[0, 0])
Cn = from_triu_1d(statevars[1:7], like=C)
SAn = from_triu_1d(statevars[7:], like=C)

Check warning on line 81 in src/felupe/constitution/hyperelasticity/models/_morph.py

View check run for this annotation

Codecov / codecov/patch

src/felupe/constitution/hyperelasticity/models/_morph.py#L79-L81

Added lines #L79 - L81 were not covered by tests

# distortional part of right Cauchy-Green deformation tensor
I3 = det(C)
CG = C * I3 ** (-1 / 3)

Check warning on line 85 in src/felupe/constitution/hyperelasticity/models/_morph.py

View check run for this annotation

Codecov / codecov/patch

src/felupe/constitution/hyperelasticity/models/_morph.py#L84-L85

Added lines #L84 - L85 were not covered by tests

# inverse of and incremental right Cauchy-Green deformation tensor
invC = inv(C)
dC = C - Cn

Check warning on line 89 in src/felupe/constitution/hyperelasticity/models/_morph.py

View check run for this annotation

Codecov / codecov/patch

src/felupe/constitution/hyperelasticity/models/_morph.py#L88-L89

Added lines #L88 - L89 were not covered by tests

# eigenvalues of right Cauchy-Green deformation tensor (sorted in ascending order)
λCG = eigvalsh(CG)

Check warning on line 92 in src/felupe/constitution/hyperelasticity/models/_morph.py

View check run for this annotation

Codecov / codecov/patch

src/felupe/constitution/hyperelasticity/models/_morph.py#L92

Added line #L92 was not covered by tests

# Tresca invariant of distortional part of right Cauchy-Green deformation tensor
CTG = λCG[-1] - λCG[0]

Check warning on line 95 in src/felupe/constitution/hyperelasticity/models/_morph.py

View check run for this annotation

Codecov / codecov/patch

src/felupe/constitution/hyperelasticity/models/_morph.py#L95

Added line #L95 was not covered by tests

# maximum Tresca invariant in load history
CTS = maximum(CTG, CTSn)

Check warning on line 98 in src/felupe/constitution/hyperelasticity/models/_morph.py

View check run for this annotation

Codecov / codecov/patch

src/felupe/constitution/hyperelasticity/models/_morph.py#L98

Added line #L98 was not covered by tests

def sigmoid(x):

Check warning on line 100 in src/felupe/constitution/hyperelasticity/models/_morph.py

View check run for this annotation

Codecov / codecov/patch

src/felupe/constitution/hyperelasticity/models/_morph.py#L100

Added line #L100 was not covered by tests
"Algebraic sigmoid function."
return 1 / sqrt(1 + x**2)

Check warning on line 102 in src/felupe/constitution/hyperelasticity/models/_morph.py

View check run for this annotation

Codecov / codecov/patch

src/felupe/constitution/hyperelasticity/models/_morph.py#L102

Added line #L102 was not covered by tests

# material parameters
α = p[0] + p[1] * sigmoid(p[2] * CTS)
β = p[3] * sigmoid(p[2] * CTS)
γ = p[4] * CTS * (1 - sigmoid(CTS / p[5]))

Check warning on line 107 in src/felupe/constitution/hyperelasticity/models/_morph.py

View check run for this annotation

Codecov / codecov/patch

src/felupe/constitution/hyperelasticity/models/_morph.py#L105-L107

Added lines #L105 - L107 were not covered by tests

LG = sym(dev(invC @ dC)) @ CG
λLG = eigvalsh(LG)
LTG = λLG[-1] - λLG[0]
LG_LTG = if_else(LTG > 0, LG / LTG, LG)

Check warning on line 112 in src/felupe/constitution/hyperelasticity/models/_morph.py

View check run for this annotation

Codecov / codecov/patch

src/felupe/constitution/hyperelasticity/models/_morph.py#L109-L112

Added lines #L109 - L112 were not covered by tests

# limiting stresses "L" and additional stresses "A"
SL = (γ * expm(p[6] * LG_LTG * CTG / CTS) + p[7] * LG_LTG) @ invC
SA = (SAn + β * LTG * SL) / (1 + β * LTG)

Check warning on line 116 in src/felupe/constitution/hyperelasticity/models/_morph.py

View check run for this annotation

Codecov / codecov/patch

src/felupe/constitution/hyperelasticity/models/_morph.py#L115-L116

Added lines #L115 - L116 were not covered by tests

# second Piola-Kirchhoff stress tensor
dψdC = (2 * α * dev(CG) @ invC + dev(SA @ C) @ invC) / 2
statevars_new = try_stack([[CTS], triu_1d(C), triu_1d(SA)], fallback=statevars)

Check warning on line 120 in src/felupe/constitution/hyperelasticity/models/_morph.py

View check run for this annotation

Codecov / codecov/patch

src/felupe/constitution/hyperelasticity/models/_morph.py#L119-L120

Added lines #L119 - L120 were not covered by tests

return real_to_dual(dψdC, C), statevars_new

Check warning on line 122 in src/felupe/constitution/hyperelasticity/models/_morph.py

View check run for this annotation

Codecov / codecov/patch

src/felupe/constitution/hyperelasticity/models/_morph.py#L122

Added line #L122 was not covered by tests


def morph_representative_directions(C, statevars, p, ε=1e-8):
Expand Down

0 comments on commit e066834

Please sign in to comment.