|
| 1 | +#pragma once |
| 2 | +#include <EigenLinearSolvers/config.h> |
| 3 | + |
| 4 | +#include <EigenLinearSolvers/EigenDirectSparseSolver.h> |
| 5 | + |
| 6 | +#if __has_include(<sofa/component/linearsolver/iterative/MatrixLinearSolver.h>) |
| 7 | +#include <sofa/component/linearsolver/iterative/MatrixLinearSolver.h> |
| 8 | +#else |
| 9 | +#include <SofaBaseLinearSolver/MatrixLinearSolver.h> |
| 10 | +#endif |
| 11 | + |
| 12 | +#include <variant> |
| 13 | +#include <Eigen/SparseCore> |
| 14 | + |
| 15 | +#include <sofa/helper/OptionsGroup.h> |
| 16 | +#include <EigenLinearSolvers/FindMetis.h> |
| 17 | + |
| 18 | +namespace EigenLinearSolvers |
| 19 | +{ |
| 20 | + |
| 21 | +/** |
| 22 | + * Partial template specialization of EigenDirectSparseSolver for a matrix of type CompressedRowSparseMatrix |
| 23 | + */ |
| 24 | +template<class TBlockType, class EigenSolver> |
| 25 | +class EigenDirectSparseSolver< |
| 26 | + sofa::linearalgebra::CompressedRowSparseMatrix<TBlockType>, |
| 27 | + sofa::linearalgebra::FullVector<typename sofa::linearalgebra::CompressedRowSparseMatrix<TBlockType>::Real>, |
| 28 | + EigenSolver > |
| 29 | + : public sofa::component::linearsolver::MatrixLinearSolver< |
| 30 | + sofa::linearalgebra::CompressedRowSparseMatrix<TBlockType>, |
| 31 | + sofa::linearalgebra::FullVector<typename sofa::linearalgebra::CompressedRowSparseMatrix<TBlockType>::Real> > |
| 32 | +{ |
| 33 | +public: |
| 34 | + typedef sofa::linearalgebra::CompressedRowSparseMatrix<TBlockType> Matrix; |
| 35 | + using Real = typename Matrix::Real; |
| 36 | + typedef sofa::linearalgebra::FullVector<Real> Vector; |
| 37 | + |
| 38 | + SOFA_ABSTRACT_CLASS(SOFA_TEMPLATE3(EigenDirectSparseSolver, Matrix, Vector, EigenSolver), |
| 39 | + SOFA_TEMPLATE2(sofa::component::linearsolver::MatrixLinearSolver, Matrix, Vector)); |
| 40 | + |
| 41 | + using NaturalOrderSolver = typename EigenSolver::NaturalOrderSolver; |
| 42 | + using AMDOrderSolver = typename EigenSolver::AMDOrderSolver; |
| 43 | + using COLAMDOrderSolver = typename EigenSolver::COLAMDOrderSolver; |
| 44 | +#if EIGENLINEARSOLVERS_HAS_METIS_INCLUDE == 1 |
| 45 | + using MetisOrderSolver = typename EigenSolver::MetisOrderSolver; |
| 46 | +#endif |
| 47 | + |
| 48 | + ~EigenDirectSparseSolver() override = default; |
| 49 | + |
| 50 | + void init() override; |
| 51 | + void reinit() override; |
| 52 | + |
| 53 | + using EigenSparseMatrix = Eigen::SparseMatrix<Real, Eigen::RowMajor>; |
| 54 | + using EigenSparseMatrixMap = Eigen::Map<EigenSparseMatrix>; |
| 55 | + using EigenVectorXdMap = Eigen::Map<Eigen::Matrix<Real, Eigen::Dynamic, 1> >; |
| 56 | + |
| 57 | + void solve (Matrix& A, Vector& x, Vector& b) override; |
| 58 | + void invert(Matrix& A) override; |
| 59 | + |
| 60 | +protected: |
| 61 | + |
| 62 | + sofa::core::objectmodel::Data<sofa::helper::OptionsGroup> d_orderingMethod; |
| 63 | + unsigned int m_selectedOrderingMethod { std::numeric_limits<unsigned int>::max() }; |
| 64 | + |
| 65 | + std::variant<NaturalOrderSolver, AMDOrderSolver, COLAMDOrderSolver |
| 66 | +#if EIGENLINEARSOLVERS_HAS_METIS_INCLUDE == 1 |
| 67 | + , MetisOrderSolver |
| 68 | +#endif |
| 69 | + > m_solver; |
| 70 | + |
| 71 | + Eigen::ComputationInfo getSolverInfo() const; |
| 72 | + void updateSolverOderingMethod(); |
| 73 | + |
| 74 | + sofa::linearalgebra::CompressedRowSparseMatrix<Real> Mfiltered; |
| 75 | + std::unique_ptr<EigenSparseMatrixMap> m_map; |
| 76 | + |
| 77 | + typename sofa::linearalgebra::CompressedRowSparseMatrix<Real>::VecIndex MfilteredrowBegin; |
| 78 | + typename sofa::linearalgebra::CompressedRowSparseMatrix<Real>::VecIndex MfilteredcolsIndex; |
| 79 | + |
| 80 | + EigenDirectSparseSolver(); |
| 81 | +}; |
| 82 | + |
| 83 | +} |
0 commit comments