From e41f0b982c9c4228b812bbc3f214c8b9f28946cf Mon Sep 17 00:00:00 2001
From: Denis Davydov <davydden@gmail.com>
Date: Sat, 12 Dec 2015 20:18:02 +0100
Subject: [PATCH] allow creation of PETSc preconditioners without a matrix

---
 include/deal.II/lac/petsc_precondition.h | 13 ++++++++++
 source/lac/petsc_precondition.cc         | 31 ++++++++++++++++++------
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/include/deal.II/lac/petsc_precondition.h b/include/deal.II/lac/petsc_precondition.h
index da608b85e1..4750f06b0c 100644
--- a/include/deal.II/lac/petsc_precondition.h
+++ b/include/deal.II/lac/petsc_precondition.h
@@ -137,6 +137,12 @@ namespace PETScWrappers
      */
     PreconditionJacobi ();
 
+    /**
+     * A constructor intended to be used with SLEPc objects.
+     */
+    PreconditionJacobi (const MPI_Comm communicator,
+                        const AdditionalData &additional_data = AdditionalData());
+
 
     /**
      * Constructor. Take the matrix which is used to form the preconditioner,
@@ -159,6 +165,13 @@ namespace PETScWrappers
      * Store a copy of the flags for this particular preconditioner.
      */
     AdditionalData additional_data;
+
+    /**
+     * Initializes the preconditioner object without knowing a particular matrix.
+     * This function sets up appropriate parameters to the underlying PETSc object
+     * after it has been created.
+     */
+    void initialize();
   };
 
 
diff --git a/source/lac/petsc_precondition.cc b/source/lac/petsc_precondition.cc
index e93175998a..b4ab5d23f4 100644
--- a/source/lac/petsc_precondition.cc
+++ b/source/lac/petsc_precondition.cc
@@ -101,6 +101,17 @@ namespace PETScWrappers
 
 
   /* ----------------- PreconditionJacobi -------------------- */
+  PreconditionJacobi::PreconditionJacobi (const MPI_Comm comm,
+                                          const AdditionalData &additional_data_)
+  {
+    additional_data = additional_data_;
+
+    int ierr = PCCreate(comm, &pc);
+    AssertThrow (ierr == 0, ExcPETScError(ierr));
+
+    initialize();
+  }
+
 
   PreconditionJacobi::PreconditionJacobi ()
   {}
@@ -112,6 +123,16 @@ namespace PETScWrappers
     initialize(matrix, additional_data);
   }
 
+  void
+  PreconditionJacobi::initialize()
+  {
+    int ierr;
+    ierr = PCSetType (pc, const_cast<char *>(PCJACOBI));
+    AssertThrow (ierr == 0, ExcPETScError(ierr));
+
+    ierr = PCSetFromOptions (pc);
+    AssertThrow (ierr == 0, ExcPETScError(ierr));
+  }
 
   void
   PreconditionJacobi::initialize (const MatrixBase     &matrix_,
@@ -121,15 +142,9 @@ namespace PETScWrappers
     additional_data = additional_data_;
 
     create_pc();
+    initialize();
 
-    int ierr;
-    ierr = PCSetType (pc, const_cast<char *>(PCJACOBI));
-    AssertThrow (ierr == 0, ExcPETScError(ierr));
-
-    ierr = PCSetFromOptions (pc);
-    AssertThrow (ierr == 0, ExcPETScError(ierr));
-
-    ierr = PCSetUp (pc);
+    int ierr = PCSetUp (pc);
     AssertThrow (ierr == 0, ExcPETScError(ierr));
   }
 
-- 
2.39.5