Caribou
EigenSparseSolver.h
1 #pragma once
2 
3 #include <Caribou/config.h>
4 #include <SofaCaribou/Algebra/EigenMatrix.h>
5 #include <SofaCaribou/Algebra/EigenVector.h>
6 #include <SofaCaribou/Solver/LinearSolver.h>
7 
8 #include <sofa/core/behavior/LinearSolver.h>
9 #include <SofaBaseLinearSolver/DefaultMultiMatrixAccessor.h>
10 #include <Eigen/Sparse>
11 
12 namespace SofaCaribou::solver {
13 
14 namespace internal {
15 template <typename T>
16 struct solver_traits {};
17 }
18 
28 template <class EigenSolver_t>
29 class EigenSparseSolver : public sofa::core::behavior::LinearSolver, public SofaCaribou::solver::LinearSolver {
30 public:
31  SOFA_CLASS(SOFA_TEMPLATE(EigenSparseSolver, EigenSolver_t), sofa::core::behavior::LinearSolver);
32  using EigenSolver = EigenSolver_t;
33  using SparseMatrix = std::remove_cv_t<typename EigenSolver::MatrixType>;
34  using Vector = Eigen::Matrix<FLOATING_POINT_TYPE, Eigen::Dynamic, 1>;
35 
40  virtual void assemble (const sofa::core::MechanicalParams* mparams);
41 
50  void resetSystem() final;
51 
58  void setSystemMBKMatrix(const sofa::core::MechanicalParams* mparams) final;
59 
65  void setSystemRHVector(sofa::core::MultiVecDerivId b_id) final;
66 
72  void setSystemLHVector(sofa::core::MultiVecDerivId x_id) final;
73 
75  void solveSystem() override;
76 
81  inline virtual auto symmetric() const -> bool {return p_is_symmetric;}
82 
84  inline virtual void set_symmetric(bool is_symmetric) { p_is_symmetric = is_symmetric; }
85 
87  auto solver() const -> const EigenSolver & { return p_solver; }
88 
90  auto solver() -> EigenSolver & { return p_solver; }
91 
93  auto mechanical_params() const -> const sofa::core::MechanicalParams & { return p_mechanical_params; }
94 
95 
103  auto matrix_accessor() const -> const sofa::component::linearsolver::DefaultMultiMatrixAccessor & { return p_accessor; }
104 
106  auto A() const -> const SparseMatrix & { return p_A; }
107 
109  auto b_id() const -> const sofa::core::MultiVecDerivId & { return p_b_id; }
110 
112  auto x_id() const -> const sofa::core::MultiVecDerivId & { return p_x_id; }
113 
115  auto A_is_factorized() const -> bool { return p_A_is_factorized; }
116 
117  // SOFA overrides
118  static auto GetCustomTemplateName() -> std::string;
119 
120  template<class Derived>
121  static auto canCreate(Derived* o, sofa::core::objectmodel::BaseContext* context, sofa::core::objectmodel::BaseObjectDescription* arg) -> bool;
122 
123 private:
127  sofa::defaulttype::BaseMatrix * create_new_matrix(sofa::Size rows, sofa::Size cols) const override {
128  auto * matrix = new SofaCaribou::Algebra::EigenMatrix<SparseMatrix> (static_cast<Eigen::Index>(rows), static_cast<Eigen::Index>(cols));
129  if (symmetric()) {
130  matrix->set_symmetric(symmetric());
131  }
132  return matrix;
133  }
134 
138  sofa::defaulttype::BaseVector * create_new_vector(sofa::Size n) const override {
140  }
141 
145  bool solve(const sofa::defaulttype::BaseMatrix * A,
146  const sofa::defaulttype::BaseVector * F,
147  sofa::defaulttype::BaseVector * X) const override;
148 
149 private:
151 
153  EigenSolver p_solver;
154 
156  sofa::core::MechanicalParams p_mechanical_params;
157 
159  sofa::component::linearsolver::DefaultMultiMatrixAccessor p_accessor;
160 
162  sofa::core::MultiVecDerivId p_b_id;
163 
165  sofa::core::MultiVecDerivId p_x_id;
166 
168  SparseMatrix p_A;
169 
171  Vector p_x;
172 
174  Vector p_b;
175 
177  bool p_A_is_factorized;
178 
181  bool p_is_symmetric = false;
182 };
183 
184 } // namespace SofaCaribou::solver
SofaCaribou::solver::EigenSparseSolver::solveSystem
void solveSystem() override
Solves the system using the Eigen solver.
Definition: EigenSparseSolver.inl:189
SofaCaribou::solver::EigenSparseSolver::setSystemMBKMatrix
void setSystemMBKMatrix(const sofa::core::MechanicalParams *mparams) final
Set the linear system matrix A = (mM + bB + kK), storing the coefficients m, b and k of the mechanica...
Definition: EigenSparseSolver.inl:106
SofaCaribou::solver::EigenSparseSolver::resetSystem
void resetSystem() final
Reset the complete system (A, x and b are cleared).
Definition: EigenSparseSolver.inl:20
SofaCaribou::Algebra::EigenVector
This class can be use to represent any Eigen vector within SOFA.
Definition: EigenVector.h:23
SofaCaribou::solver::EigenSparseSolver::set_symmetric
virtual void set_symmetric(bool is_symmetric)
Explicitly states if this matrix is symmetric.
Definition: EigenSparseSolver.h:84
SofaCaribou::solver::EigenSparseSolver::x_id
auto x_id() const -> const sofa::core::MultiVecDerivId &
Get a readonly reference to the left-hand side unknown vector identifier.
Definition: EigenSparseSolver.h:112
SofaCaribou::solver::EigenSparseSolver::matrix_accessor
auto matrix_accessor() const -> const sofa::component::linearsolver::DefaultMultiMatrixAccessor &
Get a readonly reference to the multi-matrix accessor.
Definition: EigenSparseSolver.h:103
SofaCaribou::solver::EigenSparseSolver::assemble
virtual void assemble(const sofa::core::MechanicalParams *mparams)
Assemble the system matrix A = (mM + bB + kK) inside the SparseMatrix p_A.
Definition: EigenSparseSolver.inl:28
SofaCaribou::solver::EigenSparseSolver::solver
auto solver() const -> const EigenSolver &
Get a readonly reference to the backend solver.
Definition: EigenSparseSolver.h:87
SofaCaribou::solver::EigenSparseSolver::setSystemLHVector
void setSystemLHVector(sofa::core::MultiVecDerivId x_id) final
Gives the identifier of the left-hand side vector x.
Definition: EigenSparseSolver.inl:169
SofaCaribou::solver::EigenSparseSolver::symmetric
virtual auto symmetric() const -> bool
States if the system matrix is symmetric.
Definition: EigenSparseSolver.h:81
SofaCaribou::solver::EigenSparseSolver::A_is_factorized
auto A_is_factorized() const -> bool
True if the solver has successfully factorize the system matrix.
Definition: EigenSparseSolver.h:115
SofaCaribou::solver::LinearSolver
Base interface for linear solvers.
Definition: LinearSolver.h:14
SofaCaribou::solver::EigenSparseSolver::b_id
auto b_id() const -> const sofa::core::MultiVecDerivId &
Get a readonly reference to the right-hand side vector identifier.
Definition: EigenSparseSolver.h:109
SofaCaribou::solver::EigenSparseSolver::solver
auto solver() -> EigenSolver &
Get a reference to the backend solver.
Definition: EigenSparseSolver.h:90
SofaCaribou::solver::EigenSparseSolver::A
auto A() const -> const SparseMatrix &
Get a readonly reference to the global assembled system matrix.
Definition: EigenSparseSolver.h:106
SofaCaribou::Algebra::EigenMatrix
This class can be use to represent any Eigen matrix within SOFA.
Definition: EigenMatrix.h:51
SofaCaribou::solver::EigenSparseSolver::setSystemRHVector
void setSystemRHVector(sofa::core::MultiVecDerivId b_id) final
Gives the identifier of the right-hand side vector b.
Definition: EigenSparseSolver.inl:150
SofaCaribou::solver::EigenSparseSolver::mechanical_params
auto mechanical_params() const -> const sofa::core::MechanicalParams &
Get a readonly reference to the mechanical parameters.
Definition: EigenSparseSolver.h:93
SofaCaribou::solver::EigenSparseSolver
Base class for sparse direct solvers using Eigen as a backend solver.
Definition: EigenSparseSolver.h:29