diff --git a/dolfinx_materials/mfront.py b/dolfinx_materials/mfront.py index 41f31fd..b623e70 100644 --- a/dolfinx_materials/mfront.py +++ b/dolfinx_materials/mfront.py @@ -52,6 +52,7 @@ def __init__( parameters={}, rotation_matrix=None, dt=0, + finite_strain_options=None, ): """ Parameters @@ -74,6 +75,13 @@ def __init__( a 3D rotation matrix expressing the rotation from the global frame to the material frame. The matrix can be spatially variable (either UFL matrix or function of Tensor type) + finite_strain_options: dict + A dictionary with {"stress": "PK1" | "PK2", "tangent": "DPK1_DF" | "DS_DEGL"} + specifying if we should work with 1st (PK1) or 2nd (PK2) Piola-Kirchhoff stress. + Attention: the tangent operator choice should match the corresponding stress choice, + if one wants to use automatic differentiation. Otherwise, wrong derivatives will be + calculated. + Default choice is PK1/F. """ self.path = str(path) # ensure string in case we use a PosixPath from pathlib self.name = name @@ -84,6 +92,10 @@ def __init__( self.integration_type = ( mgis_bv.IntegrationType.IntegrationWithConsistentTangentOperator ) + if finite_strain_options is None: + self.finite_strain_options = {"stress": "PK1", "tangent": "DPK1_DF"} + else: + self.finite_strain_options = finite_strain_options self.dt = dt # Loading the behaviour self.load_behaviour(self.path) @@ -95,9 +107,13 @@ def load_behaviour(self, path): if self.is_finite_strain: # finite strain options bopts = mgis_bv.FiniteStrainBehaviourOptions() - bopts.stress_measure = mgis_bv.FiniteStrainBehaviourOptionsStressMeasure.PK1 - bopts.tangent_operator = ( - mgis_bv.FiniteStrainBehaviourOptionsTangentOperator.DPK1_DF + bopts.stress_measure = getattr( + mgis_bv.FiniteStrainBehaviourOptionsStressMeasure, + self.finite_strain_options["stress"], + ) + bopts.tangent_operator = getattr( + mgis_bv.FiniteStrainBehaviourOptionsTangentOperator, + self.finite_strain_options["tangent"], ) self.behaviour = mgis_bv.load(bopts, path, self.name, self.hypothesis) else: diff --git a/tests/mfront/LogarithmicStrainPlasticity.mfront b/tests/mfront/LogarithmicStrainPlasticity.mfront new file mode 100644 index 0000000..5473922 --- /dev/null +++ b/tests/mfront/LogarithmicStrainPlasticity.mfront @@ -0,0 +1,27 @@ +@DSL Implicit; + +@Behaviour LogarithmicStrainPlasticity; +@Author Thomas Helfer/Jérémy Bleyer; +@Date 07 / 04 / 2020; + +@StrainMeasure Hencky; + +@Algorithm NewtonRaphson; +@Epsilon 1.e-14; +@Theta 1; + +@MaterialProperty stress s0; +s0.setGlossaryName("YieldStress"); +@MaterialProperty stress H0; +H0.setEntryName("HardeningSlope"); + +@Brick StandardElastoViscoPlasticity{ + stress_potential : "Hooke" { + young_modulus : 210e9, + poisson_ratio : 0.3 + }, + inelastic_flow : "Plastic" { + criterion : "Mises", + isotropic_hardening : "Linear" {H : "H0", R0 : "s0"} + } +}; diff --git a/tests/mfront/test_finite_strain.py b/tests/mfront/test_finite_strain.py new file mode 100644 index 0000000..c60d66d --- /dev/null +++ b/tests/mfront/test_finite_strain.py @@ -0,0 +1,37 @@ +import pathlib +import numpy as np +import sys +import pytest +import ufl +from dolfinx_materials.mfront import MFrontMaterial + +path = pathlib.Path(__file__).parent.absolute() + +sys.path.append(str(path.parent.absolute())) + + +def test_mfront_finite_strain_options(): + material = MFrontMaterial( + path / "src/libBehaviour.so", + "LogarithmicStrainPlasticity", + ) + assert material.behaviour.getBehaviourType() == "StandardFiniteStrainBehaviour" + assert material.behaviour.getKinematic() == "F_CAUCHY" + assert material.gradient_names == ["DeformationGradient"] + assert material.flux_names == ["FirstPiolaKirchhoffStress"] + assert material.tangent_block_names == [ + ("FirstPiolaKirchhoffStress", "DeformationGradient") + ] + + material = MFrontMaterial( + path / "src/libBehaviour.so", + "LogarithmicStrainPlasticity", + finite_strain_options={"stress": "PK2", "tangent": "DS_DEGL"}, + ) + assert material.behaviour.getBehaviourType() == "StandardFiniteStrainBehaviour" + assert material.behaviour.getKinematic() == "F_CAUCHY" + assert material.gradient_names == ["DeformationGradient"] + assert material.flux_names == ["SecondPiolaKirchhoffStress"] + assert material.tangent_block_names == [ + ("SecondPiolaKirchhoffStress", "GreenLagrangeStrain") + ]