Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2026 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 :
19 :
20 : #ifndef LIBMESH_LIBMESH_EXCEPTIONS_H
21 : #define LIBMESH_LIBMESH_EXCEPTIONS_H
22 :
23 : #include "libmesh/libmesh_config.h"
24 :
25 : #include "libmesh/libmesh_abort.h"
26 :
27 : #include <stdexcept>
28 : #include <string>
29 : #include <sstream>
30 :
31 : namespace libMesh {
32 :
33 : /**
34 : * A terminate handler. libMesh sets this to handle uncaught
35 : * exceptions; it can also be called manually to cleanup, print
36 : * any diagnostics, do cleanup, and abort.
37 : *
38 : * If an uncaught exception is a TerminationException, as thrown by
39 : * libmesh_terminate(), the handler avoids any diagnostic output.
40 : *
41 : * If an uncaught exception is a std::exception, its message is
42 : * printed, followed by stack trace and performance log output.
43 : */
44 : void libmesh_terminate_handler();
45 :
46 : /**
47 : * Toggle hardware trap floating point exceptions
48 : */
49 : void enableFPE(bool on);
50 :
51 : /**
52 : * Toggle libMesh reporting of segmentation faults
53 : */
54 : void enableSEGV(bool on);
55 :
56 : /**
57 : * Toggle libMesh handling of SIGINT (Ctrl+C) interrupts
58 : */
59 : void enableSIGINT(bool on);
60 :
61 : /**
62 : * A class to represent the internal "this should never happen"
63 : * errors, to be thrown by "libmesh_error();"
64 : */
65 : class LogicError : public std::logic_error
66 : {
67 : public:
68 : LogicError() : std::logic_error( "Error in libMesh internal logic" ) {}
69 3655 : LogicError(const std::string & msg) : std::logic_error( msg ) {}
70 : };
71 :
72 :
73 : /**
74 : * A class to stub for features that should be in libMesh, but
75 : * haven't been written yet, to be thrown by
76 : * "libmesh_not_implemented();"
77 : */
78 : class NotImplemented : public std::logic_error
79 : {
80 : public:
81 0 : NotImplemented(std::string msg="") : std::logic_error( "Error: feature not implemented!\n" + msg ) {}
82 : };
83 :
84 :
85 : /**
86 : * A class representing a failed attempt by the library to open a
87 : * file (or construct an fstream, etc), to be thrown by
88 : * "libmesh_file_error(filename);" For ease of debugging, "filename"
89 : * should include any (absolute or relative or implicit) pathname
90 : * that was part of the failed open.
91 : */
92 : class FileError : public std::runtime_error
93 : {
94 : public:
95 0 : FileError(const std::string & filename, const std::string msg="") :
96 0 : std::runtime_error("Error with file `" + filename + "'\n" + std::move(msg)) {}
97 : };
98 :
99 :
100 : /**
101 : * A class representing the detection of an unexpected degeneracy,
102 : * e.g. a negative-determinant Jacobian in a map expected to be
103 : * positive, or a non-trivial kernel in a map expected to be a
104 : * bijection (such as a singular matrix).
105 : *
106 : * libMesh::FEMap throws this if it encounters a point xi in an
107 : * element's "master space" at which the mapping to physical space has
108 : * a too-small (negative, or zero, or nearly zero) Jacobian
109 : * determinant, where "too-small" is determined by a particular
110 : * library method's assigned tolerance.
111 : *
112 : * libMesh::DenseMatrix throws this if it is asked to solve a system
113 : * with a singular matrix and a method (such as lu_solve()) that
114 : * cannot handle singularities.
115 : */
116 : class DegenerateMap : public std::runtime_error
117 : {
118 : public:
119 0 : DegenerateMap(std::string msg="") :
120 0 : std::runtime_error( "Degenerate map, e.g. negative Jacobian or singular matrix.\n" + msg ) {}
121 : };
122 :
123 :
124 : /**
125 : * A class representing a solver's failure to converge, to be thrown
126 : * by "libmesh_convergence_failure();" This should be a last
127 : * resort; more often, a solve which has failed should be
128 : * reattempted after switching to a smaller timestep, adding
129 : * underrelaxation, taking a smaller continuation step, etc.
130 : */
131 : class ConvergenceFailure : public std::runtime_error
132 : {
133 : public:
134 550658 : ConvergenceFailure(const std::string & err_msg="Unrecoverable failure to converge") : std::runtime_error( err_msg ) {}
135 : };
136 :
137 :
138 : /**
139 : * A class representing that a dynamic cast failed to produce expected output.
140 : */
141 : class DynamicCastFailure: public std::runtime_error
142 : {
143 : public:
144 : DynamicCastFailure() : std::runtime_error( "Failed dynamic cast!" ) {}
145 : };
146 :
147 : /**
148 : * A class representing a floating point exception.
149 : */
150 : class FloatingPointException: public std::runtime_error
151 : {
152 : public:
153 : FloatingPointException() : std::runtime_error( "libmesh FPE!" ) {}
154 : };
155 :
156 : /**
157 : * A class representing an exception during a solve.
158 : */
159 : class SolverException: public std::exception
160 : {
161 : public:
162 0 : SolverException(int error_code_in) :
163 : std::exception(),
164 0 : error_code(error_code_in)
165 : {
166 0 : std::ostringstream oss;
167 0 : oss << "Error code " << error_code << " during solve." << std::endl;
168 0 : what_message = oss.str();
169 0 : }
170 :
171 : /**
172 : * Virtual destructor, gotta have one of those.
173 : */
174 0 : virtual ~SolverException() = default;
175 :
176 : /**
177 : * Override the what() function to provide a generic error message.
178 : */
179 0 : virtual const char * what() const noexcept override
180 : {
181 : // std::string::c_str() is noexcept in C++11, so it's safe to call
182 : // in what() because it can't throw.
183 0 : return what_message.c_str();
184 : }
185 :
186 : /**
187 : * The error code generated by the solver.
188 : */
189 : int error_code;
190 :
191 : /**
192 : * string which holds the message built in the constructor.
193 : */
194 : std::string what_message;
195 : };
196 :
197 : /**
198 : * A class representing an exception used only to send a program to
199 : * the terminate handler for abort after cleanup, while bypassing the
200 : * usual debugging output (performance logs, stack traces,
201 : * "terminating" messages) that the handler does to ease debugging of
202 : * uncaught error exceptions.
203 : *
204 : * We don't even inherit from std::exception here, to avoid being
205 : * caught as that type.
206 : */
207 : class TerminationException
208 : {
209 : public:
210 0 : TerminationException() {}
211 :
212 : const char * what() const noexcept { return "libMesh termination requested"; }
213 : };
214 :
215 : }
216 :
217 : #ifdef LIBMESH_ENABLE_EXCEPTIONS
218 : #define libmesh_noexcept noexcept
219 :
220 : #define LIBMESH_THROW(e) do { throw e; } while (0)
221 : #define libmesh_rethrow throw
222 : #define libmesh_try try
223 : #define libmesh_catch(e) catch(e)
224 :
225 : #else
226 :
227 : #define LIBMESH_THROW(e) do { libMesh::err << e.what(); libMesh::libmesh_abort(); } while (0)
228 : #define libmesh_rethrow
229 : #define libmesh_try
230 : #define libmesh_catch(e) if (0)
231 :
232 : #endif // LIBMESH_ENABLE_EXCEPTIONS
233 :
234 : #endif // LIBMESH_LIBMESH_EXCEPTIONS_H
|