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