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