LCOV - code coverage report
Current view: top level - include/solvers - petsc_nonlinear_solver.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 2 10 20.0 %
Date: 2025-08-19 19:27:09 Functions: 3 10 30.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      73             : /**
      74             :  * This class provides an interface to PETSc
      75             :  * iterative solvers that is compatible with the \p libMesh
      76             :  * \p NonlinearSolver<>
      77             :  *
      78             :  * \author Benjamin Kirk
      79             :  * \date 2002-2007
      80             :  */
      81             : template <typename T>
      82         210 : class PetscNonlinearSolver : public NonlinearSolver<T>
      83             : {
      84             : public:
      85             :   /**
      86             :    * The type of system
      87             :    */
      88             :   typedef NonlinearImplicitSystem sys_type;
      89             : 
      90             :   /**
      91             :    *  Constructor. Initializes Petsc data structures
      92             :    */
      93             :   explicit
      94             :   PetscNonlinearSolver (sys_type & system);
      95             : 
      96             :   /**
      97             :    * Destructor.
      98             :    */
      99             :   ~PetscNonlinearSolver ();
     100             : 
     101             :   /**
     102             :    * Release all memory and clear data structures.
     103             :    */
     104             :   virtual void clear () override;
     105             : 
     106             :   /**
     107             :    * Initialize data structures if not done so already.
     108             :    * May assign a name to the solver in some implementations
     109             :    */
     110             :   virtual void init (const char * name = nullptr) override;
     111             : 
     112             :   /**
     113             :    * \returns The raw PETSc snes context pointer. This method calls init() so in that vein, we have
     114             :    * an optional name prefix argument that if provided will be given to the SNES context
     115             :    */
     116             :   SNES snes(const char * name = nullptr);
     117             : 
     118             :   /**
     119             :    * Call the Petsc solver.  It calls the method below, using the
     120             :    * same matrix for the system and preconditioner matrices.
     121             :    */
     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             : 
     129             :   /**
     130             :    * Prints a useful message about why the latest nonlinear solve
     131             :    * con(di)verged.
     132             :    */
     133             :   virtual void print_converged_reason() override;
     134             : 
     135             :   /**
     136             :    * \returns The currently-available (or most recently obtained, if
     137             :    * the SNES object has been destroyed) convergence reason.
     138             :    *
     139             :    * Refer to PETSc docs for the meaning of different
     140             :    * SNESConvergedReasons.
     141             :    */
     142             :   SNESConvergedReason get_converged_reason();
     143             : 
     144             :   /**
     145             :    * Get the total number of linear iterations done in the last solve
     146             :    */
     147             :   virtual int get_total_linear_iterations() override;
     148             : 
     149             :   /**
     150             :    * \returns The current nonlinear iteration number if called
     151             :    * *during* the solve(), for example by the user-specified residual
     152             :    * or Jacobian function.
     153             :    */
     154           0 :   virtual unsigned get_current_nonlinear_iteration_number() const override
     155           0 :   { return _current_nonlinear_iteration_number; }
     156             : 
     157             :   /**
     158             :    * Set if the residual should be zeroed out in the callback
     159             :    */
     160           0 :   void set_residual_zero_out(bool state) { _zero_out_residual = state; }
     161             : 
     162             :   /**
     163             :    * Set if the jacobian should be zeroed out in the callback
     164             :    */
     165           0 :   void set_jacobian_zero_out(bool state) { _zero_out_jacobian = state; }
     166             : 
     167             :   /**
     168             :    * Set to true to use the libMesh's default monitor, set to false to use your own
     169             :    */
     170           0 :   void use_default_monitor(bool state) { _default_monitor = state; }
     171             : 
     172             :   /**
     173             :    * Set to true to let PETSc reuse the base vector
     174             :    */
     175           0 :   void set_snesmf_reuse_base(bool state) { _snesmf_reuse_base = state; }
     176             : 
     177             :   /**
     178             :    * @return Whether we are reusing the nonlinear function evaluation as the base for doing
     179             :    * matrix-free approximation of the Jacobian action
     180             :    */
     181        2398 :   bool snes_mf_reuse_base() const { return _snesmf_reuse_base; }
     182             : 
     183             :   /**
     184             :    * Set whether we are computing the base vector for matrix-free finite-differencing
     185             :    */
     186           0 :   void set_computing_base_vector(bool computing_base_vector) { _computing_base_vector = computing_base_vector; }
     187             : 
     188             :   /**
     189             :    * @return whether we are computing the base vector for matrix-free finite-differencing
     190             :    */
     191           0 :   bool computing_base_vector() const { return _computing_base_vector; }
     192             : 
     193             :   /**
     194             :    * Abstract base class to be used to implement a custom line-search algorithm
     195             :    */
     196             :   class ComputeLineSearchObject
     197             :   {
     198             :   public:
     199             :     virtual ~ComputeLineSearchObject () = default;
     200             : 
     201             :     virtual void linesearch (SNESLineSearch linesearch) = 0;
     202             :   };
     203             : 
     204             :   /**
     205             :    * A callable object that can be used to specify a custom line-search
     206             :    */
     207             :   std::unique_ptr<ComputeLineSearchObject> linesearch_object;
     208             : 
     209             :   /**
     210             :     * Setup the default monitor if required
     211             :     */
     212             :   void setup_default_monitor();
     213             : 
     214             :   /**
     215             :    * Getter for preconditioner reuse
     216             :    */
     217             :   virtual bool reuse_preconditioner() const override;
     218             : 
     219             :   /**
     220             :    *  Getter for the maximum iterations flag for preconditioner reuse
     221             :    */
     222             :   virtual unsigned int reuse_preconditioner_max_linear_its() const override;
     223             : 
     224             :   /**
     225             :    *  Immediately force a new preconditioner, even if reuse is set
     226             :    */
     227             :   virtual void force_new_preconditioner() override;
     228             : 
     229             : protected:
     230             : 
     231             :   /**
     232             :    * Nonlinear solver context
     233             :    */
     234             :   WrappedPetsc<SNES> _snes;
     235             : 
     236             :   /**
     237             :    * Store the reason for SNES convergence/divergence for use even after the _snes
     238             :    * has been cleared.
     239             :    *
     240             :    * \note \p print_converged_reason() will always \e try to get the
     241             :    * current reason with SNESGetConvergedReason(), but if the SNES
     242             :    * object has already been cleared, it will fall back on this stored
     243             :    * value.  This value is therefore necessarily \e not cleared by the
     244             :    * \p clear() function.
     245             :    */
     246             :   SNESConvergedReason _reason;
     247             : 
     248             :   /**
     249             :    * Stores the total number of linear iterations from the last solve.
     250             :    */
     251             :   PetscInt _n_linear_iterations;
     252             : 
     253             :   /**
     254             :    * Stores the current nonlinear iteration number
     255             :    */
     256             :   unsigned _current_nonlinear_iteration_number;
     257             : 
     258             :   /**
     259             :    * true to zero out residual before going into application level call-back, otherwise false
     260             :    */
     261             :   bool _zero_out_residual;
     262             : 
     263             :   /**
     264             :    * true to zero out jacobian before going into application level call-back, otherwise false
     265             :    */
     266             :   bool _zero_out_jacobian;
     267             : 
     268             :   /**
     269             :    * true if we want the default monitor to be set, false for no monitor (i.e. user code can use their own)
     270             :    */
     271             :   bool _default_monitor;
     272             : 
     273             :   /**
     274             :    * True, If we want the base vector to be used for differencing even if the function provided to SNESSetFunction()
     275             :    * is not the same as that provided to MatMFFDSetFunction().
     276             :    * https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/SNES/MatSNESMFSetReuseBase.html
     277             :    */
     278             :   bool _snesmf_reuse_base;
     279             : 
     280             :   void build_mat_null_space(NonlinearImplicitSystem::ComputeVectorSubspace * computeSubspaceObject,
     281             :                             void (*)(std::vector<NumericVector<Number> *> &, sys_type &),
     282             :                             MatNullSpace *);
     283             : 
     284             :   /**
     285             :    * Whether we are computing the base vector for matrix-free finite differencing
     286             :    */
     287             :   bool _computing_base_vector;
     288             : 
     289             :   /**
     290             :     * Whether we've triggered the preconditioner reuse
     291             :     */
     292             :   bool _setup_reuse;
     293             : 
     294             : #if defined(LIBMESH_ENABLE_AMR) && defined(LIBMESH_HAVE_METAPHYSICL)
     295             :   /**
     296             :    * Wrapper object for interacting with the "new" libMesh PETSc DM. The new libMesh PETSc DM
     297             :    * implementation is capable of geometric multigrid while the old implementation is not. The new
     298             :    * implementation can be activated from the command line with --use_petsc_dm
     299             :    */
     300             :   PetscDMWrapper _dm_wrapper;
     301             : #endif
     302             : 
     303             :   /// Wrapper for matrix-free finite-difference Jacobians
     304             :   PetscMFFDMatrix<Number> _mffd_jac;
     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

Generated by: LCOV version 1.14