trilinos_aztec_linear_solver.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #include "libmesh/libmesh_common.h"
21 
22 #ifdef LIBMESH_TRILINOS_HAVE_AZTECOO
23 
24 
25 // Local Includes
27 #include "libmesh/string_to_enum.h"
34 
35 namespace libMesh
36 {
37 
38 
39 /*----------------------- functions ----------------------------------*/
40 template <typename T>
42  LinearSolver<T>(comm)
43 {
44  if (this->n_processors() == 1)
46  else
48 }
49 
50 
51 
52 template <typename T>
54 {
55  if (this->initialized())
56  {
57  this->_is_initialized = false;
58 
59  // Mimic PETSc default solver and preconditioner
60  this->_solver_type = GMRES;
61 
62  if (this->n_processors() == 1)
63  this->_preconditioner_type = ILU_PRECOND;
64  else
65  this->_preconditioner_type = BLOCK_JACOBI_PRECOND;
66  }
67 }
68 
69 
70 
71 template <typename T>
72 void AztecLinearSolver<T>::init (const char * /*name*/)
73 {
74  // Initialize the data structures if not done so already.
75  if (!this->initialized())
76  {
77  this->_is_initialized = true;
78 
79  _linear_solver = new AztecOO();
80 
81  set_solver_type();
82 
83  switch(this->_preconditioner_type)
84  {
85  case ILU_PRECOND:
86  _linear_solver->SetAztecOption(AZ_precond,AZ_dom_decomp);
87  _linear_solver->SetAztecOption(AZ_subdomain_solve,AZ_ilu);
88  break;
89 
91  _linear_solver->SetAztecOption(AZ_precond,AZ_Jacobi);
92  break;
93 
94  case ICC_PRECOND:
95  _linear_solver->SetAztecOption(AZ_precond,AZ_dom_decomp);
96  _linear_solver->SetAztecOption(AZ_subdomain_solve,AZ_icc);
97  break;
98 
99  case LU_PRECOND:
100  _linear_solver->SetAztecOption(AZ_precond,AZ_dom_decomp);
101  _linear_solver->SetAztecOption(AZ_subdomain_solve,AZ_lu);
102  break;
103 
104  default:
105  _linear_solver->SetAztecOption(AZ_precond,AZ_dom_decomp);
106  _linear_solver->SetAztecOption(AZ_subdomain_solve,AZ_ilu);
107  }
108  }
109 }
110 
111 
112 
113 
114 template <typename T>
115 std::pair<unsigned int, Real>
117  SparseMatrix<T> & precond_in,
118  NumericVector<T> & solution_in,
119  NumericVector<T> & rhs_in,
120  const double tol,
121  const unsigned int m_its)
122 {
123  LOG_SCOPE("solve()", "AztecLinearSolver");
124 
125  // Make sure the data passed in are really of Epetra types
126  EpetraMatrix<T> * matrix = cast_ptr<EpetraMatrix<T> *>(&matrix_in);
127  EpetraMatrix<T> * precond = cast_ptr<EpetraMatrix<T> *>(&precond_in);
128  EpetraVector<T> * solution = cast_ptr<EpetraVector<T> *>(&solution_in);
129  EpetraVector<T> * rhs = cast_ptr<EpetraVector<T> *>(&rhs_in);
130 
131  this->init();
132 
133  // Close the matrices and vectors in case this wasn't already done.
134  matrix->close ();
135  precond->close ();
136  solution->close ();
137  rhs->close ();
138 
139  _linear_solver->SetAztecOption(AZ_max_iter,m_its);
140  _linear_solver->SetAztecParam(AZ_tol,tol);
141 
142  Epetra_FECrsMatrix * emat = matrix->mat();
143  Epetra_Vector * esol = solution->vec();
144  Epetra_Vector * erhs = rhs->vec();
145 
146  _linear_solver->Iterate(emat, esol, erhs, m_its, tol);
147 
148  // return the # of its. and the final residual norm.
149  return std::make_pair(_linear_solver->NumIters(), _linear_solver->TrueResidual());
150 }
151 
152 
153 
154 template <typename T>
155 std::pair<unsigned int, Real>
159  const double,
160  const unsigned int)
161 {
162  libmesh_not_implemented();
163 }
164 
165 
166 
167 template <typename T>
168 std::pair<unsigned int, Real>
170  const SparseMatrix<T> &,
173  const double,
174  const unsigned int)
175 {
176  libmesh_not_implemented();
177 }
178 
179 
180 
181 template <typename T>
182 void AztecLinearSolver<T>::get_residual_history(std::vector<double> & /* hist */)
183 {
184  libmesh_not_implemented();
185 }
186 
187 
188 
189 
190 template <typename T>
192 {
193  return _linear_solver->TrueResidual();
194 }
195 
196 
197 
198 template <typename T>
200 {
201  const double *status = _linear_solver->GetAztecStatus();
202 
203  switch (static_cast<int>(status[AZ_why]))
204  {
205  case AZ_normal :
206  libMesh::out << "AztecOO converged.\n";
207  break;
208  case AZ_maxits :
209  libMesh::out << "AztecOO failed to converge within maximum iterations.\n";
210  break;
211  case AZ_param :
212  libMesh::out << "AztecOO failed to support a user-requested parameter.\n";
213  break;
214  case AZ_breakdown :
215  libMesh::out << "AztecOO encountered numerical breakdown.\n";
216  break;
217  case AZ_loss :
218  libMesh::out << "AztecOO encountered numerical loss of precision.\n";
219  break;
220  case AZ_ill_cond :
221  libMesh::out << "AztecOO encountered an ill-conditioned GMRES Hessian.\n";
222  break;
223  default:
224  libMesh::out << "AztecOO reported an unrecognized condition.\n";
225  break;
226  }
227 }
228 
229 
230 
231 template <typename T>
233 {
234  const double *status = _linear_solver->GetAztecStatus();
235 
236  switch (static_cast<int>(status[AZ_why]))
237  {
238  case AZ_normal :
239  return CONVERGED_RTOL_NORMAL;
240  case AZ_maxits :
241  return DIVERGED_ITS;
242  default :
243  break;
244  }
245  return DIVERGED_NULL;
246 }
247 
248 
249 
250 template <typename T>
252 {
253  switch (this->_solver_type)
254  {
255  case CG:
256  _linear_solver->SetAztecOption(AZ_solver, AZ_cg); return;
257 
258  case CGS:
259  _linear_solver->SetAztecOption(AZ_solver, AZ_cgs); return;
260 
261  case TFQMR:
262  _linear_solver->SetAztecOption(AZ_solver, AZ_tfqmr); return;
263 
264  case BICGSTAB:
265  _linear_solver->SetAztecOption(AZ_solver, AZ_bicgstab); return;
266 
267  case GMRES:
268  _linear_solver->SetAztecOption(AZ_solver, AZ_gmres); return;
269 
270  default:
271  libMesh::err << "ERROR: Unsupported AztecOO Solver: "
272  << Utility::enum_to_string(this->_solver_type) << std::endl
273  << "Continuing with AztecOO defaults" << std::endl;
274  }
275 }
276 
277 //------------------------------------------------------------------
278 // Explicit instantiations
279 template class AztecLinearSolver<Number>;
280 
281 } // namespace libMesh
282 
283 
284 
285 #endif // #ifdef LIBMESH_TRILINOS_HAVE_AZTECOO
void get_residual_history(std::vector< double > &hist)
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
Definition: diff_context.h:40
processor_id_type n_processors() const
void init(triangulateio &t)
AztecLinearSolver(const libMesh::Parallel::Communicator &comm)
MPI_Status status
Definition: status.h:41
OStreamProxy err(std::cerr)
virtual std::pair< unsigned int, Real > solve(SparseMatrix< T > &matrix_in, NumericVector< T > &solution_in, NumericVector< T > &rhs_in, const double tol, const unsigned int m_its) override
virtual void init(const char *name=nullptr) override
virtual void close() override
std::string enum_to_string(const T e)
virtual void print_converged_reason() const override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
PreconditionerType _preconditioner_type
virtual LinearConvergenceReason get_converged_reason() const override
bool initialized()
Definition: libmesh.C:258
Epetra_FECrsMatrix * mat()
OStreamProxy out(std::cout)