]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add a test that tests PETSc (in)ability to recover from errors.
authorWolfgang Bangerth <bangerth@colostate.edu>
Thu, 25 May 2023 21:40:57 +0000 (15:40 -0600)
committerWolfgang Bangerth <bangerth@colostate.edu>
Thu, 25 May 2023 21:40:57 +0000 (15:40 -0600)
tests/petsc/petsc_snes_06.cc [new file with mode: 0644]
tests/petsc/petsc_snes_06.output [new file with mode: 0644]

diff --git a/tests/petsc/petsc_snes_06.cc b/tests/petsc/petsc_snes_06.cc
new file mode 100644 (file)
index 0000000..cc446fa
--- /dev/null
@@ -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 <deal.II/base/parameter_handler.h>
+
+#include <deal.II/lac/petsc_block_sparse_matrix.h>
+#include <deal.II/lac/petsc_block_vector.h>
+#include <deal.II/lac/petsc_snes.h>
+
+#include <cmath>
+
+#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<VectorType, MatrixType>;
+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 (file)
index 0000000..a38ca4c
--- /dev/null
@@ -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.
+--------------------------------------------------------
+

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.