} \
while (0)
-// Shorthand notation for User error codes.
-# define AssertUser(code, name) \
- do \
- { \
- int ierr = (code); \
- AssertThrow(ierr == 0, \
- StandardExceptions::ExcFunctionNonzeroReturn(name, ierr)); \
- } \
- while (0)
-
namespace PETScWrappers
{
+ namespace
+ {
+ /**
+ * A function that calls the function object given by its first argument
+ * with the set of arguments following at the end. If the call returns
+ * regularly, the current function returns zero to indicate success. If
+ * the call fails with an exception, then the current function returns with
+ * an error code of -1. In that case, the exception thrown by `f` is
+ * captured and `eptr` is set to the exception. In case of success,
+ * `eptr` is set to `nullptr`.
+ */
+ template <typename F, typename... Args>
+ int
+ call_and_possibly_capture_exception(const F & f,
+ std::exception_ptr &eptr,
+ Args &&...args)
+ {
+ // See whether there is already something in the exception pointer
+ // variable. There is no reason why this should be so, and
+ // we should probably bail out:
+ AssertThrow(eptr == nullptr, ExcInternalError());
+
+ // Call the function and if that succeeds, return zero:
+ try
+ {
+ f(std::forward<Args>(args)...);
+ eptr = nullptr;
+ return 0;
+ }
+ // In case of an exception, capture the exception and
+ // return -1:
+ catch (...)
+ {
+ eptr = std::current_exception();
+ return -1;
+ }
+ }
+ } // namespace
+
+
+
template <typename VectorType, typename PMatrixType, typename AMatrixType>
- DEAL_II_CXX20_REQUIRES((concepts::is_dealii_petsc_vector_type<VectorType> ||
- std::constructible_from<VectorType, Vec>))
+ DEAL_II_CXX20_REQUIRES(
+ (concepts::is_dealii_petsc_vector_type<VectorType> ||
+ std::constructible_from<
+ VectorType,
+ Vec>)&&(concepts::is_dealii_petsc_matrix_type<PMatrixType> ||
+ std::constructible_from<
+ PMatrixType,
+ Mat>)&&(concepts::is_dealii_petsc_matrix_type<AMatrixType> ||
+ std::constructible_from<AMatrixType, Mat>))
NonlinearSolver<VectorType, PMatrixType, AMatrixType>::NonlinearSolver(
const NonlinearSolverData &data,
const MPI_Comm mpi_comm)
} \
while (0)
-// Shorthand notation for User error codes.
-# define AssertUser(code, name) \
- do \
- { \
- int ierr = (code); \
- AssertThrow(ierr == 0, \
- StandardExceptions::ExcFunctionNonzeroReturn(name, ierr)); \
- } \
- while (0)
-
namespace PETScWrappers
{
+ namespace
+ {
+ /**
+ * A function that calls the function object given by its first argument
+ * with the set of arguments following at the end. If the call returns
+ * regularly, the current function returns zero to indicate success. If
+ * the call fails with an exception, then the current function returns with
+ * an error code of -1. In that case, the exception thrown by `f` is
+ * captured and `eptr` is set to the exception. In case of success,
+ * `eptr` is set to `nullptr`.
+ */
+ template <typename F, typename... Args>
+ int
+ call_and_possibly_capture_exception(const F & f,
+ std::exception_ptr &eptr,
+ Args &&...args)
+ {
+ // See whether there is already something in the exception pointer
+ // variable. There is no reason why this should be so, and
+ // we should probably bail out:
+ AssertThrow(eptr == nullptr, ExcInternalError());
+
+ // Call the function and if that succeeds, return zero:
+ try
+ {
+ f(std::forward<Args>(args)...);
+ eptr = nullptr;
+ return 0;
+ }
+ // In case of an exception, capture the exception and
+ // return -1:
+ catch (...)
+ {
+ eptr = std::current_exception();
+ return -1;
+ }
+ }
+ } // namespace
+
+
+
template <typename VectorType, typename PMatrixType, typename AMatrixType>
- DEAL_II_CXX20_REQUIRES((concepts::is_dealii_petsc_vector_type<VectorType> ||
- std::constructible_from<VectorType, Vec>))
+ DEAL_II_CXX20_REQUIRES(
+ (concepts::is_dealii_petsc_vector_type<VectorType> ||
+ std::constructible_from<
+ VectorType,
+ Vec>)&&(concepts::is_dealii_petsc_matrix_type<PMatrixType> ||
+ std::constructible_from<
+ PMatrixType,
+ Mat>)&&(concepts::is_dealii_petsc_matrix_type<AMatrixType> ||
+ std::constructible_from<AMatrixType, Mat>))
TimeStepper<VectorType, PMatrixType, AMatrixType>::TimeStepper(
const TimeStepperData &data,
const MPI_Comm mpi_comm)