libMesh
Loading...
Searching...
No Matches
trilinos_aztec_linear_solver.C
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 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
26#include "libmesh/libmesh_logging.h"
27#include "libmesh/enum_to_string.h"
28#include "libmesh/trilinos_aztec_linear_solver.h"
29#include "libmesh/trilinos_epetra_matrix.h"
30#include "libmesh/trilinos_epetra_vector.h"
31#include "libmesh/enum_preconditioner_type.h"
32#include "libmesh/enum_solver_type.h"
33#include "libmesh/enum_convergence_flags.h"
34
35namespace libMesh
36{
37
38
39/*----------------------- functions ----------------------------------*/
40template <typename T>
49
50
51
52template <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
71template <typename T>
72void 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
114template <typename T>
115std::pair<unsigned int, Real>
117 SparseMatrix<T> & precond_in,
118 NumericVector<T> & solution_in,
119 NumericVector<T> & rhs_in,
120 const std::optional<double> tol,
121 const std::optional<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 const int max_its = this->get_int_solver_setting("max_its", m_its);
140 const double rel_tol = this->get_real_solver_setting("rel_tol", tol);
141
142 _linear_solver->SetAztecOption(AZ_max_iter,max_its);
143 _linear_solver->SetAztecParam(AZ_tol,rel_tol);
144
145 Epetra_FECrsMatrix * emat = matrix->mat();
146 Epetra_Vector * esol = solution->vec();
147 Epetra_Vector * erhs = rhs->vec();
148
149 _linear_solver->Iterate(emat, esol, erhs, max_its, rel_tol);
150
151 // return the # of its. and the final residual norm.
152 return std::make_pair(_linear_solver->NumIters(), _linear_solver->TrueResidual());
153}
154
155
156
157template <typename T>
158std::pair<unsigned int, Real>
162 const std::optional<double>,
163 const std::optional<unsigned int>)
164{
165 libmesh_not_implemented();
166}
167
168
169
170template <typename T>
171std::pair<unsigned int, Real>
173 const SparseMatrix<T> &,
176 const std::optional<double>,
177 const std::optional<unsigned int>)
178{
179 libmesh_not_implemented();
180}
181
182
183
184template <typename T>
185void AztecLinearSolver<T>::get_residual_history(std::vector<double> & /* hist */)
186{
187 libmesh_not_implemented();
188}
189
190
191
192
193template <typename T>
195{
196 return _linear_solver->TrueResidual();
197}
198
199
200
201template <typename T>
203{
204 const double *status = _linear_solver->GetAztecStatus();
205
206 switch (static_cast<int>(status[AZ_why]))
207 {
208 case AZ_normal :
209 libMesh::out << "AztecOO converged.\n";
210 break;
211 case AZ_maxits :
212 libMesh::out << "AztecOO failed to converge within maximum iterations.\n";
213 break;
214 case AZ_param :
215 libMesh::out << "AztecOO failed to support a user-requested parameter.\n";
216 break;
217 case AZ_breakdown :
218 libMesh::out << "AztecOO encountered numerical breakdown.\n";
219 break;
220 case AZ_loss :
221 libMesh::out << "AztecOO encountered numerical loss of precision.\n";
222 break;
223 case AZ_ill_cond :
224 libMesh::out << "AztecOO encountered an ill-conditioned GMRES Hessian.\n";
225 break;
226 default:
227 libMesh::out << "AztecOO reported an unrecognized condition.\n";
228 break;
229 }
230}
231
232
233
234template <typename T>
236{
237 const double *status = _linear_solver->GetAztecStatus();
238
239 switch (static_cast<int>(status[AZ_why]))
240 {
241 case AZ_normal :
243 case AZ_maxits :
244 return DIVERGED_ITS;
245 default :
246 break;
247 }
248 return DIVERGED_NULL;
249}
250
251
252
253template <typename T>
255{
256 switch (this->_solver_type)
257 {
258 case CG:
259 _linear_solver->SetAztecOption(AZ_solver, AZ_cg); return;
260
261 case CGS:
262 _linear_solver->SetAztecOption(AZ_solver, AZ_cgs); return;
263
264 case TFQMR:
265 _linear_solver->SetAztecOption(AZ_solver, AZ_tfqmr); return;
266
267 case BICGSTAB:
268 _linear_solver->SetAztecOption(AZ_solver, AZ_bicgstab); return;
269
270 case GMRES:
271 _linear_solver->SetAztecOption(AZ_solver, AZ_gmres); return;
272
273 default:
274 libMesh::err << "ERROR: Unsupported AztecOO Solver: "
275 << Utility::enum_to_string(this->_solver_type) << std::endl
276 << "Continuing with AztecOO defaults" << std::endl;
277 }
278}
279
280//------------------------------------------------------------------
281// Explicit instantiations
282template class LIBMESH_EXPORT AztecLinearSolver<Number>;
283
284} // namespace libMesh
285
286
287
288#endif // #ifdef LIBMESH_TRILINOS_HAVE_AZTECOO
This class provides an interface to AztecOO iterative solvers that is compatible with the libMesh Lin...
virtual void clear() override
Release all memory and clear data structures.
void get_residual_history(std::vector< double > &hist)
Fills the input vector with the sequence of residual norms from the latest iterative solve.
void set_solver_type()
Tells AztecOO to use the user-specified solver stored in _solver_type.
virtual LinearConvergenceReason get_converged_reason() const override
virtual void print_converged_reason() const override
Prints a useful message about why the latest linear solve con(di)verged.
virtual std::pair< unsigned int, Real > solve(SparseMatrix< T > &matrix_in, NumericVector< T > &solution_in, NumericVector< T > &rhs_in, const std::optional< double > tol=std::nullopt, const std::optional< unsigned int > m_its=std::nullopt) override
Call the Aztec solver.
AztecLinearSolver(const libMesh::Parallel::Communicator &comm)
Constructor.
virtual void init(const char *name=nullptr) override
Initialize data structures if not done so already.
This class provides a nice interface to the Epetra data structures for parallel, sparse matrices.
virtual void close() override
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
Epetra_FECrsMatrix * mat()
This class provides a nice interface to the Trilinos Epetra_Vector object.
This base class can be inherited from to provide interfaces to linear solvers from different packages...
PreconditionerType _preconditioner_type
Enum stating with type of preconditioner to use.
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
processor_id_type n_processors() const
Generic shell matrix, i.e.
Generic sparse matrix.
std::string enum_to_string(const T e)
The libMesh namespace provides an interface to certain functionality in the library.
OStreamProxy err
OStreamProxy out
bool initialized()
Checks that library initialization has been done.
Definition libmesh.C:324
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
LinearConvergenceReason
Linear solver convergence flags (taken from the PETSc flags).