libMesh
linear_solver.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 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 
38 namespace libMesh
39 {
40 
41 //------------------------------------------------------------------
42 // LinearSolver members
43 template <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 
57 template <typename T>
58 std::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
78 
79 
80 #ifdef LIBMESH_TRILINOS_HAVE_AZTECOO
81  case TRILINOS_SOLVERS:
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 
98 template <typename T>
101 {
102  if (_preconditioner)
103  return _preconditioner->type();
104 
105  return _preconditioner_type;
106 }
107 
108 template <typename T>
109 void
111 {
112  if (_preconditioner)
113  _preconditioner->set_type(pct);
114  else
115  _preconditioner_type = pct;
116 }
117 
118 template <typename T>
119 void
121 {
122  libmesh_error_msg_if(this->_is_initialized,
123  "Preconditioner must be attached before the solver is initialized!");
124 
125  _preconditioner_type = SHELL_PRECOND;
126  _preconditioner = preconditioner;
127 }
128 
129 template <typename T>
130 void
132 {
133  same_preconditioner = reuse_flag;
134 }
135 
136 template <typename T>
137 void
138 LinearSolver<T>::restrict_solve_to(const std::vector<unsigned int> * const dofs,
139  const SubsetSolveMode /*subset_solve_mode*/)
140 {
141  if (dofs != nullptr)
142  libmesh_not_implemented();
143 }
144 
145 
146 template <typename T>
147 std::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");
155 
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 
171 template <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 
178 template <typename T>
180 {
181  _solver_configuration = &solver_configuration;
182 }
183 
184 template <typename T>
185 double 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 
205 template <typename T>
206 int 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
229 template class LIBMESH_EXPORT LinearSolver<Number>;
230 
231 
232 
233 } // namespace libMesh
LinearConvergenceReason
Linear solver convergence flags (taken from the PETSc flags).
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
Definition: vector_fe_ex5.C:44
The libMesh namespace provides an interface to certain functionality in the library.
Generic sparse matrix.
Definition: vector_fe_ex5.C:46
This base class can be inherited from to provide interfaces to linear solvers from different packages...
This class provides a uniform interface for preconditioners.
void libmesh_ignore(const Args &...)
LinearSolver(const libMesh::Parallel::Communicator &comm_in)
Constructor.
Definition: linear_solver.C:44
bool _is_initialized
Flag that tells if init() has been called.
Definition: libmesh.C:257
This class stores solver configuration data, e.g.
An object whose state is distributed along a set of processors.
PreconditionerType
Defines an enum for preconditioner types.
std::string enum_to_string(const T e)
virtual void close()=0
Calls the SparseMatrix&#39;s internal assembly routines, ensuring that the values are consistent across p...
OStreamProxy out
virtual void get_transpose(SparseMatrix< T > &dest) const =0
Copies the transpose of the matrix into dest, which may be *this.
SolverPackage
Defines an enum for various linear solver packages.
SubsetSolveMode
defines an enum for the question what happens to the dofs outside the given subset when a system is s...