From 0c5d8d59916a6393f3d13823a88ddb69c7e68ab1 Mon Sep 17 00:00:00 2001 From: Denis Davydov Date: Tue, 15 Dec 2015 11:32:18 +0100 Subject: [PATCH] allow creation of PETSc preconditioners without a matrix (Jacobi/BoomerAMG) --- include/deal.II/lac/petsc_precondition.h | 46 +++++++++++++-- source/lac/petsc_precondition.cc | 75 ++++++++++++++++++------ 2 files changed, 97 insertions(+), 24 deletions(-) diff --git a/include/deal.II/lac/petsc_precondition.h b/include/deal.II/lac/petsc_precondition.h index 4750f06b0c..48008b4fcd 100644 --- a/include/deal.II/lac/petsc_precondition.h +++ b/include/deal.II/lac/petsc_precondition.h @@ -137,12 +137,6 @@ 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, @@ -151,6 +145,14 @@ namespace PETScWrappers PreconditionJacobi (const MatrixBase &matrix, const AdditionalData &additional_data = AdditionalData()); + /** + * Same as above but without setting a matrix to form the preconditioner. + * Intended to be used with SLEPc objects. + */ + PreconditionJacobi (const MPI_Comm communicator, + const AdditionalData &additional_data = AdditionalData()); + + /** * Initializes the preconditioner object and calculate all data that is * necessary for applying it in a solver. This function is automatically @@ -217,6 +219,14 @@ namespace PETScWrappers PreconditionBlockJacobi (const MatrixBase &matrix, const AdditionalData &additional_data = AdditionalData()); + /** + * Same as above but without setting a matrix to form the preconditioner. + * Intended to be used with SLEPc objects. + */ + PreconditionBlockJacobi (const MPI_Comm communicator, + const AdditionalData &additional_data = AdditionalData()); + + /** * Initializes the preconditioner object and calculate all data that is * necessary for applying it in a solver. This function is automatically @@ -231,6 +241,14 @@ 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(); + }; @@ -713,6 +731,14 @@ namespace PETScWrappers PreconditionBoomerAMG (const MatrixBase &matrix, const AdditionalData &additional_data = AdditionalData()); + /** + * Same as above but without setting a matrix to form the preconditioner. + * Intended to be used with SLEPc objects. + */ + PreconditionBoomerAMG (const MPI_Comm communicator, + const AdditionalData &additional_data = AdditionalData()); + + /** * Initializes the preconditioner object and calculate all data that is * necessary for applying it in a solver. This function is automatically @@ -727,6 +753,14 @@ 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 b4ab5d23f4..8906e0c466 100644 --- a/source/lac/petsc_precondition.cc +++ b/source/lac/petsc_precondition.cc @@ -150,6 +150,17 @@ namespace PETScWrappers /* ----------------- PreconditionBlockJacobi -------------------- */ + PreconditionBlockJacobi::PreconditionBlockJacobi (const MPI_Comm comm, + const AdditionalData &additional_data_) + { + additional_data = additional_data_; + + int ierr = PCCreate(comm, &pc); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + + initialize(); + } + PreconditionBlockJacobi::PreconditionBlockJacobi () {} @@ -163,22 +174,28 @@ namespace PETScWrappers } void - PreconditionBlockJacobi::initialize (const MatrixBase &matrix_, - const AdditionalData &additional_data_) + PreconditionBlockJacobi::initialize() { - matrix = static_cast(matrix_); - additional_data = additional_data_; - - create_pc(); - int ierr; ierr = PCSetType (pc, const_cast(PCBJACOBI)); AssertThrow (ierr == 0, ExcPETScError(ierr)); ierr = PCSetFromOptions (pc); AssertThrow (ierr == 0, ExcPETScError(ierr)); + } - ierr = PCSetUp (pc); + + void + PreconditionBlockJacobi::initialize (const MatrixBase &matrix_, + const AdditionalData &additional_data_) + { + matrix = static_cast(matrix_); + additional_data = additional_data_; + + create_pc(); + initialize(); + + int ierr = PCSetUp (pc); AssertThrow (ierr == 0, ExcPETScError(ierr)); } @@ -434,6 +451,24 @@ namespace PETScWrappers PreconditionBoomerAMG::PreconditionBoomerAMG () {} + PreconditionBoomerAMG::PreconditionBoomerAMG (const MPI_Comm comm, + const AdditionalData &additional_data_) + { + additional_data = additional_data_; + + int ierr = PCCreate(comm, &pc); + AssertThrow (ierr == 0, ExcPETScError(ierr)); + +#ifdef PETSC_HAVE_HYPRE + initialize(); +#else // PETSC_HAVE_HYPRE + (void)pc; + Assert (false, + ExcMessage ("Your PETSc installation does not include a copy of " + "the hypre package necessary for this preconditioner.")); +#endif + } + PreconditionBoomerAMG::PreconditionBoomerAMG (const MatrixBase &matrix, const AdditionalData &additional_data) @@ -441,17 +476,9 @@ namespace PETScWrappers initialize(matrix, additional_data); } - void - PreconditionBoomerAMG::initialize (const MatrixBase &matrix_, - const AdditionalData &additional_data_) + PreconditionBoomerAMG::initialize () { - matrix = static_cast(matrix_); - additional_data = additional_data_; - -#ifdef PETSC_HAVE_HYPRE - create_pc(); - int ierr; ierr = PCSetType (pc, const_cast(PCHYPRE)); AssertThrow (ierr == 0, ExcPETScError(ierr)); @@ -490,8 +517,20 @@ namespace PETScWrappers ierr = PCSetFromOptions (pc); AssertThrow (ierr == 0, ExcPETScError(ierr)); + } - ierr = PCSetUp (pc); + void + PreconditionBoomerAMG::initialize (const MatrixBase &matrix_, + const AdditionalData &additional_data_) + { + matrix = static_cast(matrix_); + additional_data = additional_data_; + +#ifdef PETSC_HAVE_HYPRE + create_pc(); + initialize (); + + int ierr = PCSetUp (pc); AssertThrow (ierr == 0, ExcPETScError(ierr)); #else // PETSC_HAVE_HYPRE -- 2.39.5