3 #include <sofa/core/behavior/ForceField.h>
4 #include <sofa/core/behavior/MechanicalState.h>
5 #include <sofa/helper/OptionsGroup.h>
7 #include <SofaCaribou/Topology/FictitiousGrid.h>
9 #include <Eigen/Sparse>
11 #include <Caribou/Geometry/Hexahedron.h>
12 #include <Caribou/Geometry/RectangularHexahedron.h>
14 namespace SofaCaribou::forcefield {
16 using namespace sofa::core;
17 using namespace sofa::core::objectmodel;
18 using namespace sofa::core::behavior;
19 using namespace sofa::core::topology;
20 using sofa::defaulttype::Vec3Types;
28 using DataTypes = Vec3Types;
29 using Inherit = ForceField<DataTypes>;
30 using VecCoord =
typename DataTypes::VecCoord;
31 using VecDeriv =
typename DataTypes::VecDeriv;
32 using Coord =
typename DataTypes::Coord;
33 using Deriv =
typename DataTypes::Deriv;
34 using Real =
typename Coord::value_type;
43 template<
int nRows,
int nColumns,
int Options=Eigen::RowMajor>
44 using Matrix = Eigen::Matrix<Real, nRows, nColumns, Options>;
46 template<
int nRows,
int nColumns>
47 using Map = Eigen::Map<const Matrix<nRows, nColumns, Eigen::RowMajor>>;
49 template<
int nRows,
int Options=0>
50 using Vector = Eigen::Matrix<Real, nRows, 1, Options>;
53 using MapVector = Eigen::Map<const Vector<nRows, Eigen::ColMajor>>;
55 using Mat33 = Matrix<3, 3, Eigen::RowMajor>;
56 using Vec3 = Vector<3>;
57 using Mat2424 = Matrix<24, 24, Eigen::RowMajor>;
58 using Vec24 = Vector<24>;
60 template <
typename ObjectType>
61 using Link = SingleLink<FictitiousGridElasticForce, ObjectType, BaseLink::FLAG_STRONGLINK>;
67 Matrix<NumberOfNodes, 3> dN_dx = Matrix<NumberOfNodes, 3, Eigen::RowMajor>::Zero();
68 Mat33 F = Mat33::Identity();
92 void reinit()
override;
95 const MechanicalParams* mparams,
97 const Data<VecCoord>& d_x,
98 const Data<VecDeriv>& d_v)
override;
101 const MechanicalParams* ,
103 const Data<VecDeriv>& )
override;
105 void draw(
const sofa::core::visual::VisualParams* vparams)
override;
107 SReal getPotentialEnergy(
108 const MechanicalParams* ,
109 const Data<VecCoord>& )
const override
112 void addKToMatrix(sofa::defaulttype::BaseMatrix * , SReal ,
unsigned int & )
override;
114 void computeBBox(
const sofa::core::ExecParams* params,
bool onlyVisible)
override;
116 template <
typename T>
118 Hexahedron hexahedron(std::size_t hexa_id,
const T & x)
const
120 auto * grid = d_grid_container.get();
121 const auto &node_indices = grid->get_node_indices_of(hexa_id);
124 for (std::size_t j = 0; j < 8; ++j) {
125 const auto &node_id = node_indices[j];
126 m.row(j) = MapVector<3>(&x[node_id][0]);
129 return Hexahedron(m);
133 IntegrationMethod integration_method()
const
135 const auto m =
static_cast<IntegrationMethod
> (d_integration_method.getValue().getSelectedId());
137 case IntegrationMethod::Regular:
138 return IntegrationMethod::Regular;
139 case IntegrationMethod::SubdividedVolume:
140 return IntegrationMethod::SubdividedVolume;
141 case IntegrationMethod::SubdividedGauss:
142 return IntegrationMethod::SubdividedGauss;
144 return IntegrationMethod::Regular;
149 std::string integration_method_as_string()
const
151 return d_integration_method.getValue().getSelectedItem();
155 void set_integration_method(
const IntegrationMethod & m) {
156 auto index =
static_cast<unsigned int > (m);
157 sofa::helper::WriteAccessor<Data< sofa::helper::OptionsGroup >> d = d_integration_method;
158 d->setSelectedItem(index);
161 const std::vector<GaussNode> & gauss_nodes_of(std::size_t hexahedron_id)
const {
162 return p_quadrature_nodes[hexahedron_id];
165 const Matrix<24, 24> & stiffness_matrix_of(std::size_t hexahedron_id)
const {
166 return p_stiffness_matrices[hexahedron_id];
170 const Eigen::SparseMatrix<Real> & K();
173 const Vector<Eigen::Dynamic> & eigenvalues();
180 virtual void compute_K();
183 Data< Real > d_youngModulus;
184 Data< Real > d_poissonRatio;
185 Data< bool > d_linear_strain;
186 Data< bool > d_corotated;
187 Data< sofa::helper::OptionsGroup > d_integration_method;
188 Link<FictitiousGrid> d_grid_container;
191 bool recompute_compute_tangent_stiffness =
false;
192 std::vector<Matrix<24, 24>> p_stiffness_matrices;
193 std::vector<std::vector<GaussNode>> p_quadrature_nodes;
194 std::vector<Mat33> p_initial_rotation;
195 std::vector<Mat33> p_current_rotation;
196 Eigen::SparseMatrix<Real> p_K;
197 Vector<Eigen::Dynamic> p_eigenvalues;
198 bool K_is_up_to_date;
199 bool eigenvalues_are_up_to_date;