petsc_linear_solver.h
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 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_LINEAR_SOLVER_H 00021 #define LIBMESH_PETSC_LINEAR_SOLVER_H 00022 00023 #include "libmesh/libmesh_config.h" 00024 00025 #ifdef LIBMESH_HAVE_PETSC 00026 00027 #include "libmesh/petsc_macro.h" 00028 00033 EXTERN_C_FOR_PETSC_BEGIN 00034 #if PETSC_VERSION_LESS_THAN(2,2,0) 00035 # include <petscsles.h> 00036 #else 00037 # include <petscksp.h> 00038 #endif 00039 EXTERN_C_FOR_PETSC_END 00040 00041 // Local includes 00042 #include "libmesh/linear_solver.h" 00043 00044 // C++ includes 00045 #include <cstddef> 00046 #include <vector> 00047 00048 //-------------------------------------------------------------------- 00049 // Functions with C linkage to pass to PETSc. PETSc will call these 00050 // methods as needed for preconditioning 00051 // 00052 // Since they must have C linkage they have no knowledge of a namespace. 00053 // Give them an obscure name to avoid namespace pollution. 00054 extern "C" 00055 { 00056 // Older versions of PETSc do not have the different int typedefs. 00057 // On 64-bit machines, PetscInt may actually be a long long int. 00058 // This change occurred in Petsc-2.2.1. 00059 #if PETSC_VERSION_LESS_THAN(2,2,1) 00060 typedef int PetscErrorCode; 00061 typedef int PetscInt; 00062 #endif 00063 00064 #if PETSC_VERSION_LESS_THAN(3,0,1) && PETSC_VERSION_RELEASE 00065 00069 PetscErrorCode __libmesh_petsc_preconditioner_setup (void * ctx); 00070 00075 PetscErrorCode __libmesh_petsc_preconditioner_apply(void *ctx, Vec x, Vec y); 00076 #else 00077 PetscErrorCode __libmesh_petsc_preconditioner_setup (PC); 00078 PetscErrorCode __libmesh_petsc_preconditioner_apply(PC, Vec x, Vec y); 00079 #endif 00080 } // end extern "C" 00081 00082 00083 namespace libMesh 00084 { 00085 00086 // forward declarations 00087 template <typename T> class PetscMatrix; 00088 00097 template <typename T> 00098 class PetscLinearSolver : public LinearSolver<T> 00099 { 00100 public: 00104 PetscLinearSolver (); 00105 00109 ~PetscLinearSolver (); 00110 00114 void clear (); 00115 00119 void init (); 00120 00124 void init (PetscMatrix<T>* matrix); 00125 00133 virtual void restrict_solve_to (const std::vector<unsigned int>* const dofs, 00134 const SubsetSolveMode subset_solve_mode=SUBSET_ZERO); 00135 00140 std::pair<unsigned int, Real> 00141 solve (SparseMatrix<T> &matrix_in, 00142 NumericVector<T> &solution_in, 00143 NumericVector<T> &rhs_in, 00144 const double tol, 00145 const unsigned int m_its) 00146 { 00147 return this->solve(matrix_in, matrix_in, solution_in, rhs_in, tol, m_its); 00148 } 00149 00150 00155 std::pair<unsigned int, Real> 00156 adjoint_solve (SparseMatrix<T> &matrix_in, 00157 NumericVector<T> &solution_in, 00158 NumericVector<T> &rhs_in, 00159 const double tol, 00160 const unsigned int m_its); 00161 00162 00178 std::pair<unsigned int, Real> 00179 solve (SparseMatrix<T> &matrix, 00180 SparseMatrix<T> &preconditioner, 00181 NumericVector<T> &solution, 00182 NumericVector<T> &rhs, 00183 const double tol, 00184 const unsigned int m_its); 00185 00189 std::pair<unsigned int, Real> 00190 solve (const ShellMatrix<T>& shell_matrix, 00191 NumericVector<T>& solution_in, 00192 NumericVector<T>& rhs_in, 00193 const double tol, 00194 const unsigned int m_its); 00195 00201 virtual std::pair<unsigned int, Real> 00202 solve (const ShellMatrix<T>& shell_matrix, 00203 const SparseMatrix<T>& precond_matrix, 00204 NumericVector<T>& solution_in, 00205 NumericVector<T>& rhs_in, 00206 const double tol, 00207 const unsigned int m_its); 00208 00214 PC pc() { this->init(); return _pc; } 00215 00221 KSP ksp() { this->init(); return _ksp; } 00222 00227 void get_residual_history(std::vector<double>& hist); 00228 00235 Real get_initial_residual(); 00236 00241 virtual void print_converged_reason(); 00242 00243 private: 00244 00249 void set_petsc_solver_type (); 00250 00254 static PetscErrorCode _petsc_shell_matrix_mult(Mat mat, Vec arg, Vec dest); 00255 00259 static PetscErrorCode _petsc_shell_matrix_mult_add(Mat mat, Vec arg, Vec add, Vec dest); 00260 00264 static PetscErrorCode _petsc_shell_matrix_get_diagonal(Mat mat, Vec dest); 00265 00266 // SLES removed from >= PETSc 2.2.0 00267 #if PETSC_VERSION_LESS_THAN(2,2,0) 00268 00272 SLES _sles; 00273 00274 #endif 00275 00279 PC _pc; 00280 00284 KSP _ksp; 00285 00290 IS _restrict_solve_to_is; 00291 00297 IS _restrict_solve_to_is_complement; 00298 00303 size_t _restrict_solve_to_is_local_size(void)const; 00304 00310 void _create_complement_is (const NumericVector<T> &vec_in); 00311 00316 SubsetSolveMode _subset_solve_mode; 00317 00318 }; 00319 00320 00321 /*----------------------- functions ----------------------------------*/ 00322 template <typename T> 00323 inline 00324 PetscLinearSolver<T>::PetscLinearSolver (): 00325 _restrict_solve_to_is(NULL), 00326 _restrict_solve_to_is_complement(NULL), 00327 _subset_solve_mode(SUBSET_ZERO) 00328 { 00329 if (libMesh::n_processors() == 1) 00330 this->_preconditioner_type = ILU_PRECOND; 00331 else 00332 this->_preconditioner_type = BLOCK_JACOBI_PRECOND; 00333 } 00334 00335 00336 00337 template <typename T> 00338 inline 00339 PetscLinearSolver<T>::~PetscLinearSolver () 00340 { 00341 this->clear (); 00342 } 00343 00344 00345 00346 template <typename T> 00347 inline size_t 00348 PetscLinearSolver<T>:: 00349 _restrict_solve_to_is_local_size(void)const 00350 { 00351 libmesh_assert(_restrict_solve_to_is); 00352 00353 PetscInt s; 00354 int ierr = ISGetLocalSize(_restrict_solve_to_is,&s); 00355 CHKERRABORT(libMesh::COMM_WORLD,ierr); 00356 00357 return static_cast<size_t>(s); 00358 } 00359 00360 00361 00362 template <typename T> 00363 void 00364 PetscLinearSolver<T>::_create_complement_is (const NumericVector<T> & 00365 #if PETSC_VERSION_LESS_THAN(3,0,0) 00366 // unnamed to avoid compiler "unused parameter" warning 00367 #else 00368 vec_in 00369 #endif 00370 ) 00371 { 00372 libmesh_assert(_restrict_solve_to_is); 00373 #if PETSC_VERSION_LESS_THAN(3,0,0) 00374 // No ISComplement in PETSc 2.3.3 00375 libmesh_not_implemented(); 00376 #else 00377 if(_restrict_solve_to_is_complement==NULL) 00378 { 00379 int ierr = ISComplement(_restrict_solve_to_is, 00380 vec_in.first_local_index(), 00381 vec_in.last_local_index(), 00382 &_restrict_solve_to_is_complement); 00383 CHKERRABORT(libMesh::COMM_WORLD,ierr); 00384 } 00385 #endif 00386 } 00387 00388 00389 00390 } // namespace libMesh 00391 00392 00393 #endif // #ifdef LIBMESH_HAVE_PETSC 00394 #endif // LIBMESH_PETSC_LINEAR_SOLVER_H
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:48 UTC
Hosted By: