]> https://gitweb.dealii.org/ - dealii.git/commitdiff
allow initialisation of PETSc solvers with preconditioners; make SLEPc::Transformatio...
authorDenis Davydov <davydden@gmail.com>
Sat, 12 Dec 2015 19:51:22 +0000 (20:51 +0100)
committerDenis Davydov <davydden@gmail.com>
Tue, 29 Dec 2015 09:12:01 +0000 (10:12 +0100)
include/deal.II/lac/petsc_solver.h
source/lac/petsc_solver.cc

index d0a1e1aed1f9378d5728b7f66e76a6cdb1e2f432..55a18791e3229b685d7c5419aa34f928baf0baa7 100644 (file)
 
 #  include <petscksp.h>
 
+#ifdef DEAL_II_WITH_SLEPC
+#include <deal.II/lac/slepc_spectral_transformation.h>
+#endif
+
 DEAL_II_NAMESPACE_OPEN
 
+#ifdef DEAL_II_WITH_SLEPC
+namespace SLEPcWrappers
+{
+  // forward declarations
+  class TransformationBase;
+}
+#endif
 
 namespace PETScWrappers
 {
@@ -145,6 +156,12 @@ namespace PETScWrappers
      */
     SolverControl &control() const;
 
+    /**
+     * Initialise the solver with the preconditioner.
+     * This function is intended for use with SLEPc spectral transformation class.
+     */
+    void initialise(const PreconditionerBase &preconditioner);
+
     /**
      * Exception
      */
@@ -221,10 +238,9 @@ namespace PETScWrappers
       ~SolverData ();
 
       /**
-       * Objects for Krylov subspace solvers and preconditioners.
+       * Object for Krylov subspace solvers.
        */
       KSP  ksp;
-      PC   pc;
     };
 
     /**
@@ -232,6 +248,11 @@ namespace PETScWrappers
      * in the main solver routine if necessary.
      */
     std_cxx11::shared_ptr<SolverData> solver_data;
+
+    /**
+     * Make the transformation class a friend, since it needs to set the solver.
+     */
+    friend SLEPcWrappers::TransformationBase;
   };
 
 
index 4f810cdfadcb63b1311712e258b22ff2cfa2be82..4e702f4bce29a8b61221f7728e09392bac74f756 100644 (file)
@@ -33,14 +33,17 @@ namespace PETScWrappers
 
   SolverBase::SolverData::~SolverData ()
   {
-    // destroy the solver object
+    if (ksp != NULL)
+      {
+        // destroy the solver object
 #if DEAL_II_PETSC_VERSION_LT(3,2,0)
-    int ierr = KSPDestroy (ksp);
+        int ierr = KSPDestroy (ksp);
 #else
-    int ierr = KSPDestroy (&ksp);
+        int ierr = KSPDestroy (&ksp);
 #endif
 
-    AssertThrow (ierr == 0, ExcPETScError(ierr));
+        AssertThrow (ierr == 0, ExcPETScError(ierr));
+      }
   }
 
 
@@ -202,6 +205,40 @@ namespace PETScWrappers
     return 0;
   }
 
+  void
+  SolverBase::initialise(const PreconditionerBase &preconditioner)
+  {
+    int ierr;
+
+    solver_data.reset (new SolverData());
+
+    ierr = KSPCreate (mpi_communicator, &solver_data->ksp);
+    AssertThrow (ierr == 0, ExcPETScError(ierr));
+
+    // let derived classes set the solver
+    // type, and the preconditioning
+    // object set the type of
+    // preconditioner
+    set_solver_type (solver_data->ksp);
+
+    ierr = KSPSetPC (solver_data->ksp, preconditioner.get_pc());
+    AssertThrow (ierr == 0, ExcPETScError(ierr));
+
+    // then a convergence monitor
+    // function. that function simply
+    // checks with the solver_control
+    // object we have in this object for
+    // convergence
+    KSPSetConvergenceTest (solver_data->ksp, &convergence_test,
+                           reinterpret_cast<void *>(&solver_control),
+                           PETSC_NULL);
+
+    // set the command line options provided
+    // by the user to override the defaults
+    ierr = KSPSetFromOptions (solver_data->ksp);
+    AssertThrow (ierr == 0, ExcPETScError(ierr));
+  }
+
 
 
   /* ---------------------- SolverRichardson ------------------------ */

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.