18 #include "libmesh/libmesh_common.h"
20 #ifdef LIBMESH_HAVE_PETSC
23 #include "libmesh/petsc_preconditioner.h"
24 #include "libmesh/petsc_macro.h"
25 #include "libmesh/petsc_matrix.h"
26 #include "libmesh/petsc_vector.h"
27 #include "libmesh/libmesh_common.h"
28 #include "libmesh/enum_preconditioner_type.h"
34 PetscPreconditioner<T>::PetscPreconditioner (
const libMesh::Parallel::Communicator & comm_in) :
35 Preconditioner<T>(comm_in)
41 void PetscPreconditioner<T>::apply(
const NumericVector<T> & x, NumericVector<T> & y)
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));
46 Vec x_vec = x_pvec.vec();
47 Vec y_vec = y_pvec.vec();
49 PetscErrorCode ierr = PCApply(_pc, x_vec, y_vec);
57 void PetscPreconditioner<T>::init ()
59 libmesh_error_msg_if(!this->_matrix,
"ERROR: No matrix set for PetscPreconditioner, but init() called");
68 PetscErrorCode ierr = PCCreate(this->comm().
get(), _pc.get());
71 auto pmatrix = cast_ptr<PetscMatrix<T> *>(this->_matrix);
72 _mat = pmatrix->mat();
75 PetscErrorCode ierr = PCSetOperators(_pc, _mat, _mat);
85 set_petsc_preconditioner_type(this->_preconditioner_type, *_pc);
93 void PetscPreconditioner<T>::clear()
101 template <
typename T>
102 PC PetscPreconditioner<T>::pc()
109 template <
typename T>
110 void PetscPreconditioner<T>::set_petsc_preconditioner_type (
const PreconditionerType & preconditioner_type, PC & pc)
112 PetscErrorCode ierr = 0;
115 Parallel::communicator comm;
116 PetscObjectGetComm((PetscObject)pc, & comm);
117 Parallel::Communicator communicator(comm);
119 switch (preconditioner_type)
121 case IDENTITY_PRECOND:
122 ierr = PCSetType (pc, const_cast<KSPType>(PCNONE));
123 CHKERRABORT(comm,ierr);
126 case CHOLESKY_PRECOND:
127 ierr = PCSetType (pc, const_cast<KSPType>(PCCHOLESKY));
128 CHKERRABORT(comm,ierr);
132 ierr = PCSetType (pc, const_cast<KSPType>(PCICC));
133 CHKERRABORT(comm,ierr);
139 if (communicator.size())
141 ierr = PCSetType (pc, const_cast<KSPType>(PCILU));
142 CHKERRABORT(comm,ierr);
149 ierr = PCSetType (pc, const_cast<KSPType>(PCBJACOBI));
150 CHKERRABORT(comm,ierr);
153 set_petsc_subpreconditioner_type(PCILU, pc);
161 if (communicator.size())
163 ierr = PCSetType (pc, const_cast<KSPType>(PCLU));
164 CHKERRABORT(comm,ierr);
171 ierr = PCSetType (pc, const_cast<KSPType>(PCBJACOBI));
172 CHKERRABORT(comm,ierr);
175 set_petsc_subpreconditioner_type(PCLU, pc);
185 ierr = PCSetType (pc, const_cast<KSPType>(PCASM));
186 CHKERRABORT(comm,ierr);
191 ierr = PCSetType (pc, const_cast<KSPType>(PCJACOBI));
192 CHKERRABORT(comm,ierr);
195 case BLOCK_JACOBI_PRECOND:
196 ierr = PCSetType (pc, const_cast<KSPType>(PCBJACOBI));
197 CHKERRABORT(comm,ierr);
201 ierr = PCSetType (pc, const_cast<KSPType>(PCSOR));
202 CHKERRABORT(comm,ierr);
205 case EISENSTAT_PRECOND:
206 ierr = PCSetType (pc, const_cast<KSPType>(PCEISENSTAT));
207 CHKERRABORT(comm,ierr);
211 ierr = PCSetType (pc, const_cast<KSPType>(PCHYPRE));
212 CHKERRABORT(comm,ierr);
216 ierr = PCSetType (pc, const_cast<KSPType>(PCSVD));
217 CHKERRABORT(comm,ierr);
221 ierr = PCSetType (pc, const_cast<KSPType>(PCMAT));
222 CHKERRABORT(comm,ierr);
226 ierr = PCSetType (pc, const_cast<KSPType>(PCSHELL));
227 CHKERRABORT(comm,ierr);
231 libMesh::err <<
"ERROR: Unsupported PETSC Preconditioner: "
232 << preconditioner_type << std::endl
233 <<
"Continuing with PETSC defaults" << std::endl;
238 #ifdef LIBMESH_HAVE_PETSC_HYPRE
239 if (preconditioner_type == AMG_PRECOND)
241 ierr = PCHYPRESetType(pc,
"boomeramg");
242 CHKERRABORT(comm,ierr);
247 ierr = PCSetFromOptions(pc);
248 CHKERRABORT(comm,ierr);
252 template <
typename T>
253 void PetscPreconditioner<T>::set_petsc_subpreconditioner_type(
const PCType type, PC & pc)
256 PetscErrorCode ierr = 0;
259 Parallel::communicator comm;
260 PetscObjectGetComm((PetscObject)pc, & comm);
261 Parallel::Communicator communicator(comm);
271 CHKERRABORT(comm,ierr);
284 ierr = PCBJacobiGetSubKSP(pc, &n_local, LIBMESH_PETSC_NULLPTR,
286 CHKERRABORT(comm,ierr);
289 for (PetscInt i=0; i<n_local; ++i)
293 ierr = KSPGetPC(subksps[i], &subpc);
294 CHKERRABORT(comm,ierr);
297 ierr = PCSetType(subpc, type);
298 CHKERRABORT(comm,ierr);
311 #endif // #ifdef LIBMESH_HAVE_PETSC
bool _is_initialized
Flag that tells if init() has been called.
template class LIBMESH_EXPORT PetscPreconditioner< Number >