HermesCommon  2.0
linear_matrix_solver.cpp
1 // This file is part of HermesCommon
2 //
3 // Copyright (c) 2009 hp-FEM group at the University of Nevada, Reno (UNR).
4 // Email: hpfem-group@unr.edu, home page: http://hpfem.org/.
5 //
6 // Hermes2D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published
8 // by the Free Software Foundation; either version 2 of the License,
9 // or (at your option) any later version.
10 //
11 // Hermes2D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with Hermes2D; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "linear_matrix_solver.h"
23 #include "umfpack_solver.h"
24 #include "superlu_solver.h"
25 #include "amesos_solver.h"
26 #include "petsc_solver.h"
27 #include "mumps_solver.h"
28 #include "newton_solver_nox.h"
29 #include "aztecoo_solver.h"
30 #include "api.h"
31 
32 using namespace Hermes::Algebra;
33 
34 namespace Hermes
35 {
36  namespace Solvers
37  {
38  template<typename Scalar>
39  LinearMatrixSolver<Scalar>::LinearMatrixSolver()
40  {
41  sln = NULL;
42  time = -1.0;
43  }
44 
45  template<typename Scalar>
46  LinearMatrixSolver<Scalar>::~LinearMatrixSolver()
47  {
48  if(sln != NULL)
49  delete [] sln;
50  }
51 
52  template<typename Scalar>
54  {
55  return sln;
56  }
57 
58  template<typename Scalar>
60  {
61  return error;
62  }
63 
64  template<typename Scalar>
66  {
67  return time;
68  }
69 
70  template<typename Scalar>
72  {
73  set_factorization_scheme(HERMES_REUSE_FACTORIZATION_COMPLETELY);
74  }
75 
76  template<typename Scalar>
78  {
79  Vector<Scalar>* rhs_dummy = NULL;
80  switch (Hermes::HermesCommonApi.get_integral_param_value(Hermes::matrixSolverType))
81  {
82  case Hermes::SOLVER_AZTECOO:
83  {
84 #if defined HAVE_AZTECOO && defined HAVE_EPETRA
85  if(rhs != NULL) return new AztecOOSolver<Scalar>(static_cast<EpetraMatrix<Scalar>*>(matrix), static_cast<EpetraVector<Scalar>*>(rhs));
86  else return new AztecOOSolver<Scalar>(static_cast<EpetraMatrix<Scalar>*>(matrix), static_cast<EpetraVector<Scalar>*>(rhs_dummy));
87 #else
88  throw Hermes::Exceptions::Exception("AztecOO not installed.");
89 #endif
90  break;
91  }
92  case Hermes::SOLVER_AMESOS:
93  {
94 #if defined HAVE_AMESOS && defined HAVE_EPETRA
95  if(rhs != NULL) return new AmesosSolver<Scalar>("Amesos_Klu", static_cast<EpetraMatrix<Scalar>*>(matrix), static_cast<EpetraVector<Scalar>*>(rhs));
96  else return new AmesosSolver<Scalar>("Amesos_Klu", static_cast<EpetraMatrix<Scalar>*>(matrix), static_cast<EpetraVector<Scalar>*>(rhs_dummy));
97 #else
98  throw Hermes::Exceptions::Exception("Amesos not installed.");
99 #endif
100  break;
101  }
102  case Hermes::SOLVER_MUMPS:
103  {
104 #ifdef WITH_MUMPS
105  if(rhs != NULL) return new MumpsSolver<Scalar>(static_cast<MumpsMatrix<Scalar>*>(matrix), static_cast<MumpsVector<Scalar>*>(rhs));
106  else return new MumpsSolver<Scalar>(static_cast<MumpsMatrix<Scalar>*>(matrix), static_cast<MumpsVector<Scalar>*>(rhs_dummy));
107 #else
108  throw Hermes::Exceptions::Exception("MUMPS was not installed.");
109 #endif
110  break;
111  }
112  case Hermes::SOLVER_PETSC:
113  {
114 #ifdef WITH_PETSC
115  if(rhs != NULL) return new PetscLinearMatrixSolver<Scalar>(static_cast<PetscMatrix<Scalar>*>(matrix), static_cast<PetscVector<Scalar>*>(rhs));
116  else return new PetscLinearMatrixSolver<Scalar>(static_cast<PetscMatrix<Scalar>*>(matrix), static_cast<PetscVector<Scalar>*>(rhs_dummy));
117 #else
118  throw Hermes::Exceptions::Exception("PETSc not installed.");
119 #endif
120  break;
121  }
122  case Hermes::SOLVER_UMFPACK:
123  {
124 #ifdef WITH_UMFPACK
125  if(rhs != NULL) return new UMFPackLinearMatrixSolver<Scalar>(static_cast<UMFPackMatrix<Scalar>*>(matrix), static_cast<UMFPackVector<Scalar>*>(rhs));
126  else return new UMFPackLinearMatrixSolver<Scalar>(static_cast<UMFPackMatrix<Scalar>*>(matrix), static_cast<UMFPackVector<Scalar>*>(rhs_dummy));
127 #else
128  throw Hermes::Exceptions::Exception("UMFPACK was not installed.");
129 #endif
130  break;
131  }
132  case Hermes::SOLVER_SUPERLU:
133  {
134 #ifdef WITH_SUPERLU
135  if(rhs != NULL) return new SuperLUSolver<Scalar>(static_cast<SuperLUMatrix<Scalar>*>(matrix), static_cast<SuperLUVector<Scalar>*>(rhs));
136  else return new SuperLUSolver<Scalar>(static_cast<SuperLUMatrix<Scalar>*>(matrix), static_cast<SuperLUVector<Scalar>*>(rhs_dummy));
137 #else
138  throw Hermes::Exceptions::Exception("SuperLU was not installed.");
139 #endif
140  break;
141  }
142  default:
143  throw Hermes::Exceptions::Exception("Unknown matrix solver requested in create_linear_solver().");
144  }
145  return NULL;
146  }
147 
148  template<typename Scalar>
150  {
151  factorization_scheme = reuse_scheme;
152  }
153 
154  template<typename Scalar>
156  {
157  this->tolerance = tol;
158  }
159 
160  template<typename Scalar>
162  {
163  this->max_iters = iters;
164  }
165 
167 
168  template HERMES_API LinearMatrixSolver<std::complex<double> >* create_linear_solver(Matrix<std::complex<double> >* matrix, Vector<std::complex<double> >* rhs);
169 
170  template class HERMES_API LinearMatrixSolver<double>;
171  template class HERMES_API LinearMatrixSolver<std::complex<double> >;
172  template class HERMES_API DirectSolver<double>;
173  template class HERMES_API DirectSolver<std::complex<double> >;
174  template class HERMES_API IterSolver<double>;
175  template class HERMES_API IterSolver<std::complex<double> >;
176  }
177 }