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 (
"cusolver")) {
182 solverName_ =
"cusolver";
184 else if (Amesos2::query (
"basker")) {
185 solverName_ =
"basker";
187 else if (Amesos2::query (
"shylubasker")) {
188 solverName_ =
"shylubasker";
190 else if (Amesos2::query (
"ShyLUBasker")) {
191 solverName_ =
"shylubasker";
193 else if (Amesos2::query (
"superlumt")) {
194 solverName_ =
"superlumt";
196 else if (Amesos2::query (
"pardiso_mkl")) {
197 solverName_ =
"pardiso_mkl";
199 else if (Amesos2::query (
"mumps")) {
200 solverName_ =
"mumps";
202 else if (Amesos2::query (
"lapack")) {
203 solverName_ =
"lapack";
205 else if (Amesos2::query (
"umfpack")) {
206 solverName_ =
"umfpack";
214 virtual ~LinearSolver () {}
220 void setMatrix (
const Teuchos::RCP<const OP>& A) {
223 using Teuchos::TypeNameTraits;
224 typedef crs_matrix_type MAT;
225 const char prefix[] =
"Amesos2::Details::LinearSolver::setMatrix: ";
228 solver_ = Teuchos::null;
236 RCP<const MAT> A_mat = Teuchos::rcp_dynamic_cast<
const MAT> (A);
237 TEUCHOS_TEST_FOR_EXCEPTION
238 (A_mat.is_null (), std::invalid_argument,
239 "Amesos2::Details::LinearSolver::setMatrix: "
240 "The input matrix A must be a CrsMatrix.");
241 if (solver_.is_null ()) {
248 RCP<solver_type> solver;
250 solver = Amesos2::create<MAT, MV> (solverName_, A_mat, null, null);
252 catch (std::exception& e) {
253 TEUCHOS_TEST_FOR_EXCEPTION
254 (
true, std::invalid_argument, prefix <<
"Failed to create Amesos2 "
255 "solver named \"" << solverName_ <<
"\". "
256 "Amesos2::create<MAT = " << TypeNameTraits<MAT>::name ()
257 <<
", MV = " << TypeNameTraits<MV>::name ()
258 <<
" threw an exception: " << e.what ());
260 TEUCHOS_TEST_FOR_EXCEPTION
261 (solver.is_null (), std::invalid_argument, prefix <<
"Failed to "
262 "create Amesos2 solver named \"" << solverName_ <<
"\". "
263 "Amesos2::create<MAT = " << TypeNameTraits<MAT>::name ()
264 <<
", MV = " << TypeNameTraits<MV>::name ()
265 <<
" returned null.");
268 if (! params_.is_null ()) {
269 solver->setParameters (params_);
272 }
else if (A_ != A) {
273 solver_->setA (A_mat);
282 Teuchos::RCP<const OP> getMatrix ()
const {
287 void solve (MV& X,
const MV& B) {
288 const char prefix[] =
"Amesos2::Details::LinearSolver::solve: ";
289 TEUCHOS_TEST_FOR_EXCEPTION
290 (solver_.is_null (), std::runtime_error, prefix <<
"The solver does not "
291 "exist yet. You must call setMatrix() with a nonnull matrix before you "
292 "may call this method.");
293 TEUCHOS_TEST_FOR_EXCEPTION
294 (A_.is_null (), std::runtime_error, prefix <<
"The matrix has not been "
295 "set yet. You must call setMatrix() with a nonnull matrix before you "
296 "may call this method.");
297 solver_->solve (&X, &B);
301 void setParameters (
const Teuchos::RCP<Teuchos::ParameterList>& params) {
302 if (! solver_.is_null ()) {
303 solver_->setParameters (params);
313 const char prefix[] =
"Amesos2::Details::LinearSolver::symbolic: ";
314 TEUCHOS_TEST_FOR_EXCEPTION
315 (solver_.is_null (), std::runtime_error, prefix <<
"The solver does not "
316 "exist yet. You must call setMatrix() with a nonnull matrix before you "
317 "may call this method.");
318 TEUCHOS_TEST_FOR_EXCEPTION
319 (A_.is_null (), std::runtime_error, prefix <<
"The matrix has not been "
320 "set yet. You must call setMatrix() with a nonnull matrix before you "
321 "may call this method.");
322 solver_->symbolicFactorization ();
328 const char prefix[] =
"Amesos2::Details::LinearSolver::numeric: ";
329 TEUCHOS_TEST_FOR_EXCEPTION
330 (solver_.is_null (), std::runtime_error, prefix <<
"The solver does not "
331 "exist yet. You must call setMatrix() with a nonnull matrix before you "
332 "may call this method.");
333 TEUCHOS_TEST_FOR_EXCEPTION
334 (A_.is_null (), std::runtime_error, prefix <<
"The matrix has not been "
335 "set yet. You must call setMatrix() with a nonnull matrix before you "
336 "may call this method.");
337 solver_->numericFactorization ();
341 std::string description ()
const {
342 using Teuchos::TypeNameTraits;
343 if (solver_.is_null ()) {
344 std::ostringstream os;
345 os <<
"\"Amesos2::Details::LinearSolver\": {"
346 <<
"MV: " << TypeNameTraits<MV>::name ()
347 <<
", OP: " << TypeNameTraits<OP>::name ()
348 <<
", NormType: " << TypeNameTraits<NormType>::name ()
352 return solver_->description ();
358 describe (Teuchos::FancyOStream& out,
359 const Teuchos::EVerbosityLevel verbLevel =
360 Teuchos::Describable::verbLevel_default)
const
362 using Teuchos::TypeNameTraits;
364 if (solver_.is_null ()) {
365 if (verbLevel > Teuchos::VERB_NONE) {
366 Teuchos::OSTab tab0 (out);
367 out <<
"\"Amesos2::Details::LinearSolver\":" << endl;
368 Teuchos::OSTab tab1 (out);
369 out <<
"MV: " << TypeNameTraits<MV>::name () << endl
370 <<
"OP: " << TypeNameTraits<OP>::name () << endl
371 <<
"NormType: " << TypeNameTraits<NormType>::name () << endl;
374 if (! solver_.is_null ()) {
375 solver_->describe (out, verbLevel);
380 std::string solverName_;
381 Teuchos::RCP<solver_type> solver_;
382 Teuchos::RCP<const OP> A_;
383 Teuchos::RCP<Teuchos::ParameterList> params_;
386 template<
class MV,
class OP,
class NormType>
387 Teuchos::RCP<Trilinos::Details::LinearSolver<MV, OP, NormType> >
392 return rcp (
new Amesos2::Details::LinearSolver<MV, OP, NormType> (solverName));
395 template<
class MV,
class OP,
class NormType>
400 #ifdef HAVE_TEUCHOSCORE_CXX11
401 typedef std::shared_ptr<Amesos2::Details::LinearSolverFactory<MV, OP, NormType> > ptr_type;
404 typedef Teuchos::RCP<Amesos2::Details::LinearSolverFactory<MV, OP, NormType> > ptr_type;
406 #endif // HAVE_TEUCHOSCORE_CXX11
409 Trilinos::Details::registerLinearSolverFactory<MV, OP, NormType> (
"Amesos2", factory);
422 #define AMESOS2_DETAILS_LINEARSOLVERFACTORY_INSTANT(SC, LO, GO, NT) \
423 template class Amesos2::Details::LinearSolverFactory<Tpetra::MultiVector<SC, LO, GO, NT>, \
424 Tpetra::Operator<SC, LO, GO, NT>, \
425 typename Tpetra::MultiVector<SC, LO, GO, NT>::mag_type>;
427 #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:389
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:398
Contains declarations for Amesos2::create and Amesos2::query.