@@ -111,98 +111,28 @@ void PetscPreconditioner<T>::set_petsc_preconditioner_type (const Preconditioner
111111 PetscErrorCode ierr = PetscObjectGetComm ((PetscObject )pc , & comm );
112112 if (ierr != LIBMESH_PETSC_SUCCESS )
113113 libmesh_error_msg ("Error retrieving communicator" );
114- Parallel ::Communicator communicator (comm );
114+
115+ #define CasePCSetType (PreconditionerType , PCType ) \
116+ case PreconditionerType: \
117+ LibmeshPetscCallA(comm, PCSetType (pc, const_cast<KSPType>(PCType))); \
118+ break;
115119
116120 switch (preconditioner_type )
117121 {
118- case IDENTITY_PRECOND :
119- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCNONE )));
120- break ;
121-
122- case CHOLESKY_PRECOND :
123- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCCHOLESKY )));
124- break ;
125-
126- case ICC_PRECOND :
127- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCICC )));
128- break ;
129-
130- case ILU_PRECOND :
131- {
132- // In serial, just set the ILU preconditioner type
133- if (communicator .size ())
134- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCILU )));
135- else
136- {
137- // But PETSc has no truly parallel ILU, instead you have to set
138- // an actual parallel preconditioner (e.g. block Jacobi) and then
139- // assign ILU sub-preconditioners.
140- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCBJACOBI )));
141-
142- // Set ILU as the sub preconditioner type
143- set_petsc_subpreconditioner_type (PCILU , pc );
144- }
145- break ;
146- }
147-
148- case LU_PRECOND :
149- {
150- // In serial, just set the LU preconditioner type
151- if (communicator .size ())
152- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCLU )));
153- else
154- {
155- // But PETSc has no truly parallel LU, instead you have to set
156- // an actual parallel preconditioner (e.g. block Jacobi) and then
157- // assign LU sub-preconditioners.
158- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCBJACOBI )));
159-
160- // Set ILU as the sub preconditioner type
161- set_petsc_subpreconditioner_type (PCLU , pc );
162- }
163- break ;
164- }
165-
166- case ASM_PRECOND :
167- {
168- // In parallel, I think ASM uses ILU by default as the sub-preconditioner...
169- // I tried setting a different sub-preconditioner here, but apparently the matrix
170- // is not in the correct state (at this point) to call PCSetUp().
171- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCASM )));
172- break ;
173- }
174-
175- case JACOBI_PRECOND :
176- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCJACOBI )));
177- break ;
178-
179- case BLOCK_JACOBI_PRECOND :
180- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCBJACOBI )));
181- break ;
182-
183- case SOR_PRECOND :
184- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCSOR )));
185- break ;
186-
187- case EISENSTAT_PRECOND :
188- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCEISENSTAT )));
189- break ;
190-
191- case AMG_PRECOND :
192- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCHYPRE )));
193- break ;
194-
195- case SVD_PRECOND :
196- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCSVD )));
197- break ;
198-
199- case USER_PRECOND :
200- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCMAT )));
201- break ;
202-
203- case SHELL_PRECOND :
204- LibmeshPetscCall2 (communicator , PCSetType (pc , const_cast < KSPType > (PCSHELL )));
205- break ;
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 )
206136
207137 default :
208138 libMesh ::err << "ERROR: Unsupported PETSC Preconditioner: "
@@ -214,60 +144,15 @@ void PetscPreconditioner<T>::set_petsc_preconditioner_type (const Preconditioner
214144 // HYPRE is available
215145#ifdef LIBMESH_HAVE_PETSC_HYPRE
216146 if (preconditioner_type == AMG_PRECOND )
217- LibmeshPetscCall2 ( communicator , PCHYPRESetType (pc , "boomeramg" ));
147+ LibmeshPetscCallA ( comm , PCHYPRESetType (pc , "boomeramg" ));
218148#endif
219149
220150 // Let the commandline override stuff
221- LibmeshPetscCall2 (communicator , PCSetFromOptions (pc ));
222- }
223-
224-
225- template < typename T >
226- void PetscPreconditioner < T > ::set_petsc_subpreconditioner_type (const PCType type , PC & pc )
227- {
228- // get the communicator from the PETSc object
229- Parallel ::communicator comm ;
230- PetscErrorCode ierr = PetscObjectGetComm ((PetscObject )pc , & comm );
231- if (ierr != LIBMESH_PETSC_SUCCESS )
232- libmesh_error_msg ("Error retrieving communicator" );
233-
234- // All docs say must call KSPSetUp or PCSetUp before calling PCBJacobiGetSubKSP.
235- // You must call PCSetUp after the preconditioner operators have been set, otherwise you get the:
236- //
237- // "Object is in wrong state!"
238- // "Matrix must be set first."
239- //
240- // error messages...
241- LibmeshPetscCallA (comm , PCSetUp (pc ));
242-
243- // To store array of local KSP contexts on this processor
244- KSP * subksps ;
245-
246- // the number of blocks on this processor
247- PetscInt n_local ;
248-
249- // The global number of the first block on this processor.
250- // This is not used, so we just pass null instead.
251- // int first_local;
252-
253- // Fill array of local KSP contexts
254- LibmeshPetscCallA (comm , PCBJacobiGetSubKSP (pc , & n_local , LIBMESH_PETSC_NULLPTR , & subksps ));
255-
256- // Loop over sub-ksp objects, set ILU preconditioner
257- for (PetscInt i = 0 ; i < n_local ; ++ i )
258- {
259- // Get pointer to sub KSP object's PC
260- PC subpc ;
261- LibmeshPetscCallA (comm , KSPGetPC (subksps [i ], & subpc ));
262-
263- // Set requested type on the sub PC
264- LibmeshPetscCallA (comm , PCSetType (subpc , type ));
265- }
151+ LibmeshPetscCallA (comm , PCSetFromOptions (pc ));
266152}
267153
268154
269155
270-
271156//------------------------------------------------------------------
272157// Explicit instantiations
273158template class LIBMESH_EXPORT PetscPreconditioner < Number > ;
0 commit comments