$extrastylesheet
petsc_nonlinear_solver.h
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 
00019 
00020 #ifndef LIBMESH_PETSC_NONLINEAR_SOLVER_H
00021 #define LIBMESH_PETSC_NONLINEAR_SOLVER_H
00022 
00023 #include "libmesh/libmesh_config.h"
00024 
00025 // Petsc include files.
00026 #ifdef LIBMESH_HAVE_PETSC
00027 
00028 // Local includes
00029 #include "libmesh/nonlinear_solver.h"
00030 #include "libmesh/petsc_macro.h"
00031 
00032 // PETSc includes
00033 EXTERN_C_FOR_PETSC_BEGIN
00034 # include <petscsnes.h>
00035 EXTERN_C_FOR_PETSC_END
00036 
00037 // C++ includes
00038 
00039 namespace libMesh
00040 {
00041 // Allow users access to these functions in case they want to reuse them.  Note that users shouldn't
00042 // need access to these most of the time as they are used internally by this object.
00043 extern "C"
00044 {
00045   PetscErrorCode __libmesh_petsc_snes_monitor (SNES, PetscInt its, PetscReal fnorm, void *);
00046   PetscErrorCode __libmesh_petsc_snes_residual (SNES, Vec x, Vec r, void *ctx);
00047 #if PETSC_RELEASE_LESS_THAN(3,5,0)
00048   PetscErrorCode __libmesh_petsc_snes_jacobian (SNES, Vec x, Mat *jac, Mat *pc, MatStructure *msflag, void *ctx);
00049 #else
00050   PetscErrorCode __libmesh_petsc_snes_jacobian (SNES, Vec x, Mat jac, Mat pc, void *ctx);
00051 #endif
00052 }
00053 
00062 template <typename T>
00063 class PetscNonlinearSolver : public NonlinearSolver<T>
00064 {
00065 public:
00069   typedef NonlinearImplicitSystem sys_type;
00070 
00074   explicit
00075   PetscNonlinearSolver (sys_type& system);
00076 
00080   ~PetscNonlinearSolver ();
00081 
00085   virtual void clear ();
00086 
00091   virtual void init (const char* name = NULL);
00092 
00096   SNES snes() { this->init(); return _snes; }
00097 
00102   virtual std::pair<unsigned int, Real> solve (SparseMatrix<T>&,    // System Jacobian Matrix
00103                                                NumericVector<T>&,   // Solution vector
00104                                                NumericVector<T>&,   // Residual vector
00105                                                const double,        // Stopping tolerance
00106                                                const unsigned int); // N. Iterations
00107 
00112   virtual void print_converged_reason();
00113 
00119   SNESConvergedReason get_converged_reason();
00120 
00124   virtual int get_total_linear_iterations();
00125 
00131   virtual unsigned get_current_nonlinear_iteration_number() const { return _current_nonlinear_iteration_number; }
00132 
00136   void set_residual_zero_out(bool state) { _zero_out_residual = state; }
00137 
00141   void set_jacobian_zero_out(bool state) { _zero_out_jacobian = state; }
00142 
00146   void use_default_monitor(bool state) { _default_monitor = state; }
00147 
00148 protected:
00152   SNES _snes;
00153 
00161   SNESConvergedReason _reason;
00162 
00166   PetscInt _n_linear_iterations;
00167 
00171   unsigned _current_nonlinear_iteration_number;
00172 
00176   bool _zero_out_residual;
00177 
00181   bool _zero_out_jacobian;
00182 
00186   bool _default_monitor;
00187 
00188 #if !PETSC_VERSION_LESS_THAN(3,3,0)
00189   void build_mat_null_space(NonlinearImplicitSystem::ComputeVectorSubspace* computeSubspaceObject,
00190                             void (*)(std::vector<NumericVector<Number>*>&, sys_type&),
00191                             MatNullSpace*);
00192 #endif
00193 private:
00194   friend PetscErrorCode __libmesh_petsc_snes_residual (SNES snes, Vec x, Vec r, void *ctx);
00195 #if PETSC_RELEASE_LESS_THAN(3,5,0)
00196   friend PetscErrorCode __libmesh_petsc_snes_jacobian (SNES snes, Vec x, Mat *jac, Mat *pc, MatStructure *msflag, void *ctx);
00197 #else
00198   friend PetscErrorCode __libmesh_petsc_snes_jacobian (SNES snes, Vec x, Mat jac, Mat pc, void *ctx);
00199 #endif
00200 };
00201 
00202 
00203 
00204 } // namespace libMesh
00205 
00206 
00207 #endif // #ifdef LIBMESH_HAVE_PETSC
00208 #endif // LIBMESH_PETSC_NONLINEAR_SOLVER_H