libMesh
petsc_solver_exception.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2024 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/libmesh_exceptions.h"
26 
27 #ifdef I
28 # define LIBMESH_SAW_I
29 #endif
30 
31 #include "libmesh/ignore_warnings.h"
32 #include <petscsys.h>
33 #include "libmesh/restore_warnings.h"
34 
35 #ifndef LIBMESH_SAW_I
36 # undef I // Avoid complex.h contamination
37 #endif
38 
39 namespace libMesh
40 {
41 
42 // Forward declarations
43 namespace Parallel
44 {
45 class Communicator;
46 }
47 
48 // The SolverException class is only defined when exceptions are enabled.
49 #ifdef LIBMESH_ENABLE_EXCEPTIONS
50 
55 {
56 public:
57  PetscSolverException(int error_code_in) :
58  SolverException(error_code_in)
59  {
60  const char * text;
61  char * specific;
62  // This is one scenario where we don't catch the error code
63  // returned by a PETSc function :)
64  PetscErrorMessage(error_code, &text, &specific);
65 
66  // Usually the "specific" error message string is more useful than
67  // the generic text corresponding to the error_code, since many
68  // SETERRQ calls just use error_code == 1
69  if (specific)
70  what_message = std::string(specific);
71  else if (text)
72  what_message = std::string(text);
73  }
74 };
75 
76 
77 
78 // Macro which we call after every PETSc function that returns an error code.
79 #define LIBMESH_CHKERR(ierr) \
80  do { \
81  if (ierr != 0) { \
82  throw PetscSolverException(ierr); \
83  } } while (0)
84 
85 // Two-argument CHKERR macro that takes both a comm and an error
86 // code. When exceptions are enabled, the comm is not used for
87 // anything, so we libmesh_ignore() it. This macro is useful when you
88 // need to call LIBMESH_CHKERR but you're not in a ParallelObject.
89 #define LIBMESH_CHKERR2(comm, ierr) \
90  do { \
91  libmesh_ignore(comm); \
92  LIBMESH_CHKERR(ierr); \
93  } while (0)
94 
95 #else
96 
97 // If we don't have exceptions enabled, just fall back on calling
98 // PETSc's CHKERRABORT macro.
99 #define LIBMESH_CHKERR(ierr) CHKERRABORT(this->comm().get(), ierr);
100 
101 // Two argument version of the function above where you pass in the comm
102 // instead of relying on it being available from the "this" pointer.
103 #define LIBMESH_CHKERR2(comm, ierr) CHKERRABORT(comm.get(), ierr);
104 
105 // Let's also be backwards-compatible with the old macro name.
106 #define LIBMESH_CHKERRABORT(ierr) LIBMESH_CHKERR(ierr)
107 
108 #endif
109 
110 #define PETSC_BEGIN_END(Function) \
111  template<class ...Args> \
112  inline \
113  void Function ## BeginEnd(const Parallel::Communicator & comm, const Args&... args) \
114  { \
115  PetscErrorCode ierr = 0; \
116  ierr = Function ## Begin(args...); \
117  LIBMESH_CHKERR2(comm, ierr); \
118  ierr = Function ## End(args...); \
119  LIBMESH_CHKERR2(comm, ierr); \
120  }
121 
122 PETSC_BEGIN_END(VecScatter) // VecScatterBeginEnd
123 PETSC_BEGIN_END(MatAssembly) // MatAssemblyBeginEnd
124 PETSC_BEGIN_END(VecAssembly) // VecAssemblyBeginEnd
125 PETSC_BEGIN_END(VecGhostUpdate) // VecGhostUpdateBeginEnd
126 
127 } // namespace libMesh
128 
129 #endif // LIBMESH_HAVE_PETSC
130 #endif // LIBMESH_PETSC_SOLVER_EXCEPTION_H
int error_code
The error code generated by the solver.
The libMesh namespace provides an interface to certain functionality in the library.
std::string what_message
string which holds the message built in the constructor.
A class representing an exception during a solve.
A specialization of the SolverException class for PETSc.