3 #include <sofa/core/behavior/ForceField.h>
4 #include <sofa/core/topology/BaseTopology.h>
5 #include <sofa/core/behavior/MechanicalState.h>
6 #include <sofa/helper/OptionsGroup.h>
8 #include <Eigen/Sparse>
10 #include <Caribou/Geometry/Hexahedron.h>
12 namespace SofaCaribou::forcefield {
14 using namespace sofa::core;
15 using namespace sofa::core::objectmodel;
16 using namespace sofa::core::behavior;
17 using namespace sofa::core::topology;
18 using sofa::defaulttype::Vec3Types;
26 using DataTypes = Vec3Types;
27 using Inherit = ForceField<DataTypes>;
28 using VecCoord =
typename DataTypes::VecCoord;
29 using VecDeriv =
typename DataTypes::VecDeriv;
30 using Coord =
typename DataTypes::Coord;
31 using Deriv =
typename DataTypes::Deriv;
32 using Real =
typename Coord::value_type;
35 static constexpr INTEGER_TYPE NumberOfNodes = Hexahedron::NumberOfNodesAtCompileTime;
38 template<
int nRows,
int nColumns,
int Options=Eigen::RowMajor>
39 using Matrix = Eigen::Matrix<Real, nRows, nColumns, Options>;
41 template<
int nRows,
int nColumns>
42 using Map = Eigen::Map<const Matrix<nRows, nColumns, Eigen::RowMajor>>;
44 template<
int nRows,
int Options=0>
45 using Vector = Eigen::Matrix<Real, nRows, 1, Options>;
48 using MapVector = Eigen::Map<const Vector<nRows, Eigen::ColMajor>>;
50 using Rotation = Hexahedron::Matrix<3,3>;
51 using Mat33 = Matrix<3, 3, Eigen::RowMajor>;
52 using Vec3 = Vector<3>;
53 using Mat2424 = Matrix<24, 24, Eigen::RowMajor>;
54 using Vec24 = Vector<24>;
56 template <
typename ObjectType>
57 using Link = SingleLink<HexahedronElasticForce, ObjectType, BaseLink::FLAG_STRONGLINK>;
63 Real jacobian_determinant = 0;
64 Matrix<NumberOfNodes, 3> dN_dx = Matrix<NumberOfNodes, 3>::Zero();
65 Mat33 F = Mat33::Identity();
82 void reinit()
override;
85 const MechanicalParams* mparams,
87 const Data<VecCoord>& d_x,
88 const Data<VecDeriv>& d_v)
override;
91 const MechanicalParams* ,
93 const Data<VecDeriv>& )
override;
95 void draw(
const sofa::core::visual::VisualParams* vparams)
override;
97 SReal getPotentialEnergy(
98 const MechanicalParams* ,
99 const Data<VecCoord>& )
const override
102 void addKToMatrix(sofa::defaulttype::BaseMatrix * , SReal ,
unsigned int & )
override;
104 void computeBBox(
const sofa::core::ExecParams* params,
bool onlyVisible)
override;
106 template <
typename T>
108 Hexahedron hexahedron(std::size_t hexa_id,
const T & x)
const
110 auto * topology = d_topology_container.get();
111 const auto &node_indices = topology->getHexahedron(hexa_id);
114 for (std::size_t j = 0; j < 8; ++j) {
115 const auto &node_id = node_indices[j];
116 m.row(j) = MapVector<3>(&x[node_id][0]);
119 return Hexahedron(m);
123 IntegrationMethod integration_method()
const
125 const auto m =
static_cast<IntegrationMethod
> (d_integration_method.getValue().getSelectedId());
127 if (m == IntegrationMethod::OnePointGauss)
128 return IntegrationMethod::OnePointGauss;
130 return IntegrationMethod::Regular;
134 std::string integration_method_as_string()
const
136 return d_integration_method.getValue().getSelectedItem();
140 void set_integration_method(
const IntegrationMethod & m) {
141 auto index =
static_cast<unsigned int > (m);
142 sofa::helper::WriteAccessor<Data< sofa::helper::OptionsGroup >> d = d_integration_method;
143 d->setSelectedItem(index);
146 const std::vector<GaussNode> & gauss_nodes_of(std::size_t hexahedron_id)
const {
147 return p_quadrature_nodes[hexahedron_id];
150 const Matrix<24, 24> & stiffness_matrix_of(std::size_t hexahedron_id)
const {
151 return p_stiffness_matrices[hexahedron_id];
155 const Eigen::SparseMatrix<Real> & K();
158 const Vector<Eigen::Dynamic> & eigenvalues();
165 virtual void compute_K();
168 Data< Real > d_youngModulus;
169 Data< Real > d_poissonRatio;
170 Data< bool > d_corotated;
171 Data< sofa::helper::OptionsGroup > d_integration_method;
172 Link<BaseMeshTopology> d_topology_container;
175 std::vector<Matrix<24, 24>> p_stiffness_matrices;
176 std::vector<std::vector<GaussNode>> p_quadrature_nodes;
177 std::vector<Rotation> p_initial_rotation;
178 std::vector<Rotation> p_current_rotation;
179 Eigen::SparseMatrix<Real> p_K;
180 Vector<Eigen::Dynamic> p_eigenvalues;
181 bool K_is_up_to_date =
false;
182 bool eigenvalues_are_up_to_date =
false;