svMultiPhysics
Loading...
Searching...
No Matches
FEException.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Stanford University, The Regents of the University of California, and others.
2// SPDX-License-Identifier: BSD-3-Clause
3
4#ifndef SVMP_FE_EXCEPTION_H
5#define SVMP_FE_EXCEPTION_H
6
7/**
8 * @file FEException.h
9 * @brief Exception hierarchy for error handling in the FE library
10 *
11 * This header defines FE-specific exception types that derive from the shared
12 * solver exception infrastructure in Exception.h. FEException marks
13 * failures from finite-element assembly, backend, DOF, and element operations.
14 */
15
16#include "Exception.h"
17
18#include <sstream>
19#include <string>
20#include <utility>
21
22namespace svmp {
23namespace FE {
24
25class FEException : public ExceptionBase {
26public:
27 FEException(const std::string& message,
28 StatusCode status = StatusCode::Unknown,
29 const char* file = "",
30 int line = 0,
31 const char* function = "")
32 : ExceptionBase(message,
33 status,
34 "FE Exception",
35 file,
36 line,
37 function)
38 {
39 }
40
41 FEException(const std::string& message,
42 const char* file,
43 int line,
44 const char* function = "")
45 : FEException(message, StatusCode::Unknown, file, line, function)
46 {
47 }
48
49 StatusCode status() const noexcept { return status_code(); }
50};
51
53public:
54 InvalidArgumentException(const std::string& message,
55 const char* file = "",
56 int line = 0,
57 const char* function = "")
58 : FEException(message, StatusCode::InvalidArgument, file, line,
59 function)
60 {
61 }
62};
63
65public:
66 InvalidElementException(const std::string& message,
67 std::string element_type = "",
68 const char* file = "",
69 int line = 0,
70 const char* function = "")
71 : FEException(build_message(message, element_type),
72 StatusCode::InvalidArgument,
73 file,
74 line,
75 function),
76 element_type_(std::move(element_type))
77 {
78 }
79
80 const std::string& element_type() const noexcept { return element_type_; }
81
82private:
83 static std::string build_message(const std::string& message,
84 const std::string& element_type)
85 {
86 if (element_type.empty()) {
87 return message;
88 }
89
90 return message + " (Element type: " + element_type + ")";
91 }
92
93 std::string element_type_;
94};
95
96class DofException : public FEException {
97public:
98 DofException(const std::string& message,
99 long long dof_index = invalid_dof_index(),
100 const char* file = "",
101 int line = 0,
102 const char* function = "")
103 : FEException(build_message(message, dof_index),
104 StatusCode::InvalidArgument,
105 file,
106 line,
107 function),
108 dof_index_(dof_index)
109 {
110 }
111
112 long long dof_index() const noexcept { return dof_index_; }
113 static constexpr long long invalid_dof_index() noexcept { return -1; }
114
115private:
116 static std::string build_message(const std::string& message,
117 long long dof_index)
118 {
119 if (dof_index == invalid_dof_index()) {
120 return message;
121 }
122
123 return message + " (DOF index: " + std::to_string(dof_index) + ")";
124 }
125
126 long long dof_index_ = invalid_dof_index();
127};
128
130public:
131 AssemblyException(const std::string& message,
132 const char* file = "",
133 int line = 0,
134 const char* function = "")
135 : FEException(message, StatusCode::InvalidState, file, line, function)
136 {
137 }
138};
139
141public:
142 BackendException(const std::string& message,
143 std::string backend_name = "",
144 int error_code = 0,
145 const char* file = "",
146 int line = 0,
147 const char* function = "")
148 : FEException(build_message(message, backend_name, error_code),
149 StatusCode::DependencyError,
150 file,
151 line,
152 function),
153 backend_name_(std::move(backend_name)),
154 error_code_(error_code)
155 {
156 }
157
158 const std::string& backend_name() const noexcept { return backend_name_; }
159 int error_code() const noexcept { return error_code_; }
160
161private:
162 static std::string build_message(const std::string& message,
163 const std::string& backend_name,
164 int error_code)
165 {
166 std::ostringstream oss;
167 oss << message;
168 if (!backend_name.empty() || error_code != 0) {
169 oss << " (";
170 if (!backend_name.empty()) {
171 oss << "Backend: " << backend_name;
172 }
173 if (error_code != 0) {
174 if (!backend_name.empty()) {
175 oss << ", ";
176 }
177 oss << "Error code: " << error_code;
178 }
179 oss << ")";
180 }
181 return oss.str();
182 }
183
184 std::string backend_name_;
185 int error_code_ = 0;
186};
187
189public:
190 NotImplementedException(const std::string& feature,
191 const char* file = "",
192 int line = 0,
193 const char* function = "")
194 : FEException("Feature not implemented: " + feature,
195 StatusCode::NotImplemented,
196 file,
197 line,
198 function)
199 {
200 }
201};
202
204public:
205 NotInitializedException(const std::string &feature,
206 const char *file,
207 int line = 0,
208 const char *function = "")
209 : FEException("Missing initialization: " + feature,
210 StatusCode::InvalidState,
211 file,
212 line,
213 function)
214 {
215 }
216};
217
219public:
220 ConvergenceException(const std::string& message,
221 int iteration = -1,
222 double residual = 0.0,
223 const char* file = "",
224 int line = 0,
225 const char* function = "")
226 : FEException(build_message(message, iteration, residual),
227 StatusCode::InvalidState,
228 file,
229 line,
230 function),
231 iteration_(iteration),
232 residual_(residual)
233 {
234 }
235
236 int iteration() const noexcept { return iteration_; }
237 double residual() const noexcept { return residual_; }
238
239private:
240 static std::string build_message(const std::string& message,
241 int iteration,
242 double residual)
243 {
244 std::ostringstream oss;
245 oss << message;
246 if (iteration >= 0) {
247 oss << " (Iteration: " << iteration;
248 if (residual > 0.0) {
249 oss << ", Residual: " << residual;
250 }
251 oss << ")";
252 }
253 return oss.str();
254 }
255
256 int iteration_ = -1;
257 double residual_ = 0.0;
258};
259
261public:
262 SingularMappingException(const std::string& message,
263 double jacobian_det = 0.0,
264 const char* file = "",
265 int line = 0,
266 const char* function = "")
267 : FEException(build_message(message, jacobian_det),
268 StatusCode::InvalidState,
269 file,
270 line,
271 function),
272 jacobian_det_(jacobian_det)
273 {
274 }
275
276 double jacobian_det() const noexcept { return jacobian_det_; }
277
278private:
279 static std::string build_message(const std::string& message, double det)
280 {
281 return message + " (Jacobian determinant: " + std::to_string(det) +
282 ")";
283 }
284
285 double jacobian_det_ = 0.0;
286};
287
288template <class ExceptionT, class... Args>
289[[noreturn]] inline void raise(SourceLocation location, Args&&... args)
290{
291 ::svmp::raise<ExceptionT>(location, std::forward<Args>(args)...);
292}
293
294template <class ExceptionT = FEException, class... Args>
295inline void throw_if(bool condition, SourceLocation location, Args&&... args)
296{
297 if (condition) {
298 ::svmp::FE::raise<ExceptionT>(location, std::forward<Args>(args)...);
299 }
300}
301
302template <class ExceptionT = InvalidArgumentException, class... Args>
303inline void check_arg(bool condition, SourceLocation location, Args&&... args)
304{
305 ::svmp::check_arg<ExceptionT>(condition, location,
306 std::forward<Args>(args)...);
307}
308
309template <class ExceptionT = InvalidArgumentException, class PointerT,
310 class... Args>
311inline void check_not_null(PointerT ptr, SourceLocation location,
312 Args&&... args)
313{
314 ::svmp::check_not_null<ExceptionT>(ptr, location, std::forward<Args>(args)...);
315}
316
317template <class ExceptionT = InvalidArgumentException, class IndexT,
318 class SizeT>
319inline void check_index(IndexT index, SizeT size, SourceLocation location)
320{
321 const long long fe_check_index_value = static_cast<long long>(index);
322 const long long fe_check_size_value = static_cast<long long>(size);
323
324 ::svmp::FE::check_arg<ExceptionT>(
325 fe_check_index_value >= 0 &&
326 fe_check_index_value < fe_check_size_value,
327 location,
328 "Index " + std::to_string(fe_check_index_value) +
329 " out of bounds [0, " + std::to_string(fe_check_size_value) + ")");
330}
331
332[[noreturn]] inline void not_implemented(const std::string& feature,
333 SourceLocation location)
334{
335 ::svmp::FE::raise<NotImplementedException>(location, feature);
336}
337
338} // namespace FE
339} // namespace svmp
340
341#endif // SVMP_FE_EXCEPTION_H
Definition Exception.h:271
Definition FEException.h:129
Definition FEException.h:140
Definition FEException.h:218
Definition FEException.h:96
Definition FEException.h:25
Definition FEException.h:52
Definition FEException.h:64
Definition FEException.h:188
Definition FEException.h:203
Definition FEException.h:260
Definition Exception.h:70