Caribou
TetrahedronElasticForce.h
1 #pragma once
2 
3 #include <sofa/core/objectmodel/BaseObject.h>
4 #include <sofa/helper/OptionsGroup.h>
5 #include <sofa/core/topology/BaseTopology.h>
6 #include <sofa/core/behavior/ForceField.h>
7 
8 #include <Caribou/Geometry/Tetrahedron.h>
9 
10 namespace SofaCaribou::forcefield {
11 
12 using namespace sofa::core;
13 using namespace sofa::core::objectmodel;
14 using namespace sofa::core::behavior;
15 using namespace sofa::core::topology;
16 using sofa::defaulttype::Vec3Types;
17 
18 class TetrahedronElasticForce : public ForceField<Vec3Types> {
19 public:
20  SOFA_CLASS(TetrahedronElasticForce, SOFA_TEMPLATE(ForceField, Vec3Types));
21 
22  // Type definitions
24  using Inherit = ForceField<Vec3Types>;
25  using DataTypes = typename Inherit::DataTypes;
26  using VecCoord = typename DataTypes::VecCoord;
27  using VecDeriv = typename DataTypes::VecDeriv;
28  using Coord = typename DataTypes::Coord;
29  using Deriv = typename DataTypes::Deriv;
30  using Real = typename Coord::value_type;
31 
32 
33  template<int nRows, int nColumns, int Options=Eigen::RowMajor>
34  using Matrix = Eigen::Matrix<Real, nRows, nColumns, Options>;
35 
36  template<int nRows, int nColumns, int Options=Eigen::RowMajor>
37  using MatrixI = Eigen::Matrix<UNSIGNED_INTEGER_TYPE, nRows, nColumns, Options>;
38 
39  template<int nRows, int nColumns>
40  using Map = Eigen::Map<const Matrix<nRows, nColumns, Eigen::RowMajor>>;
41 
42  template<int nRows, int Options=0>
43  using Vector = Eigen::Matrix<Real, nRows, 1, Options>;
44 
45  template<int nRows>
46  using MapVector = Eigen::Map<const Vector<nRows>>;
47 
48  using Rotation = Tetrahedron::Matrix<3,3>;
49  using Mat33 = Tetrahedron::Matrix<3,3>;
50  using Vec3 = Vector<3>;
51  static constexpr INTEGER_TYPE Dimension = 3;
52  static constexpr INTEGER_TYPE NumberOfNodes = Tetrahedron::NumberOfNodesAtCompileTime;
53 
54  template <typename ObjectType>
55  using Link = SingleLink<TetrahedronElasticForce, ObjectType, BaseLink::FLAG_STRONGLINK>;
56 
57  // Data structures
58 
59  struct GaussNode {
60  Real weight = 0;
61  Real jacobian_determinant = 0;
62  Matrix<NumberOfNodes, 3> dN_dx = Matrix<NumberOfNodes, 3, Eigen::RowMajor>::Zero();
63  };
64 
65  // Public methods
67 
68  void init() override;
69  void reinit() override;
70  void draw(const sofa::core::visual::VisualParams* vparams) override;
71 
72  void addForce(
73  const MechanicalParams* mparams,
74  Data<VecDeriv>& d_f,
75  const Data<VecCoord>& d_x,
76  const Data<VecDeriv>& d_v) override;
77 
78  void addDForce(
79  const MechanicalParams* /*mparams*/,
80  Data<VecDeriv>& /*d_df*/,
81  const Data<VecDeriv>& /*d_dx*/) override;
82 
83  void addKToMatrix(
84  sofa::defaulttype::BaseMatrix * /*matrix*/,
85  SReal /*kFact*/,
86  unsigned int & /*offset*/) override;
87 
88  SReal getPotentialEnergy(
89  const MechanicalParams* /* mparams */,
90  const Data<VecCoord>& /* d_x */) const override
91  {return 0;}
92 
93  void computeBBox(const sofa::core::ExecParams* params, bool onlyVisible) override;
94 
95 private:
97  void compute_K();
98 
99  template <typename T>
100  inline
101  Tetrahedron tetrahedron(std::size_t tetrahedron_id, const T & x) const
102  {
103  auto * topology = d_topology_container.get();
104  const auto &node_indices = topology->getTetrahedron(tetrahedron_id);
105 
106  Matrix<NumberOfNodes, 3> m;
107  for (std::size_t j = 0; j < NumberOfNodes; ++j) {
108  const auto &node_id = node_indices[j];
109  m.row(j) = MapVector<3>(&x[node_id][0]);
110  }
111 
112  return Tetrahedron(m);
113  }
114 
115 private:
116  Data< Real > d_youngModulus;
117  Data< Real > d_poissonRatio;
118  Data< bool > d_corotated;
119  Link<BaseMeshTopology> d_topology_container;
120 
121 private:
122  std::vector<Matrix<12, 12>> p_stiffness_matrices;
123  std::vector<GaussNode> p_quadrature_nodes; // Linear tetrahedrons only have 1 gauss node per element
124  std::vector<Rotation> p_initial_rotation;
125  std::vector<Rotation> p_current_rotation;
126 };
127 
128 } // namespace SofaCaribou::forcefield
caribou::geometry::Tetrahedron
Definition: Tetrahedron.h:12
SofaCaribou::forcefield::TetrahedronElasticForce::GaussNode
Definition: TetrahedronElasticForce.h:59
SofaCaribou::forcefield::TetrahedronElasticForce
Definition: TetrahedronElasticForce.h:18