Caribou
NeoHookeanMaterial.h
1 #pragma once
2 
3 #include <Caribou/Algebra/Tensor.h>
4 #include <SofaCaribou/Material/HyperelasticMaterial.h>
5 
6 namespace SofaCaribou::material {
7 
8 template<class DataTypes>
9 class NeoHookeanMaterial : public HyperelasticMaterial<DataTypes> {
10  static constexpr auto Dimension = DataTypes::spatial_dimensions;
11  using Coord = typename DataTypes::Coord;
12  using Real = typename Coord::value_type;
13 public:
14  SOFA_CLASS(SOFA_TEMPLATE(NeoHookeanMaterial, DataTypes), SOFA_TEMPLATE(HyperelasticMaterial, DataTypes));
15 
17  : d_young_modulus(initData(&d_young_modulus,
18  Real(1000), "young_modulus",
19  "Young's modulus of the material",
20  true /*displayed_in_GUI*/, false /*read_only_in_GUI*/))
21  , d_poisson_ratio(initData(&d_poisson_ratio,
22  Real(0.3), "poisson_ratio",
23  "Poisson's ratio of the material",
24  true /*displayed_in_GUI*/, false /*read_only_in_GUI*/))
25  {
26  }
27 
33  void before_update() override {
34  const Real young_modulus = d_young_modulus.getValue();
35  const Real poisson_ratio = d_poisson_ratio.getValue();
36  mu = young_modulus / (2.0 * (1.0 + poisson_ratio));
37  l = young_modulus * poisson_ratio / ((1.0 + poisson_ratio) * (1.0 - 2.0 * poisson_ratio));
38  }
39 
46  Real
47  strain_energy_density(const Real & J, const Eigen::Matrix<Real, Dimension, Dimension> & C) const override {
48  const auto lnJ = log(J);
49  return mu/2.*(C.trace()-3) - mu*lnJ + l/2 *lnJ*lnJ;
50  }
51 
53  virtual Eigen::Matrix<Real, Dimension, Dimension>
54  PK2_stress(const Real & J, const Eigen::Matrix<Real, Dimension, Dimension> & C) const override {
55 
56  static const auto Id = Eigen::Matrix<Real, Dimension, Dimension, Eigen::RowMajor>::Identity();
57  const auto Ci = C.inverse();
58 
59  return (Id - Ci)*mu + Ci*(l*log(J));
60  }
61 
63  virtual Eigen::Matrix<Real, 6, 6>
64  PK2_stress_jacobian(const Real & J, const Eigen::Matrix<Real, Dimension, Dimension> & C) const override {
65  using caribou::algebra::symmetric_dyad_1;
66  using caribou::algebra::symmetric_dyad_2;
67 
68  const auto Ci = C.inverse().eval();
69 
70  Eigen::Matrix<Real, 6, 6> D = l*symmetric_dyad_1(Ci) + 2*(mu - l*log(J))*symmetric_dyad_2(Ci);
71  return D;
72  }
73 
74 private:
75  // Private members
76  Real mu; // Lame's mu parameter
77  Real l; // Lame's lambda parameter
78 
79  // Data members
80  sofa::core::objectmodel::Data<Real> d_young_modulus;
81  sofa::core::objectmodel::Data<Real> d_poisson_ratio;
82 };
83 
84 } // namespace SofaCaribou::material
SofaCaribou::material::HyperelasticMaterial
Definition: HyperelasticMaterial.h:11
SofaCaribou::material::NeoHookeanMaterial
Definition: NeoHookeanMaterial.h:9
SofaCaribou::material::NeoHookeanMaterial::PK2_stress_jacobian
virtual Eigen::Matrix< Real, 6, 6 > PK2_stress_jacobian(const Real &J, const Eigen::Matrix< Real, Dimension, Dimension > &C) const override
Get the jacobian of the second Piola-Kirchhoff stress tensor w.r.t the right Cauchy-Green strain tens...
Definition: NeoHookeanMaterial.h:64
SofaCaribou::material::NeoHookeanMaterial::PK2_stress
virtual Eigen::Matrix< Real, Dimension, Dimension > PK2_stress(const Real &J, const Eigen::Matrix< Real, Dimension, Dimension > &C) const override
Get the second Piola-Kirchhoff stress tensor from the right Cauchy-Green strain tensor C.
Definition: NeoHookeanMaterial.h:54
SofaCaribou::material::NeoHookeanMaterial::strain_energy_density
Real strain_energy_density(const Real &J, const Eigen::Matrix< Real, Dimension, Dimension > &C) const override
Get the strain energy density Psi from the right Cauchy-Green strain tensor C.
Definition: NeoHookeanMaterial.h:47
SofaCaribou::material::NeoHookeanMaterial::before_update
void before_update() override
This is called just before the material is updated on every points (usually just before a Newton step...
Definition: NeoHookeanMaterial.h:33