diff --git a/README.md b/README.md index fee9fca..b1bd2a6 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ A = Mat.hessian([defgrad])[0] ``` ## Template classes for hyperelasticity -matADi provides several simple template classes suitable for simple hyperelastic materials. Some isotropic hyperelastic material formulations are located in `matadi.models` (see list below). These strain energy functions have to be passed as the `fun` argument into an instance of `MaterialHyperelastic`. Usage is exactly the same as described above. To convert a hyperelastic material based on the deformation gradient into a mixed three-field formulation suitable for nearly-incompressible behavior (*displacements*, *pressure* and *volume ratio*) an instance of a `MaterialHyperelastic` class has to be passed to `ThreeFieldVariation`. For *plane strain* or *plane stress* use `MaterialHyperelasticPlaneStrain` or `MaterialHyperelasticPlaneStressIncompressible` instead of `MaterialHyperelastic`. +matADi provides several simple template classes suitable for simple hyperelastic materials. Some isotropic hyperelastic material formulations are located in `matadi.models` (see list below). These strain energy functions have to be passed as the `fun` argument into an instance of `MaterialHyperelastic`. Usage is exactly the same as described above. To convert a hyperelastic material based on the deformation gradient into a mixed three-field formulation suitable for nearly-incompressible behavior (*displacements*, *pressure* and *volume ratio*) an instance of a `MaterialHyperelastic` class has to be passed to `ThreeFieldVariation`. For *plane strain* or *plane stress* use `MaterialHyperelasticPlaneStrain`, `MaterialHyperelasticPlaneStressIncompressible` or `MaterialHyperelasticPlaneStressLinearElastic` instead of `MaterialHyperelastic`. ```python diff --git a/matadi/__about__.py b/matadi/__about__.py index 479dad0..40b07ef 100644 --- a/matadi/__about__.py +++ b/matadi/__about__.py @@ -1 +1 @@ -__version__ = "0.0.22" +__version__ = "0.0.23" diff --git a/matadi/__init__.py b/matadi/__init__.py index c012d39..8faa7f9 100644 --- a/matadi/__init__.py +++ b/matadi/__init__.py @@ -17,6 +17,7 @@ MaterialComposite, MaterialHyperelasticPlaneStrain, MaterialHyperelasticPlaneStressIncompressible, + MaterialHyperelasticPlaneStressLinearElastic, ) from ._lab import Lab diff --git a/matadi/_templates.py b/matadi/_templates.py index 68fc00c..320498c 100644 --- a/matadi/_templates.py +++ b/matadi/_templates.py @@ -66,6 +66,22 @@ def _fun_wrapper(self, x, **kwargs): return self.fun(F, **kwargs) +class MaterialHyperelasticPlaneStressLinearElastic(MaterialHyperelasticPlaneStrain): + def __init__(self, fun, **kwargs): + super().__init__(fun, **kwargs) + + def _fun_wrapper(self, x, **kwargs): + F = horzcat(vertcat(x[0], zeros(1, 2)), zeros(3, 1)) + # stress-free thickness ratio for linear elastic material + # s_33 != 0 = 2 mu e_33 + lmbda (e_11 + e_22 + e_33) + # e_33 = - (e_11 + e_22) * lmbda / (2 mu + lmbda) + # F_33 = 1 + e_33 + F[2, 2] = 1 - (F[0, 0] + F[1, 1] - 2) * ( + kwargs["lmbda"] / (2 * kwargs["mu"] + kwargs["lmbda"]) + ) + return self.fun(F, **kwargs) + + class MaterialComposite: def __init__(self, materials): "Composite Material as a sum of a list of materials." diff --git a/pyproject.toml b/pyproject.toml index 7a594e6..862b657 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "matadi" -version = "0.0.22" +version = "0.0.23" description = "Material Definition with Automatic Differentiation" readme = "README.md" requires-python = ">=3.6" diff --git a/setup.cfg b/setup.cfg index 585ed01..7207fd9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = matadi -version = 0.0.22 +version = 0.0.23 author = Andreas Dutzler author_email = a.dutzler@gmail.com description = Material Definition with Automatic Differentiation diff --git a/tests/test_plane.py b/tests/test_plane.py index d2588eb..5d27d99 100644 --- a/tests/test_plane.py +++ b/tests/test_plane.py @@ -3,8 +3,9 @@ from matadi import ( MaterialHyperelasticPlaneStrain, MaterialHyperelasticPlaneStressIncompressible, + MaterialHyperelasticPlaneStressLinearElastic, ) -from matadi.models import neo_hooke +from matadi.models import neo_hooke, linear_elastic def pre(): @@ -40,7 +41,7 @@ def test_plane_strain(): assert DW[0].shape == (2, 2, 2, 2, 8, 1000) -def test_plane_stress(): +def test_plane_stress_incompr(): # data FF = pre() @@ -64,6 +65,32 @@ def test_plane_stress(): assert DW[0].shape == (2, 2, 2, 2, 8, 1000) +def test_plane_stress_linear(): + + # data + FF = pre() + + # init Material + W = MaterialHyperelasticPlaneStressLinearElastic( + fun=linear_elastic, + mu=1.0, + lmbda=200.0, + ) + + W0 = W.function([FF]) + dW = W.gradient([FF]) + DW = W.hessian([FF]) + + assert W0[0].shape == (8, 1000) + assert dW[0].shape == (2, 2, 8, 1000) + assert DW[0].shape == (2, 2, 2, 2, 8, 1000) + + assert W0[0].shape == (8, 1000) + assert dW[0].shape == (2, 2, 8, 1000) + assert DW[0].shape == (2, 2, 2, 2, 8, 1000) + + if __name__ == "__main__": test_plane_strain() - test_plane_stress() + test_plane_stress_incompr() + test_plane_stress_linear()