From: Wolfgang Bangerth Date: Thu, 25 May 2023 21:40:57 +0000 (-0600) Subject: Add a test that tests PETSc (in)ability to recover from errors. X-Git-Tag: v9.5.0-rc1~189^2~1 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9ed70a5f3d3725f237ddfde73850098b7306491b;p=dealii.git Add a test that tests PETSc (in)ability to recover from errors. --- diff --git a/tests/petsc/petsc_snes_06.cc b/tests/petsc/petsc_snes_06.cc new file mode 100644 index 0000000000..cc446faec4 --- /dev/null +++ b/tests/petsc/petsc_snes_06.cc @@ -0,0 +1,96 @@ +//----------------------------------------------------------- +// +// Copyright (C) 2023 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +//----------------------------------------------------------- + +#include + +#include +#include +#include + +#include + +#include "../tests.h" + +/** + * Find the solution of f(x)=sin(x)=0, which is rather simple to solve, starting + * at x=1. + * + * This test lets the residual function throw an exception if the step + * length was too large from the previous point of evaluation. Let's + * see whether PETSc SNES manages to recover by reducing the step + * length. + */ +using VectorType = PETScWrappers::MPI::Vector; +using MatrixType = PETScWrappers::MPI::SparseMatrix; +using Solver = PETScWrappers::NonlinearSolver; +using real_type = Solver::real_type; + +int +main(int argc, char **argv) +{ + initlog(); + Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1); + + { + PETScWrappers::NonlinearSolverData data; + Solver solver(data); + + const double starting_x = 1; + double last_residual_eval = starting_x; + + solver.residual = [&](const VectorType &X, VectorType &F) -> void { + deallog << "Evaluating the residual at x=" << X(0) << std::endl; + + if (std::abs(X(0) - last_residual_eval) > 1) + { + deallog << "Too large a step. Throwing a recoverable exception." + << std::endl; + throw RecoverableUserCallbackError(); + } + + F(0) = std::sin(X(0)); + F.compress(VectorOperation::insert); + + last_residual_eval = X(0); + }; + + solver.jacobian = + [&](const VectorType &X, MatrixType &A, MatrixType &P) -> void { + deallog << "Evaluating the Jacobian at x=" << X(0) << std::endl; + + P.set(0, 0, std::cos(X(0))); + P.compress(VectorOperation::insert); + A.set(0, 0, std::cos(X(0))); + A.compress(VectorOperation::insert); + }; + + auto commsize = Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD); + auto commrank = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD); + VectorType x(MPI_COMM_WORLD, 1, commrank == commsize - 1 ? 1 : 0); + x(0) = starting_x; + + try + { + const auto nit = solver.solve(x); + + deallog << "Found the solution x=" << x(0) << " after " << nit + << " iterations." << std::endl; + } + catch (std::exception &exc) + { + deallog << exc.what() << std::endl; + } + } +} diff --git a/tests/petsc/petsc_snes_06.output b/tests/petsc/petsc_snes_06.output new file mode 100644 index 0000000000..a38ca4c761 --- /dev/null +++ b/tests/petsc/petsc_snes_06.output @@ -0,0 +1,20 @@ + +DEAL::Evaluating the residual at x=1.00000 +DEAL::Evaluating the Jacobian at x=1.00000 +DEAL::Evaluating the residual at x=-0.557408 +DEAL::Too large a step. Throwing a recoverable exception. +DEAL:: +-------------------------------------------------------- +An error occurred in line <0> of file <> in function + +The violated condition was: + +Additional information: + A user call-back function encountered a recoverable error, but the + underlying library that called the call-back did not manage to recover + from the error and aborted its operation. + + See the glossary entry on user call-back functions for more + information. +-------------------------------------------------------- +