14 #ifndef AMESOS2_DETAILS_LINEARSOLVERFACTORY_DEF_HPP
15 #define AMESOS2_DETAILS_LINEARSOLVERFACTORY_DEF_HPP
17 #include "Amesos2_config.h"
19 #include "Amesos2_Solver.hpp"
20 #include "Trilinos_Details_LinearSolver.hpp"
21 #include "Trilinos_Details_LinearSolverFactory.hpp"
22 #include <type_traits>
25 #ifdef HAVE_AMESOS2_EPETRA
26 # include "Epetra_CrsMatrix.h"
27 #endif // HAVE_AMESOS2_EPETRA
30 #ifndef HAVE_AMESOS2_TPETRA
31 # define HAVE_AMESOS2_TPETRA
32 #endif // HAVE_AMESOS2_TPETRA
34 #ifdef HAVE_AMESOS2_TPETRA
35 # include "Tpetra_CrsMatrix.hpp"
36 #endif // HAVE_AMESOS2_TPETRA
47 struct GetMatrixType {
51 #ifdef HAVE_AMESOS2_EPETRA
52 static_assert(! std::is_same<OP, Epetra_MultiVector>::value,
53 "Amesos2::Details::GetMatrixType: OP = Epetra_MultiVector. "
54 "This probably means that you mixed up MV and OP.");
55 #endif // HAVE_AMESOS2_EPETRA
57 #ifdef HAVE_AMESOS2_TPETRA
58 static_assert(! std::is_same<OP, Tpetra::MultiVector<
typename OP::scalar_type,
59 typename OP::local_ordinal_type,
typename OP::global_ordinal_type,
60 typename OP::node_type> >::value,
61 "Amesos2::Details::GetMatrixType: OP = Tpetra::MultiVector. "
62 "This probably means that you mixed up MV and OP.");
63 #endif // HAVE_AMESOS2_TPETRA
66 #ifdef HAVE_AMESOS2_EPETRA
68 struct GetMatrixType<Epetra_Operator> {
69 typedef Epetra_CrsMatrix type;
71 #endif // HAVE_AMESOS2_EPETRA
74 #ifdef HAVE_AMESOS2_TPETRA
75 template<
class S,
class LO,
class GO,
class NT>
76 struct GetMatrixType<Tpetra::Operator<S, LO, GO, NT> > {
77 typedef Tpetra::CrsMatrix<S, LO, GO, NT> type;
79 #endif // HAVE_AMESOS2_TPETRA
81 template<
class MV,
class OP,
class NormType>
83 public Trilinos::Details::LinearSolver<MV, OP, NormType>,
84 virtual public Teuchos::Describable
87 #ifdef HAVE_AMESOS2_EPETRA
88 static_assert(! std::is_same<OP, Epetra_MultiVector>::value,
89 "Amesos2::Details::LinearSolver: OP = Epetra_MultiVector. "
90 "This probably means that you mixed up MV and OP.");
91 static_assert(! std::is_same<MV, Epetra_Operator>::value,
92 "Amesos2::Details::LinearSolver: MV = Epetra_Operator. "
93 "This probably means that you mixed up MV and OP.");
94 #endif // HAVE_AMESOS2_EPETRA
103 typedef typename GetMatrixType<OP>::type crs_matrix_type;
104 static_assert(! std::is_same<crs_matrix_type, int>::value,
105 "Amesos2::Details::LinearSolver: The given OP type is not "
124 LinearSolver (
const std::string& solverName) :
125 solverName_ (solverName)
133 if (solverName ==
"") {
135 if (Amesos2::query (
"klu2")) {
136 solverName_ =
"klu2";
138 else if (Amesos2::query (
"superlu")) {
139 solverName_ =
"superlu";
141 else if (Amesos2::query (
"superludist")) {
142 solverName_ =
"superludist";
144 else if (Amesos2::query (
"cholmod")) {
145 solverName_ =
"cholmod";
147 else if (Amesos2::query (
"cusolver")) {
148 solverName_ =
"cusolver";
150 else if (Amesos2::query (
"basker")) {
151 solverName_ =
"basker";
153 else if (Amesos2::query (
"shylubasker")) {
154 solverName_ =
"shylubasker";
156 else if (Amesos2::query (
"ShyLUBasker")) {
157 solverName_ =
"shylubasker";
159 else if (Amesos2::query (
"superlumt")) {
160 solverName_ =
"superlumt";
162 else if (Amesos2::query (
"pardiso_mkl")) {
163 solverName_ =
"pardiso_mkl";
165 else if (Amesos2::query (
"css_mkl")) {
166 solverName_ =
"css_mkl";
168 else if (Amesos2::query (
"mumps")) {
169 solverName_ =
"mumps";
171 else if (Amesos2::query (
"lapack")) {
172 solverName_ =
"lapack";
174 else if (Amesos2::query (
"umfpack")) {
175 solverName_ =
"umfpack";
177 else if (Amesos2::query (
"tacho")) {
178 solverName_ =
"tacho";
186 virtual ~LinearSolver () {}
192 void setMatrix (
const Teuchos::RCP<const OP>& A) {
195 using Teuchos::TypeNameTraits;
196 typedef crs_matrix_type MAT;
197 const char prefix[] =
"Amesos2::Details::LinearSolver::setMatrix: ";
200 solver_ = Teuchos::null;
208 RCP<const MAT> A_mat = Teuchos::rcp_dynamic_cast<
const MAT> (A);
209 TEUCHOS_TEST_FOR_EXCEPTION
210 (A_mat.is_null (), std::invalid_argument,
211 "Amesos2::Details::LinearSolver::setMatrix: "
212 "The input matrix A must be a CrsMatrix.");
213 if (solver_.is_null ()) {
220 RCP<solver_type> solver;
222 solver = Amesos2::create<MAT, MV> (solverName_, A_mat, null, null);
224 catch (std::exception& e) {
225 TEUCHOS_TEST_FOR_EXCEPTION
226 (
true, std::invalid_argument, prefix <<
"Failed to create Amesos2 "
227 "solver named \"" << solverName_ <<
"\". "
228 "Amesos2::create<MAT = " << TypeNameTraits<MAT>::name ()
229 <<
", MV = " << TypeNameTraits<MV>::name ()
230 <<
" threw an exception: " << e.what ());
232 TEUCHOS_TEST_FOR_EXCEPTION
233 (solver.is_null (), std::invalid_argument, prefix <<
"Failed to "
234 "create Amesos2 solver named \"" << solverName_ <<
"\". "
235 "Amesos2::create<MAT = " << TypeNameTraits<MAT>::name ()
236 <<
", MV = " << TypeNameTraits<MV>::name ()
237 <<
" returned null.");
240 if (! params_.is_null ()) {
241 solver->setParameters (params_);
244 }
else if (A_ != A) {
245 solver_->setA (A_mat);
254 Teuchos::RCP<const OP> getMatrix ()
const {
259 void solve (MV& X,
const MV& B) {
260 const char prefix[] =
"Amesos2::Details::LinearSolver::solve: ";
261 TEUCHOS_TEST_FOR_EXCEPTION
262 (solver_.is_null (), std::runtime_error, prefix <<
"The solver does not "
263 "exist yet. You must call setMatrix() with a nonnull matrix before you "
264 "may call this method.");
265 TEUCHOS_TEST_FOR_EXCEPTION
266 (A_.is_null (), std::runtime_error, prefix <<
"The matrix has not been "
267 "set yet. You must call setMatrix() with a nonnull matrix before you "
268 "may call this method.");
269 solver_->solve (&X, &B);
273 void setParameters (
const Teuchos::RCP<Teuchos::ParameterList>& params) {
274 if (! solver_.is_null ()) {
275 solver_->setParameters (params);
285 const char prefix[] =
"Amesos2::Details::LinearSolver::symbolic: ";
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_->symbolicFactorization ();
300 const char prefix[] =
"Amesos2::Details::LinearSolver::numeric: ";
301 TEUCHOS_TEST_FOR_EXCEPTION
302 (solver_.is_null (), std::runtime_error, prefix <<
"The solver does not "
303 "exist yet. You must call setMatrix() with a nonnull matrix before you "
304 "may call this method.");
305 TEUCHOS_TEST_FOR_EXCEPTION
306 (A_.is_null (), std::runtime_error, prefix <<
"The matrix has not been "
307 "set yet. You must call setMatrix() with a nonnull matrix before you "
308 "may call this method.");
309 solver_->numericFactorization ();
313 std::string description ()
const {
314 using Teuchos::TypeNameTraits;
315 if (solver_.is_null ()) {
316 std::ostringstream os;
317 os <<
"\"Amesos2::Details::LinearSolver\": {"
318 <<
"MV: " << TypeNameTraits<MV>::name ()
319 <<
", OP: " << TypeNameTraits<OP>::name ()
320 <<
", NormType: " << TypeNameTraits<NormType>::name ()
324 return solver_->description ();
330 describe (Teuchos::FancyOStream& out,
331 const Teuchos::EVerbosityLevel verbLevel =
332 Teuchos::Describable::verbLevel_default)
const
334 using Teuchos::TypeNameTraits;
336 if (solver_.is_null ()) {
337 if (verbLevel > Teuchos::VERB_NONE) {
338 Teuchos::OSTab tab0 (out);
339 out <<
"\"Amesos2::Details::LinearSolver\":" << endl;
340 Teuchos::OSTab tab1 (out);
341 out <<
"MV: " << TypeNameTraits<MV>::name () << endl
342 <<
"OP: " << TypeNameTraits<OP>::name () << endl
343 <<
"NormType: " << TypeNameTraits<NormType>::name () << endl;
346 if (! solver_.is_null ()) {
347 solver_->describe (out, verbLevel);
352 std::string solverName_;
353 Teuchos::RCP<solver_type> solver_;
354 Teuchos::RCP<const OP> A_;
355 Teuchos::RCP<Teuchos::ParameterList> params_;
358 template<
class MV,
class OP,
class NormType>
359 Teuchos::RCP<Trilinos::Details::LinearSolver<MV, OP, NormType> >
364 return rcp (
new Amesos2::Details::LinearSolver<MV, OP, NormType> (solverName));
367 template<
class MV,
class OP,
class NormType>
372 #ifdef HAVE_TEUCHOSCORE_CXX11
373 typedef std::shared_ptr<Amesos2::Details::LinearSolverFactory<MV, OP, NormType> > ptr_type;
376 typedef Teuchos::RCP<Amesos2::Details::LinearSolverFactory<MV, OP, NormType> > ptr_type;
378 #endif // HAVE_TEUCHOSCORE_CXX11
381 Trilinos::Details::registerLinearSolverFactory<MV, OP, NormType> (
"Amesos2", factory);
394 #define AMESOS2_DETAILS_LINEARSOLVERFACTORY_INSTANT(SC, LO, GO, NT) \
395 template class Amesos2::Details::LinearSolverFactory<Tpetra::MultiVector<SC, LO, GO, NT>, \
396 Tpetra::Operator<SC, LO, GO, NT>, \
397 typename Tpetra::MultiVector<SC, LO, GO, NT>::mag_type>;
399 #endif // AMESOS2_DETAILS_LINEARSOLVERFACTORY_DEF_HPP
Interface for a "factory" that creates Amesos2 solvers.
Definition: Amesos2_Details_LinearSolverFactory_decl.hpp:43
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:361
Interface to Amesos2 solver objects.
Definition: Amesos2_Solver_decl.hpp:44
static void registerLinearSolverFactory()
Register this LinearSolverFactory with the central registry.
Definition: Amesos2_Details_LinearSolverFactory_def.hpp:370
Contains declarations for Amesos2::create and Amesos2::query.