This article shows how to implement hyperviscoelastic behaviours in
MFront
.
The hyperelastic behaviour is left unspecified. We only assume that one can compute \(\underline{S}^{\infty}\) and its derivative \({\displaystyle \frac{\displaystyle \partial \underline{S}^{\infty}}{\displaystyle \partial \underline{C}}}\).
The reader can refer to the following pages describing the implementation of various hyperelastic behaviours:
The formalism used by most hyperelastic behaviours is described in this page.
An example of implementation based on the Signorini hyperelastic behaviour is available here: SignoriniHyperViscoelasticity.mfront
Compatibility with previous versions of
TFEL
This implementation presented here is based on the version \(3.0\) of
TFEL
. However, only a few adaptations are required for used with previous versions:
- the first line of the file must be replace by:
@Parser DefaultFiniteStrainParser;
- the
power
function is not available. It can be replaced by explicit multiplications.- the
computeDeterminantSecondDerivative
is not available. It can be replaced by the following code:Stensor4::dsquare(C)-(C^id)-I1*Stensor4::Id()+(id^dI2_dC)
- the use of the
auto
keyword is only permitted by theC++11
standard, which is default forTFEL-3.0
. The user is left with two choices:
- replace
auto
with explicit types:real
for scalars,Stensor
for symmetric tensors,Stensor4
for linear forms on symmetric tensors (“fourth order tensors”). However, in this case, the implementation can be less efficient as it leads to an explicit evaluation of intermediate results.- specify the appropriate flag to the
C++
compiler. Assuming that the current shell isbash
and that the compiler isg++
, this can be done by invoking mfront as follows:CXXFLAGS="`tfel-config --oflags` -std=c++11" mfront --obuild --interface=aster SignoriniHyperViscoelasticity-tfel-2.0.3.mfront`
An implementation where those changes were made is available here
The hyperelastic behaviour is supposed to decouple the volumetric stress \(\underline{S}^{v\,\infty}\) and the isochoric stress \(S^{i\,\infty}\): \[ \underline{S}^{\infty}=\underline{S}^{v\,\infty}+\underline{S}^{i\,\infty} \]
The second Piola-Kirchhoff stress is given by:
\[ \underline{S}= \underline{S}^{\infty}+\sum_{i=1}^{N}\underline{H}_{i} \]
where \(\underline{H}_{i}\) are the overstresses.
The algorithm used to update \(\underline{H}_{i}\) is the following:
\[ {\left.\underline{H}_{i}\right|_{t+\Delta\,t}}=\exp{\left(-{{\displaystyle \frac{\displaystyle dt}{\displaystyle \tau_{i}}}}\right)}{\left.\underline{H}_{i}\right|_{t}}+g_{i}\,\tau_{i}{\left(1-\exp{\left(-{{\displaystyle \frac{\displaystyle dt}{\displaystyle \tau_{i}}}}\right)}\right)}{{\displaystyle \frac{\displaystyle {\left({\left.S^{i\,\infty}\right|_{t+\Delta\,t}}-{\left.S^{i\,\infty}\right|_{t}}\right)}}{\displaystyle dt}}} \]
// updating the viscoelastic stresses and computing the Second
// Piola-Kirchhoff stress
= Sv+Se;
StressStensor S if(dt>0){
for(unsigned short i=0;i!=Nv;++i){
const auto dtr = dt/tau[i];
[i] = exp(-dtr);
e[i] = e[i]*H[i]+g[i]*(1-e[i])/dtr*(Se-Se_1);
H+= H[i];
S }
}
The function
convertSecondPiolaKirchhoffStressToCauchyStress
converts
the second Piola Kirchhoff stress to the Cauchy stress using the
deformation gradient. It is used as follows:
= convertSecondPiolaKirchhoffStressToCauchyStress(S,F1); sig
Assuming that \({\displaystyle \frac{\displaystyle \partial \underline{S}^{v\,\infty}}{\displaystyle \partial \underline{C}}}\) and \({\displaystyle \frac{\displaystyle \partial \underline{S}^{i\,\infty}}{\displaystyle \partial \underline{C}}}\) are known, the expression of the consistent tangent operator is:
\[ \begin{aligned} {\displaystyle \frac{\displaystyle \partial \underline{S}^{v\,\infty}}{\displaystyle \partial \underline{C}}} &= {\displaystyle \frac{\displaystyle \partial \underline{S}^{v\,\infty}}{\displaystyle \partial \underline{C}}}+{\displaystyle \frac{\displaystyle \partial \underline{S}^{i\,\infty}}{\displaystyle \partial \underline{C}}}+ \sum_{i=1}^{N}{\displaystyle \frac{\displaystyle \partial {\left.\underline{H}_{i}\right|_{t+\Delta\,t}}}{\displaystyle \partial \underline{C}}}\\ &= {\displaystyle \frac{\displaystyle \partial \underline{S}^{v\,\infty}}{\displaystyle \partial \underline{C}}}+ {\displaystyle \frac{\displaystyle \partial \underline{S}^{i\,\infty}}{\displaystyle \partial \underline{C}}}\,\underbrace{{\left(1+\sum_{i=1}^{N}g_{i}\,\tau_{i}\,{{\displaystyle \frac{\displaystyle {\left(1-\exp{\left(-{{\displaystyle \frac{\displaystyle dt}{\displaystyle \tau_{i}}}}\right)}\right)}}{\displaystyle dt}}}\right)}}_{c} \end{aligned} \]
This expression can be implemented in a straightforward manner:
auto c = real(1);
if(dt>0){
for(unsigned short i=0;i!=Nv;++i){
const auto dtr = dt/tau[i];
+= g[i]*(1-e[i])/dtr;
c }
}
= dSv_dC+c*dSi_dC; dS_dC