libMesh
petsc_preconditioner.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 #include "libmesh/libmesh_common.h"
19 
20 #ifdef LIBMESH_HAVE_PETSC
21 
22 // Local Includes
23 #include "libmesh/petsc_preconditioner.h"
24 #include "libmesh/petsc_macro.h"
25 #include "libmesh/petsc_matrix_base.h"
26 #include "libmesh/petsc_vector.h"
27 #include "libmesh/libmesh_common.h"
28 #include "libmesh/enum_preconditioner_type.h"
29 
30 namespace libMesh
31 {
32 
33 template <typename T>
35  Preconditioner<T>(comm_in)
36 {}
37 
38 
39 
40 template <typename T>
42 {
43  PetscVector<T> & x_pvec = cast_ref<PetscVector<T> &>(const_cast<NumericVector<T> &>(x));
44  PetscVector<T> & y_pvec = cast_ref<PetscVector<T> &>(const_cast<NumericVector<T> &>(y));
45 
46  Vec x_vec = x_pvec.vec();
47  Vec y_vec = y_pvec.vec();
48 
49  LibmeshPetscCall(PCApply(_pc, x_vec, y_vec));
50 }
51 
52 
53 
54 
55 template <typename T>
57 {
58  libmesh_error_msg_if(!this->_matrix, "ERROR: No matrix set for PetscPreconditioner, but init() called");
59 
60  // Clear the preconditioner in case it has been created in the past
61  if (!this->_is_initialized)
62  {
63  // Should probably use PCReset(), but it's not working at the moment so we'll destroy instead
64  if (_pc)
65  _pc.destroy();
66 
67  LibmeshPetscCall(PCCreate(this->comm().get(), _pc.get()));
68 
69  auto pmatrix = cast_ptr<PetscMatrixBase<T> *>(this->_matrix);
70  _mat = pmatrix->mat();
71  }
72 
73  LibmeshPetscCall(PCSetOperators(_pc, _mat, _mat));
74 
75  // Set the PCType. Note: this used to be done *before* the call to
76  // PCSetOperators(), and only when !_is_initialized, but
77  // 1.) Some preconditioners (those employing sub-preconditioners,
78  // for example) have to call PCSetUp(), and can only do this after
79  // the operators have been set.
80  // 2.) It should be safe to call set_petsc_preconditioner_type()
81  // multiple times.
82  set_petsc_preconditioner_type(this->_preconditioner_type, *_pc);
83 
84  this->_is_initialized = true;
85 }
86 
87 
88 
89 template <typename T>
91 {
92  // Calls custom deleter
93  _pc.destroy();
94 }
95 
96 
97 
98 template <typename T>
100 {
101  return _pc;
102 }
103 
104 
105 
106 template <typename T>
108 {
109  // get the communicator from the PETSc object
110  Parallel::communicator comm;
111  PetscErrorCode ierr = PetscObjectGetComm((PetscObject)pc, & comm);
112  if (ierr != LIBMESH_PETSC_SUCCESS)
113  libmesh_error_msg("Error retrieving communicator");
114 
115  #define CasePCSetType(PreconditionerType, PCType) \
116  case PreconditionerType: \
117  LibmeshPetscCallA(comm, PCSetType (pc, const_cast<KSPType>(PCType))); \
118  break;
119 
120  switch (preconditioner_type)
121  {
122  CasePCSetType(IDENTITY_PRECOND, PCNONE)
123  CasePCSetType(CHOLESKY_PRECOND, PCCHOLESKY)
124  CasePCSetType(ICC_PRECOND, PCICC)
125  CasePCSetType(ILU_PRECOND, PCILU)
126  CasePCSetType(LU_PRECOND, PCLU)
127  CasePCSetType(ASM_PRECOND, PCASM)
128  CasePCSetType(JACOBI_PRECOND, PCJACOBI)
129  CasePCSetType(BLOCK_JACOBI_PRECOND, PCBJACOBI)
130  CasePCSetType(SOR_PRECOND, PCSOR)
131  CasePCSetType(EISENSTAT_PRECOND, PCEISENSTAT)
132  CasePCSetType(AMG_PRECOND, PCHYPRE)
133  CasePCSetType(SVD_PRECOND, PCSVD)
134  CasePCSetType(USER_PRECOND, PCMAT)
135  CasePCSetType(SHELL_PRECOND, PCSHELL)
136 
137  default:
138  libMesh::err << "ERROR: Unsupported PETSC Preconditioner: "
139  << Utility::enum_to_string(preconditioner_type) << std::endl
140  << "Continuing with PETSC defaults" << std::endl;
141  }
142 
143  // Set additional options if we are doing AMG and
144  // HYPRE is available
145 #ifdef LIBMESH_HAVE_PETSC_HYPRE
146  if (preconditioner_type == AMG_PRECOND)
147  LibmeshPetscCallA(comm, PCHYPRESetType(pc, "boomeramg"));
148 #endif
149 
150  // Let the commandline override stuff
151  LibmeshPetscCallA(comm, PCSetFromOptions(pc));
152 }
153 
154 
155 
156 //------------------------------------------------------------------
157 // Explicit instantiations
158 template class LIBMESH_EXPORT PetscPreconditioner<Number>;
159 
160 } // namespace libMesh
161 
162 #endif // #ifdef LIBMESH_HAVE_PETSC
OStreamProxy err
This class provides a nice interface to PETSc&#39;s Vec object.
Definition: petsc_vector.h:73
This class provides an interface to the suite of preconditioners available from PETSc.
virtual void init() override
Initialize data structures if not done so already.
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
Definition: vector_fe_ex5.C:44
The libMesh namespace provides an interface to certain functionality in the library.
virtual void apply(const NumericVector< T > &x, NumericVector< T > &y) override
Computes the preconditioned vector y based on input vector x.
This class provides a uniform interface for preconditioners.
bool _is_initialized
Flag that tells if init() has been called.
Definition: libmesh.C:257
PetscPreconditioner(const libMesh::Parallel::Communicator &comm_in)
Constructor.
virtual void clear() override
Release all memory and clear data structures.
static void set_petsc_preconditioner_type(const PreconditionerType &preconditioner_type, PC &pc)
Tells PETSc to use the user-specified preconditioner.
PreconditionerType
Defines an enum for preconditioner types.
std::string enum_to_string(const T e)