libMesh
Loading...
Searching...
No Matches
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// Local Includes
21#include "libmesh/libmesh_logging.h"
22#include "libmesh/linear_solver.h"
23#include "libmesh/laspack_linear_solver.h"
24#include "libmesh/eigen_sparse_linear_solver.h"
25#include "libmesh/petsc_linear_solver.h"
26#include "libmesh/trilinos_aztec_linear_solver.h"
27#include "libmesh/preconditioner.h"
28#include "libmesh/sparse_matrix.h"
29#include "libmesh/enum_to_string.h"
30#include "libmesh/solver_configuration.h"
31#include "libmesh/enum_solver_package.h"
32#include "libmesh/enum_preconditioner_type.h"
33#include "libmesh/enum_solver_type.h"
34
35// C++ Includes
36#include <memory>
37
38namespace libMesh
39{
40
41//------------------------------------------------------------------
42// LinearSolver members
43template <typename T>
45 ParallelObject (comm_in),
46 _solver_type (GMRES),
47 _preconditioner_type (ILU_PRECOND),
48 _is_initialized (false),
49 _preconditioner (nullptr),
50 same_preconditioner (false),
51 _solver_configuration(nullptr)
52{
53}
54
55
56
57template <typename T>
58std::unique_ptr<LinearSolver<T>>
60 const SolverPackage solver_package)
61{
62 // Avoid unused parameter warnings when no solver packages are enabled.
63 libmesh_ignore(comm);
64
65 // Build the appropriate solver
66 switch (solver_package)
67 {
68#ifdef LIBMESH_HAVE_LASPACK
69 case LASPACK_SOLVERS:
70 return std::make_unique<LaspackLinearSolver<T>>(comm);
71#endif
72
73
74#ifdef LIBMESH_HAVE_PETSC
75 case PETSC_SOLVERS:
76 return std::make_unique<PetscLinearSolver<T>>(comm);
77#endif
79
80#ifdef LIBMESH_TRILINOS_HAVE_AZTECOO
82 return std::make_unique<AztecLinearSolver<T>>(comm);
83#endif
84
85
86#ifdef LIBMESH_HAVE_EIGEN
87 case EIGEN_SOLVERS:
88 return std::make_unique<EigenSparseLinearSolver<T>>(comm);
89#endif
90
91 default:
92 libmesh_error_msg("ERROR: Unrecognized solver package: " << solver_package);
93 }
94
95 return std::unique_ptr<LinearSolver<T>>();
96}
97
98template <typename T>
101{
102 if (_preconditioner)
103 return _preconditioner->type();
104
105 return _preconditioner_type;
106}
107
108template <typename T>
109void
111{
112 if (_preconditioner)
113 _preconditioner->set_type(pct);
114 else
115 _preconditioner_type = pct;
116}
117
118template <typename T>
119void
121{
122 libmesh_error_msg_if(this->_is_initialized,
123 "Preconditioner must be attached before the solver is initialized!");
125 _preconditioner_type = SHELL_PRECOND;
126 _preconditioner = preconditioner;
127}
128
129template <typename T>
130void
132{
133 same_preconditioner = reuse_flag;
135
136template <typename T>
137void
138LinearSolver<T>::restrict_solve_to(const std::vector<unsigned int> * const dofs,
139 const SubsetSolveMode /*subset_solve_mode*/)
141 if (dofs != nullptr)
142 libmesh_not_implemented();
143}
144
145
146template <typename T>
147std::pair<unsigned int, Real> LinearSolver<T>::adjoint_solve (SparseMatrix<T> & mat,
148 NumericVector<T> & sol,
149 NumericVector<T> & rhs,
150 const std::optional<double> tol,
151 const std::optional<unsigned int> n_its)
152{
153 // Log how long the linear solve takes.
154 LOG_SCOPE("adjoint_solve()", "LinearSolver");
156 // Take the discrete adjoint
157 mat.close();
158 mat.get_transpose(mat);
159
160 // Call the solve function for the relevant linear algebra library and
161 // solve the transpose matrix
162 const std::pair<unsigned int, Real> totalrval = this->solve (mat, sol, rhs, tol, n_its);
163
164 // Now transpose back and restore the original matrix
165 // by taking the discrete adjoint
166 mat.get_transpose(mat);
167
168 return totalrval;
169}
170
171template <typename T>
173{
174 LinearConvergenceReason reason = this->get_converged_reason();
175 libMesh::out << "Linear solver convergence/divergence reason: " << Utility::enum_to_string(reason) << std::endl;
176}
177
178template <typename T>
180{
181 _solver_configuration = &solver_configuration;
182}
183
184template <typename T>
185double LinearSolver<T>::get_real_solver_setting (const std::string & setting_name,
186 const std::optional<double> & setting,
187 const std::optional<double> default_value)
188{
189 if (setting.has_value())
190 return setting.value();
191 else if (_solver_configuration)
192 {
193 if (const auto it = this->_solver_configuration->real_valued_data.find(setting_name);
194 it != this->_solver_configuration->real_valued_data.end())
195 return double(it->second);
196 }
197 else if (default_value.has_value())
198 return default_value.value();
199 else
200 libmesh_error_msg("Iteration configuration parameter to the linear solver should either be supplied through input arguments or a SolverConfiguration object!");
201
202 return 0.0;
203}
204
205template <typename T>
206int LinearSolver<T>::get_int_solver_setting (const std::string & setting_name,
207 const std::optional<int> & setting,
208 const std::optional<int> default_value)
209{
210 if (setting.has_value())
211 return setting.value();
212 else if (_solver_configuration)
213 {
214 if (const auto it = this->_solver_configuration->int_valued_data.find(setting_name);
215 it != this->_solver_configuration->int_valued_data.end())
216 return it->second;
217 }
218 else if (default_value.has_value())
219 return default_value.value();
220 else
221 libmesh_error_msg("Iteration configuration parameter to the linear solver should either be supplied through input arguments or a SolverConfiguration object!");
222
223 return 0.0;
224
225}
226
227//------------------------------------------------------------------
228// Explicit instantiations
229template class LIBMESH_EXPORT LinearSolver<Number>;
230
231
232
233} // namespace libMesh
This base class can be inherited from to provide interfaces to linear solvers from different packages...
virtual void restrict_solve_to(const std::vector< unsigned int > *const dofs, const SubsetSolveMode subset_solve_mode=SUBSET_ZERO)
After calling this method, all successive solves will be restricted to the given set of dofs,...
int get_int_solver_setting(const std::string &setting_name, const std::optional< int > &setting, const std::optional< int > default_value=std::nullopt)
Get solver settings based on optional parameters and the solver configuration object.
PreconditionerType preconditioner_type() const
static std::unique_ptr< LinearSolver< T > > build(const libMesh::Parallel::Communicator &comm_in, const SolverPackage solver_package=libMesh::default_solver_package())
Builds a LinearSolver using the linear solver package specified by solver_package.
double get_real_solver_setting(const std::string &setting_name, const std::optional< double > &setting, const std::optional< double > default_value=std::nullopt)
Get solver settings based on optional parameters and the solver configuration object.
virtual void print_converged_reason() const
Prints a useful message about why the latest linear solve con(di)verged.
void set_preconditioner_type(const PreconditionerType pct)
Sets the type of preconditioner to use.
LinearSolver(const libMesh::Parallel::Communicator &comm_in)
Constructor.
void set_solver_configuration(SolverConfiguration &solver_configuration)
Set the solver configuration object.
virtual void reuse_preconditioner(bool)
Set the same_preconditioner flag, which indicates if we reuse the same preconditioner for subsequent ...
void attach_preconditioner(Preconditioner< T > *preconditioner)
Attaches a Preconditioner object to be used.
virtual std::pair< unsigned int, Real > adjoint_solve(SparseMatrix< T > &, NumericVector< T > &, NumericVector< T > &, const std::optional< double > tol=std::nullopt, const std::optional< unsigned int > m_its=std::nullopt)
Function to solve the adjoint system.
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
An object whose state is distributed along a set of processors.
This class provides a uniform interface for preconditioners.
This class stores solver configuration data, e.g.
Generic sparse matrix.
virtual void close()=0
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
virtual void get_transpose(SparseMatrix< T > &dest) const =0
Copies the transpose of the matrix into dest, which may be *this.
std::string enum_to_string(const T e)
The libMesh namespace provides an interface to certain functionality in the library.
SubsetSolveMode
defines an enum for the question what happens to the dofs outside the given subset when a system is s...
void libmesh_ignore(const Args &...)
OStreamProxy out
SolverPackage
Defines an enum for various linear solver packages.
PreconditionerType
Defines an enum for preconditioner types.
LinearConvergenceReason
Linear solver convergence flags (taken from the PETSc flags).