1 // The libMesh Finite Element Library. 2 // Copyright (C) 2002-2020 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 #ifndef LIBMESH_PETSC_SOLVER_EXCEPTION_H 19 #define LIBMESH_PETSC_SOLVER_EXCEPTION_H 20 21 #include "libmesh/libmesh_common.h" 22 23 #ifdef LIBMESH_HAVE_PETSC 24 25 #include "libmesh_exceptions.h" 26 #ifdef I 27 # define LIBMESH_SAW_I 28 #endif 29 #include <petscsys.h> 30 #ifndef LIBMESH_SAW_I 31 # undef I // Avoid complex.h contamination 32 #endif 33 34 namespace libMesh 35 { 36 37 // The SolverException class is only defined when exceptions are enabled. 38 #ifdef LIBMESH_ENABLE_EXCEPTIONS 39 40 /** 41 * A specialization of the SolverException class for PETSc. 42 */ 43 class PetscSolverException : public SolverException 44 { 45 public: PetscSolverException(int error_code_in)46 PetscSolverException(int error_code_in) : 47 SolverException(error_code_in) 48 { 49 const char * text; 50 char * specific; 51 // This is one scenario where we don't catch the error code 52 // returned by a PETSc function :) 53 PetscErrorMessage(error_code, &text, &specific); 54 55 // Usually the "specific" error message string is more useful than 56 // the generic text corresponding to the error_code, since many 57 // SETERRQ calls just use error_code == 1 58 if (specific) 59 what_message = std::string(specific); 60 else if (text) 61 what_message = std::string(text); 62 } 63 }; 64 65 66 67 // Macro which we call after every PETSc function that returns an error code. 68 #define LIBMESH_CHKERR(ierr) \ 69 do { \ 70 if (ierr != 0) { \ 71 throw PetscSolverException(ierr); \ 72 } } while (0) 73 74 #else 75 76 // If we don't have exceptions enabled, just fall back on calling 77 // PETSc's CHKERRABORT macro. 78 #define LIBMESH_CHKERR(ierr) CHKERRABORT(this->comm().get(), ierr); 79 80 // Let's also be backwards-compatible with the old macro name. 81 #define LIBMESH_CHKERRABORT(ierr) LIBMESH_CHKERR(ierr) 82 83 #endif 84 85 } // namespace libMesh 86 87 #endif // LIBMESH_HAVE_PETSC 88 #endif // LIBMESH_PETSC_SOLVER_EXCEPTION_H 89