1111#include < fstream>
1212
1313// -----------------------------------------------------------------------------
14+ //
15+ // Subsequent macros assume a single template parameter and SparseQR fails due to requiring 2 parameters. this is because the OrderingType is not filled in.
16+ // SparseLU has a default declaration of _OrderingType to use COLAMDOrdering but SparseQR doesn't - so this just mimics that behavior. If Eigen adds such a default in the future this line will need to be guarded to avoid multiple defaults
17+ namespace Eigen {
18+ template <typename _MatrixType, typename _OrderingType = COLAMDOrdering<typename _MatrixType::StorageIndex> > class SparseQR ;
19+ }
1420#include < Eigen/Sparse>
1521#ifdef POLYSOLVE_WITH_ACCELERATE
1622#include < Eigen/AccelerateSupport>
2127#ifdef POLYSOLVE_WITH_UMFPACK
2228#include < Eigen/UmfPackSupport>
2329#endif
30+ #ifdef POLYSOLVE_WITH_SPQR
31+ #include < Eigen/SPQRSupport>
32+ namespace polysolve ::linear {
33+ template <>
34+ void EigenDirect<Eigen::SPQR<StiffnessMatrix>>::analyze_pattern(const StiffnessMatrix& A, const int precond_num) {
35+ m_Solver.compute (A);
36+ }
37+ template <>
38+ void EigenDirect<Eigen::SPQR<StiffnessMatrix>>::factorize(const StiffnessMatrix &A)
39+ {
40+ m_Solver.compute (A);
41+ if (m_Solver.info () == Eigen::NumericalIssue)
42+ {
43+ throw std::runtime_error (" [EigenDirect] NumericalIssue encountered." );
44+ }
45+ }
46+ }
47+ #endif
2448#ifdef POLYSOLVE_WITH_SUPERLU
2549#include < Eigen/SuperLUSupport>
2650#endif
@@ -293,6 +317,10 @@ namespace polysolve::linear
293317 else if (solver == " Eigen::SparseLU" )
294318 {
295319 RETURN_DIRECT_SOLVER_PTR (SparseLU, " Eigen::SparseLU" );
320+ }
321+ else if (solver == " Eigen::SparseQR" )
322+ {
323+ RETURN_DIRECT_SOLVER_PTR (SparseQR, " Eigen::SparseQR" );
296324#ifdef POLYSOLVE_WITH_ACCELERATE
297325 }
298326 else if (solver == " Eigen::AccelerateLLT" )
@@ -335,6 +363,12 @@ namespace polysolve::linear
335363 {
336364 RETURN_DIRECT_SOLVER_PTR (SuperLU, " Eigen::SuperLU" );
337365#endif
366+ #ifdef POLYSOLVE_WITH_SPQR
367+ }
368+ else if (solver == " Eigen::SPQR" )
369+ {
370+ RETURN_DIRECT_SOLVER_PTR (SPQR, " Eigen::SPQR" );
371+ #endif
338372#ifdef POLYSOLVE_WITH_MKL
339373 }
340374 else if (solver == " Eigen::PardisoLLT" )
@@ -465,6 +499,7 @@ namespace polysolve::linear
465499 return {{
466500 " Eigen::SimplicialLDLT" ,
467501 " Eigen::SparseLU" ,
502+ " Eigen::SparseQR" ,
468503#ifdef POLYSOLVE_WITH_ACCELERATE
469504 " Eigen::AccelerateLLT" ,
470505 " Eigen::AccelerateLDLT" ,
@@ -481,6 +516,9 @@ namespace polysolve::linear
481516#ifdef POLYSOLVE_WITH_SUPERLU
482517 " Eigen::SuperLU" ,
483518#endif
519+ #ifdef POLYSOLVE_WITH_SPQR
520+ " Eigen::SPQR" ,
521+ #endif
484522#ifdef POLYSOLVE_WITH_MKL
485523 " Eigen::PardisoLLT" ,
486524 " Eigen::PardisoLDLT" ,
0 commit comments