This article shows how to implement an isotropic elliptic yield criterion of the Green type in MFront. Such an example illustrates the usage of StandardElasticity brick (see this page). This page is inspired by the paper of Fritzen et al. (See [1]).

The whole implementation is available here.

# Description of the behaviour

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}}$

## Elastic behaviour

The stress $$\underline{\sigma}$$ is related to the the elastic strain $$\underline{\varepsilon}^{\mathrm{el}}$$ by a the standard Hooke law expressed using the Lamé coefficients: $\underline{\sigma}= \lambda\,{\mathrm{tr}{\left(\underline{\varepsilon}^{\mathrm{el}}\right)}}\underline{I}+2\,\mu\,\underline{\varepsilon}^{\mathrm{el}}$

Cette relation est directement prise en charge par la brique StandardElasticity.

## Plastic flow

The behaviour is based on the definition of an equivalent stress $$\sigma_{\mathrm{eq}}$$ defined as follows: $\sigma_{\mathrm{eq}}=\sqrt{{{\displaystyle \frac{\displaystyle 3}{\displaystyle 2}}}\,C\,\underline{s}\,\colon\,\underline{s}+F\,{\mathrm{tr}{\left(\underline{\sigma}\right)}}^{2}}$ where $$\underline{s}$$ is the deviatoric stress tensor: $\underline{s}=\underline{\sigma}-{{\displaystyle \frac{\displaystyle 1}{\displaystyle 3}}}\,{\mathrm{tr}{\left(\underline{\sigma}\right)}}\,\underline{I}$ This equivalent stress is an homogeneous function of the stress of degree 1.

The plastic part of the behaviour is described by the following yield surface: $f{\left(\underline{\sigma}\right)} = \sigma_{\mathrm{eq}}-\sigma_{0}$ where $$\sigma_{0}$$ is the yield stress.

Following the principle of maximum plastic dissipation, 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 1}{\displaystyle \sigma_{\mathrm{eq}}}}}\,{\left({{\displaystyle \frac{\displaystyle 3}{\displaystyle 2}}}\,C\,\underline{s}+F\,{\mathrm{tr}{\left(\underline{\sigma}\right)}}\,\underline{I}\right)}$

Since the equivalent stress is an homogeneous function of degree 1, the equivalent plastic strain $$p$$ is well defined and the plastic strain rate can be written: $\underline{\dot{\varepsilon}}^{\mathrm{p}}=\dot{p}\,\underline{n}$

# Integration algorithm

The previous constitutive equations will be integrated using a standard implicit scheme.

The first thing that the integration will determine is whether a plastic flow occurs during the time step. To do this, a plastic prediction of the stress is made. If this prediction is inside the yield surface, the step is purely elastic and the integration is trivial. On the other hand, the material must lie on the yield surface at the end of the time step.

## State variables

The state variable considered will be:

• the elastic strain $$\underline{\varepsilon}^{\mathrm{el}}$$, which is automatically declared by the StandardElasticity brick as eel.
• the equivalent plastic strain $$p$$.

### Implicit system

Assuming a plastic loading, the system of equations to be solved is: \left\{ \begin{aligned} \Delta\,\underline{\varepsilon}^{\mathrm{el}}-\Delta\,\underline{\varepsilon}^{\mathrm{to}}+\Delta\,p\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}} &= 0 \\ f{\left({\left.\sigma_{\mathrm{eq}}\right|_{t+\theta\,\Delta\,t}}\right)} &= 0 \\ \end{aligned} \right.

where $${\left.X\right|_{t+\theta\,\Delta\,t}}$$ is the value of $$X$$ at $$t+\theta\,\Delta\,t$$, $$\theta$$ being a numerical parameter. In the following, the first (tensorial) equation is noted $$f_{\underline{\varepsilon}^{\mathrm{el}}}$$ and the second (scalar) equation is noted $$f_{p}$$.

In practice, it is physically sound to make satisfy exactly the yield condition at the end of the time step (otherwise, stress extrapolation can lead to stress state outside the yield surface and spurious oscillations can also be observed). This leads to the choice $$\theta=1$$.

### Computation of the jacobian

The jacobian $$J$$ of the implicit system can be decomposed by blocks: $J= \begin{pmatrix} {\displaystyle \frac{\displaystyle \partial f_{\underline{\varepsilon}^{\mathrm{el}}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{el}}}} & {\displaystyle \frac{\displaystyle \partial f_{\underline{\varepsilon}^{\mathrm{el}}}}{\displaystyle \partial \Delta\,p}} & \\\\ {\displaystyle \frac{\displaystyle \partial f_{p}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{el}}}} & {\displaystyle \frac{\displaystyle \partial f_{p}}{\displaystyle \partial \Delta\,p}} \\ \end{pmatrix}$

The expression of the previous terms is given by:

\left\{ \begin{aligned} {\displaystyle \frac{\displaystyle \partial f_{\underline{\varepsilon}^{\mathrm{el}}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{el}}}} &= \underline{I} + dp\,{\displaystyle \frac{\displaystyle \partial {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{el}}}}\\ {\displaystyle \frac{\displaystyle \partial f_{\underline{\varepsilon}^{\mathrm{el}}}}{\displaystyle \partial \Delta\,p}} &= {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\\ {\displaystyle \frac{\displaystyle \partial f_{p}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{el}}}} &= -\theta\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\,\colon\,{\left.\underline{\underline{\mathbf{D}}}\right|_{t+\theta\,\Delta\,t}}\\ {\displaystyle \frac{\displaystyle \partial f_{p}}{\displaystyle \partial \Delta\,p}} &= 0 \end{aligned} \right.

\begin{aligned} {\displaystyle \frac{\displaystyle \partial {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{el}}}} &={\displaystyle \frac{\displaystyle \partial {\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}}{\displaystyle \partial {\left.\sigma\right|_{t+\theta\,\Delta\,t}}}}\,{\displaystyle \frac{\displaystyle \partial {\left.\sigma\right|_{t+\theta\,\Delta\,t}}}{\displaystyle \partial {\left.\underline{\varepsilon}^{\mathrm{el}}\right|_{t+\theta\,\Delta\,t}}}}\,{\displaystyle \frac{\displaystyle \partial {\left.\underline{\varepsilon}^{\mathrm{el}}\right|_{t+\theta\,\Delta\,t}}}{\displaystyle \partial \Delta\,\underline{\varepsilon}^{\mathrm{el}}}}\\ &={{\displaystyle \frac{\displaystyle \theta}{\displaystyle \sigma_{\mathrm{eq}}}}}\,{\left({{\displaystyle \frac{\displaystyle 3}{\displaystyle 2}}}\,C\,{\left(\underline{\underline{\mathbf{I}}}-{{\displaystyle \frac{\displaystyle 1}{\displaystyle 3}}}\,\underline{I}\,\otimes\,{\underline{I}}\right)}+F\,\underline{I}\,\otimes\,{\underline{I}}-{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\,\otimes\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\right)}\,\colon\,{\left.\underline{\underline{\mathbf{D}}}\right|_{t+\theta\,\Delta\,t}}\\ &={{\displaystyle \frac{\displaystyle \theta}{\displaystyle \sigma_{\mathrm{eq}}}}}\,{\left({{\displaystyle \frac{\displaystyle 3}{\displaystyle 2}}}\,C\,\,\underline{\underline{\mathbf{I}}}+{\left(F-{\left({{\displaystyle \frac{\displaystyle C}{\displaystyle 2}}}\right)}\right)}\,\underline{I}\,\otimes\,\underline{I}-{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\,\otimes\,{\left.\underline{n}\right|_{t+\theta\,\Delta\,t}}\right)}\,\colon\,{\left.\underline{\underline{\mathbf{D}}}\right|_{t+\theta\,\Delta\,t}}\\ \end{aligned}

This expression could be further simplified.

Assuming an elastic loading, the system of equations to be solved is trivially: \left\{ \begin{aligned} \Delta\,\underline{\varepsilon}^{\mathrm{el}}-\Delta\,\underline{\varepsilon}^{\mathrm{to}}&= 0 \\ \Delta\,p &= 0 \\ \end{aligned} \right.

The jacobian associated with this system is the identity matrix.

# Implementation

In the plastic loading case, the system of equations to be solved is non-linear. We choose the Newton-Raphson algorithm with an analytical jacobian. Compared to other algorithm available in MFront (Runge-Kutta, Broyden, Newton-Raphson with numerical jacobian, etc..), this algorithm is generally the most efficient in pratice.

## Preamble

The implementation begins with the choice of the Implicit domain specific language (dsl):

@DSL Implicit;

Note that this dsl automatically declares the elastic strain eel as a state variable.

As discussed before, we explicit state that a fully implicit integration will be used by default:

@Theta 1;

This value can be changed at runtime by modifying the theta parameter.

The stopping criterion is chosen low, to ensure the quality of the consistent tangent operator (the default value, $$10^{-8}$$ is enough to ensure a good estimation of the state variable evolution, but is not enough to have a proper estimation of the consistent tangent operator):

@Epsilon 1e-14;

We then declare that we want to support all the modelling hypotheses:

@ModellingHypotheses {".+"};

The support of plane stress modelling hypotheses are handled by the StandardElasticity brick and will not be discussed here.

### Usage of the StandardElasticity brick

To implement this behaviour, we will use the StandardElasticity brick which provides:

• Automatic computation of the stress tensor at various stages of the behaviour integration.
• Automatic computation of the consistent tangent operator.
• Automatic support for plane stress and generalized plane stress modelling hypotheses (The axial strain is defined as an additional state variable and the associated equation in the implicit system is added to enforce the plane stess condition).
• Automatic addition of the standard terms associated with the elastic strain state variable.

This behaviour brick is fully described here.

The usage of the StandardElasticity is declared as follows:

@Brick StandardElasticity;

### Elastic stiffness tensor

The elastic stiffness tensor $$D$$ is defined using @ComputeStiffnessTensor keyword by giving the elastic material properties as constants:

@ComputeStiffnessTensor<UnAltered> {150e9,0.3};

This computed stiffness is stored in a variable D. A second variable D_tdt is also introduced. As the material properties are constants, D_tdt is an alias to D.

The elastic material properties can be changed at runtime time by modifying the following parameters: YoungModulus and PoissonRatio.

Rather than constants, one can also use correlations implemented in seperate MFront files. This allows to take into account the dependency of the material properties with the temperature for example. In this case, the variable D contains the stiffness tensor at $$t+\theta\,\Delta\,t$$ and the variable D_tdt contains the stiffness tensor at $$t+\Delta\,t$$.

Another possibility is to use the @RequireStiffnessTensor keyword. In this case, the elastic material properties must be computed by the calling solver at the end of the time step (and furnished to the mechanical behaviours through hidden material properties).

### Variable declarations

#### State variables

As stated earlier, the state variable eel is automatically declared by the Implicit dsl.

The equivalent plastic strain state variable p is declared as:

@StateVariable real p;

We then associate the appropriate glossary name to this variable:

p.setGlossaryName("EquivalentPlasticStrain");

#### Parameters

The definition of yield surface introduces three material coefficients $$C$$, $$F$$ and $$\sigma_{0}$$ that we declare as a parameter:

@Parameter C = 0.8;
C.setEntryName("GreenYieldCriterion_C");
@Parameter F = 0.2;
F.setEntryName("GreenYieldCriterion_F");
@Parameter s0 = 150e6;
s0.setGlossaryName("YieldStress");

The YieldStress is an entry of the glossary (see here).

#### Local variable

To select the implicit system associated either with the elastic or plastic loading case, we introduce a boolean local variable b.

@LocalVariable bool b; // if true, plastic loading

## Initialization of the local variables, determination of the loading case

Before solving the implicit system, the code block introduced by the @InitLocalVariables keyword is executed. For this behaviour, this block will select either the elastic or plastic loading case.

We first make an elastic prediction of the stress at the end of the time step. We use the computeElasticPrediction method introduced by the StandardElasticity brick. This method takes into account the modelling hypothesis, which is mandatory for plane stress modelling hypotheses. We then make an elastic prediction of the Hill equivalent stress and check whether or not this elastic prediction is inside the elastic domain. The latter information is stored in the boolean value b which will be false (no plastic loading) if the loading is elastic.

@InitLocalVariables{
const auto sig_el  = computeElasticPrediction();
const auto s_el    = deviator(sig_el);
const auto tr_el   = trace(sig_el);
const auto seq     = sqrt(3*C*(s_el|s_el)/2+F*tr_el*tr_el);
b = seq-s0 > 0;
}

## Implicit system and jacobian

Finally, we describe how the implicit system and the computation of the jacobian is written in a code block introduced by the @Integrator keyword.

We use the following facts:

• The equations of implicit system are initialized to the state variables increments (i.e. feel is initialized to deel).
• The jacobian $$J$$ is initialized to the identity (i.e. dfeel_ddeel is initialized to the identity tensor).
• The increment of the total strain is automatically deduced from feel by the StandardElasticity brick.

Apart from those facts, the code is an almost direct translation of the mathematical expression described in previous sections and boils down to the following lines of code:

@Integrator{
constexpr const auto id    = Stensor::Id();
constexpr const auto id4 = Stensor4::Id();
if(b){
const auto hC   = C/2;
const auto s    = deviator(sig);
const auto tr   = trace(sig);
const auto seq  = sqrt(3*hC*(s|s)+F*tr*tr);
const auto iseq = 1/(max(seq,real(1.e-10*young)));
const auto n    = eval(iseq*(3*hC*s+F*tr*id));
// elasticity
feel        += dp*n;
dfeel_ddeel += theta*dp*iseq*(3*hC*id4+(F-hC)*(id^id)-(n^n))*D;
dfeel_ddp    = n;
// plasticity
fp           = (seq-s0)/young;
dfp_ddp      = strain(0);
dfp_ddeel    = theta*(n|D)/young;
}
}

# References

1.
Fritzen, Felix, Forest, Samuel, Kondo, Djimedo and Böhlke, Thomas. Computational homogenization of porous materials of green type. Computational Mechanics. 1 July 2013. Vol. 52, no. 1, p. 121–134. DOI 10.1007/s00466-012-0801-z. Available from: https://link.springer.com/article/10.1007/s00466-012-0801-z