48 #ifndef AMESOS2_DETAILS_LINEARSOLVERFACTORY_DEF_HPP 
   49 #define AMESOS2_DETAILS_LINEARSOLVERFACTORY_DEF_HPP 
   51 #include "Amesos2_config.h" 
   53 #include "Amesos2_Solver.hpp" 
   54 #include "Trilinos_Details_LinearSolver.hpp" 
   55 #include "Trilinos_Details_LinearSolverFactory.hpp" 
   56 #include <type_traits> 
   59 #ifdef HAVE_AMESOS2_EPETRA 
   60 #  include "Epetra_CrsMatrix.h" 
   61 #endif // HAVE_AMESOS2_EPETRA 
   64 #ifndef HAVE_AMESOS2_TPETRA 
   65 #  define HAVE_AMESOS2_TPETRA 
   66 #endif // HAVE_AMESOS2_TPETRA 
   68 #ifdef HAVE_AMESOS2_TPETRA 
   69 #  include "Tpetra_CrsMatrix.hpp" 
   70 #endif // HAVE_AMESOS2_TPETRA 
   81 struct GetMatrixType {
 
   85 #ifdef HAVE_AMESOS2_EPETRA 
   86   static_assert(! std::is_same<OP, Epetra_MultiVector>::value,
 
   87                 "Amesos2::Details::GetMatrixType: OP = Epetra_MultiVector.  " 
   88                 "This probably means that you mixed up MV and OP.");
 
   89 #endif // HAVE_AMESOS2_EPETRA 
   91 #ifdef HAVE_AMESOS2_TPETRA 
   92   static_assert(! std::is_same<OP, Tpetra::MultiVector<
typename OP::scalar_type,
 
   93                 typename OP::local_ordinal_type, 
typename OP::global_ordinal_type,
 
   94                 typename OP::node_type> >::value,
 
   95                 "Amesos2::Details::GetMatrixType: OP = Tpetra::MultiVector.  " 
   96                 "This probably means that you mixed up MV and OP.");
 
   97 #endif // HAVE_AMESOS2_TPETRA 
  100 #ifdef HAVE_AMESOS2_EPETRA 
  102 struct GetMatrixType<Epetra_Operator> {
 
  103   typedef Epetra_CrsMatrix type;
 
  105 #endif // HAVE_AMESOS2_EPETRA 
  108 #ifdef HAVE_AMESOS2_TPETRA 
  109 template<
class S, 
class LO, 
class GO, 
class NT>
 
  110 struct GetMatrixType<Tpetra::Operator<S, LO, GO, NT> > {
 
  111   typedef Tpetra::CrsMatrix<S, LO, GO, NT> type;
 
  113 #endif // HAVE_AMESOS2_TPETRA 
  115 template<
class MV, 
class OP, 
class NormType>
 
  117     public Trilinos::Details::LinearSolver<MV, OP, NormType>,
 
  118     virtual public Teuchos::Describable
 
  121 #ifdef HAVE_AMESOS2_EPETRA 
  122   static_assert(! std::is_same<OP, Epetra_MultiVector>::value,
 
  123                 "Amesos2::Details::LinearSolver: OP = Epetra_MultiVector.  " 
  124                 "This probably means that you mixed up MV and OP.");
 
  125   static_assert(! std::is_same<MV, Epetra_Operator>::value,
 
  126                 "Amesos2::Details::LinearSolver: MV = Epetra_Operator.  " 
  127                 "This probably means that you mixed up MV and OP.");
 
  128 #endif // HAVE_AMESOS2_EPETRA 
  137   typedef typename GetMatrixType<OP>::type crs_matrix_type;
 
  138   static_assert(! std::is_same<crs_matrix_type, int>::value,
 
  139                 "Amesos2::Details::LinearSolver: The given OP type is not " 
  158   LinearSolver (
const std::string& solverName) :
 
  159     solverName_ (solverName)
 
  167     if (solverName == 
"") {
 
  169       if (Amesos2::query (
"klu2")) {
 
  170         solverName_ = 
"klu2";
 
  172       else if (Amesos2::query (
"superlu")) {
 
  173         solverName_ = 
"superlu";
 
  175       else if (Amesos2::query (
"superludist")) {
 
  176         solverName_ = 
"superludist";
 
  178       else if (Amesos2::query (
"cholmod")) {
 
  179         solverName_ = 
"cholmod";
 
  181       else if (Amesos2::query (
"basker")) {
 
  182         solverName_ = 
"basker";
 
  184       else if (Amesos2::query (
"shylubasker")) {
 
  185         solverName_ = 
"shylubasker";
 
  187       else if (Amesos2::query (
"ShyLUBasker")) {
 
  188         solverName_ = 
"shylubasker";
 
  190       else if (Amesos2::query (
"superlumt")) {
 
  191         solverName_ = 
"superlumt";
 
  193       else if (Amesos2::query (
"pardiso_mkl")) {
 
  194         solverName_ = 
"pardiso_mkl";
 
  196       else if (Amesos2::query (
"mumps")) {
 
  197         solverName_ = 
"mumps";
 
  199       else if (Amesos2::query (
"lapack")) {
 
  200         solverName_ = 
"lapack";
 
  202       else if (Amesos2::query (
"umfpack")) {
 
  203         solverName_ = 
"umfpack";
 
  211   virtual ~LinearSolver () {}
 
  217   void setMatrix (
const Teuchos::RCP<const OP>& A) {
 
  220     using Teuchos::TypeNameTraits;
 
  221     typedef crs_matrix_type MAT;
 
  222     const char prefix[] = 
"Amesos2::Details::LinearSolver::setMatrix: ";
 
  225       solver_ = Teuchos::null;
 
  233       RCP<const MAT> A_mat = Teuchos::rcp_dynamic_cast<
const MAT> (A);
 
  234       TEUCHOS_TEST_FOR_EXCEPTION
 
  235         (A_mat.is_null (), std::invalid_argument,
 
  236          "Amesos2::Details::LinearSolver::setMatrix: " 
  237          "The input matrix A must be a CrsMatrix.");
 
  238       if (solver_.is_null ()) {
 
  245         RCP<solver_type> solver;
 
  247           solver = Amesos2::create<MAT, MV> (solverName_, A_mat, null, null);
 
  249         catch (std::exception& e) {
 
  250           TEUCHOS_TEST_FOR_EXCEPTION
 
  251             (
true, std::invalid_argument, prefix << 
"Failed to create Amesos2 " 
  252              "solver named \"" << solverName_ << 
"\".  " 
  253              "Amesos2::create<MAT = " << TypeNameTraits<MAT>::name ()
 
  254              << 
", MV = " << TypeNameTraits<MV>::name ()
 
  255              << 
" threw an exception: " << e.what ());
 
  257         TEUCHOS_TEST_FOR_EXCEPTION
 
  258           (solver.is_null (), std::invalid_argument, prefix << 
"Failed to " 
  259            "create Amesos2 solver named \"" << solverName_ << 
"\".  " 
  260            "Amesos2::create<MAT = " << TypeNameTraits<MAT>::name ()
 
  261            << 
", MV = " << TypeNameTraits<MV>::name ()
 
  262            << 
" returned null.");
 
  265         if (! params_.is_null ()) {
 
  266           solver->setParameters (params_);
 
  269       } 
else if (A_ != A) {
 
  270         solver_->setA (A_mat);
 
  279   Teuchos::RCP<const OP> getMatrix ()
 const {
 
  284   void solve (MV& X, 
const MV& B) {
 
  285     const char prefix[] = 
"Amesos2::Details::LinearSolver::solve: ";
 
  286     TEUCHOS_TEST_FOR_EXCEPTION
 
  287       (solver_.is_null (), std::runtime_error, prefix << 
"The solver does not " 
  288        "exist yet.  You must call setMatrix() with a nonnull matrix before you " 
  289        "may call this method.");
 
  290     TEUCHOS_TEST_FOR_EXCEPTION
 
  291       (A_.is_null (), std::runtime_error, prefix << 
"The matrix has not been " 
  292        "set yet.  You must call setMatrix() with a nonnull matrix before you " 
  293        "may call this method.");
 
  294     solver_->solve (&X, &B);
 
  298   void setParameters (
const Teuchos::RCP<Teuchos::ParameterList>& params) {
 
  299     if (! solver_.is_null ()) {
 
  300       solver_->setParameters (params);
 
  310     const char prefix[] = 
"Amesos2::Details::LinearSolver::symbolic: ";
 
  311     TEUCHOS_TEST_FOR_EXCEPTION
 
  312       (solver_.is_null (), std::runtime_error, prefix << 
"The solver does not " 
  313        "exist yet.  You must call setMatrix() with a nonnull matrix before you " 
  314        "may call this method.");
 
  315     TEUCHOS_TEST_FOR_EXCEPTION
 
  316       (A_.is_null (), std::runtime_error, prefix << 
"The matrix has not been " 
  317        "set yet.  You must call setMatrix() with a nonnull matrix before you " 
  318        "may call this method.");
 
  319     solver_->symbolicFactorization ();
 
  325     const char prefix[] = 
"Amesos2::Details::LinearSolver::numeric: ";
 
  326     TEUCHOS_TEST_FOR_EXCEPTION
 
  327       (solver_.is_null (), std::runtime_error, prefix << 
"The solver does not " 
  328        "exist yet.  You must call setMatrix() with a nonnull matrix before you " 
  329        "may call this method.");
 
  330     TEUCHOS_TEST_FOR_EXCEPTION
 
  331       (A_.is_null (), std::runtime_error, prefix << 
"The matrix has not been " 
  332        "set yet.  You must call setMatrix() with a nonnull matrix before you " 
  333        "may call this method.");
 
  334     solver_->numericFactorization ();
 
  338   std::string description ()
 const {
 
  339     using Teuchos::TypeNameTraits;
 
  340     if (solver_.is_null ()) {
 
  341       std::ostringstream os;
 
  342       os << 
"\"Amesos2::Details::LinearSolver\": {" 
  343          << 
"MV: " << TypeNameTraits<MV>::name ()
 
  344          << 
", OP: " << TypeNameTraits<OP>::name ()
 
  345          << 
", NormType: " << TypeNameTraits<NormType>::name ()
 
  349       return solver_->description ();
 
  355   describe (Teuchos::FancyOStream& out,
 
  356             const Teuchos::EVerbosityLevel verbLevel =
 
  357             Teuchos::Describable::verbLevel_default)
 const 
  359     using Teuchos::TypeNameTraits;
 
  361     if (solver_.is_null ()) {
 
  362       if (verbLevel > Teuchos::VERB_NONE) {
 
  363         Teuchos::OSTab tab0 (out);
 
  364         out << 
"\"Amesos2::Details::LinearSolver\":" << endl;
 
  365         Teuchos::OSTab tab1 (out);
 
  366         out << 
"MV: " << TypeNameTraits<MV>::name () << endl
 
  367             << 
"OP: " << TypeNameTraits<OP>::name () << endl
 
  368             << 
"NormType: " << TypeNameTraits<NormType>::name () << endl;
 
  371     if (! solver_.is_null ()) {
 
  372       solver_->describe (out, verbLevel);
 
  377   std::string solverName_;
 
  378   Teuchos::RCP<solver_type> solver_;
 
  379   Teuchos::RCP<const OP> A_;
 
  380   Teuchos::RCP<Teuchos::ParameterList> params_;
 
  383 template<
class MV, 
class OP, 
class NormType>
 
  384 Teuchos::RCP<Trilinos::Details::LinearSolver<MV, OP, NormType> >
 
  389   return rcp (
new Amesos2::Details::LinearSolver<MV, OP, NormType> (solverName));
 
  392 template<
class MV, 
class OP, 
class NormType>
 
  397 #ifdef HAVE_TEUCHOSCORE_CXX11 
  398   typedef std::shared_ptr<Amesos2::Details::LinearSolverFactory<MV, OP, NormType> > ptr_type;
 
  401   typedef Teuchos::RCP<Amesos2::Details::LinearSolverFactory<MV, OP, NormType> > ptr_type;
 
  403 #endif // HAVE_TEUCHOSCORE_CXX11 
  406   Trilinos::Details::registerLinearSolverFactory<MV, OP, NormType> (
"Amesos2", factory);
 
  419 #define AMESOS2_DETAILS_LINEARSOLVERFACTORY_INSTANT(SC, LO, GO, NT) \ 
  420   template class Amesos2::Details::LinearSolverFactory<Tpetra::MultiVector<SC, LO, GO, NT>, \ 
  421                                                        Tpetra::Operator<SC, LO, GO, NT>, \ 
  422                                                        typename Tpetra::MultiVector<SC, LO, GO, NT>::mag_type>; 
  424 #endif // AMESOS2_DETAILS_LINEARSOLVERFACTORY_DEF_HPP 
Interface for a "factory" that creates Amesos2 solvers. 
Definition: Amesos2_Details_LinearSolverFactory_decl.hpp:77
virtual Teuchos::RCP< Trilinos::Details::LinearSolver< MV, OP, NormType > > getLinearSolver(const std::string &solverName)
Get an instance of a Amesos2 solver. 
Definition: Amesos2_Details_LinearSolverFactory_def.hpp:386
Interface to Amesos2 solver objects. 
Definition: Amesos2_Solver_decl.hpp:78
static void registerLinearSolverFactory()
Register this LinearSolverFactory with the central registry. 
Definition: Amesos2_Details_LinearSolverFactory_def.hpp:395
Contains declarations for Amesos2::create and Amesos2::query.