libMesh
petsc_nonlinear_solver.h
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 #ifndef LIBMESH_PETSC_NONLINEAR_SOLVER_H
21 #define LIBMESH_PETSC_NONLINEAR_SOLVER_H
22 
23 #include "libmesh/libmesh_config.h"
24 
25 // Petsc include files.
26 #ifdef LIBMESH_HAVE_PETSC
27 
28 // Local includes
29 #include "libmesh/nonlinear_solver.h"
30 #include "libmesh/petsc_macro.h"
31 #include "libmesh/wrapped_petsc.h"
32 #include "libmesh/petsc_dm_wrapper.h"
33 #include "libmesh/petsc_mffd_matrix.h"
34 
35 // PETSc includes
36 #ifdef I
37 # define LIBMESH_SAW_I
38 #endif
39 #include <petscsnes.h>
40 #ifndef LIBMESH_SAW_I
41 # undef I // Avoid complex.h contamination
42 #endif
43 
44 namespace libMesh
45 {
46 class ResidualContext;
47 
48 // Allow users access to these functions in case they want to reuse them. Users shouldn't
49 // need access to these most of the time as they are used internally by this object.
50 extern "C"
51 {
52  PetscErrorCode libmesh_petsc_recalculate_monitor(SNES snes, PetscInt it, PetscReal norm, void* mctx);
53  PetscErrorCode libmesh_petsc_snes_monitor (SNES, PetscInt its, PetscReal fnorm, void *);
54  PetscErrorCode libmesh_petsc_snes_residual (SNES, Vec x, Vec r, void * ctx);
55  PetscErrorCode libmesh_petsc_snes_fd_residual (SNES, Vec x, Vec r, void * ctx);
56  PetscErrorCode libmesh_petsc_snes_mffd_residual (SNES snes, Vec x, Vec r, void * ctx);
57  PetscErrorCode libmesh_petsc_snes_mffd_interface (void * ctx, Vec x, Vec r);
58  PetscErrorCode libmesh_petsc_snes_jacobian (SNES, Vec x, Mat jac, Mat pc, void * ctx);
59  PetscErrorCode libmesh_petsc_snes_precheck(SNESLineSearch, Vec X, Vec Y, PetscBool * changed, void * context);
60  PetscErrorCode libmesh_petsc_snes_postcheck(SNESLineSearch, Vec x, Vec y, Vec w, PetscBool * changed_y, PetscBool * changed_w, void * context);
61  PetscErrorCode libmesh_petsc_linesearch_shellfunc(SNESLineSearch linesearch, void * ctx);
62 
63 #ifdef LIBMESH_ENABLE_DEPRECATED
64  PetscErrorCode __libmesh_petsc_snes_monitor (SNES, PetscInt its, PetscReal fnorm, void *);
65  PetscErrorCode __libmesh_petsc_snes_residual (SNES, Vec x, Vec r, void * ctx);
66  PetscErrorCode __libmesh_petsc_snes_fd_residual (SNES, Vec x, Vec r, void * ctx);
67  PetscErrorCode __libmesh_petsc_snes_mffd_interface (void * ctx, Vec x, Vec r);
68  PetscErrorCode __libmesh_petsc_snes_jacobian (SNES, Vec x, Mat jac, Mat pc, void * ctx);
69  PetscErrorCode __libmesh_petsc_snes_postcheck(SNESLineSearch, Vec x, Vec y, Vec w, PetscBool * changed_y, PetscBool * changed_w, void * context);
70 #endif
71 }
72 
81 template <typename T>
83 {
84 public:
89 
93  explicit
95 
100 
104  virtual void clear () override;
105 
110  virtual void init (const char * name = nullptr) override;
111 
116  SNES snes(const char * name = nullptr);
117 
122  virtual std::pair<unsigned int, Real>
123  solve (SparseMatrix<T> &, // System Jacobian Matrix
124  NumericVector<T> &, // Solution vector
125  NumericVector<T> &, // Residual vector
126  const double, // Stopping tolerance
127  const unsigned int) override; // N. Iterations
128 
133  virtual void print_converged_reason() override;
134 
142  SNESConvergedReason get_converged_reason();
143 
147  virtual int get_total_linear_iterations() override;
148 
154  virtual unsigned get_current_nonlinear_iteration_number() const override
156 
160  void set_residual_zero_out(bool state) { _zero_out_residual = state; }
161 
165  void set_jacobian_zero_out(bool state) { _zero_out_jacobian = state; }
166 
170  void use_default_monitor(bool state) { _default_monitor = state; }
171 
175  void set_snesmf_reuse_base(bool state) { _snesmf_reuse_base = state; }
176 
181  bool snes_mf_reuse_base() const { return _snesmf_reuse_base; }
182 
187 
192 
197  {
198  public:
199  virtual ~ComputeLineSearchObject () = default;
200 
201  virtual void linesearch (SNESLineSearch linesearch) = 0;
202  };
203 
207  std::unique_ptr<ComputeLineSearchObject> linesearch_object;
208 
212  void setup_default_monitor();
213 
217  virtual bool reuse_preconditioner() const override;
218 
222  virtual unsigned int reuse_preconditioner_max_linear_its() const override;
223 
227  virtual void force_new_preconditioner() override;
228 
229 protected:
230 
235 
246  SNESConvergedReason _reason;
247 
252 
257 
262 
267 
272 
279 
281  void (*)(std::vector<NumericVector<Number> *> &, sys_type &),
282  MatNullSpace *);
283 
288 
293 
294 #if defined(LIBMESH_ENABLE_AMR) && defined(LIBMESH_HAVE_METAPHYSICL)
295 
301 #endif
302 
305 
306 private:
307  friend ResidualContext libmesh_petsc_snes_residual_helper (SNES snes, Vec x, void * ctx);
308  friend PetscErrorCode libmesh_petsc_snes_residual (SNES snes, Vec x, Vec r, void * ctx);
309  friend PetscErrorCode libmesh_petsc_snes_fd_residual (SNES snes, Vec x, Vec r, void * ctx);
310  friend PetscErrorCode libmesh_petsc_snes_mffd_residual (SNES snes, Vec x, Vec r, void * ctx);
311  friend PetscErrorCode libmesh_petsc_snes_jacobian (SNES snes, Vec x, Mat jac, Mat pc, void * ctx);
312  friend PetscErrorCode libmesh_petsc_snes_precheck (SNESLineSearch,
313  Vec X,
314  Vec Y,
315  PetscBool * changed,
316  void * context);
317 };
318 
319 } // namespace libMesh
320 
321 
322 #endif // #ifdef LIBMESH_HAVE_PETSC
323 #endif // LIBMESH_PETSC_NONLINEAR_SOLVER_H
unsigned _current_nonlinear_iteration_number
Stores the current nonlinear iteration number.
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
SNES snes(const char *name=nullptr)
friend PetscErrorCode libmesh_petsc_snes_residual(SNES snes, Vec x, Vec r, void *ctx)
PetscErrorCode __libmesh_petsc_snes_jacobian(SNES, Vec x, Mat jac, Mat pc, void *ctx)
virtual unsigned int reuse_preconditioner_max_linear_its() const override
Getter for the maximum iterations flag for preconditioner reuse.
PetscErrorCode libmesh_petsc_snes_fd_residual(SNES, Vec x, Vec r, void *ctx)
PetscNonlinearSolver(sys_type &system)
Constructor.
void use_default_monitor(bool state)
Set to true to use the libMesh&#39;s default monitor, set to false to use your own.
WrappedPetsc< SNES > _snes
Nonlinear solver context.
PetscErrorCode __libmesh_petsc_snes_monitor(SNES, PetscInt its, PetscReal fnorm, void *)
friend PetscErrorCode libmesh_petsc_snes_jacobian(SNES snes, Vec x, Mat jac, Mat pc, void *ctx)
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
Definition: vector_fe_ex5.C:44
This base class can be inherited from to provide interfaces to nonlinear solvers from different packa...
virtual void clear() override
Release all memory and clear data structures.
PetscErrorCode libmesh_petsc_snes_postcheck(SNESLineSearch, Vec x, Vec y, Vec w, PetscBool *changed_y, PetscBool *changed_w, void *context)
PetscErrorCode __libmesh_petsc_snes_residual(SNES, Vec x, Vec r, void *ctx)
virtual int get_total_linear_iterations() override
Get the total number of linear iterations done in the last solve.
bool _zero_out_residual
true to zero out residual before going into application level call-back, otherwise false ...
The libMesh namespace provides an interface to certain functionality in the library.
This class defines a wrapper around the PETSc DM infrastructure.
PetscErrorCode libmesh_petsc_snes_monitor(SNES, PetscInt its, PetscReal fnorm, void *)
PetscErrorCode __libmesh_petsc_snes_mffd_interface(void *ctx, Vec x, Vec r)
This class provides an interface to PETSc iterative solvers that is compatible with the libMesh Nonli...
bool _setup_reuse
Whether we&#39;ve triggered the preconditioner reuse.
~PetscNonlinearSolver()
Destructor.
Generic sparse matrix.
Definition: vector_fe_ex5.C:46
PetscErrorCode libmesh_petsc_snes_mffd_residual(SNES snes, Vec x, Vec r, void *ctx)
const sys_type & system() const
friend PetscErrorCode libmesh_petsc_snes_fd_residual(SNES snes, Vec x, Vec r, void *ctx)
bool _zero_out_jacobian
true to zero out jacobian before going into application level call-back, otherwise false ...
PetscInt _n_linear_iterations
Stores the total number of linear iterations from the last solve.
friend PetscErrorCode libmesh_petsc_snes_mffd_residual(SNES snes, Vec x, Vec r, void *ctx)
friend ResidualContext libmesh_petsc_snes_residual_helper(SNES snes, Vec x, void *ctx)
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
PetscErrorCode __libmesh_petsc_snes_fd_residual(SNES, Vec x, Vec r, void *ctx)
void setup_default_monitor()
Setup the default monitor if required.
auto norm(const T &a) -> decltype(std::abs(a))
Definition: tensor_tools.h:74
virtual unsigned get_current_nonlinear_iteration_number() const override
void set_residual_zero_out(bool state)
Set if the residual should be zeroed out in the callback.
SNESConvergedReason _reason
Store the reason for SNES convergence/divergence for use even after the _snes has been cleared...
void set_jacobian_zero_out(bool state)
Set if the jacobian should be zeroed out in the callback.
PetscDMWrapper _dm_wrapper
Wrapper object for interacting with the "new" libMesh PETSc DM.
PetscErrorCode libmesh_petsc_snes_mffd_interface(void *ctx, Vec x, Vec r)
PetscMFFDMatrix< Number > _mffd_jac
Wrapper for matrix-free finite-difference Jacobians.
virtual void linesearch(SNESLineSearch linesearch)=0
SNESConvergedReason get_converged_reason()
PetscErrorCode libmesh_petsc_linesearch_shellfunc(SNESLineSearch linesearch, void *ctx)
Abstract base class to be used to implement a custom line-search algorithm.
std::unique_ptr< ComputeLineSearchObject > linesearch_object
A callable object that can be used to specify a custom line-search.
virtual void force_new_preconditioner() override
Immediately force a new preconditioner, even if reuse is set.
PetscErrorCode libmesh_petsc_snes_jacobian(SNES, Vec x, Mat jac, Mat pc, void *ctx)
virtual void print_converged_reason() override
Prints a useful message about why the latest nonlinear solve con(di)verged.
PetscErrorCode libmesh_petsc_snes_precheck(SNESLineSearch, Vec X, Vec Y, PetscBool *changed, void *context)
void set_snesmf_reuse_base(bool state)
Set to true to let PETSc reuse the base vector.
void build_mat_null_space(NonlinearImplicitSystem::ComputeVectorSubspace *computeSubspaceObject, void(*)(std::vector< NumericVector< Number > *> &, sys_type &), MatNullSpace *)
bool _default_monitor
true if we want the default monitor to be set, false for no monitor (i.e.
virtual void init(const char *name=nullptr) override
Initialize data structures if not done so already.
friend PetscErrorCode libmesh_petsc_snes_precheck(SNESLineSearch, Vec X, Vec Y, PetscBool *changed, void *context)
virtual std::pair< unsigned int, Real > solve(SparseMatrix< T > &, NumericVector< T > &, NumericVector< T > &, const double, const unsigned int) override
Call the Petsc solver.
PetscErrorCode __libmesh_petsc_snes_postcheck(SNESLineSearch, Vec x, Vec y, Vec w, PetscBool *changed_y, PetscBool *changed_w, void *context)
virtual bool reuse_preconditioner() const override
Getter for preconditioner reuse.
void * ctx
bool _computing_base_vector
Whether we are computing the base vector for matrix-free finite differencing.
void set_computing_base_vector(bool computing_base_vector)
Set whether we are computing the base vector for matrix-free finite-differencing. ...
NonlinearImplicitSystem sys_type
The type of system.
PetscErrorCode libmesh_petsc_snes_residual(SNES, Vec x, Vec r, void *ctx)
bool _snesmf_reuse_base
True, If we want the base vector to be used for differencing even if the function provided to SNESSet...
PetscErrorCode libmesh_petsc_recalculate_monitor(SNES snes, PetscInt it, PetscReal norm, void *mctx)
Callable abstract base class to be used as a callback to provide the solver with a basis for the syst...