]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Clean up after ourselves. 15188/head
authorWolfgang Bangerth <bangerth@colostate.edu>
Tue, 9 May 2023 15:19:05 +0000 (09:19 -0600)
committerWolfgang Bangerth <bangerth@colostate.edu>
Tue, 9 May 2023 20:16:20 +0000 (14:16 -0600)
source/sundials/kinsol.cc

index a1db0684e1fae3d6dc4db15c17c9c2b78494ee36..a37bbaea0c817df9b00e99daa0b66cfae8fd36f8 100644 (file)
@@ -21,6 +21,7 @@
 
 #ifdef DEAL_II_WITH_SUNDIALS
 
+#  include <deal.II/base/scope_exit.h>
 #  include <deal.II/base/utilities.h>
 
 #  include <deal.II/lac/block_vector.h>
@@ -657,9 +658,40 @@ namespace SUNDIALS
     //   recover and we no longer need the exception
     // - If we have any other exception, rethrow it
     // - If no exception, test that SUNDIALS really did successfully return
+    //
+    // This all creates difficult exit paths from this function. We have to
+    // do some manual clean ups to get rid of the explicitly created
+    // temporary objects of this class. To avoid having to repeat the clean-up
+    // code on each exit path, we package it up and put the code into a
+    // ScopeExit object that is executed automatically on each such path
+    // out of this function.
     Assert(pending_exception == nullptr, ExcInternalError());
     status = KINSol(kinsol_mem, solution, data.strategy, u_scale, f_scale);
 
+    ScopeExit upon_exit([this, &J, &LS]() mutable {
+    // Free the vectors which are no longer used.
+#  ifdef DEAL_II_WITH_MPI
+      if (is_serial_vector<VectorType>::value == false)
+        {
+          N_VDestroy_Parallel(solution);
+          N_VDestroy_Parallel(u_scale);
+          N_VDestroy_Parallel(f_scale);
+        }
+      else
+#  endif
+        {
+          N_VDestroy_Serial(solution);
+          N_VDestroy_Serial(u_scale);
+          N_VDestroy_Serial(f_scale);
+        }
+
+      if (J != nullptr)
+        SUNMatDestroy(J);
+      if (LS != nullptr)
+        SUNLinSolFree(LS);
+      KINFree(&kinsol_mem);
+    });
+
     if (pending_exception)
       {
         try
@@ -684,35 +716,15 @@ namespace SUNDIALS
 
     internal::copy(initial_guess_and_solution, solution);
 
-    // Free the vectors which are no longer used.
-#  ifdef DEAL_II_WITH_MPI
-    if (is_serial_vector<VectorType>::value == false)
-      {
-        N_VDestroy_Parallel(solution);
-        N_VDestroy_Parallel(u_scale);
-        N_VDestroy_Parallel(f_scale);
-      }
-    else
-#  endif
-      {
-        N_VDestroy_Serial(solution);
-        N_VDestroy_Serial(u_scale);
-        N_VDestroy_Serial(f_scale);
-      }
-
     long nniters;
     status = KINGetNumNonlinSolvIters(kinsol_mem, &nniters);
     AssertKINSOL(status);
 
-    if (J != nullptr)
-      SUNMatDestroy(J);
-    if (LS != nullptr)
-      SUNLinSolFree(LS);
-    KINFree(&kinsol_mem);
-
     return static_cast<unsigned int>(nniters);
   }
 
+
+
   template <typename VectorType>
   void
   KINSOL<VectorType>::set_functions_to_trigger_an_assert()

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.