deal.II version GIT relicensing-2289-g1e5549a87a 2024-12-21 21:30:00+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
exceptions.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 1998 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_exceptions_h
16#define dealii_exceptions_h
17
18#include <deal.II/base/config.h>
19
21#include <Kokkos_Macros.hpp>
22#if KOKKOS_VERSION >= 40200
23# include <Kokkos_Abort.hpp>
24#else
25# include <Kokkos_Core.hpp>
26#endif
28
29#include <exception>
30#include <ostream>
31#include <string>
32#include <type_traits>
33
35
36
50class ExceptionBase : public std::exception
51{
52public:
57
62
66 virtual ~ExceptionBase() noexcept override = default;
67
73 operator=(const ExceptionBase &) = delete;
74
80 void
81 set_fields(const char *file,
82 const int line,
83 const char *function,
84 const char *cond,
85 const char *exc_name);
86
87
91 virtual const char *
92 what() const noexcept override;
93
97 const char *
98 get_exc_name() const;
99
103 void
104 print_exc_data(std::ostream &out) const;
105
110 virtual void
111 print_info(std::ostream &out) const;
112
117 void
118 print_stack_trace(std::ostream &out) const;
119
120protected:
124 const char *file;
125
129 unsigned int line;
130
134 const char *function;
135
139 const char *cond;
140
144 const char *exc;
145
151
152#ifdef DEAL_II_HAVE_GLIBC_STACKTRACE
156 void *raw_stacktrace[25];
157#endif
158
159private:
163 void
164 generate_message() const;
165
170 mutable std::string what_str;
171};
172
173#ifndef DOXYGEN
174
191# define DeclException0(Exception0) \
192 class Exception0 : public ::ExceptionBase \
193 {}
194
195
215# define DeclExceptionMsg(Exception, defaulttext) \
216 class Exception : public ::ExceptionBase \
217 { \
218 public: \
219 Exception(const std::string &msg = defaulttext) \
220 : arg(msg) \
221 {} \
222 virtual ~Exception() noexcept \
223 {} \
224 virtual void \
225 print_info(std::ostream &out) const override \
226 { \
227 out << " " << arg << std::endl; \
228 } \
229 \
230 private: \
231 const std::string arg; \
232 }
233
251# define DeclException1(Exception1, type1, outsequence) \
252 class Exception1 : public ::ExceptionBase \
253 { \
254 public: \
255 Exception1(type1 const &a1) \
256 : arg1(a1) \
257 {} \
258 virtual ~Exception1() noexcept \
259 {} \
260 virtual void \
261 print_info(std::ostream &out) const override \
262 { \
263 out << " " outsequence << std::endl; \
264 } \
265 \
266 private: \
267 type1 const arg1; \
268 }
269
270
288# define DeclException2(Exception2, type1, type2, outsequence) \
289 class Exception2 : public ::ExceptionBase \
290 { \
291 public: \
292 Exception2(type1 const &a1, type2 const &a2) \
293 : arg1(a1) \
294 , arg2(a2) \
295 {} \
296 virtual ~Exception2() noexcept \
297 {} \
298 virtual void \
299 print_info(std::ostream &out) const override \
300 { \
301 out << " " outsequence << std::endl; \
302 } \
303 \
304 private: \
305 type1 const arg1; \
306 type2 const arg2; \
307 }
308
309
327# define DeclException3(Exception3, type1, type2, type3, outsequence) \
328 class Exception3 : public ::ExceptionBase \
329 { \
330 public: \
331 Exception3(type1 const &a1, type2 const &a2, type3 const &a3) \
332 : arg1(a1) \
333 , arg2(a2) \
334 , arg3(a3) \
335 {} \
336 virtual ~Exception3() noexcept \
337 {} \
338 virtual void \
339 print_info(std::ostream &out) const override \
340 { \
341 out << " " outsequence << std::endl; \
342 } \
343 \
344 private: \
345 type1 const arg1; \
346 type2 const arg2; \
347 type3 const arg3; \
348 }
349
350
368# define DeclException4(Exception4, type1, type2, type3, type4, outsequence) \
369 class Exception4 : public ::ExceptionBase \
370 { \
371 public: \
372 Exception4(type1 const &a1, \
373 type2 const &a2, \
374 type3 const &a3, \
375 type4 const &a4) \
376 : arg1(a1) \
377 , arg2(a2) \
378 , arg3(a3) \
379 , arg4(a4) \
380 {} \
381 virtual ~Exception4() noexcept \
382 {} \
383 virtual void \
384 print_info(std::ostream &out) const override \
385 { \
386 out << " " outsequence << std::endl; \
387 } \
388 \
389 private: \
390 type1 const arg1; \
391 type2 const arg2; \
392 type3 const arg3; \
393 type4 const arg4; \
394 }
395
396
414# define DeclException5( \
415 Exception5, type1, type2, type3, type4, type5, outsequence) \
416 class Exception5 : public ::ExceptionBase \
417 { \
418 public: \
419 Exception5(type1 const &a1, \
420 type2 const &a2, \
421 type3 const &a3, \
422 type4 const &a4, \
423 type5 const &a5) \
424 : arg1(a1) \
425 , arg2(a2) \
426 , arg3(a3) \
427 , arg4(a4) \
428 , arg5(a5) \
429 {} \
430 virtual ~Exception5() noexcept \
431 {} \
432 virtual void \
433 print_info(std::ostream &out) const override \
434 { \
435 out << " " outsequence << std::endl; \
436 } \
437 \
438 private: \
439 type1 const arg1; \
440 type2 const arg2; \
441 type3 const arg3; \
442 type4 const arg4; \
443 type5 const arg5; \
444 }
445
446#else /*ifndef DOXYGEN*/
447
448// Dummy definitions for doxygen:
449
466# define DeclException0(Exception0) \
467 \
468 static ::ExceptionBase &Exception0()
469
489# define DeclExceptionMsg(Exception, defaulttext) \
490 \
491 \
492 static ::ExceptionBase &Exception()
493
511# define DeclException1(Exception1, type1, outsequence) \
512 \
513 \
514 static ::ExceptionBase &Exception1(type1 arg1)
515
516
534# define DeclException2(Exception2, type1, type2, outsequence) \
535 \
536 \
537 static ::ExceptionBase &Exception2(type1 arg1, type2 arg2)
538
539
557# define DeclException3(Exception3, type1, type2, type3, outsequence) \
558 \
559 \
560 static ::ExceptionBase &Exception3(type1 arg1, type2 arg2, type3 arg3)
561
562
580# define DeclException4(Exception4, type1, type2, type3, type4, outsequence) \
581 \
582 \
583 static ::ExceptionBase &Exception4(type1 arg1, \
584 type2 arg2, \
585 type3 arg3, \
586 type4 arg4)
587
588
606# define DeclException5( \
607 Exception5, type1, type2, type3, type4, type5, outsequence) \
608 \
609 \
610 static ::ExceptionBase &Exception5( \
611 type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)
612
613#endif /*ifndef DOXYGEN*/
614
615
628{
638 "A piece of code is attempting a division by zero. This is "
639 "likely going to lead to results that make no sense.");
640
653 std::complex<double>,
654 << "In a significant number of places, deal.II checks that some intermediate "
655 << "value is a finite number (as opposed to plus or minus infinity, or "
656 << "NaN/Not a Number). In the current function, we encountered a number "
657 << "that is not finite (its value is " << arg1 << " and therefore "
658 << "violates the current assertion).\n\n"
659 << "This may be due to the fact that some operation in this function "
660 << "created such a value, or because one of the arguments you passed "
661 << "to the function already had this value from some previous "
662 << "operation. In the latter case, this function only triggered the "
663 << "error but may not actually be responsible for the computation of "
664 << "the number that is not finite.\n\n"
665 << "There are two common cases where this situation happens. First, your "
666 << "code (or something in deal.II) divides by zero in a place where this "
667 << "should not happen. Or, you are trying to solve a linear system "
668 << "with an unsuitable solver (such as an indefinite or non-symmetric "
669 << "linear system using a Conjugate Gradient solver); such attempts "
670 << "oftentimes yield an operation somewhere that tries to divide "
671 << "by zero or take the square root of a negative value.\n\n"
672 << "In any case, when trying to find the source of the error, "
673 << "recall that the location where you are getting this error is "
674 << "simply the first place in the program where there is a check "
675 << "that a number (e.g., an element of a solution vector) is in fact "
676 << "finite, but that the actual error that computed the number "
677 << "may have happened far earlier. To find this location, you "
678 << "may want to add checks for finiteness in places of your "
679 << "program visited before the place where this error is produced. "
680 << "One way to check for finiteness is to use the 'AssertIsFinite' "
681 << "macro.");
682
687 std::size_t,
688 "Your program tried to allocate some memory but this "
689 "allocation failed. Typically, this either means that "
690 "you simply do not have enough memory in your system, "
691 "or that you are (erroneously) trying to allocate "
692 "a chunk of memory that is simply beyond all reasonable "
693 "size, for example because the size of the object has "
694 "been computed incorrectly."
695 "\n\n"
696 "In the current case, the request was for "
697 << arg1 << " bytes.");
698
704 int,
705 << "Destroying memory handler while " << arg1
706 << " objects are still allocated.");
707
712 "An input/output error has occurred. There are a number of "
713 "reasons why this may be happening, both for reading and "
714 "writing operations."
715 "\n\n"
716 "If this happens during an operation that tries to read "
717 "data: First, you may be "
718 "trying to read from a file that doesn't exist or that is "
719 "not readable given its file permissions. Second, deal.II "
720 "uses this error at times if it tries to "
721 "read information from a file but where the information "
722 "in the file does not correspond to the expected format. "
723 "An example would be a truncated file, or a mesh file "
724 "that contains not only sections that describe the "
725 "vertices and cells, but also sections for additional "
726 "data that deal.II does not understand."
727 "\n\n"
728 "If this happens during an operation that tries to write "
729 "data: you may be trying to write to a file to which file "
730 "or directory permissions do not allow you to write. A "
731 "typical example is where you specify an output file in "
732 "a directory that does not exist.");
733
741 std::string,
742 << "Could not open file " << arg1
743 << "."
744 "\n\n"
745 "If this happens during an operation that tries to read "
746 "data: you may be "
747 "trying to read from a file that doesn't exist or that is "
748 "not readable given its file permissions."
749 "\n\n"
750 "If this happens during an operation that tries to write "
751 "data: you may be trying to write to a file to which file "
752 "or directory permissions do not allow you to write. A "
753 "typical example is where you specify an output file in "
754 "a directory that does not exist.");
755
765 "You are trying to use functionality in deal.II that is "
766 "currently not implemented. In many cases, this indicates "
767 "that there simply didn't appear much of a need for it, or "
768 "that the author of the original code did not have the "
769 "time to implement a particular case. If you hit this "
770 "exception, it is therefore worth the time to look into "
771 "the code to find out whether you may be able to "
772 "implement the missing functionality. If you do, please "
773 "consider providing a patch to the deal.II development "
774 "sources (see the deal.II website on how to contribute).");
775
797 "This exception -- which is used in many places in the "
798 "library -- usually indicates that some condition which "
799 "the author of the code thought must be satisfied at a "
800 "certain point in an algorithm, is not fulfilled. An "
801 "example would be that the first part of an algorithm "
802 "sorts elements of an array in ascending order, and "
803 "a second part of the algorithm later encounters an "
804 "element that is not larger than the previous one."
805 "\n\n"
806 "There is usually not very much you can do if you "
807 "encounter such an exception since it indicates an error "
808 "in deal.II, not in your own program. Try to come up with "
809 "the smallest possible program that still demonstrates "
810 "the error and contact the deal.II mailing lists with it "
811 "to obtain help.");
812
821 "You (or a place in the library) are trying to call a "
822 "function that is declared as a virtual function in a "
823 "base class but that has not been overridden in your "
824 "derived class."
825 "\n\n"
826 "This exception happens in cases where the base class "
827 "cannot provide a useful default implementation for "
828 "the virtual function, but where we also do not want "
829 "to mark the function as abstract (i.e., with '=0' at the end) "
830 "because the function is not essential to the class in many "
831 "contexts. In cases like this, the base class provides "
832 "a dummy implementation that makes the compiler happy, but "
833 "that then throws the current exception."
834 "\n\n"
835 "A concrete example would be the 'Function' class. It declares "
836 "the existence of 'value()' and 'gradient()' member functions, "
837 "and both are marked as 'virtual'. Derived classes have to "
838 "override these functions for the values and gradients of a "
839 "particular function. On the other hand, not every function "
840 "has a gradient, and even for those that do, not every program "
841 "actually needs to evaluate it. Consequently, there is no "
842 "*requirement* that a derived class actually override the "
843 "'gradient()' function (as there would be had it been marked "
844 "as abstract). But, since the base class cannot know how to "
845 "compute the gradient, if a derived class does not override "
846 "the 'gradient()' function and it is called anyway, then the "
847 "default implementation in the base class will simply throw "
848 "an exception."
849 "\n\n"
850 "The exception you see is what happens in cases such as the "
851 "one just illustrated. To fix the problem, you need to "
852 "investigate whether the function being called should indeed have "
853 "been called; if the answer is 'yes', then you need to "
854 "implement the missing override in your class.");
855
860 std::string,
861 << "Please provide an implementation for the function \""
862 << arg1 << "\"");
863
869 std::string,
870 int,
871 << "The function \"" << arg1 << "\" returned the nonzero value " << arg2
872 << ", but the calling site expected the return value to be zero. "
873 "This error often happens when the function in question is a 'callback', "
874 "that is a user-provided function called from somewhere within deal.II "
875 "or within an external library such as PETSc, Trilinos, SUNDIALS, etc., "
876 "that expect these callbacks to indicate errors via nonzero return "
877 "codes.");
878
883
888
896 int,
897 << "You are trying to execute functionality that is "
898 << "impossible in " << arg1
899 << "d or simply does not make any sense.");
900
909 int,
910 int,
911 << "You are trying to execute functionality that is "
912 << "impossible in dimensions <" << arg1 << ',' << arg2
913 << "> or simply does not make any sense.");
914
915
920 "In a check in the code, deal.II encountered a zero in "
921 "a place where this does not make sense. See the condition "
922 "that was being checked and that is printed further up "
923 "in the error message to get more information on what "
924 "the erroneous zero corresponds to.");
925
931 "The object you are trying to access is empty but it makes "
932 "no sense to attempt the operation you are trying on an "
933 "empty object.");
934
943 std::size_t,
944 std::size_t,
945 << "Two sizes or dimensions were supposed to be equal, "
946 << "but aren't. They are " << arg1 << " and " << arg2 << '.');
947
954 long long,
955 long long,
956 << "Two integers should be equal to each other after a type conversion but "
957 << "aren't. A typical cause of this problem is that the integral types "
958 << "used by deal.II and an external library are different (e.g., one uses "
959 << "32-bit integers and the other uses 64-bit integers). The integers are "
960 << arg1 << " and " << arg2 << '.');
961
967 std::size_t,
968 std::size_t,
969 std::size_t,
970 << "The size or dimension of one object, " << arg1
971 << " was supposed to be "
972 << "equal to one of two values, but isn't. The two possible "
973 << "values are " << arg2 << " and " << arg3 << '.');
974
989 std::size_t,
990 std::size_t,
991 std::size_t,
992 << "Index " << arg1 << " is not in the half-open range [" << arg2 << ','
993 << arg3 << ")."
994 << (arg2 == arg3 ?
995 " In the current case, this half-open range is in fact empty, "
996 "suggesting that you are accessing an element of an empty "
997 "collection such as a vector that has not been set to the "
998 "correct size." :
999 ""));
1000
1016 template <typename T>
1019 T,
1020 T,
1021 T,
1022 << "Index " << arg1 << " is not in the half-open range [" << arg2 << ','
1023 << arg3 << ")."
1024 << (arg2 == arg3 ?
1025 " In the current case, this half-open range is in fact empty, "
1026 "suggesting that you are accessing an element of an empty "
1027 "collection such as a vector that has not been set to the "
1028 "correct size." :
1029 ""));
1030
1035 int,
1036 int,
1037 << "Number " << arg1 << " must be larger than or equal "
1038 << arg2 << '.');
1039
1043 template <typename T>
1045 T,
1046 T,
1047 << "Number " << arg1 << " must be larger than or equal "
1048 << arg2 << '.');
1049
1055 int,
1056 int,
1057 << "Division " << arg1 << " by " << arg2
1058 << " has remainder different from zero.");
1059
1069 "You are trying to use an iterator, but the iterator is "
1070 "in an invalid state. This may indicate that the iterator "
1071 "object has not been initialized, or that it has been "
1072 "moved beyond the end of the range of valid elements.");
1073
1079 "You are trying to use an iterator, but the iterator is "
1080 "pointing past the end of the range of valid elements. "
1081 "It is not valid to dereference the iterator in this "
1082 "case.");
1083
1097 DeclException1(ExcMessage, std::string, << arg1);
1098
1103 "You are trying an operation on a vector that is only "
1104 "allowed if the vector has no ghost elements, but the "
1105 "vector you are operating on does have ghost elements."
1106 "\n\n"
1107 "Specifically, there are two kinds of operations that "
1108 "are typically not allowed on vectors with ghost elements. "
1109 "First, vectors with ghost elements are read-only "
1110 "and cannot appear in operations that write into these "
1111 "vectors. Second, reduction operations (such as computing "
1112 "the norm of a vector, or taking dot products between "
1113 "vectors) are not allowed to ensure that each vector "
1114 "element is counted only once (as opposed to once for "
1115 "the owner of the element plus once for each process "
1116 "on which the element is stored as a ghost copy)."
1117 "\n\n"
1118 "See the glossary entry on 'Ghosted vectors' for more "
1119 "information.");
1120
1126 int,
1127 << "Something went wrong when making cell " << arg1
1128 << ". Read the docs and the source code "
1129 << "for more information.");
1130
1139 "You are trying an operation of the form 'vector = C', "
1140 "'matrix = C', or 'tensor = C' with a nonzero scalar value "
1141 "'C'. However, such assignments are only allowed if the "
1142 "C is zero, since the semantics for assigning any other "
1143 "value are not clear. For example: one could interpret "
1144 "assigning a matrix a value of 1 to mean the matrix has a "
1145 "norm of 1, the matrix is the identity matrix, or the "
1146 "matrix contains only 1s. Similar problems exist with "
1147 "vectors and tensors. Hence, to avoid this ambiguity, such "
1148 "assignments are not permitted.");
1149
1155 "You are attempting to use functionality that is only available "
1156 "if deal.II was configured to use LAPACK, but when you configured "
1157 "the library, cmake did not find a valid LAPACK library."
1158 "\n\n"
1159 "You will have to ensure that your system has a usable LAPACK "
1160 "installation and re-install deal.II, making sure that cmake "
1161 "finds the LAPACK installation. You can check this by "
1162 "looking at the summary printed at the end of the cmake "
1163 "output.");
1164
1170 "You are attempting to use functionality that requires that deal.II is configured "
1171 "with HDF5 support. However, when you called 'cmake', HDF5 support "
1172 "was not detected."
1173 "\n\n"
1174 "You will have to ensure that your system has a usable HDF5 "
1175 "installation and re-install deal.II, making sure that cmake "
1176 "finds the HDF5 installation. You can check this by "
1177 "looking at the summary printed at the end of the cmake "
1178 "output.");
1179
1185 "You are attempting to use functionality that is only available "
1186 "if deal.II was configured to use MPI."
1187 "\n\n"
1188 "You will have to ensure that your system has a usable MPI "
1189 "installation and re-install deal.II, making sure that cmake "
1190 "finds the MPI installation. You can check this by "
1191 "looking at the summary printed at the end of the cmake "
1192 "output.");
1193
1199 "You are attempting to use functionality that is only available "
1200 "if deal.II was configured to use the function parser which "
1201 "relies on the muparser library, but cmake did not "
1202 "find a valid muparser library on your system and also did "
1203 "not choose the one that comes bundled with deal.II."
1204 "\n\n"
1205 "You will have to ensure that your system has a usable muparser "
1206 "installation and re-install deal.II, making sure that cmake "
1207 "finds the muparser installation. You can check this by "
1208 "looking at the summary printed at the end of the cmake "
1209 "output.");
1210
1211
1217 "You are attempting to use functionality that is only available "
1218 "if deal.II was configured to use Assimp, but cmake did not "
1219 "find a valid Assimp library."
1220 "\n\n"
1221 "You will have to ensure that your system has a usable Assimp "
1222 "installation and re-install deal.II, making sure that cmake "
1223 "finds the Assimp installation. You can check this by "
1224 "looking at the summary printed at the end of the cmake "
1225 "output.");
1226
1232 "You are attempting to use functionality that is only available if deal.II "
1233 "was configured to use Trilinos' SEACAS library (which provides ExodusII), "
1234 "but cmake did not find a valid SEACAS library."
1235 "\n\n"
1236 "You will have to ensure that your system has a usable ExodusII "
1237 "installation and re-install deal.II, making sure that cmake "
1238 "finds the ExodusII installation. You can check this by "
1239 "looking at the summary printed at the end of the cmake "
1240 "output.");
1241
1247 "You are attempting to use functionality that is only available "
1248 "if deal.II was configured to use CGAL, but cmake did not "
1249 "find a valid CGAL library."
1250 "\n\n"
1251 "You will have to ensure that your system has a usable CGAL "
1252 "installation and re-install deal.II, making sure that cmake "
1253 "finds the CGAL installation. You can check this by "
1254 "looking at the summary printed at the end of the cmake "
1255 "output.");
1256
1257#ifdef DEAL_II_WITH_MPI
1280 {
1281 public:
1282 ExcMPI(const int error_code);
1283
1284 virtual void
1285 print_info(std::ostream &out) const override;
1286
1287 const int error_code;
1288 };
1289#endif // DEAL_II_WITH_MPI
1290
1291
1292
1293#ifdef DEAL_II_TRILINOS_WITH_SEACAS
1303 {
1304 public:
1310 ExcExodusII(const int error_code);
1311
1315 virtual void
1316 print_info(std::ostream &out) const override;
1317
1321 const int error_code;
1322 };
1323#endif // DEAL_II_TRILINOS_WITH_SEACAS
1324
1331 "A user call-back function encountered a recoverable error, "
1332 "but the underlying library that called the call-back did not "
1333 "manage to recover from the error and aborted its operation."
1334 "\n\n"
1335 "See the glossary entry on user call-back functions for more "
1336 "information.");
1337
1340} /*namespace StandardExceptions*/
1341
1342
1343
1351{
1352 namespace internals
1353 {
1361 extern bool allow_abort_on_exception;
1362 } // namespace internals
1363
1382 void
1383 set_additional_assert_output(const char *const p);
1384
1395 void
1397
1412 void
1414
1423 void
1425
1433 namespace internals
1434 {
1439 [[noreturn]] void
1440 abort(const ExceptionBase &exc) noexcept;
1441
1458
1476 template <typename ExceptionType>
1477 [[noreturn]] void
1479 const char *file,
1480 int line,
1481 const char *function,
1482 const char *cond,
1483 const char *exc_name,
1484 ExceptionType e)
1485 {
1486 static_assert(std::is_base_of_v<ExceptionBase, ExceptionType>,
1487 "The provided exception must inherit from ExceptionBase.");
1488 // Fill the fields of the exception object
1489 e.set_fields(file, line, function, cond, exc_name);
1490
1491 switch (handling)
1492 {
1494 {
1495 if (::deal_II_exceptions::internals::
1498 else
1499 {
1500 // We are not allowed to abort, so just throw the error:
1501 throw e;
1502 }
1503 }
1505 throw e;
1506 // this function should never return (and AssertNothrow can);
1507 // something must have gone wrong in the error handling code for us
1508 // to get this far, so throw an exception.
1509 default:
1510 throw ::StandardExceptions::ExcInternalError();
1511 }
1512 }
1513
1517 void
1518 do_issue_error_nothrow(const ExceptionBase &e) noexcept;
1519
1528 template <typename ExceptionType>
1529 void
1530 issue_error_nothrow(const char *file,
1531 int line,
1532 const char *function,
1533 const char *cond,
1534 const char *exc_name,
1535 ExceptionType e) noexcept
1536 {
1537 static_assert(std::is_base_of_v<ExceptionBase, ExceptionType>,
1538 "The provided exception must inherit from ExceptionBase.");
1539 // Fill the fields of the exception object
1540 e.set_fields(file, line, function, cond, exc_name);
1541 // avoid moving a bunch of code into the header by dispatching to
1542 // another function:
1544 }
1545 } /*namespace internals*/
1546
1547} /*namespace deal_II_exceptions*/
1548
1549
1550
1576#ifdef DEBUG
1577# if KOKKOS_VERSION >= 30600
1578# ifdef DEAL_II_HAVE_BUILTIN_EXPECT
1579# define Assert(cond, exc) \
1580 do \
1581 { \
1582 KOKKOS_IF_ON_HOST(({ \
1583 if (__builtin_expect(!(cond), false)) \
1584 ::deal_II_exceptions::internals::issue_error_noreturn( \
1585 ::deal_II_exceptions::internals::ExceptionHandling:: \
1586 abort_or_throw_on_exception, \
1587 __FILE__, \
1588 __LINE__, \
1589 __PRETTY_FUNCTION__, \
1590 #cond, \
1591 #exc, \
1592 exc); \
1593 })) \
1594 KOKKOS_IF_ON_DEVICE(({ \
1595 if (!(cond)) \
1596 Kokkos::abort(#cond); \
1597 })) \
1598 } \
1599 while (false)
1600# else /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
1601# define Assert(cond, exc) \
1602 do \
1603 { \
1604 KOKKOS_IF_ON_HOST(({ \
1605 if (!(cond)) \
1606 ::deal_II_exceptions::internals::issue_error_noreturn( \
1607 ::deal_II_exceptions::internals::ExceptionHandling:: \
1608 abort_or_throw_on_exception, \
1609 __FILE__, \
1610 __LINE__, \
1611 __PRETTY_FUNCTION__, \
1612 #cond, \
1613 #exc, \
1614 exc); \
1615 })) \
1616 KOKKOS_IF_ON_DEVICE(({ \
1617 if (!(cond)) \
1618 Kokkos::abort(#cond); \
1619 })) \
1620 } \
1621 while (false)
1622# endif /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
1623# else /*if KOKKOS_VERSION >= 30600*/
1624# ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST
1625# ifdef DEAL_II_HAVE_BUILTIN_EXPECT
1626# define Assert(cond, exc) \
1627 do \
1628 { \
1629 if (__builtin_expect(!(cond), false)) \
1630 ::deal_II_exceptions::internals::issue_error_noreturn( \
1631 ::deal_II_exceptions::internals::ExceptionHandling:: \
1632 abort_or_throw_on_exception, \
1633 __FILE__, \
1634 __LINE__, \
1635 __PRETTY_FUNCTION__, \
1636 #cond, \
1637 #exc, \
1638 exc); \
1639 } \
1640 while (false)
1641# else /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
1642# define Assert(cond, exc) \
1643 do \
1644 { \
1645 if (!(cond)) \
1646 ::deal_II_exceptions::internals::issue_error_noreturn( \
1647 ::deal_II_exceptions::internals::ExceptionHandling:: \
1648 abort_or_throw_on_exception, \
1649 __FILE__, \
1650 __LINE__, \
1651 __PRETTY_FUNCTION__, \
1652 #cond, \
1653 #exc, \
1654 exc); \
1655 } \
1656 while (false)
1657# endif /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
1658# else /*#ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST*/
1659# define Assert(cond, exc) \
1660 do \
1661 { \
1662 if (!(cond)) \
1663 Kokkos::abort(#cond); \
1664 } \
1665 while (false)
1666# endif /*ifdef KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST*/
1667# endif /*KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST*/
1668#else /*ifdef DEBUG*/
1669# ifdef DEAL_II_HAVE_CXX20
1670/*
1671 * In order to avoid unused parameters (etc.) warnings we need to use cond
1672 * and exc without actually evaluating the expression and generating code.
1673 * We accomplish this by using decltype(...) and create a dummy pointer
1674 * with these signatures. Notably, this approach works with C++20 onwards.
1675 */
1676# define Assert(cond, exc) \
1677 do \
1678 { \
1679 typename std::remove_reference<decltype(cond)>::type \
1680 *dealii_assert_variable_a = nullptr; \
1681 typename std::remove_reference<decltype(exc)>::type \
1682 *dealii_assert_variable_b = nullptr; \
1683 (void)dealii_assert_variable_a; \
1684 (void)dealii_assert_variable_b; \
1685 } \
1686 while (false)
1687# else
1688# define Assert(cond, exc) \
1689 do \
1690 { \
1691 } \
1692 while (false)
1693# endif
1694#endif /*ifdef DEBUG*/
1695
1696
1697
1724#ifdef DEBUG
1725# ifdef DEAL_II_HAVE_BUILTIN_EXPECT
1726# define AssertNothrow(cond, exc) \
1727 do \
1728 { \
1729 if (__builtin_expect(!(cond), false)) \
1730 ::deal_II_exceptions::internals::issue_error_nothrow( \
1731 __FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #exc, exc); \
1732 } \
1733 while (false)
1734# else /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
1735# define AssertNothrow(cond, exc) \
1736 do \
1737 { \
1738 if (!(cond)) \
1739 ::deal_II_exceptions::internals::issue_error_nothrow( \
1740 __FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #exc, exc); \
1741 } \
1742 while (false)
1743# endif /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
1744#else
1745# define AssertNothrow(cond, exc) \
1746 do \
1747 { \
1748 } \
1749 while (false)
1750#endif
1751
1779#ifdef DEAL_II_HAVE_BUILTIN_EXPECT
1780# define AssertThrow(cond, exc) \
1781 do \
1782 { \
1783 if (__builtin_expect(!(cond), false)) \
1784 ::deal_II_exceptions::internals::issue_error_noreturn( \
1785 ::deal_II_exceptions::internals::ExceptionHandling:: \
1786 throw_on_exception, \
1787 __FILE__, \
1788 __LINE__, \
1789 __PRETTY_FUNCTION__, \
1790 #cond, \
1791 #exc, \
1792 exc); \
1793 } \
1794 while (false)
1795#else /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
1796# define AssertThrow(cond, exc) \
1797 do \
1798 { \
1799 if (!(cond)) \
1800 ::deal_II_exceptions::internals::issue_error_noreturn( \
1801 ::deal_II_exceptions::internals::ExceptionHandling:: \
1802 throw_on_exception, \
1803 __FILE__, \
1804 __LINE__, \
1805 __PRETTY_FUNCTION__, \
1806 #cond, \
1807 #exc, \
1808 exc); \
1809 } \
1810 while (false)
1811#endif /*ifdef DEAL_II_HAVE_BUILTIN_EXPECT*/
1812
1813
1855#define DEAL_II_NOT_IMPLEMENTED() \
1856 ::deal_II_exceptions::internals::issue_error_noreturn( \
1857 ::deal_II_exceptions::internals::ExceptionHandling:: \
1858 abort_or_throw_on_exception, \
1859 __FILE__, \
1860 __LINE__, \
1861 __PRETTY_FUNCTION__, \
1862 nullptr, \
1863 nullptr, \
1864 ::StandardExceptions::ExcNotImplemented())
1865
1866
1938#define DEAL_II_ASSERT_UNREACHABLE() \
1939 ::deal_II_exceptions::internals::issue_error_noreturn( \
1940 ::deal_II_exceptions::internals::ExceptionHandling:: \
1941 abort_or_throw_on_exception, \
1942 __FILE__, \
1943 __LINE__, \
1944 __PRETTY_FUNCTION__, \
1945 nullptr, \
1946 nullptr, \
1947 ::StandardExceptions::ExcMessage( \
1948 "The program has hit a line of code that the programmer " \
1949 "marked with the macro DEAL_II_ASSERT_UNREACHABLE() to " \
1950 "indicate that the program should never reach this " \
1951 "location. You will have to find out (best done in a " \
1952 "debugger) why that happened. Typical reasons include " \
1953 "passing invalid arguments to functions (for example, if " \
1954 "a function takes an 'enum' with two possible values " \
1955 "as argument, but you call the function with a third " \
1956 "value), or if the programmer of the code that triggered " \
1957 "the error believed that a variable can only have " \
1958 "specific values, but either that assumption is wrong " \
1959 "or the computation of that value is buggy." \
1960 "\n\n" \
1961 "In those latter conditions, where some internal " \
1962 "assumption is not satisfied, there may not be very " \
1963 "much you can do if you encounter such an exception, " \
1964 "since it indicates an error in deal.II, not in your " \
1965 "own program. If that is the situation you encounter, " \
1966 "try to come up with " \
1967 "the smallest possible program that still demonstrates " \
1968 "the error and contact the deal.II mailing lists with it " \
1969 "to obtain help."))
1970
1971
1972namespace deal_II_exceptions
1973{
1974 namespace internals
1975 {
1981 template <typename T, typename U>
1982 inline DEAL_II_HOST_DEVICE constexpr bool
1983 compare_for_equality(const T &t, const U &u)
1984 {
1985 using common_type = std::common_type_t<T, U>;
1986 return static_cast<common_type>(t) == static_cast<common_type>(u);
1987 }
1988
1989
1995 template <typename T, typename U>
1996 inline DEAL_II_HOST_DEVICE constexpr bool
1997 compare_less_than(const T &t, const U &u)
1998 {
1999 using common_type = std::common_type_t<T, U>;
2000 return (static_cast<common_type>(t) < static_cast<common_type>(u));
2001 }
2002 } // namespace internals
2003} // namespace deal_II_exceptions
2004
2005
2026#define AssertDimension(dim1, dim2) \
2027 Assert(::deal_II_exceptions::internals::compare_for_equality(dim1, \
2028 dim2), \
2029 ::ExcDimensionMismatch((dim1), (dim2)))
2030
2039#define AssertIntegerConversion(index1, index2) \
2040 Assert(::deal_II_exceptions::internals::compare_for_equality( \
2041 index1, index2), \
2042 ::ExcInvalidIntegerConversion((index1), (index2)))
2043
2048#define AssertThrowIntegerConversion(index1, index2) \
2049 AssertThrow(::deal_II_exceptions::internals::compare_for_equality( \
2050 index1, index2), \
2051 ::ExcInvalidIntegerConversion((index1), (index2)))
2052
2070#define AssertVectorVectorDimension(VEC, DIM1, DIM2) \
2071 AssertDimension(VEC.size(), DIM1); \
2072 for (const auto &subvector : VEC) \
2073 { \
2074 (void)subvector; \
2075 AssertDimension(subvector.size(), DIM2); \
2076 }
2077
2078namespace internal
2079{
2080 // Workaround to allow for commas in template parameter lists
2081 // in preprocessor macros as found in
2082 // https://stackoverflow.com/questions/13842468/comma-in-c-c-macro
2083 template <typename F>
2085
2086 template <typename T, typename U>
2087 struct argument_type<T(U)>
2088 {
2089 using type = U;
2090 };
2091
2092 template <typename F>
2094} // namespace internal
2095
2115#define AssertIndexRange(index, range) \
2116 Assert(::deal_II_exceptions::internals::compare_less_than(index, \
2117 range), \
2118 ExcIndexRangeType<::internal::argument_type_t<void( \
2119 std::common_type_t<decltype(index), decltype(range)>)>>((index), \
2120 0, \
2121 (range)))
2122
2142#define AssertIsFinite(number) \
2143 Assert(::numbers::is_finite(number), \
2144 ::ExcNumberNotFinite(std::complex<double>(number)))
2145
2151#define AssertIsNotUsed(obj) Assert((obj)->used() == false, ExcInternalError())
2152
2153#ifdef DEAL_II_WITH_MPI
2174# define AssertThrowMPI(error_code) \
2175 AssertThrow(error_code == MPI_SUCCESS, ::ExcMPI(error_code))
2176#else
2177# define AssertThrowMPI(error_code) \
2178 do \
2179 { \
2180 } \
2181 while (false)
2182#endif // DEAL_II_WITH_MPI
2183
2184#ifdef DEAL_II_TRILINOS_WITH_SEACAS
2202# define AssertThrowExodusII(error_code) \
2203 AssertThrow(error_code == 0, \
2204 ::StandardExceptions::ExcExodusII(error_code));
2205#endif // DEAL_II_TRILINOS_WITH_SEACAS
2206
2207using namespace StandardExceptions;
2208
2210
2211#endif
void generate_message() const
void print_stack_trace(std::ostream &out) const
const char * file
Definition exceptions.h:124
std::string what_str
Definition exceptions.h:170
const char * get_exc_name() const
virtual ~ExceptionBase() noexcept override=default
int n_stacktrace_frames
Definition exceptions.h:150
void set_fields(const char *file, const int line, const char *function, const char *cond, const char *exc_name)
virtual void print_info(std::ostream &out) const
virtual const char * what() const noexcept override
const char * exc
Definition exceptions.h:144
const char * function
Definition exceptions.h:134
void print_exc_data(std::ostream &out) const
unsigned int line
Definition exceptions.h:129
void * raw_stacktrace[25]
Definition exceptions.h:156
const char * cond
Definition exceptions.h:139
virtual void print_info(std::ostream &out) const override
virtual void print_info(std::ostream &out) const override
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
Definition config.h:512
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
Definition config.h:555
static ::ExceptionBase & ExcIndexRangeType(T arg1, T arg2, T arg3)
static ::ExceptionBase & ExcImpossibleInDimSpacedim(int arg1, int arg2)
#define DeclException0(Exception0)
Definition exceptions.h:466
static ::ExceptionBase & ExcInvalidIterator()
static ::ExceptionBase & ExcOutOfMemory(std::size_t arg1)
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcGhostsPresent()
static ::ExceptionBase & ExcFileNotOpen(std::string arg1)
static ::ExceptionBase & ExcZero()
static ::ExceptionBase & ExcNeedsAssimp()
static ::ExceptionBase & ExcNeedsFunctionparser()
static ::ExceptionBase & ExcNotMultiple(int arg1, int arg2)
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcNeedsMPI()
static ::ExceptionBase & ExcFunctionNotProvided(std::string arg1)
static ::ExceptionBase & ExcEmptyObject()
static ::ExceptionBase & ExcScalarAssignmentOnlyForZeroValue()
static ::ExceptionBase & ExcMemoryLeak(int arg1)
static ::ExceptionBase & ExcLowerRangeType(T arg1, T arg2)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
static ::ExceptionBase & ExcIteratorPastEnd()
static ::ExceptionBase & ExcNeedsExodusII()
static ::ExceptionBase & ExcDimensionMismatch2(std::size_t arg1, std::size_t arg2, std::size_t arg3)
#define DeclException2(Exception2, type1, type2, outsequence)
Definition exceptions.h:534
static ::ExceptionBase & ExcLowerRange(int arg1, int arg2)
static ::ExceptionBase & ExcGridHasInvalidCell(int arg1)
static ::ExceptionBase & ExcNumberNotFinite(std::complex< double > arg1)
static ::ExceptionBase & ExcPureFunctionCalled()
#define DeclExceptionMsg(Exception, defaulttext)
Definition exceptions.h:489
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDivideByZero()
static ::ExceptionBase & ExcNeedsHDF5()
static ::ExceptionBase & ExcNeedsLAPACK()
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition exceptions.h:557
static ::ExceptionBase & ExcNeedsCGAL()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcInvalidState()
#define DeclException1(Exception1, type1, outsequence)
Definition exceptions.h:511
static ::ExceptionBase & RecoverableUserCallbackError()
static ::ExceptionBase & ExcInvalidIntegerConversion(long long arg1, long long arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcFunctionNonzeroReturn(std::string arg1, int arg2)
constexpr bool compare_less_than(const T &t, const U &u)
constexpr bool compare_for_equality(const T &t, const U &u)
void issue_error_noreturn(ExceptionHandling handling, const char *file, int line, const char *function, const char *cond, const char *exc_name, ExceptionType e)
void abort(const ExceptionBase &exc) noexcept
void do_issue_error_nothrow(const ExceptionBase &e) noexcept
void issue_error_nothrow(const char *file, int line, const char *function, const char *cond, const char *exc_name, ExceptionType e) noexcept
void enable_abort_on_exception()
Definition exceptions.cc:88
void disable_abort_on_exception()
Definition exceptions.cc:80
void set_additional_assert_output(const char *const p)
void suppress_stacktrace_in_exceptions()
Definition exceptions.cc:72
typename argument_type< F >::type argument_type_t
STL namespace.
#define DEAL_II_HOST_DEVICE
Definition numbers.h:30