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 "Core/Exception.h"
17
18#include <sstream>
19#include <string>
20#include <utility>
21
22namespace svmp::FE {
23
24/**
25 * @defgroup FE_CommonExceptions Exceptions
26 * @ingroup FE_Common
27 * @brief FE exception hierarchy.
28 *
29 * @details All FE-specific exceptions derive from FEException, which itself
30 * derives from the shared solver ExceptionBase. Specialized subclasses carry
31 * structured context (element type, DOF index, backend name and error code,
32 * iteration counts, Jacobian determinants) so call sites can report
33 * actionable diagnostics.
34 *
35 * Throw FE exceptions through the canonical core helpers in Core/Exception.h:
36 *
37 * @code
38 * svmp::raise<ExceptionT>(message);
39 * svmp::throw_if<ExceptionT>(failure_condition, message);
40 * svmp::check<ExceptionT>(valid_condition, message);
41 * svmp::check_not_null<ExceptionT>(ptr, message);
42 * svmp::check_index<ExceptionT>(index, size);
43 * svmp::not_implemented(message);
44 * @endcode
45 *
46 * check() raises when its (success) condition is false; throw_if() raises when
47 * its (failure) condition is true. FE owns exception types; helper spelling is
48 * owned by the core layer.
49 * @{
50 */
51
52/**
53 * @brief Base exception type for errors originating in the FE library
54 *
55 * Carries a status code and source location alongside the message. Derived
56 * classes select an appropriate StatusCode and may attach additional
57 * structured context.
58 */
59class FEException : public ExceptionBase {
60public:
61 /**
62 * @brief Construct with a message and optional status code.
63 * @param message Human-readable error description.
64 * @param status Status code classifying the failure.
65 *
66 * @details The source location is stamped by svmp::raise(); construct FE
67 * exceptions through the core helpers rather than passing file/line/function.
68 */
69 explicit FEException(const std::string& message,
70 StatusCode status = StatusCode::Unknown)
71 : ExceptionBase(message, status, "FE Exception")
72 {
73 }
74
75 /**
76 * @brief Status code classifying the failure.
77 * @return The status code recorded at construction.
78 */
79 StatusCode status() const noexcept { return status_code(); }
80};
81
82/**
83 * @brief An argument failed validation
84 */
85SVMP_DEFINE_EXCEPTION(InvalidArgumentException, FEException,
86 StatusCode::InvalidArgument);
87
88/**
89 * @brief Unsupported or malformed element request
90 *
91 * Records the offending element type so error reports can name it.
92 */
94public:
95 /**
96 * @brief Construct with a message and optional element-type context.
97 * @param message Human-readable error description.
98 * @param element_type Name of the offending element type; appended to the message when non-empty.
99 */
100 InvalidElementException(const std::string& message,
101 std::string element_type = "")
102 : FEException(build_message(message, element_type),
103 StatusCode::InvalidArgument),
104 element_type_(std::move(element_type))
105 {
106 }
107
108 /**
109 * @brief Name of the offending element type.
110 * @return Element-type name; empty when not provided.
111 */
112 const std::string& element_type() const noexcept { return element_type_; }
113
114private:
115 static std::string build_message(const std::string& message,
116 const std::string& element_type)
117 {
118 if (element_type.empty()) {
119 return message;
120 }
121
122 return message + " (Element type: " + element_type + ")";
123 }
124
125 std::string element_type_;
126};
127
128/**
129 * @brief Degree-of-freedom numbering or lookup failure
130 *
131 * Records the offending DOF index so error reports can name it.
132 */
133class DofException : public FEException {
134public:
135 /**
136 * @brief Construct with a message and optional DOF-index context.
137 * @param message Human-readable error description.
138 * @param dof_index Offending DOF index; appended to the message unless it equals invalid_dof_index().
139 */
140 DofException(const std::string& message,
141 long long dof_index = invalid_dof_index())
142 : FEException(build_message(message, dof_index),
143 StatusCode::InvalidArgument),
144 dof_index_(dof_index)
145 {
146 }
147
148 /**
149 * @brief Offending DOF index.
150 * @return DOF index; invalid_dof_index() when not provided.
151 */
152 long long dof_index() const noexcept { return dof_index_; }
153 /**
154 * @brief Sentinel meaning "no DOF index attached".
155 * @return The sentinel value -1.
156 */
157 static constexpr long long invalid_dof_index() noexcept { return -1; }
158
159private:
160 static std::string build_message(const std::string& message,
161 long long dof_index)
162 {
163 if (dof_index == invalid_dof_index()) {
164 return message;
165 }
166
167 return message + " (DOF index: " + std::to_string(dof_index) + ")";
168 }
169
170 long long dof_index_ = invalid_dof_index();
171};
172
173/**
174 * @brief Global assembly failure
175 */
176SVMP_DEFINE_EXCEPTION(AssemblyException, FEException, StatusCode::InvalidState);
177
178/**
179 * @brief Failure reported by a linear-algebra or solver backend
180 *
181 * Records the backend name and its native error code so error reports can
182 * identify the failing dependency.
183 */
185public:
186 /**
187 * @brief Construct with a message and optional backend context.
188 * @param message Human-readable error description.
189 * @param backend_name Name of the failing backend; appended to the message when non-empty.
190 * @param error_code Backend-native error code; appended to the message when nonzero.
191 */
192 BackendException(const std::string& message,
193 std::string backend_name = "",
194 int error_code = 0)
195 : FEException(build_message(message, backend_name, error_code),
196 StatusCode::DependencyError),
197 backend_name_(std::move(backend_name)),
198 error_code_(error_code)
199 {
200 }
201
202 /**
203 * @brief Name of the failing backend.
204 * @return Backend name; empty when not provided.
205 */
206 const std::string& backend_name() const noexcept { return backend_name_; }
207 /**
208 * @brief Backend-native error code.
209 * @return Error code; zero when not provided.
210 */
211 int error_code() const noexcept { return error_code_; }
212
213private:
214 static std::string build_message(const std::string& message,
215 const std::string& backend_name,
216 int error_code)
217 {
218 std::ostringstream oss;
219 oss << message;
220 if (!backend_name.empty() || error_code != 0) {
221 oss << " (";
222 if (!backend_name.empty()) {
223 oss << "Backend: " << backend_name;
224 }
225 if (error_code != 0) {
226 if (!backend_name.empty()) {
227 oss << ", ";
228 }
229 oss << "Error code: " << error_code;
230 }
231 oss << ")";
232 }
233 return oss.str();
234 }
235
236 std::string backend_name_;
237 int error_code_ = 0;
238};
239
240/**
241 * @brief Requested feature is not implemented.
242 *
243 * @details Alias for svmp::NotImplementedException (Core/Exception.h), the single
244 * not-implemented type used across the solver and the default raised by
245 * svmp::not_implemented(). Kept in the FE namespace for source compatibility; it
246 * derives from CoreException, not FEException.
247 */
249
250/**
251 * @brief Required initialization step has not been performed
252 */
254public:
255 /**
256 * @brief Construct from the name of the uninitialized feature.
257 * @param feature Description of the missing initialization.
258 */
259 explicit NotInitializedException(const std::string& feature)
260 : FEException("Missing initialization: " + feature,
261 StatusCode::InvalidState)
262 {
263 }
264};
265
266/**
267 * @brief Iterative process failed to converge
268 *
269 * Records the iteration count and final residual so error reports can show
270 * how far the iteration progressed.
271 */
273public:
274 /**
275 * @brief Construct with a message and optional iteration context.
276 * @param message Human-readable error description.
277 * @param iteration Iteration at which the failure was detected; appended to the message when non-negative.
278 * @param residual Final residual; appended to the message when positive.
279 */
280 ConvergenceException(const std::string& message,
281 int iteration = -1,
282 double residual = 0.0)
283 : FEException(build_message(message, iteration, residual),
284 StatusCode::InvalidState),
285 iteration_(iteration),
286 residual_(residual)
287 {
288 }
289
290 /**
291 * @brief Iteration at which the failure was detected.
292 * @return Iteration count; -1 when not provided.
293 */
294 int iteration() const noexcept { return iteration_; }
295 /**
296 * @brief Final residual value.
297 * @return Residual; 0.0 when not provided.
298 */
299 double residual() const noexcept { return residual_; }
300
301private:
302 static std::string build_message(const std::string& message,
303 int iteration,
304 double residual)
305 {
306 std::ostringstream oss;
307 oss << message;
308 if (iteration >= 0) {
309 oss << " (Iteration: " << iteration;
310 if (residual > 0.0) {
311 oss << ", Residual: " << residual;
312 }
313 oss << ")";
314 }
315 return oss.str();
316 }
317
318 int iteration_ = -1;
319 double residual_ = 0.0;
320};
321
322/**
323 * @brief Element geometric mapping is singular or inverted
324 *
325 * Records the offending Jacobian determinant so error reports can show the
326 * degeneracy.
327 */
329public:
330 /**
331 * @brief Construct with a message and the offending Jacobian determinant.
332 * @param message Human-readable error description.
333 * @param jacobian_det Jacobian determinant at the failure point; appended to the message.
334 */
335 SingularMappingException(const std::string& message,
336 double jacobian_det = 0.0)
337 : FEException(build_message(message, jacobian_det),
338 StatusCode::InvalidState),
339 jacobian_det_(jacobian_det)
340 {
341 }
342
343 /**
344 * @brief Jacobian determinant at the failure point.
345 * @return The determinant recorded at construction.
346 */
347 double jacobian_det() const noexcept { return jacobian_det_; }
348
349private:
350 static std::string build_message(const std::string& message, double det)
351 {
352 return message + " (Jacobian determinant: " + std::to_string(det) +
353 ")";
354 }
355
356 double jacobian_det_ = 0.0;
357};
358
359/** @} */
360
361} // namespace svmp::FE
362
363#endif // SVMP_FE_EXCEPTION_H
Definition Exception.h:258
Global assembly failure.
Definition FEException.h:176
Failure reported by a linear-algebra or solver backend.
Definition FEException.h:184
int error_code() const noexcept
Backend-native error code.
Definition FEException.h:211
BackendException(const std::string &message, std::string backend_name="", int error_code=0)
Construct with a message and optional backend context.
Definition FEException.h:192
const std::string & backend_name() const noexcept
Name of the failing backend.
Definition FEException.h:206
Iterative process failed to converge.
Definition FEException.h:272
double residual() const noexcept
Final residual value.
Definition FEException.h:299
ConvergenceException(const std::string &message, int iteration=-1, double residual=0.0)
Construct with a message and optional iteration context.
Definition FEException.h:280
int iteration() const noexcept
Iteration at which the failure was detected.
Definition FEException.h:294
Degree-of-freedom numbering or lookup failure.
Definition FEException.h:133
DofException(const std::string &message, long long dof_index=invalid_dof_index())
Construct with a message and optional DOF-index context.
Definition FEException.h:140
static constexpr long long invalid_dof_index() noexcept
Sentinel meaning "no DOF index attached".
Definition FEException.h:157
long long dof_index() const noexcept
Offending DOF index.
Definition FEException.h:152
Base exception type for errors originating in the FE library.
Definition FEException.h:59
StatusCode status() const noexcept
Status code classifying the failure.
Definition FEException.h:79
FEException(const std::string &message, StatusCode status=StatusCode::Unknown)
Construct with a message and optional status code.
Definition FEException.h:69
Unsupported or malformed element request.
Definition FEException.h:93
InvalidElementException(const std::string &message, std::string element_type="")
Construct with a message and optional element-type context.
Definition FEException.h:100
const std::string & element_type() const noexcept
Name of the offending element type.
Definition FEException.h:112
Required initialization step has not been performed.
Definition FEException.h:253
NotInitializedException(const std::string &feature)
Construct from the name of the uninitialized feature.
Definition FEException.h:259
Element geometric mapping is singular or inverted.
Definition FEException.h:328
SingularMappingException(const std::string &message, double jacobian_det=0.0)
Construct with a message and the offending Jacobian determinant.
Definition FEException.h:335
double jacobian_det() const noexcept
Jacobian determinant at the failure point.
Definition FEException.h:347
A requested operation or feature is not implemented.
Definition Exception.h:352