$extrastylesheet
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