This article shows how to implement an orthotropic plastic behaviour
with isotropic linear hardening in MFront
.
The implementation is available here.
The behaviour is described by a standard decomposition of the strain \(\underline{\varepsilon}^{\mathrm{to}}\) in an elastic and a plastic component, respectively denoted \(\underline{\varepsilon}^{\mathrm{el}}\) and \(\underline{\varepsilon}^{\mathrm{p}}\):
\[ \underline{\varepsilon}^{\mathrm{to}}=\underline{\varepsilon}^{\mathrm{el}}+\underline{\varepsilon}^{\mathrm{p}} \qquad{(1)}\]
The stress \(\underline{\sigma}\) is related to the the elastic strain \(\underline{\varepsilon}^{\mathrm{el}}\) by a the standard Hooke behaviour:
\[ \underline{\sigma}= \lambda\,{\mathrm{tr}{\left(\underline{\varepsilon}^{\mathrm{el}}\right)}}\,\underline{I}+2\,\mu\,\underline{\varepsilon}^{\mathrm{el}} \qquad{(2)}\]
The plastic part of the behaviour is described by the following yield surface: \[ f{\left(\sigma_{\mathrm{eq}},p\right)} = \sigma_{\mathrm{eq}}-\sigma_{0}-R\,p \qquad{(3)}\]
where \(\sigma_{\mathrm{eq}}\) is the vonMises stress defined below, \(p\) is the equivalent plastic strain, \(\sigma_{0}\) is the yield stress and \(R\) is the hardening slope.
The von Mises stress is defined by: \[ \sigma_{\mathrm{eq}}=\sqrt{{{\displaystyle \frac{\displaystyle 3}{\displaystyle 2}}}\,\underline{s}\,\colon\,\underline{s}}=\sqrt{3\,J_{2}} \] where:
The previous expression can be rewritten by introducing a fourth order tensor called \(\underline{\underline{\mathbf{M}}}\): \[ \sigma_{\mathrm{eq}}=\sqrt{\sigma\,\colon\,\underline{\underline{\mathbf{M}}}\,\colon\,\underline{\sigma}} \]
The tensor \(\underline{\underline{\mathbf{M}}}\) is given by: \[ \underline{\underline{\mathbf{M}}}={{\displaystyle \frac{\displaystyle 3}{\displaystyle 2}}}\,{\left(\underline{\underline{\mathbf{I}}}-{{\displaystyle \frac{\displaystyle 1}{\displaystyle 3}}}\,\underline{I}\,\otimes\,\underline{I}\right)} \]
The plastic flow is assumed to be associated, so the flow direction \(\underline{n}\) is given by \({\displaystyle \frac{\displaystyle \partial f}{\displaystyle \partial \underline{\sigma}}}\):
\[ \underline{n} = {\displaystyle \frac{\displaystyle \partial f}{\displaystyle \partial \underline{\sigma}}} = {{\displaystyle \frac{\displaystyle 3}{\displaystyle 2\,\sigma_{\mathrm{eq}}}}}\,\underline{s} \]
One may readily check that:
\[ \underline{n}\,\colon\underline{n}={{\displaystyle \frac{\displaystyle 3}{\displaystyle 2}}} \qquad{(4)}\]
The previous constitutive equations will be integrated using a standard implicit scheme which, due to the isotropy of the elastic behaviour, the quadratic nature of the equivalent stress and the linearity of the isotropic hardening rule can be solved analytically.
Assuming that a plastic flow occurs, the plastic increment \(\Delta\,\underline{\varepsilon}^{\mathrm{p}}\) over the time step is approximated by:
\[ \Delta\,\underline{\varepsilon}^{\mathrm{p}}= \Delta\,p\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}} \]
The slip of strain given by Equation (1) may be written incrementally:
\[ \Delta\,\underline{\varepsilon}^{\mathrm{to}}=\Delta\,\underline{\varepsilon}^{\mathrm{el}}+\Delta\,\underline{\varepsilon}^{\mathrm{p}}=\Delta\,\underline{\varepsilon}^{\mathrm{el}}+\Delta\,p\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}} \qquad{(5)}\]
and projected on the deviatoric space as follows:
\[ \Delta\,\underline{s}^{\mathrm{to}} = \Delta\,\underline{s}^{\mathrm{el}}+\Delta\,p\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}} \]
The isotropy of the elastic behaviour projected on the deviatoric space leads to:
\[ \begin{aligned} {\left.\underline{s}\right|_{t+\theta\,\Delta\,t}} &= {{\displaystyle \frac{\displaystyle 2}{\displaystyle 3}}}\,{\left.\sigma_{\mathrm{eq}}\right|_{t+\theta\,\Delta\,t}}\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\\ &= 2\,{\left.\mu\right|_{t+\theta\,\Delta\,t}}\,{\left({\left.\underline{s}^{\mathrm{el}}\right|_{t}}+\theta\,\Delta\,\underline{s}^{\mathrm{el}}\right)} \\ &= 2\,{\left.\mu\right|_{t+\theta\,\Delta\,t}}\,{\left({\left.\underline{s}^{\mathrm{el}}\right|_{t}} +\theta\,\Delta\,\underline{s}^{\mathrm{to}} -\theta\,\Delta\,p\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\right)} \end{aligned} \]
The previous equations leads to:
\[ {\left({{\displaystyle \frac{\displaystyle 2}{\displaystyle 3}}}\,{\left.\sigma_{\mathrm{eq}}\right|_{t+\theta\,\Delta\,t}}+\theta\,\Delta\,p\right)}\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}} = 2\,{\left.\mu\right|_{t+\theta\,\Delta\,t}}\,{\left({\left.\underline{s}^{\mathrm{el}}\right|_{t}}+\theta\,\Delta\,\underline{s}^{\mathrm{to}}\right)} \qquad{(6)}\]
The right hand side is the value of the deviatoric part of the stress tensor that would be obtained in a pure elastic loading. The latter is commonly called the trial stress \(\underline{\sigma}^{\mathrm{tr}}\):
\[ \underline{\sigma}^{\mathrm{tr}}= {\left.\lambda\right|_{t+\theta\,\Delta\,t}}\,{\mathrm{tr}{\left({\left.\underline{\varepsilon}^{\mathrm{el}}\right|_{t}}+\theta\,\Delta\,\underline{\varepsilon}^{\mathrm{to}}\right)}}\,\underline{I}+ 2\,{\left.\mu\right|_{t+\theta\,\Delta\,t}}\,{\left({\left.\underline{\varepsilon}^{\mathrm{el}}\right|_{t}}+\theta\,\Delta\,\underline{\varepsilon}^{\mathrm{to}}\right)} \]
Its deviatoric part is denoted \({\left.\underline{s}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}}\):
\[ {\left.\underline{s}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}}=2\,{\left.\mu\right|_{t+\theta\,\Delta\,t}}\,{\left({\left.\underline{s}^{\mathrm{el}}\right|_{t}}+\theta\,\Delta\,\underline{s}^{\mathrm{to}}\right)} \]
Taking the von Mises norm of both side of Equation (6) yields:
\[ {\left({{\displaystyle \frac{\displaystyle 2}{\displaystyle 3}}}\,{\left.\sigma_{\mathrm{eq}}\right|_{t+\theta\,\Delta\,t}}+\theta\,\Delta\,p\right)}\,\sqrt{{{\displaystyle \frac{\displaystyle 3}{\displaystyle 2}}}\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\,\colon{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}} = {\left.\sigma_{\mathrm{eq}}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}} \]
where \({\left.\sigma_{\mathrm{eq}}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}}\) is the so-called trial equivalent stress.
It is important to note that \(\underline{s}^{\mathrm{tr}}\) and \({\left.\sigma_{\mathrm{eq}}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}}\) can be computed a priori, only with the known values of the elastic strain at the beginning of the time step and the total strain increment.
The previous expressions leads to a closed form expression of the normal:
\[ {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}} = {{\displaystyle \frac{\displaystyle 3}{\displaystyle 2\,{\left.\sigma_{\mathrm{eq}}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}}}}}\underline{s}^{\mathrm{tr}} \qquad{(7)}\]
Derivatives of the equivalent trial stress \({\left.\sigma_{\mathrm{eq}}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}}\) and normal \({\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\)
The following classical relationships will be useful in the following:
\[ \left\{ \begin{aligned} {\displaystyle \frac{\displaystyle \partial {\left.\sigma_{\mathrm{eq}}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}}}{\displaystyle \partial {\left.\underline{\sigma}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}}}}&={\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\\ {\displaystyle \frac{\displaystyle \partial {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}}{\displaystyle \partial {\left.\underline{\sigma}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}}}}&= {{\displaystyle \frac{\displaystyle 1}{\displaystyle {\left.\sigma_{\mathrm{eq}}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}}}}} {\left(\underline{\underline{\mathbf{M}}}-{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\,\otimes\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\right)}\\ \end{aligned} \right. \qquad{(8)}\]
Finally, taking into account Equation (4), the von Mises stress satisfies:
\[ {\left.\sigma_{\mathrm{eq}}\right|_{t+\theta\,\Delta\,t}} = {\left.\sigma_{\mathrm{eq}}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}} - 3\,{\left.\mu\right|_{t+\theta\,\Delta\,t}}\,\theta\,\Delta\,p \]
Using the fact that, during plastic loading, the stress state must be on the Yield Surface (3), the von Mises stress also satisfies:
\[ {\left.\sigma_{\mathrm{eq}}\right|_{t+\theta\,\Delta\,t}}=\sigma_{0}+R\,{\left.p\right|_{t+\theta\,\Delta\,t}}=\sigma_{0}+R\,{\left({\left.p\right|_{t}}+\theta\,\Delta\,p\right)} \]
Combining those equations yields this closed-form expression of the plastic strain increment:
\[ \Delta\,p = {{\displaystyle \frac{\displaystyle {\left.\sigma_{\mathrm{eq}}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}} - \sigma_{0} - R\,{\left.p\right|_{t}}}{\displaystyle {\left(3\,{\left.\mu\right|_{t+\theta\,\Delta\,t}}\, + R\right)}\,\theta}}} \qquad{(9)}\]
The elastic strain increment is given in closed form by Equations (5), (7) and (9):
\[ \Delta\underline{\varepsilon}^{\mathrm{el}}= \Delta\,\underline{\varepsilon}^{\mathrm{to}}-\Delta\,p\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}} \qquad{(10)}\]
The consistent tangent operator is the derivative \({\displaystyle \frac{\displaystyle \partial {\left.\underline{\sigma}\right|_{t+\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}}\) of the stress at the end of the time step with respect the increment of the strain.
Using Equation (2), this derivative can be expressed as:
\[ {\displaystyle \frac{\displaystyle \partial {\left.\underline{\sigma}\right|_{t+\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}}= {\left.\underline{\underline{\mathbf{D}}}\right|_{t+\Delta\,t}}\,\colon\,{\displaystyle \frac{\displaystyle \partial {\left.\underline{\varepsilon}^{\mathrm{el}}\right|_{t+\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}}= {\left.\underline{\underline{\mathbf{D}}}\right|_{t+\Delta\,t}}\,\colon\,{\displaystyle \frac{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{el}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}} \]
where \({\left.\underline{\underline{\mathbf{D}}}\right|_{t+\Delta\,t}}={\left.\lambda\right|_{t+\Delta\,t}}\,\,\underline{\underline{\mathbf{I}}}+2\,{\left.\mu\right|_{t+\Delta\,t}}\,\underline{I}\,\otimes\,\underline{I}\) denotes the stiffness matrix.
The derivative \({\displaystyle \frac{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{el}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}}\) can be deduced from Equation (10):
\[ {\displaystyle \frac{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{el}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}}= \underline{\underline{\mathbf{I}}} -{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\,\otimes\,{\displaystyle \frac{\displaystyle \partial \Delta\,p}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}} -\Delta\,p\,{\displaystyle \frac{\displaystyle \partial {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}} \]
Using Equation (8), the derivative \({\displaystyle \frac{\displaystyle \partial \Delta\,p}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}}\) can be deduced from Equation (9) as follows:
\[ {\displaystyle \frac{\displaystyle \partial \Delta\,p}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}}= {{\displaystyle \frac{\displaystyle 1}{\displaystyle {\left(3\,{\left.\mu\right|_{t+\theta\,\Delta\,t}}\, + R\right)}\,\theta}}}\, {\displaystyle \frac{\displaystyle \partial {\left.\sigma_{\mathrm{eq}}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}} }{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}} = {{\displaystyle \frac{\displaystyle 2\,{\left.\mu\right|_{t+\theta\,\Delta\,t}}}{\displaystyle 3\,{\left.\mu\right|_{t+\theta\,\Delta\,t}}\, + R}}}\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}} \qquad{(11)}\]
Using Equations (8) and (7), the derivative \({\displaystyle \frac{\displaystyle \partial {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}}\) is also given by:
\[ {\displaystyle \frac{\displaystyle \partial {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}}= {{\displaystyle \frac{\displaystyle 2\,{\left.\mu\right|_{t+\theta\,\Delta\,t}}\,\theta}{\displaystyle {\left.\sigma_{\mathrm{eq}}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}}}}} {\left(\underline{\underline{\mathbf{M}}}-{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\,\otimes\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\right)} \qquad{(12)}\]
Equations (11) and (12), shows that the derivatives \({\displaystyle \frac{\displaystyle \partial \Delta\,p}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}}\) and \({\displaystyle \frac{\displaystyle \partial {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}}\) are linear combinations of the two fourth order tensors \(\underline{M}\) and \({\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\,\otimes\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\) which only acts on the deviatoric parts of the symmetric tensors. The following properites then holds:
\[ \left\{ \begin{aligned} {\left.\underline{\underline{\mathbf{D}}}\right|_{t+\Delta\,t}}\,\colon\,\underline{\underline{\mathbf{M}}} &= 2\,{\left.\mu\right|_{t+\Delta\,t}}\,\underline{\underline{\mathbf{M}}}\\ {\left.\underline{\underline{\mathbf{D}}}\right|_{t+\Delta\,t}}\,\colon\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\,\otimes\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}} &= 2\,{\left.\mu\right|_{t+\Delta\,t}}\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\,\otimes\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\\ \end{aligned} \right. \]
The consistent tangent operator is then:
\[ \begin{aligned} {\displaystyle \frac{\displaystyle \partial {\left.\underline{\sigma}\right|_{t+\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}} &= {\left.\underline{\underline{\mathbf{D}}}\right|_{t+\Delta\,t}} -{\left.\underline{\underline{\mathbf{D}}}\right|_{t+\Delta\,t}}\,\colon\,{\left( {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\,\otimes\,{\displaystyle \frac{\displaystyle \partial \Delta\,p}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}} +\Delta\,p\,{\displaystyle \frac{\displaystyle \partial {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}} \right)}\\ &={\left.\underline{\underline{\mathbf{D}}}\right|_{t+\Delta\,t}} -2\,{\left.\mu\right|_{t+\theta\,\Delta\,t}}\,{\left( {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\,\otimes\,{\displaystyle \frac{\displaystyle \partial \Delta\,p}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}} +\Delta\,p\,{\displaystyle \frac{\displaystyle \partial {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}} \right)} \end{aligned} \]
and finaly,
\[ \begin{aligned} {\displaystyle \frac{\displaystyle \partial {\left.\underline{\sigma}\right|_{t+\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{to}}}} ={\left.\underline{\underline{\mathbf{D}}}\right|_{t+\Delta\,t}} -4\,{\left({\left.\mu\right|_{t+\theta\,\Delta\,t}}\right)}^{2}\, &\left( {{\displaystyle \frac{\displaystyle 1}{\displaystyle 3\,{\left.\mu\right|_{t+\theta\,\Delta\,t}}\, + R}}}\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}} \otimes\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}+\right.\\ &\left.{{\displaystyle \frac{\displaystyle \theta\Delta\,p}{\displaystyle {\left.\sigma_{\mathrm{eq}}^{\mathrm{tr}}\right|_{t+\theta\,\Delta\,t}}}}}\,{\left(\underline{\underline{\mathbf{M}}}-{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\,\otimes\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\right)}\right)\\ \end{aligned} \qquad{(13)}\]
We now describe how to make a fully implicit implementation, i.e. we fix the \(\theta\) parameter to \(1\).
This choice is consistent with the description of a plastic flow as it imposes that the material lies on the yield surface at the end of the time step if a plastic loading occurs.
With other choices, the material may be outside the yield surface at the end of the time step and spurious oscillations in the stress in time can be observed, for example during a simple uniaxial tensile test test.
The behaviour integration is trivial as all the computated quantities can be obtained thanks in closed form:
In this case, an appropriate domain specific language is the
Default
:
@DSL Default;
Contrary to other DSLs, the Default
does not provide a
built-in support for a given integration scheme.
The name of the behaviour is introduced by the
@Behaviour
keyword:
@Behaviour IsotropicLinearHardeningPlasticity;
The following lines defines the author of the implementation, the date and provides a small description:
@Author Thomas Helfer;
@Date 14/10/2016;
@Description{
An implicit implementation of a simple
isotropic plasticity behaviour with.
isotropic linear hardening
:
The yield surface is defined by"\["
" f(\sigmaeq,p) = \sigmaeq-s_{0}-H\,p"
"\]"
}
The behaviour used two state variables, the elastic strain \(\underline{\varepsilon}^{\mathrm{el}}\) and the equivalent plastic strain \(p\).
Those state variables are declared as follows:
@StateVariable StrainStensor eel;
.setGlossaryName("ElasticStrain");
eel@StateVariable strain p;
.setGlossaryName("EquivalentPlasticStrain"); p
The state variables have been associated to glossary names which are meant to:
MFront
).Increments of the state variables
The
Default
automatically declares the increments of those variables, called respectivelydeel
anddp
. The user is free to use those increments or to directly update the values of the state variables.If the increment of a state variable is defined, it is added to the state variable after the
@Integrator
code block.In our implementation, we will directly update the elastic strain and use the plastic strain increment.
In this implementation, we choose to use parameters associated respectively with the Young’ modulus, Poisson’ ratio, hardening slope and yield stress, as follows:
@Parameter stress young = 70.e9;
.setGlossaryName("YoungModulus");
young@Parameter real nu = 0.34;
.setGlossaryName("PoissonRatio");
nu@Parameter stress H = 10.e9;
.setEntryName("HardeningSlope");
H@Parameter stress s0 = 300.e6;
.setGlossaryName("YieldStress"); s0
Using material properties
The use of parameters could be replaced by the use of material properties as follows:
@MaterialProperty stress young; .setGlossaryName("YoungModulus"); young@MaterialProperty real nu; .setGlossaryName("PoissonRatio"); nu@MaterialProperty stress H; .setEntryName("HardeningSlope"); H@MaterialProperty stress s0; .setGlossaryName("YieldStress"); s0
Contrary to parameters, material properties does not have default values and must be provided by the calling solvers, which generally uses values provided by the user in its input file.
The current implementation only provides the elastic operator:
@PredictionOperator{
const auto lambda = computeLambda(young, nu);
const auto mu = computeMu(young, nu);
= lambda * Stensor4::IxI() + 2 * mu * Stensor4::Id();
Dt }
We could also provide a tangent operator, but this would mean saving an auxiliary state variable stating if a plastic loading occured at the previous time step.
The behaviour integration is implemented in the
@Integrator
code block.
The Default
DSL allows to compute the consistent tangent
operator either inside the @Integrator
code block or in a
dedicated code block name @TangentOperator
.
The first choice is simplier and more efficient for the considered
implementation, but this requires to explicitely state that the
consistent tangent operator is defined in the @Integrator
code block using the @ProvidesSymmetricTangentOperator
keyword, as follows:
@ProvidesSymmetricTangentOperator;
The consistent tangent operator may or may not be requested by the calling solver at runtime.
The @Integrator
code blocks begins by computing the
Lamé’ coefficients as follows:
@Integrator{
const auto lambda = computeLambda(young, nu);
const auto mu = computeMu(young, nu);
The next lines assume a purely elastic loading and:
+= deto;
eel if(computeTangentOperator_){
= lambda * Stensor4::IxI() + 2 * mu * Stensor4::Id();
Dt }
If required, a plastic correction will be applied to the elastic strain and the consistent tangent operator in the next part of the code.
To check of if a plastic correction must be applied, we first compute the deviator of the trial stress, the equivalent trial stress and checks if its value is outside the elastic domain at the beginning of the time step.
const auto se = 2 * mu * deviator(eel);
const auto seq_e = sigmaeq(se);
const auto plastic_loading = seq_e > s0 + H * p;
The plastic_loading
boolean value is thus
true
if a plastic correction must be applied,
false
otherwise.
If a plastic correction must be applied, we first compute the normal using Equation (7):
if(plastic_loading){
const auto iseq_e = 1 / seq_e;
const auto n = eval(3 * se / (2 * seq_e));
The
eval
function
TFEL/Math
uses expression templates to perform lazy evaluations of most tensorial operations. See its documentation for details.The eval function evaluates an expression to get its results. We could have removed it here, but the normal is used multiple times, so we choose to evaluate it once.
The increment of the equivalent plastic strain is computed using Equation (9):
const auto cste = 1 / (H + 3 * mu);
= (seq_e - s0 - H * p) * cste; dp
The value of the equivalent plastic strain will be updated
automatically after the @Integrator
code block.
Once the equivalent plastic strain is known, the elastic strain can be corrected using the split of the strain (Equation (1)):
-= dp * n; eel
The consistent tangent operator can be corrected using Equation (13):
if((computeTangentOperator_) && (smt==CONSISTENTTANGENTOPERATOR)){
-= -4 * mu * mu * (dp * iseq_e * (Stensor4::M()-(n ^ n)) + cste * (n ^ n));
Dt }
} // end of if(plastic_loading)
At this stage, the elastic strain have been updated and hols its value at the end of the time step. The last step of the implementation is to use it to compute the stress at the end of the time step:
= lambda*trace(eel)*Stensor::Id()+2*mu*eel;
sig } // end of @Integrator