13#ifndef FEM_DIFFOPS_MATERIALLAWS_HH
14#define FEM_DIFFOPS_MATERIALLAWS_HH
18#include "dune/common/config.h"
19#include "dune/common/fmatrix.hh"
22#include "linalg/determinant.hh"
26 namespace Elastomechanics
35 namespace MaterialLaws
51 template <
int dim_,
class Scalar_,
class MaterialLaw>
56 static int const dim = dim_;
69 for (
int i=0; i<
dim; ++i)
70 for (
int j=0; j<=i; ++j)
74 sigma[i][j] =
static_cast<MaterialLaw const*
>(
this)->
d1(E);
77 for (
int i=0; i<
dim-1; ++i)
78 for (
int j=i+1; j<
dim; ++j)
79 sigma[i][j] = sigma[j][i];
104 int const n =
dim*(
dim+1)/2;
109 for (
int i=0; i<n; ++i)
115 for (
int j=0; j<=i; ++j)
121 C[i][j] =
static_cast<MaterialLaw const*
>(
this)->
d2(
X,
Y);
126 for (
int i=0; i<n-1; ++i)
127 for (
int j=i+1; j<n; ++j)
155 template <
class Material>
159 using Scalar =
typename Material::Scalar;
160 static int const dim = Material::dim;
166 template <
class ... Args>
184 material.setLinearizationPoint(invariants.
d0());
192 return material.d0();
200 return 2*material.d1(invariants.
d1(e1));
208 return 4*(material.d2(invariants.
d1(e1),invariants.
d1(e2)) + material.d1(invariants.
d2(e1,e2)));
235 template <
class Material,
class DeviatoricPenalty>
237 :
public MaterialLawBase<Material::dim,typename Material::Scalar,CompressibleInvariantsMaterialLaw<Material,DeviatoricPenalty>>
240 using Scalar =
typename Material::Scalar;
241 static int const dim = Material::dim;
244 template <
class ... Args>
254 deviator = DeviatoricPenalty(bE.
determinant().d0());
255 material.setLinearizationPoint(bE.
d0());
263 return material.d0() + deviator.d0();
271 return material.d1(bE.
d1(e1)) + deviator.d1(bE.
determinant().d1(e1));
279 return material.d2(bE.
d1(e1),bE.
d1(e2)) + material.d1(bE.
d2(e1,e2))
286 DeviatoricPenalty deviator;
315 template <
int dim,
class Scalar=
double>
335 : lambda(moduli.lame()), mu(moduli.shear()), alpha(alpha_)
352 : lambda(moduli.lame()), mu(moduli.shear()), e(e_), tre(
trace(e))
369 detC =
Det(unitMatrix<Scalar,dim>()+2*e);
380 auto detc = detC.d0();
382 w = std::numeric_limits<Scalar>::infinity();
384 w += alpha*(1/detc-1 + 2*tre);
396 dw += alpha*(-std::pow(detC.d0(),-2)*detC.d1(e1)*2 + 2*
trace(e1));
407 ddw += alpha*( 2*std::pow(detC.d0(),-3)*detC.d1(e1)*2*detC.d1(e2)*2
408 - std::pow(detC.d0(),-2)*detC.d2(e1,e2)*4 );
418 return alpha * ( -6*std::pow(detC.d0(),-4)*detC.d1(e1)*2*detC.d1(e2)*2*detC.d1(e3)*2
419 + 2*std::pow(detC.d0(),-3)*detC.d2(e1,e3)*4*detC.d1(e2)*2
420 + 2*std::pow(detC.d0(),-3)*detC.d1(e1)*2*detC.d2(e2,e3)*4
421 + 2*std::pow(detC.d0(),-3)*detC.d1(e3)*detC.d2(e1,e2)*4
422 - std::pow(detC.d0(),-2)*detC.d3(e1,e2,e3)*8 );
466 template <
int dim,
class Scalar=
double>
490 : orth(orth_), orthT(
transpose(orth_)), e(0)
496 compliance[0][0] = 1 / mat_[0][0];
497 compliance[0][1] = - mat_[1][0] / mat_[0][0];
498 compliance[0][2] = - mat_[2][0] / mat_[0][0];
499 compliance[1][0] = compliance[0][1];
500 compliance[1][1] = 1 / mat_[1][1];
501 compliance[1][2] = - mat_[2][1] / mat_[1][1];
502 compliance[2][0] = compliance[0][2];
503 compliance[2][1] = compliance[1][2];
504 compliance[2][2] = 1 / mat_[2][2];
506 compliance[3][3] = 1 / mat_[1][2];
507 compliance[4][4] = 1 / mat_[0][2];
508 compliance[5][5] = 1 / mat_[0][1];
512 compliance[0][0] = 1 / mat_[0][0];
513 compliance[0][1] = - mat_[1][0] / mat_[0][0];
514 compliance[1][0] = compliance[0][1];
515 compliance[1][1] = 1 / mat_[1][1];
517 compliance[2][2] = 1/mat_[0][1];
521 stiffness = compliance;
540 : orth(orth_), orthT(
transpose(orth_)), stiffness(0), e(0)
542 for (
int i=0; i<
dim; ++i)
543 for (
int j=0; j<
dim; ++j)
544 stiffness[i][j] = mat1[i][j];
545 for (
int i=0; i<
dim*(
dim-1)/2; ++i)
546 stiffness[
dim+i][
dim+i] = mat2[i];
560 stiffness[0][0] = stiffness[1][1] = 2*mu + lambda;
561 stiffness[1][0] = stiffness[0][1] = lambda;
562 stiffness[2][2] = mu;
599 auto eps =
pack(orthT*e*orth);
600 auto sigma = stiffness * eps;
601 return 0.5 * (sigma*eps);
610 auto eps =
pack(orthT*e*orth);
611 auto eps1 =
pack(orthT*e1*orth);
612 auto sigma = stiffness * eps1;
622 auto eps1 =
pack(orthT*e1*orth);
623 auto eps2 =
pack(orthT*e2*orth);
624 auto sigma = stiffness * eps2;
646 template <
int dim,
class Scalar=
double>
670 : orth(orth_), orthT(
transpose(orth_)), e(0), a(0), G(0)
675 Scalar D = 0.75 * (2/(mat_[0][0]*mat_[1][1]) + 2/(mat_[1][1]*mat_[2][2]) + 2/(mat_[2][2]*mat_[0][0])
676 - 1/(mat_[0][0]*mat_[0][0]) - 1/(mat_[1][1]*mat_[1][1]) - 1/(mat_[2][2]*mat_[2][2]));
679a[0][0] = 1/D * (2/(3*mat_[1][1]) + 2/(3*mat_[2][2]) - 1/(3*mat_[0][0]));
680a[0][1] = 1/D * (1/(6*mat_[0][0]) + 1/(6*mat_[1][1]) - 5/(6*mat_[2][2]));
681a[0][2] = 1/D * (1/(6*mat_[0][0]) + 1/(6*mat_[2][2]) - 5/(6*mat_[1][1]));
683a[1][0] = 1/D * (1/(6*mat_[1][1]) + 1/(6*mat_[0][0]) - 5/(6*mat_[2][2]));
684a[1][1] = 1/D * (2/(3*mat_[2][2]) + 2/(3*mat_[0][0]) - 1/(3*mat_[1][1]));
685a[1][2] = 1/D * (1/(6*mat_[1][1]) + 1/(6*mat_[2][2]) - 5/(6*mat_[0][0]));
687a[2][0] = 1/D * (1/(6*mat_[2][2]) + 1/(6*mat_[0][0]) - 5/(6*mat_[1][1]));
688a[2][1] = 1/D * (1/(6*mat_[2][2]) + 1/(6*mat_[1][1]) - 5/(6*mat_[0][0]));
689a[2][2] = 1/D * (2/(3*mat_[1][1]) + 2/(3*mat_[0][0]) - 1/(3*mat_[2][2]));
694 G[0][1] = mat_[0][1]; G[0][2] = mat_[0][2];
695 G[1][0] = mat_[0][1]; G[1][2] = mat_[1][2];
696 G[2][0] = mat_[0][2]; G[2][1] = mat_[1][2];
699 stiffness[0][0] = a[0][0] ; stiffness[0][1] = a[0][1] ; stiffness[0][2] = a[0][2] ;
700 stiffness[1][0] = a[1][0] ; stiffness[1][1] = a[1][1] ; stiffness[1][2] = a[1][2] ;
701 stiffness[2][0] = a[2][0] ; stiffness[2][1] = a[2][1] ; stiffness[2][2] = a[2][2] ;
703 stiffness[3][3] = mat_[1][2];
704 stiffness[4][4] = mat_[0][2];
705 stiffness[5][5] = mat_[0][1];
710 x[0] =1;x[1] =0;x[2] =0;
711 y[0] =0;y[1] =1;y[2] =0;
712 z[0] =0;z[1] =0;z[2] =1;
741 : orth(orth_), orthT(
transpose(orth_)), stiffness(0), e(0)
743 for (
int i=0; i<
dim; ++i)
744 for (
int j=0; j<
dim; ++j)
745 stiffness[i][j] = mat1[i][j];
746 for (
int i=0; i<
dim*(
dim-1)/2; ++i)
747 stiffness[
dim+i][
dim+i] = mat2[i];
761 stiffness[0][0] = stiffness[1][1] = 2*mu + lambda;
762 stiffness[1][0] = stiffness[0][1] = lambda;
763 stiffness[2][2] = mu;
801 Scalar shear = 0 , eps = 0;
804 for(
unsigned int i = 0 ; i <
dim ; ++i)
806 for(
unsigned int j = 0 ; j <
dim ; ++j)
809 eps += a[i][j]*
trace(e*(L[i]))*
trace(e*(L[j]));
813 for(
unsigned int i = 0 ; i <
dim ; ++i)
816 for(
unsigned int j = 0 ; j <
dim ; ++j)
821 auto B = e.rightmultiplyany(L[j]);
823 shear += G[i][j]*
trace(A.rightmultiplyany(B));
828 return 0.5 * eps + shear;
837 Scalar shear = 0 , eps = 0;
840 for(
unsigned int i = 0 ; i <
dim ; ++i)
842 for(
unsigned int j = 0 ; j <
dim ; ++j)
844 eps += a[i][j]*(
trace(e*(L[i]))*
trace(e1*(L[j]))
849 for(
unsigned int i = 0 ; i <
dim ; ++i)
851 auto A = e.rightmultiplyany(L[i]);
852 auto C = e1.rightmultiplyany(L[i]);
854 for(
unsigned int j = 0 ; j <
dim ; ++j)
859 auto B = e1.rightmultiplyany(L[j]);
860 auto D = e.rightmultiplyany(L[j]);
862 shear += G[i][j]*(
trace(A.rightmultiplyany(B))+
trace(C.rightmultiplyany(D)));
869 return 0.5 * eps + shear;
879 Scalar shear = 0 , eps = 0;
882 for(
unsigned int i = 0 ; i <
dim ; ++i)
884 for(
unsigned int j = 0 ; j <
dim ; ++j)
891 for(
unsigned int i = 0 ; i <
dim ; ++i)
896 for(
unsigned int j = 0 ; j <
dim ; ++j)
904 shear += G[i][j]*(
trace(A.rightmultiplyany(B))+
trace(C.rightmultiplyany(D)));
908 return 0.5 * eps + shear;
960 template <
int dimension>
972 static int const dim = dimension;
986 : c1(c1_), c2(
dim==3?c2_:0), c3(c3_)
1004 return c1*i1 + c2*i2 + c3*
id*
id/(1+id);
1012 return c1*di1[0] + c2*di1[1] + c3*
id*(2+id)/
square(1+
id)*di1[
dim-1];
1024 double i1, i2, id, c1, c2, c3;
1049 template <
int dimension>
1081 template <
int dimension>
1093 static int const dim = dimension;
1105 : mu(moduli.shear()), a(2*moduli.poisson()/(1-2*moduli.poisson())), pstable(1,0)
1116 i3 = i[dimension-1];
1125 return mu*(i1 + 2*pstable.
d0()/a)/2;
1133 return mu*(di1[0] + 2*pstable.
d1(di1[dimension-1])/a)/2;
1141 return mu*pstable.
d2(di1[dimension-1],di2[dimension-1])/a;
1145 double i1, i3, mu, a;
1165 template <
class HyperelasticEnergy>
1169 using Scalar =
typename HyperelasticEnergy::Scalar;
1170 static int const dim = HyperelasticEnergy::dim;
1184 template<
typename... Args>
1193 HyperelasticEnergy::setLinearizationPoint(e-evp);
1226 template <
int dim,
class Scalar>
1247 template <
int dim,
class Scalar=
double>
A class for computing determinants and their derivatives.
Material parameters for isotropic linearly elastic materials.
double shear() const
Returns the shear modulus , also known as Lame's second parameter .
double lame() const
Returns the first Lame parameter .
DetIpm1< dim, Scalar > const & determinant() const
The shifted determinant of the original Green Lagrange strain tensor.
Tensor d0() const
The isochoric linearized Green-Lagrange strain tensor .
Tensor d2(Tensor const &dE1, Tensor const &dE2) const
The second derivative of the linearized Green-Lagrange strain tensor in direction dv,...
Tensor d1(Tensor const &dE) const
The first derivative of the linearized Green-Lagrange strain tensor in direction de.
Blatz-Ko material law for rubber foams in terms of the shifted invariants of the doubled Green-Lagra...
Scalar d2(Invariants const &di1, Invariants const &di2) const
Evaluates the second directional derivative .
double Scalar
The scalar field type (usually double).
Scalar d1(Invariants const &di1) const
Evaluates the first directional derivative .
void setLinearizationPoint(Invariants const &i)
Sets a new linearization point.
Scalar d0() const
Evaluates the stored energy density .
static int const dim
The spatial dimension (2 or 3).
BlatzKo(ElasticModulus const &moduli)
Constructor.
Adaptor for hyperelastic material laws, providing an easy way to formulate compressible material laws...
Scalar d1(Tensor const &e1) const
Evaluates the first directional derivative .
CompressibleInvariantsMaterialLaw(Tensor const &E, Args... args)
void setLinearizationPoint(Tensor const &e)
Defines a new evaluation/linearization point.
typename Material::Scalar Scalar
Scalar d0() const
Evaluates the stored energy density .
Scalar d2(Tensor const &e1, Tensor const &e2) const
Evaluates the second directional derivative .
Adaptor for hyperelastic material laws, providing an easy way to formulate incompressible material la...
InvariantsMaterialLaw(Args... args)
Constructor.
typename Material::Scalar Scalar
Scalar d0() const
Evaluates the stored energy density .
Scalar d1(Tensor const &e1) const
Evaluates the first directional derivative .
Scalar d2(Tensor const &e1, Tensor const &e2) const
Evaluates the second directional derivative .
void setLinearizationPoint(Tensor const &e)
Defines a new evaluation/linearization point.
Base class for hyperelastic material laws, providing default implementations of the stress and the ta...
Tensor stress() const
Returns the second Piola-Kirchhoff stress tensor corresponding to the current strain .
VoigtTensor strainToStressMatrix() const
Returns the tangent stiffness tensor mapping strain tensor variations to stress tensor (2nd Piola-Ki...
Mooney-Rivlin material law formulated in terms of the (shifted) invariants of the doubled Green-Lagr...
double Scalar
The scalar field type (usually double).
static int const dim
The spatial dimension (2 or 3).
MooneyRivlin(double c1_, double c2_, double c3_=0.0)
Constructor.
Scalar d0() const
Evaluates the stored energy density .
Scalar d1(Invariants const &di1) const
Evaluates the first directional derivative .
void setLinearizationPoint(Invariants const &i)
Sets a new linearization point.
Scalar d2(Invariants const &di1, Invariants const &di2) const
Evaluates the second directional derivative .
Neo-Hookean material law formulated in terms of the shifted invariants of the doubled Green-Lagrange...
NeoHookean(ElasticModulus const &moduli)
Constructor.
Orthotropic linear material law.
Scalar d1(Tensor const &e1) const
Computes the first derivative of the elastic energy in the direction .
Scalar d4(Tensor const &e1, Tensor const &e2, Tensor const &e3, Tensor const &e4) const
OrthotropicLinearMaterial(ElasticModulus const &p)
Default constructor.
OrthotropicLinearMaterial(Dune::FieldMatrix< Scalar, dim, dim > const &orth_, Dune::FieldMatrix< Scalar, dim, dim > const &mat_)
Constructor.
Dune::FieldMatrix< Scalar, dim *(dim+1)/2, dim *(dim+1)/2 > const & stiffnessMatrix() const
Returns the stiffness tensor.
OrthotropicLinearMaterial()
Default constructor.
void setLinearizationPoint(Tensor const &e_)
Defines the GreenLagrangeTensor around which to linearize.
Scalar d3(Tensor const &e1, Tensor const &e2, Tensor const &e3) const
OrthotropicLinearMaterial(Dune::FieldMatrix< Scalar, dim, dim > const &orth_, Dune::FieldMatrix< Scalar, dim, dim > const &mat1, Dune::FieldVector< Scalar, dim *(dim-1)/2 > const &mat2)
Constructor.
Scalar d2(Tensor const &e1, Tensor const &e2) const
Computes the second derivative of the elastic energy in directions .
Scalar d0() const
Computes the elastic energy .
OrthotropicNonLinearMaterial(ElasticModulus const &p)
Default constructor.
Scalar d0() const
Computes the elastic energy .
Scalar d3(Tensor const &e1, Tensor const &e2, Tensor const &e3) const
Dune::FieldMatrix< Scalar, dim *(dim+1)/2, dim *(dim+1)/2 > const & stiffnessMatrix() const
Returns the stiffness tensor.
OrthotropicNonLinearMaterial()
Default constructor.
Scalar d4(Tensor const &e1, Tensor const &e2, Tensor const &e3, Tensor const &e4) const
void setLinearizationPoint(Tensor const &e_)
Defines the GreenLagrangeTensor around which to linearize.
Scalar d1(Tensor const &e1) const
Computes the first derivative of the elastic energy in the direction .
OrthotropicNonLinearMaterial(Dune::FieldMatrix< Scalar, dim, dim > const &orth_, Dune::FieldMatrix< Scalar, dim, dim > const &mat_)
Constructor.
OrthotropicNonLinearMaterial(Dune::FieldMatrix< Scalar, dim, dim > const &orth_, Dune::FieldMatrix< Scalar, dim, dim > const &mat1, Dune::FieldVector< Scalar, dim *(dim-1)/2 > const &mat2)
Constructor.
Scalar d2(Tensor const &e1, Tensor const &e2) const
Computes the second derivative of the elastic energy in directions .
The St. Venant-Kirchhoff material, foundation of linear elastomechanics.
Scalar d1(Tensor const &e1) const
Evaluates the first directional derivative .
Scalar d3(Tensor const &e1, Tensor const &e2, Tensor const &e3) const
Evaluates the third directional derivative .
StVenantKirchhoff(ElasticModulus const &moduli, Scalar alpha_=0)
Constructor.
Scalar d0() const
Evaluates the stored energy density .
Scalar d2(Tensor const &e1, Tensor const &e2) const
Evaluates the second directional derivative .
void setLinearizationPoint(Tensor const &e_)
Defines the linearization/evaluation point for subsequent calls to d0, d1, d2.
StVenantKirchhoff(ElasticModulus const &moduli, Tensor const &e_)
Constructor.
StVenantKirchhoff()=default
Pretty useless default constructor.
Scalar d4(Tensor const &, Tensor const &, Tensor const &, Tensor const &) const
Evaluates the fourth directional derivative .
An adaptor for using hyperelastic stored energies for viscoplasticity.
typename HyperelasticEnergy::Scalar Scalar
ViscoPlasticEnergy()=default
Default constructor.
void setLinearizationPoint(Tensor const &e)
Sets a new linearization point.
ViscoPlasticEnergy(Tensor const &evp_, Args &&... args)
Constructor.
Numerically stable evaluation of .
double d1(double dx) const
double d2(double dx1, double dx2) const
Invariants d1(Tensor const &dA) const
Invariants d2(Tensor const &dA1, Tensor const &dA2) const
A class for representing tensors of arbitrary static rank and extents.
Dune::FieldVector< Scalar, n *(n+1)/2 > pack(Dune::FieldMatrix< Scalar, n, n > const &e, Scalar s=2.0)
Returns the Voigt vector representation of a symmetric matrix (with or without doubled off-diagonal e...
Dune::FieldMatrix< Scalar, ElastoDetails::dim(n), ElastoDetails::dim(n)> unpack(Dune::FieldVector< Scalar, n > const &c, Scalar s=2.0)
Returns the symmetric matrix representation of a Voigt vector with or without doubled off-diagonal en...
Dune::FieldMatrix< T, n, m > outerProduct(Dune::FieldVector< T, n > const &x, Dune::FieldVector< T, m > const &y)
outer vector product .
T trace(Dune::FieldMatrix< T, n, n > const &A)
Matrix trace .
Dune::FieldMatrix< T, n, n > unitMatrix()
Returns the identity matrix of size n .
T determinant(Dune::FieldMatrix< T, n, n > const &A)
Matrix determinant .
T contraction(Dune::FieldMatrix< T, n, m > const &A, Dune::FieldMatrix< T, n, m > const &B)
Matrix contraction (Frobenius product) .
R power(R base, int exp)
Computes integral powers of values in a multiplicative half-group.
R square(R x)
returns the square of its argument.
Scalar vonMisesStress(Dune::FieldMatrix< Scalar, dim, dim > const &stress)
Computes the von Mises equivalent stress .
Dune::FieldVector< Scalar, dim *(dim+1)/2 > duvautLionsJ2Flow(Dune::FieldMatrix< Scalar, dim, dim > const &cauchyStress, Dune::FieldMatrix< Scalar, dim *(dim+1)/2, dim *(dim+1)/2 > const &C, double tau, double sigmaY)
A simple Duvaut-Lions flow rule with (von Mises) yield surface.
Functional::Scalar d1(Assembler &assembler, Functional const &f, typename Functional::AnsatzVars::VariableSet &x, typename Functional::Scalar tolerance=1e-6, typename Functional::Scalar increment=1e-12, bool toFile=false, std::string const &filename=std::string("d1error"))
Functional::Scalar d2(Assembler &assembler, Functional const &f, typename Functional::AnsatzVars::VariableSet const &x, typename Functional::Scalar increment=1e-12, typename Functional::Scalar tolerance=1e-6, bool toFile=false, std::string const &savefilename=std::string("d2error"))