xref: /petsc/src/ksp/pc/interface/precon.c (revision 99a14227db32e09bdaad407e56fdbfd3ed7e9701)
1 #define PETSCKSP_DLL
2 
3 /*
4     The PC (preconditioner) interface routines, callable by users.
5 */
6 #include "private/pcimpl.h"            /*I "petscksp.h" I*/
7 
8 /* Logging support */
9 PetscClassId   PC_CLASSID;
10 PetscLogEvent  PC_SetUp, PC_SetUpOnBlocks, PC_Apply, PC_ApplyCoarse, PC_ApplyMultiple, PC_ApplySymmetricLeft;
11 PetscLogEvent  PC_ApplySymmetricRight, PC_ModifySubMatrices, PC_ApplyOnBlocks, PC_ApplyTransposeOnBlocks;
12 
13 #undef __FUNCT__
14 #define __FUNCT__ "PCGetDefaultType_Private"
15 PetscErrorCode PCGetDefaultType_Private(PC pc,const char* type[])
16 {
17   PetscErrorCode ierr;
18   PetscMPIInt    size;
19   PetscTruth     flg1,flg2,set,flg3;
20 
21   PetscFunctionBegin;
22   ierr = MPI_Comm_size(((PetscObject)pc)->comm,&size);CHKERRQ(ierr);
23   if (pc->pmat) {
24     PetscErrorCode (*f)(Mat,PetscTruth*,MatReuse,Mat*);
25     ierr = PetscObjectQueryFunction((PetscObject)pc->pmat,"MatGetDiagonalBlock_C",(void (**)(void))&f);CHKERRQ(ierr);
26     if (size == 1) {
27       ierr = MatGetFactorAvailable(pc->pmat,"petsc",MAT_FACTOR_ICC,&flg1);CHKERRQ(ierr);
28       ierr = MatGetFactorAvailable(pc->pmat,"petsc",MAT_FACTOR_ILU,&flg2);CHKERRQ(ierr);
29       ierr = MatIsSymmetricKnown(pc->pmat,&set,&flg3);CHKERRQ(ierr);
30       if (flg1 && (!flg2 || (set && flg3))) {
31 	*type = PCICC;
32       } else if (flg2) {
33 	*type = PCILU;
34       } else if (f) { /* likely is a parallel matrix run on one processor */
35 	*type = PCBJACOBI;
36       } else {
37 	*type = PCNONE;
38       }
39     } else {
40        if (f) {
41 	*type = PCBJACOBI;
42       } else {
43 	*type = PCNONE;
44       }
45     }
46   } else {
47     if (size == 1) {
48       *type = PCILU;
49     } else {
50       *type = PCBJACOBI;
51     }
52   }
53   PetscFunctionReturn(0);
54 }
55 
56 #undef __FUNCT__
57 #define __FUNCT__ "PCDestroy"
58 /*@
59    PCDestroy - Destroys PC context that was created with PCCreate().
60 
61    Collective on PC
62 
63    Input Parameter:
64 .  pc - the preconditioner context
65 
66    Level: developer
67 
68 .keywords: PC, destroy
69 
70 .seealso: PCCreate(), PCSetUp()
71 @*/
72 PetscErrorCode PETSCKSP_DLLEXPORT PCDestroy(PC pc)
73 {
74   PetscErrorCode ierr;
75 
76   PetscFunctionBegin;
77   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
78   if (--((PetscObject)pc)->refct > 0) PetscFunctionReturn(0);
79 
80   /* if memory was published with AMS then destroy it */
81   ierr = PetscObjectDepublish(pc);CHKERRQ(ierr);
82   if (pc->dm) {ierr = DMDestroy(pc->dm);CHKERRQ(ierr);}
83 
84   if (pc->ops->destroy)       {ierr =  (*pc->ops->destroy)(pc);CHKERRQ(ierr);}
85   if (pc->diagonalscaleright) {ierr = VecDestroy(pc->diagonalscaleright);CHKERRQ(ierr);}
86   if (pc->diagonalscaleleft)  {ierr = VecDestroy(pc->diagonalscaleleft);CHKERRQ(ierr);}
87 
88   if (pc->pmat) {ierr = MatDestroy(pc->pmat);CHKERRQ(ierr);}
89   if (pc->mat) {ierr = MatDestroy(pc->mat);CHKERRQ(ierr);}
90 
91   ierr = PetscHeaderDestroy(pc);CHKERRQ(ierr);
92   PetscFunctionReturn(0);
93 }
94 
95 #undef __FUNCT__
96 #define __FUNCT__ "PCGetDiagonalScale"
97 /*@C
98    PCGetDiagonalScale - Indicates if the preconditioner applies an additional left and right
99       scaling as needed by certain time-stepping codes.
100 
101    Logically Collective on PC
102 
103    Input Parameter:
104 .  pc - the preconditioner context
105 
106    Output Parameter:
107 .  flag - PETSC_TRUE if it applies the scaling
108 
109    Level: developer
110 
111    Notes: If this returns PETSC_TRUE then the system solved via the Krylov method is
112 $           D M A D^{-1} y = D M b  for left preconditioning or
113 $           D A M D^{-1} z = D b for right preconditioning
114 
115 .keywords: PC
116 
117 .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleLeft(), PCDiagonalScaleRight(), PCSetDiagonalScale()
118 @*/
119 PetscErrorCode PETSCKSP_DLLEXPORT PCGetDiagonalScale(PC pc,PetscTruth *flag)
120 {
121   PetscFunctionBegin;
122   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
123   PetscValidPointer(flag,2);
124   *flag = pc->diagonalscale;
125   PetscFunctionReturn(0);
126 }
127 
128 #undef __FUNCT__
129 #define __FUNCT__ "PCSetDiagonalScale"
130 /*@
131    PCSetDiagonalScale - Indicates the left scaling to use to apply an additional left and right
132       scaling as needed by certain time-stepping codes.
133 
134    Logically Collective on PC
135 
136    Input Parameters:
137 +  pc - the preconditioner context
138 -  s - scaling vector
139 
140    Level: intermediate
141 
142    Notes: The system solved via the Krylov method is
143 $           D M A D^{-1} y = D M b  for left preconditioning or
144 $           D A M D^{-1} z = D b for right preconditioning
145 
146    PCDiagonalScaleLeft() scales a vector by D. PCDiagonalScaleRight() scales a vector by D^{-1}.
147 
148 .keywords: PC
149 
150 .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleLeft(), PCDiagonalScaleRight(), PCGetDiagonalScale()
151 @*/
152 PetscErrorCode PETSCKSP_DLLEXPORT PCSetDiagonalScale(PC pc,Vec s)
153 {
154   PetscErrorCode ierr;
155 
156   PetscFunctionBegin;
157   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
158   PetscValidHeaderSpecific(s,VEC_CLASSID,2);
159   pc->diagonalscale     = PETSC_TRUE;
160   ierr = PetscObjectReference((PetscObject)s);CHKERRQ(ierr);
161   if (pc->diagonalscaleleft) {
162     ierr = VecDestroy(pc->diagonalscaleleft);CHKERRQ(ierr);
163   }
164   pc->diagonalscaleleft = s;
165   if (!pc->diagonalscaleright) {
166     ierr = VecDuplicate(s,&pc->diagonalscaleright);CHKERRQ(ierr);
167   }
168   ierr = VecCopy(s,pc->diagonalscaleright);CHKERRQ(ierr);
169   ierr = VecReciprocal(pc->diagonalscaleright);CHKERRQ(ierr);
170   PetscFunctionReturn(0);
171 }
172 
173 #undef __FUNCT__
174 #define __FUNCT__ "PCDiagonalScaleLeft"
175 /*@
176    PCDiagonalScaleLeft - Scales a vector by the left scaling as needed by certain time-stepping codes.
177 
178    Logically Collective on PC
179 
180    Input Parameters:
181 +  pc - the preconditioner context
182 .  in - input vector
183 +  out - scaled vector (maybe the same as in)
184 
185    Level: intermediate
186 
187    Notes: The system solved via the Krylov method is
188 $           D M A D^{-1} y = D M b  for left preconditioning or
189 $           D A M D^{-1} z = D b for right preconditioning
190 
191    PCDiagonalScaleLeft() scales a vector by D. PCDiagonalScaleRight() scales a vector by D^{-1}.
192 
193    If diagonal scaling is turned off and in is not out then in is copied to out
194 
195 .keywords: PC
196 
197 .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleSet(), PCDiagonalScaleRight(), PCDiagonalScale()
198 @*/
199 PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScaleLeft(PC pc,Vec in,Vec out)
200 {
201   PetscErrorCode ierr;
202 
203   PetscFunctionBegin;
204   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
205   PetscValidHeaderSpecific(in,VEC_CLASSID,2);
206   PetscValidHeaderSpecific(out,VEC_CLASSID,3);
207   if (pc->diagonalscale) {
208     ierr = VecPointwiseMult(out,pc->diagonalscaleleft,in);CHKERRQ(ierr);
209   } else if (in != out) {
210     ierr = VecCopy(in,out);CHKERRQ(ierr);
211   }
212   PetscFunctionReturn(0);
213 }
214 
215 #undef __FUNCT__
216 #define __FUNCT__ "PCDiagonalScaleRight"
217 /*@
218    PCDiagonalScaleRight - Scales a vector by the right scaling as needed by certain time-stepping codes.
219 
220    Logically Collective on PC
221 
222    Input Parameters:
223 +  pc - the preconditioner context
224 .  in - input vector
225 +  out - scaled vector (maybe the same as in)
226 
227    Level: intermediate
228 
229    Notes: The system solved via the Krylov method is
230 $           D M A D^{-1} y = D M b  for left preconditioning or
231 $           D A M D^{-1} z = D b for right preconditioning
232 
233    PCDiagonalScaleLeft() scales a vector by D. PCDiagonalScaleRight() scales a vector by D^{-1}.
234 
235    If diagonal scaling is turned off and in is not out then in is copied to out
236 
237 .keywords: PC
238 
239 .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleLeft(), PCDiagonalScaleSet(), PCDiagonalScale()
240 @*/
241 PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScaleRight(PC pc,Vec in,Vec out)
242 {
243   PetscErrorCode ierr;
244 
245   PetscFunctionBegin;
246   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
247   PetscValidHeaderSpecific(in,VEC_CLASSID,2);
248   PetscValidHeaderSpecific(out,VEC_CLASSID,3);
249   if (pc->diagonalscale) {
250     ierr = VecPointwiseMult(out,pc->diagonalscaleright,in);CHKERRQ(ierr);
251   } else if (in != out) {
252     ierr = VecCopy(in,out);CHKERRQ(ierr);
253   }
254   PetscFunctionReturn(0);
255 }
256 
257 #if 0
258 #undef __FUNCT__
259 #define __FUNCT__ "PCPublish_Petsc"
260 static PetscErrorCode PCPublish_Petsc(PetscObject obj)
261 {
262   PetscFunctionBegin;
263   PetscFunctionReturn(0);
264 }
265 #endif
266 
267 #undef __FUNCT__
268 #define __FUNCT__ "PCCreate"
269 /*@
270    PCCreate - Creates a preconditioner context.
271 
272    Collective on MPI_Comm
273 
274    Input Parameter:
275 .  comm - MPI communicator
276 
277    Output Parameter:
278 .  pc - location to put the preconditioner context
279 
280    Notes:
281    The default preconditioner for sparse matrices is PCILU or PCICC with 0 fill on one process and block Jacobi with PCILU or ICC
282    in parallel. For dense matrices it is always PCNONE.
283 
284    Level: developer
285 
286 .keywords: PC, create, context
287 
288 .seealso: PCSetUp(), PCApply(), PCDestroy()
289 @*/
290 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate(MPI_Comm comm,PC *newpc)
291 {
292   PC             pc;
293   PetscErrorCode ierr;
294 
295   PetscFunctionBegin;
296   PetscValidPointer(newpc,1);
297   *newpc = 0;
298 #ifndef PETSC_USE_DYNAMIC_LIBRARIES
299   ierr = PCInitializePackage(PETSC_NULL);CHKERRQ(ierr);
300 #endif
301 
302   ierr = PetscHeaderCreate(pc,_p_PC,struct _PCOps,PC_CLASSID,-1,"PC",comm,PCDestroy,PCView);CHKERRQ(ierr);
303 
304   pc->mat                  = 0;
305   pc->pmat                 = 0;
306   pc->setupcalled          = 0;
307   pc->setfromoptionscalled = 0;
308   pc->data                 = 0;
309   pc->diagonalscale        = PETSC_FALSE;
310   pc->diagonalscaleleft    = 0;
311   pc->diagonalscaleright   = 0;
312 
313   pc->modifysubmatrices   = 0;
314   pc->modifysubmatricesP  = 0;
315   *newpc = pc;
316   PetscFunctionReturn(0);
317 
318 }
319 
320 /* -------------------------------------------------------------------------------*/
321 
322 #undef __FUNCT__
323 #define __FUNCT__ "PCApply"
324 /*@
325    PCApply - Applies the preconditioner to a vector.
326 
327    Collective on PC and Vec
328 
329    Input Parameters:
330 +  pc - the preconditioner context
331 -  x - input vector
332 
333    Output Parameter:
334 .  y - output vector
335 
336    Level: developer
337 
338 .keywords: PC, apply
339 
340 .seealso: PCApplyTranspose(), PCApplyBAorAB()
341 @*/
342 PetscErrorCode PETSCKSP_DLLEXPORT PCApply(PC pc,Vec x,Vec y)
343 {
344   PetscErrorCode ierr;
345 
346   PetscFunctionBegin;
347   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
348   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
349   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
350   if (x == y) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_IDN,"x and y must be different vectors");
351   if (pc->setupcalled < 2) {
352     ierr = PCSetUp(pc);CHKERRQ(ierr);
353   }
354   if (!pc->ops->apply) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_SUP,"PC does not have apply");
355   ierr = PetscLogEventBegin(PC_Apply,pc,x,y,0);CHKERRQ(ierr);
356   ierr = (*pc->ops->apply)(pc,x,y);CHKERRQ(ierr);
357   ierr = PetscLogEventEnd(PC_Apply,pc,x,y,0);CHKERRQ(ierr);
358   PetscFunctionReturn(0);
359 }
360 
361 #undef __FUNCT__
362 #define __FUNCT__ "PCApplySymmetricLeft"
363 /*@
364    PCApplySymmetricLeft - Applies the left part of a symmetric preconditioner to a vector.
365 
366    Collective on PC and Vec
367 
368    Input Parameters:
369 +  pc - the preconditioner context
370 -  x - input vector
371 
372    Output Parameter:
373 .  y - output vector
374 
375    Notes:
376    Currently, this routine is implemented only for PCICC and PCJACOBI preconditioners.
377 
378    Level: developer
379 
380 .keywords: PC, apply, symmetric, left
381 
382 .seealso: PCApply(), PCApplySymmetricRight()
383 @*/
384 PetscErrorCode PETSCKSP_DLLEXPORT PCApplySymmetricLeft(PC pc,Vec x,Vec y)
385 {
386   PetscErrorCode ierr;
387 
388   PetscFunctionBegin;
389   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
390   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
391   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
392   if (x == y) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_IDN,"x and y must be different vectors");
393   if (pc->setupcalled < 2) {
394     ierr = PCSetUp(pc);CHKERRQ(ierr);
395   }
396   if (!pc->ops->applysymmetricleft) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_SUP,"PC does not have left symmetric apply");
397   ierr = PetscLogEventBegin(PC_ApplySymmetricLeft,pc,x,y,0);CHKERRQ(ierr);
398   ierr = (*pc->ops->applysymmetricleft)(pc,x,y);CHKERRQ(ierr);
399   ierr = PetscLogEventEnd(PC_ApplySymmetricLeft,pc,x,y,0);CHKERRQ(ierr);
400   PetscFunctionReturn(0);
401 }
402 
403 #undef __FUNCT__
404 #define __FUNCT__ "PCApplySymmetricRight"
405 /*@
406    PCApplySymmetricRight - Applies the right part of a symmetric preconditioner to a vector.
407 
408    Collective on PC and Vec
409 
410    Input Parameters:
411 +  pc - the preconditioner context
412 -  x - input vector
413 
414    Output Parameter:
415 .  y - output vector
416 
417    Level: developer
418 
419    Notes:
420    Currently, this routine is implemented only for PCICC and PCJACOBI preconditioners.
421 
422 .keywords: PC, apply, symmetric, right
423 
424 .seealso: PCApply(), PCApplySymmetricLeft()
425 @*/
426 PetscErrorCode PETSCKSP_DLLEXPORT PCApplySymmetricRight(PC pc,Vec x,Vec y)
427 {
428   PetscErrorCode ierr;
429 
430   PetscFunctionBegin;
431   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
432   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
433   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
434   if (x == y) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_IDN,"x and y must be different vectors");
435   if (pc->setupcalled < 2) {
436     ierr = PCSetUp(pc);CHKERRQ(ierr);
437   }
438   if (!pc->ops->applysymmetricright) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_SUP,"PC does not have left symmetric apply");
439   ierr = PetscLogEventBegin(PC_ApplySymmetricRight,pc,x,y,0);CHKERRQ(ierr);
440   ierr = (*pc->ops->applysymmetricright)(pc,x,y);CHKERRQ(ierr);
441   ierr = PetscLogEventEnd(PC_ApplySymmetricRight,pc,x,y,0);CHKERRQ(ierr);
442   PetscFunctionReturn(0);
443 }
444 
445 #undef __FUNCT__
446 #define __FUNCT__ "PCApplyTranspose"
447 /*@
448    PCApplyTranspose - Applies the transpose of preconditioner to a vector.
449 
450    Collective on PC and Vec
451 
452    Input Parameters:
453 +  pc - the preconditioner context
454 -  x - input vector
455 
456    Output Parameter:
457 .  y - output vector
458 
459    Level: developer
460 
461 .keywords: PC, apply, transpose
462 
463 .seealso: PCApply(), PCApplyBAorAB(), PCApplyBAorABTranspose(), PCApplyTransposeExists()
464 @*/
465 PetscErrorCode PETSCKSP_DLLEXPORT PCApplyTranspose(PC pc,Vec x,Vec y)
466 {
467   PetscErrorCode ierr;
468 
469   PetscFunctionBegin;
470   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
471   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
472   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
473   if (x == y) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_IDN,"x and y must be different vectors");
474   if (pc->setupcalled < 2) {
475     ierr = PCSetUp(pc);CHKERRQ(ierr);
476   }
477   if (!pc->ops->applytranspose) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_SUP,"PC does not have apply transpose");
478   ierr = PetscLogEventBegin(PC_Apply,pc,x,y,0);CHKERRQ(ierr);
479   ierr = (*pc->ops->applytranspose)(pc,x,y);CHKERRQ(ierr);
480   ierr = PetscLogEventEnd(PC_Apply,pc,x,y,0);CHKERRQ(ierr);
481   PetscFunctionReturn(0);
482 }
483 
484 #undef __FUNCT__
485 #define __FUNCT__ "PCApplyTransposeExists"
486 /*@
487    PCApplyTransposeExists - Test whether the preconditioner has a transpose apply operation
488 
489    Collective on PC and Vec
490 
491    Input Parameters:
492 .  pc - the preconditioner context
493 
494    Output Parameter:
495 .  flg - PETSC_TRUE if a transpose operation is defined
496 
497    Level: developer
498 
499 .keywords: PC, apply, transpose
500 
501 .seealso: PCApplyTranspose()
502 @*/
503 PetscErrorCode PETSCKSP_DLLEXPORT PCApplyTransposeExists(PC pc,PetscTruth *flg)
504 {
505   PetscFunctionBegin;
506   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
507   PetscValidPointer(flg,2);
508   if (pc->ops->applytranspose) *flg = PETSC_TRUE;
509   else                         *flg = PETSC_FALSE;
510   PetscFunctionReturn(0);
511 }
512 
513 #undef __FUNCT__
514 #define __FUNCT__ "PCApplyBAorAB"
515 /*@
516    PCApplyBAorAB - Applies the preconditioner and operator to a vector. y = B*A*x or y = A*B*x.
517 
518    Collective on PC and Vec
519 
520    Input Parameters:
521 +  pc - the preconditioner context
522 .  side - indicates the preconditioner side, one of PC_LEFT, PC_RIGHT, or PC_SYMMETRIC
523 .  x - input vector
524 -  work - work vector
525 
526    Output Parameter:
527 .  y - output vector
528 
529    Level: developer
530 
531 .keywords: PC, apply, operator
532 
533 .seealso: PCApply(), PCApplyTranspose(), PCApplyBAorABTranspose()
534 @*/
535 PetscErrorCode PETSCKSP_DLLEXPORT PCApplyBAorAB(PC pc,PCSide side,Vec x,Vec y,Vec work)
536 {
537   PetscErrorCode ierr;
538 
539   PetscFunctionBegin;
540   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
541   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
542   PetscValidHeaderSpecific(y,VEC_CLASSID,4);
543   PetscValidHeaderSpecific(work,VEC_CLASSID,5);
544   if (x == y) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_IDN,"x and y must be different vectors");
545   if (side != PC_LEFT && side != PC_SYMMETRIC && side != PC_RIGHT) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Side must be right, left, or symmetric");
546   if (pc->diagonalscale && side == PC_SYMMETRIC) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_SUP,"Cannot include diagonal scaling with symmetric preconditioner application");
547 
548   if (pc->setupcalled < 2) {
549     ierr = PCSetUp(pc);CHKERRQ(ierr);
550   }
551 
552   if (pc->diagonalscale) {
553     if (pc->ops->applyBA) {
554       Vec work2; /* this is expensive, but to fix requires a second work vector argument to PCApplyBAorAB() */
555       ierr = VecDuplicate(x,&work2);CHKERRQ(ierr);
556       ierr = PCDiagonalScaleRight(pc,x,work2);CHKERRQ(ierr);
557       ierr = (*pc->ops->applyBA)(pc,side,work2,y,work);CHKERRQ(ierr);
558       ierr = PCDiagonalScaleLeft(pc,y,y);CHKERRQ(ierr);
559       ierr = VecDestroy(work2);CHKERRQ(ierr);
560     } else if (side == PC_RIGHT) {
561       ierr = PCDiagonalScaleRight(pc,x,y);CHKERRQ(ierr);
562       ierr = PCApply(pc,y,work);CHKERRQ(ierr);
563       ierr = MatMult(pc->mat,work,y);CHKERRQ(ierr);
564       ierr = PCDiagonalScaleLeft(pc,y,y);CHKERRQ(ierr);
565     } else if (side == PC_LEFT) {
566       ierr = PCDiagonalScaleRight(pc,x,y);CHKERRQ(ierr);
567       ierr = MatMult(pc->mat,y,work);CHKERRQ(ierr);
568       ierr = PCApply(pc,work,y);CHKERRQ(ierr);
569       ierr = PCDiagonalScaleLeft(pc,y,y);CHKERRQ(ierr);
570     } else if (side == PC_SYMMETRIC) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_SUP,"Cannot provide diagonal scaling with symmetric application of preconditioner");
571   } else {
572     if (pc->ops->applyBA) {
573       ierr = (*pc->ops->applyBA)(pc,side,x,y,work);CHKERRQ(ierr);
574     } else if (side == PC_RIGHT) {
575       ierr = PCApply(pc,x,work);CHKERRQ(ierr);
576       ierr = MatMult(pc->mat,work,y);CHKERRQ(ierr);
577     } else if (side == PC_LEFT) {
578       ierr = MatMult(pc->mat,x,work);CHKERRQ(ierr);
579       ierr = PCApply(pc,work,y);CHKERRQ(ierr);
580     } else if (side == PC_SYMMETRIC) {
581       /* There's an extra copy here; maybe should provide 2 work vectors instead? */
582       ierr = PCApplySymmetricRight(pc,x,work);CHKERRQ(ierr);
583       ierr = MatMult(pc->mat,work,y);CHKERRQ(ierr);
584       ierr = VecCopy(y,work);CHKERRQ(ierr);
585       ierr = PCApplySymmetricLeft(pc,work,y);CHKERRQ(ierr);
586     }
587   }
588   PetscFunctionReturn(0);
589 }
590 
591 #undef __FUNCT__
592 #define __FUNCT__ "PCApplyBAorABTranspose"
593 /*@
594    PCApplyBAorABTranspose - Applies the transpose of the preconditioner
595    and operator to a vector. That is, applies tr(B) * tr(A) with left preconditioning,
596    NOT tr(B*A) = tr(A)*tr(B).
597 
598    Collective on PC and Vec
599 
600    Input Parameters:
601 +  pc - the preconditioner context
602 .  side - indicates the preconditioner side, one of PC_LEFT, PC_RIGHT, or PC_SYMMETRIC
603 .  x - input vector
604 -  work - work vector
605 
606    Output Parameter:
607 .  y - output vector
608 
609 
610    Notes: this routine is used internally so that the same Krylov code can be used to solve A x = b and A' x = b, with a preconditioner
611       defined by B'. This is why this has the funny form that it computes tr(B) * tr(A)
612 
613     Level: developer
614 
615 .keywords: PC, apply, operator, transpose
616 
617 .seealso: PCApply(), PCApplyTranspose(), PCApplyBAorAB()
618 @*/
619 PetscErrorCode PETSCKSP_DLLEXPORT PCApplyBAorABTranspose(PC pc,PCSide side,Vec x,Vec y,Vec work)
620 {
621   PetscErrorCode ierr;
622 
623   PetscFunctionBegin;
624   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
625   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
626   PetscValidHeaderSpecific(y,VEC_CLASSID,4);
627   PetscValidHeaderSpecific(work,VEC_CLASSID,5);
628   if (x == y) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_IDN,"x and y must be different vectors");
629   if (pc->ops->applyBAtranspose) {
630     ierr = (*pc->ops->applyBAtranspose)(pc,side,x,y,work);CHKERRQ(ierr);
631     PetscFunctionReturn(0);
632   }
633   if (side != PC_LEFT && side != PC_RIGHT) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Side must be right or left");
634 
635   if (pc->setupcalled < 2) {
636     ierr = PCSetUp(pc);CHKERRQ(ierr);
637   }
638 
639   if (side == PC_RIGHT) {
640     ierr = PCApplyTranspose(pc,x,work);CHKERRQ(ierr);
641     ierr = MatMultTranspose(pc->mat,work,y);CHKERRQ(ierr);
642   } else if (side == PC_LEFT) {
643     ierr = MatMultTranspose(pc->mat,x,work);CHKERRQ(ierr);
644     ierr = PCApplyTranspose(pc,work,y);CHKERRQ(ierr);
645   }
646   /* add support for PC_SYMMETRIC */
647   PetscFunctionReturn(0); /* actually will never get here */
648 }
649 
650 /* -------------------------------------------------------------------------------*/
651 
652 #undef __FUNCT__
653 #define __FUNCT__ "PCApplyRichardsonExists"
654 /*@
655    PCApplyRichardsonExists - Determines whether a particular preconditioner has a
656    built-in fast application of Richardson's method.
657 
658    Not Collective
659 
660    Input Parameter:
661 .  pc - the preconditioner
662 
663    Output Parameter:
664 .  exists - PETSC_TRUE or PETSC_FALSE
665 
666    Level: developer
667 
668 .keywords: PC, apply, Richardson, exists
669 
670 .seealso: PCApplyRichardson()
671 @*/
672 PetscErrorCode PETSCKSP_DLLEXPORT PCApplyRichardsonExists(PC pc,PetscTruth *exists)
673 {
674   PetscFunctionBegin;
675   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
676   PetscValidIntPointer(exists,2);
677   if (pc->ops->applyrichardson) *exists = PETSC_TRUE;
678   else                          *exists = PETSC_FALSE;
679   PetscFunctionReturn(0);
680 }
681 
682 #undef __FUNCT__
683 #define __FUNCT__ "PCApplyRichardson"
684 /*@
685    PCApplyRichardson - Applies several steps of Richardson iteration with
686    the particular preconditioner. This routine is usually used by the
687    Krylov solvers and not the application code directly.
688 
689    Collective on PC
690 
691    Input Parameters:
692 +  pc  - the preconditioner context
693 .  b   - the right hand side
694 .  w   - one work vector
695 .  rtol - relative decrease in residual norm convergence criteria
696 .  abstol - absolute residual norm convergence criteria
697 .  dtol - divergence residual norm increase criteria
698 .  its - the number of iterations to apply.
699 -  guesszero - if the input x contains nonzero initial guess
700 
701    Output Parameter:
702 +  outits - number of iterations actually used (for SOR this always equals its)
703 .  reason - the reason the apply terminated
704 -  y - the solution (also contains initial guess if guesszero is PETSC_FALSE
705 
706    Notes:
707    Most preconditioners do not support this function. Use the command
708    PCApplyRichardsonExists() to determine if one does.
709 
710    Except for the multigrid PC this routine ignores the convergence tolerances
711    and always runs for the number of iterations
712 
713    Level: developer
714 
715 .keywords: PC, apply, Richardson
716 
717 .seealso: PCApplyRichardsonExists()
718 @*/
719 PetscErrorCode PETSCKSP_DLLEXPORT PCApplyRichardson(PC pc,Vec b,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt its,PetscTruth guesszero,PetscInt *outits,PCRichardsonConvergedReason *reason)
720 {
721   PetscErrorCode ierr;
722 
723   PetscFunctionBegin;
724   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
725   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
726   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
727   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
728   if (b == y) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_IDN,"b and y must be different vectors");
729   if (pc->setupcalled < 2) {
730     ierr = PCSetUp(pc);CHKERRQ(ierr);
731   }
732   if (!pc->ops->applyrichardson) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_SUP,"PC does not have apply richardson");
733   ierr = (*pc->ops->applyrichardson)(pc,b,y,w,rtol,abstol,dtol,its,guesszero,outits,reason);CHKERRQ(ierr);
734   PetscFunctionReturn(0);
735 }
736 
737 /*
738       a setupcall of 0 indicates never setup,
739                      1 needs to be resetup,
740                      2 does not need any changes.
741 */
742 #undef __FUNCT__
743 #define __FUNCT__ "PCSetUp"
744 /*@
745    PCSetUp - Prepares for the use of a preconditioner.
746 
747    Collective on PC
748 
749    Input Parameter:
750 .  pc - the preconditioner context
751 
752    Level: developer
753 
754 .keywords: PC, setup
755 
756 .seealso: PCCreate(), PCApply(), PCDestroy()
757 @*/
758 PetscErrorCode PETSCKSP_DLLEXPORT PCSetUp(PC pc)
759 {
760   PetscErrorCode ierr;
761   const char     *def;
762 
763   PetscFunctionBegin;
764   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
765   if (!pc->mat) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be set first");
766 
767   if (pc->setupcalled > 1) {
768     ierr = PetscInfo(pc,"Setting PC with identical preconditioner\n");CHKERRQ(ierr);
769     PetscFunctionReturn(0);
770   } else if (!pc->setupcalled) {
771     ierr = PetscInfo(pc,"Setting up new PC\n");CHKERRQ(ierr);
772   } else if (pc->flag == SAME_NONZERO_PATTERN) {
773     ierr = PetscInfo(pc,"Setting up PC with same nonzero pattern\n");CHKERRQ(ierr);
774   } else {
775     ierr = PetscInfo(pc,"Setting up PC with different nonzero pattern\n");CHKERRQ(ierr);
776   }
777 
778   if (!((PetscObject)pc)->type_name) {
779     ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr);
780     ierr = PCSetType(pc,def);CHKERRQ(ierr);
781   }
782 
783   ierr = PetscLogEventBegin(PC_SetUp,pc,0,0,0);CHKERRQ(ierr);
784   if (pc->ops->setup) {
785     ierr = (*pc->ops->setup)(pc);CHKERRQ(ierr);
786   }
787   pc->setupcalled = 2;
788   ierr = PetscLogEventEnd(PC_SetUp,pc,0,0,0);CHKERRQ(ierr);
789   PetscFunctionReturn(0);
790 }
791 
792 #undef __FUNCT__
793 #define __FUNCT__ "PCSetUpOnBlocks"
794 /*@
795    PCSetUpOnBlocks - Sets up the preconditioner for each block in
796    the block Jacobi, block Gauss-Seidel, and overlapping Schwarz
797    methods.
798 
799    Collective on PC
800 
801    Input Parameters:
802 .  pc - the preconditioner context
803 
804    Level: developer
805 
806 .keywords: PC, setup, blocks
807 
808 .seealso: PCCreate(), PCApply(), PCDestroy(), PCSetUp()
809 @*/
810 PetscErrorCode PETSCKSP_DLLEXPORT PCSetUpOnBlocks(PC pc)
811 {
812   PetscErrorCode ierr;
813 
814   PetscFunctionBegin;
815   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
816   if (!pc->ops->setuponblocks) PetscFunctionReturn(0);
817   ierr = PetscLogEventBegin(PC_SetUpOnBlocks,pc,0,0,0);CHKERRQ(ierr);
818   ierr = (*pc->ops->setuponblocks)(pc);CHKERRQ(ierr);
819   ierr = PetscLogEventEnd(PC_SetUpOnBlocks,pc,0,0,0);CHKERRQ(ierr);
820   PetscFunctionReturn(0);
821 }
822 
823 #undef __FUNCT__
824 #define __FUNCT__ "PCSetModifySubMatrices"
825 /*@C
826    PCSetModifySubMatrices - Sets a user-defined routine for modifying the
827    submatrices that arise within certain subdomain-based preconditioners.
828    The basic submatrices are extracted from the preconditioner matrix as
829    usual; the user can then alter these (for example, to set different boundary
830    conditions for each submatrix) before they are used for the local solves.
831 
832    Logically Collective on PC
833 
834    Input Parameters:
835 +  pc - the preconditioner context
836 .  func - routine for modifying the submatrices
837 -  ctx - optional user-defined context (may be null)
838 
839    Calling sequence of func:
840 $     func (PC pc,PetscInt nsub,IS *row,IS *col,Mat *submat,void *ctx);
841 
842 .  row - an array of index sets that contain the global row numbers
843          that comprise each local submatrix
844 .  col - an array of index sets that contain the global column numbers
845          that comprise each local submatrix
846 .  submat - array of local submatrices
847 -  ctx - optional user-defined context for private data for the
848          user-defined func routine (may be null)
849 
850    Notes:
851    PCSetModifySubMatrices() MUST be called before KSPSetUp() and
852    KSPSolve().
853 
854    A routine set by PCSetModifySubMatrices() is currently called within
855    the block Jacobi (PCBJACOBI) and additive Schwarz (PCASM)
856    preconditioners.  All other preconditioners ignore this routine.
857 
858    Level: advanced
859 
860 .keywords: PC, set, modify, submatrices
861 
862 .seealso: PCModifySubMatrices()
863 @*/
864 PetscErrorCode PETSCKSP_DLLEXPORT PCSetModifySubMatrices(PC pc,PetscErrorCode (*func)(PC,PetscInt,const IS[],const IS[],Mat[],void*),void *ctx)
865 {
866   PetscFunctionBegin;
867   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
868   pc->modifysubmatrices  = func;
869   pc->modifysubmatricesP = ctx;
870   PetscFunctionReturn(0);
871 }
872 
873 #undef __FUNCT__
874 #define __FUNCT__ "PCModifySubMatrices"
875 /*@C
876    PCModifySubMatrices - Calls an optional user-defined routine within
877    certain preconditioners if one has been set with PCSetModifySubMarices().
878 
879    Collective on PC
880 
881    Input Parameters:
882 +  pc - the preconditioner context
883 .  nsub - the number of local submatrices
884 .  row - an array of index sets that contain the global row numbers
885          that comprise each local submatrix
886 .  col - an array of index sets that contain the global column numbers
887          that comprise each local submatrix
888 .  submat - array of local submatrices
889 -  ctx - optional user-defined context for private data for the
890          user-defined routine (may be null)
891 
892    Output Parameter:
893 .  submat - array of local submatrices (the entries of which may
894             have been modified)
895 
896    Notes:
897    The user should NOT generally call this routine, as it will
898    automatically be called within certain preconditioners (currently
899    block Jacobi, additive Schwarz) if set.
900 
901    The basic submatrices are extracted from the preconditioner matrix
902    as usual; the user can then alter these (for example, to set different
903    boundary conditions for each submatrix) before they are used for the
904    local solves.
905 
906    Level: developer
907 
908 .keywords: PC, modify, submatrices
909 
910 .seealso: PCSetModifySubMatrices()
911 @*/
912 PetscErrorCode PETSCKSP_DLLEXPORT PCModifySubMatrices(PC pc,PetscInt nsub,const IS row[],const IS col[],Mat submat[],void *ctx)
913 {
914   PetscErrorCode ierr;
915 
916   PetscFunctionBegin;
917   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
918   if (!pc->modifysubmatrices) PetscFunctionReturn(0);
919   ierr = PetscLogEventBegin(PC_ModifySubMatrices,pc,0,0,0);CHKERRQ(ierr);
920   ierr = (*pc->modifysubmatrices)(pc,nsub,row,col,submat,ctx);CHKERRQ(ierr);
921   ierr = PetscLogEventEnd(PC_ModifySubMatrices,pc,0,0,0);CHKERRQ(ierr);
922   PetscFunctionReturn(0);
923 }
924 
925 #undef __FUNCT__
926 #define __FUNCT__ "PCSetOperators"
927 /*@
928    PCSetOperators - Sets the matrix associated with the linear system and
929    a (possibly) different one associated with the preconditioner.
930 
931    Logically Collective on PC and Mat
932 
933    Input Parameters:
934 +  pc - the preconditioner context
935 .  Amat - the matrix associated with the linear system
936 .  Pmat - the matrix to be used in constructing the preconditioner, usually
937           the same as Amat.
938 -  flag - flag indicating information about the preconditioner matrix structure
939    during successive linear solves.  This flag is ignored the first time a
940    linear system is solved, and thus is irrelevant when solving just one linear
941    system.
942 
943    Notes:
944    The flag can be used to eliminate unnecessary work in the preconditioner
945    during the repeated solution of linear systems of the same size.  The
946    available options are
947 +    SAME_PRECONDITIONER -
948        Pmat is identical during successive linear solves.
949        This option is intended for folks who are using
950        different Amat and Pmat matrices and wish to reuse the
951        same preconditioner matrix.  For example, this option
952        saves work by not recomputing incomplete factorization
953        for ILU/ICC preconditioners.
954 .     SAME_NONZERO_PATTERN -
955        Pmat has the same nonzero structure during
956        successive linear solves.
957 -     DIFFERENT_NONZERO_PATTERN -
958        Pmat does not have the same nonzero structure.
959 
960     Passing a PETSC_NULL for Amat or Pmat removes the matrix that is currently used.
961 
962     If you wish to replace either Amat or Pmat but leave the other one untouched then
963     first call KSPGetOperators() to get the one you wish to keep, call PetscObjectReference()
964     on it and then pass it back in in your call to KSPSetOperators().
965 
966    Caution:
967    If you specify SAME_NONZERO_PATTERN, PETSc believes your assertion
968    and does not check the structure of the matrix.  If you erroneously
969    claim that the structure is the same when it actually is not, the new
970    preconditioner will not function correctly.  Thus, use this optimization
971    feature carefully!
972 
973    If in doubt about whether your preconditioner matrix has changed
974    structure or not, use the flag DIFFERENT_NONZERO_PATTERN.
975 
976    More Notes about Repeated Solution of Linear Systems:
977    PETSc does NOT reset the matrix entries of either Amat or Pmat
978    to zero after a linear solve; the user is completely responsible for
979    matrix assembly.  See the routine MatZeroEntries() if desiring to
980    zero all elements of a matrix.
981 
982    Level: intermediate
983 
984 .keywords: PC, set, operators, matrix, linear system
985 
986 .seealso: PCGetOperators(), MatZeroEntries()
987  @*/
988 PetscErrorCode PETSCKSP_DLLEXPORT PCSetOperators(PC pc,Mat Amat,Mat Pmat,MatStructure flag)
989 {
990   PetscErrorCode ierr;
991   PetscInt       m1,n1,m2,n2;
992 
993   PetscFunctionBegin;
994   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
995   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
996   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
997   if (Amat) PetscCheckSameComm(pc,1,Amat,2);
998   if (Pmat) PetscCheckSameComm(pc,1,Pmat,3);
999   if (pc->setupcalled && Amat && Pmat) {
1000     ierr = MatGetLocalSize(Amat,&m1,&n1);CHKERRQ(ierr);
1001     ierr = MatGetLocalSize(pc->mat,&m2,&n2);CHKERRQ(ierr);
1002     if (m1 != m2 || n1 != n2) {
1003       SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot change local size of Amat after use old sizes %D %D new sizes %D %D",m2,n2,m1,n1);
1004     }
1005     ierr = MatGetLocalSize(Pmat,&m1,&n1);CHKERRQ(ierr);
1006     ierr = MatGetLocalSize(pc->pmat,&m2,&n2);CHKERRQ(ierr);
1007     if (m1 != m2 || n1 != n2) {
1008       SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot change local size of Pmat after use old sizes %D %D new sizes %D %D",m2,n2,m1,n1);
1009     }
1010   }
1011 
1012   /* reference first in case the matrices are the same */
1013   if (Amat) {ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);}
1014   if (pc->mat) {ierr = MatDestroy(pc->mat);CHKERRQ(ierr);}
1015   if (Pmat) {ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr);}
1016   if (pc->pmat) {ierr = MatDestroy(pc->pmat);CHKERRQ(ierr);}
1017   pc->mat  = Amat;
1018   pc->pmat = Pmat;
1019 
1020   if (pc->setupcalled == 2 && flag != SAME_PRECONDITIONER) {
1021     pc->setupcalled = 1;
1022   }
1023   pc->flag = flag;
1024   PetscFunctionReturn(0);
1025 }
1026 
1027 #undef __FUNCT__
1028 #define __FUNCT__ "PCGetOperators"
1029 /*@C
1030    PCGetOperators - Gets the matrix associated with the linear system and
1031    possibly a different one associated with the preconditioner.
1032 
1033    Not collective, though parallel Mats are returned if the PC is parallel
1034 
1035    Input Parameter:
1036 .  pc - the preconditioner context
1037 
1038    Output Parameters:
1039 +  mat - the matrix associated with the linear system
1040 .  pmat - matrix associated with the preconditioner, usually the same
1041           as mat.
1042 -  flag - flag indicating information about the preconditioner
1043           matrix structure.  See PCSetOperators() for details.
1044 
1045    Level: intermediate
1046 
1047    Alternative usage: If the operators have NOT been set with KSP/PCSetOperators() then the operators
1048       are created in PC and returned to the user. In this case, if both operators
1049       mat and pmat are requested, two DIFFERENT operators will be returned. If
1050       only one is requested both operators in the PC will be the same (i.e. as
1051       if one had called KSP/PCSetOperators() with the same argument for both Mats).
1052       The user must set the sizes of the returned matrices and their type etc just
1053       as if the user created them with MatCreate(). For example,
1054 
1055 $         KSP/PCGetOperators(ksp/pc,&mat,PETSC_NULL,PETSC_NULL); is equivalent to
1056 $           set size, type, etc of mat
1057 
1058 $         MatCreate(comm,&mat);
1059 $         KSP/PCSetOperators(ksp/pc,mat,mat,SAME_NONZERO_PATTERN);
1060 $         PetscObjectDereference((PetscObject)mat);
1061 $           set size, type, etc of mat
1062 
1063      and
1064 
1065 $         KSP/PCGetOperators(ksp/pc,&mat,&pmat,PETSC_NULL); is equivalent to
1066 $           set size, type, etc of mat and pmat
1067 
1068 $         MatCreate(comm,&mat);
1069 $         MatCreate(comm,&pmat);
1070 $         KSP/PCSetOperators(ksp/pc,mat,pmat,SAME_NONZERO_PATTERN);
1071 $         PetscObjectDereference((PetscObject)mat);
1072 $         PetscObjectDereference((PetscObject)pmat);
1073 $           set size, type, etc of mat and pmat
1074 
1075     The rational for this support is so that when creating a TS, SNES, or KSP the hierarchy
1076     of underlying objects (i.e. SNES, KSP, PC, Mat) and their livespans can be completely
1077     managed by the top most level object (i.e. the TS, SNES, or KSP). Another way to look
1078     at this is when you create a SNES you do not NEED to create a KSP and attach it to
1079     the SNES object (the SNES object manages it for you). Similarly when you create a KSP
1080     you do not need to attach a PC to it (the KSP object manages the PC object for you).
1081     Thus, why should YOU have to create the Mat and attach it to the SNES/KSP/PC, when
1082     it can be created for you?
1083 
1084 
1085 .keywords: PC, get, operators, matrix, linear system
1086 
1087 .seealso: PCSetOperators(), KSPGetOperators(), KSPSetOperators(), PCGetOperatorsSet()
1088 @*/
1089 PetscErrorCode PETSCKSP_DLLEXPORT PCGetOperators(PC pc,Mat *mat,Mat *pmat,MatStructure *flag)
1090 {
1091   PetscErrorCode ierr;
1092 
1093   PetscFunctionBegin;
1094   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1095   if (mat) {
1096     if (!pc->mat) {
1097       ierr = MatCreate(((PetscObject)pc)->comm,&pc->mat);CHKERRQ(ierr);
1098       if (!pc->pmat && !pmat) { /* user did NOT request pmat, so make same as mat */
1099         pc->pmat = pc->mat;
1100         ierr     = PetscObjectReference((PetscObject)pc->pmat);CHKERRQ(ierr);
1101       }
1102     }
1103     *mat  = pc->mat;
1104   }
1105   if (pmat) {
1106     if (!pc->pmat) {
1107       ierr = MatCreate(((PetscObject)pc)->comm,&pc->mat);CHKERRQ(ierr);
1108       if (!pc->mat && !mat) { /* user did NOT request mat, so make same as pmat */
1109         pc->mat = pc->pmat;
1110         ierr    = PetscObjectReference((PetscObject)pc->mat);CHKERRQ(ierr);
1111       }
1112     }
1113     *pmat = pc->pmat;
1114   }
1115   if (flag) *flag = pc->flag;
1116   PetscFunctionReturn(0);
1117 }
1118 
1119 #undef __FUNCT__
1120 #define __FUNCT__ "PCGetOperatorsSet"
1121 /*@C
1122    PCGetOperatorsSet - Determines if the matrix associated with the linear system and
1123    possibly a different one associated with the preconditioner have been set in the PC.
1124 
1125    Not collective, though the results on all processes should be the same
1126 
1127    Input Parameter:
1128 .  pc - the preconditioner context
1129 
1130    Output Parameters:
1131 +  mat - the matrix associated with the linear system was set
1132 -  pmat - matrix associated with the preconditioner was set, usually the same
1133 
1134    Level: intermediate
1135 
1136 .keywords: PC, get, operators, matrix, linear system
1137 
1138 .seealso: PCSetOperators(), KSPGetOperators(), KSPSetOperators(), PCGetOperators()
1139 @*/
1140 PetscErrorCode PETSCKSP_DLLEXPORT PCGetOperatorsSet(PC pc,PetscTruth *mat,PetscTruth *pmat)
1141 {
1142   PetscFunctionBegin;
1143   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1144   if (mat)  *mat  = (pc->mat)  ? PETSC_TRUE : PETSC_FALSE;
1145   if (pmat) *pmat = (pc->pmat) ? PETSC_TRUE : PETSC_FALSE;
1146   PetscFunctionReturn(0);
1147 }
1148 
1149 #undef __FUNCT__
1150 #define __FUNCT__ "PCFactorGetMatrix"
1151 /*@
1152    PCFactorGetMatrix - Gets the factored matrix from the
1153    preconditioner context.  This routine is valid only for the LU,
1154    incomplete LU, Cholesky, and incomplete Cholesky methods.
1155 
1156    Not Collective on PC though Mat is parallel if PC is parallel
1157 
1158    Input Parameters:
1159 .  pc - the preconditioner context
1160 
1161    Output parameters:
1162 .  mat - the factored matrix
1163 
1164    Level: advanced
1165 
1166    Notes: Does not increase the reference count for the matrix so DO NOT destroy it
1167 
1168 .keywords: PC, get, factored, matrix
1169 @*/
1170 PetscErrorCode PETSCKSP_DLLEXPORT PCFactorGetMatrix(PC pc,Mat *mat)
1171 {
1172   PetscErrorCode ierr;
1173 
1174   PetscFunctionBegin;
1175   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1176   PetscValidPointer(mat,2);
1177   if (pc->ops->getfactoredmatrix) {
1178     ierr = (*pc->ops->getfactoredmatrix)(pc,mat);CHKERRQ(ierr);
1179   }
1180   PetscFunctionReturn(0);
1181 }
1182 
1183 #undef __FUNCT__
1184 #define __FUNCT__ "PCSetOptionsPrefix"
1185 /*@C
1186    PCSetOptionsPrefix - Sets the prefix used for searching for all
1187    PC options in the database.
1188 
1189    Logically Collective on PC
1190 
1191    Input Parameters:
1192 +  pc - the preconditioner context
1193 -  prefix - the prefix string to prepend to all PC option requests
1194 
1195    Notes:
1196    A hyphen (-) must NOT be given at the beginning of the prefix name.
1197    The first character of all runtime options is AUTOMATICALLY the
1198    hyphen.
1199 
1200    Level: advanced
1201 
1202 .keywords: PC, set, options, prefix, database
1203 
1204 .seealso: PCAppendOptionsPrefix(), PCGetOptionsPrefix()
1205 @*/
1206 PetscErrorCode PETSCKSP_DLLEXPORT PCSetOptionsPrefix(PC pc,const char prefix[])
1207 {
1208   PetscErrorCode ierr;
1209 
1210   PetscFunctionBegin;
1211   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1212   ierr = PetscObjectSetOptionsPrefix((PetscObject)pc,prefix);CHKERRQ(ierr);
1213   PetscFunctionReturn(0);
1214 }
1215 
1216 #undef __FUNCT__
1217 #define __FUNCT__ "PCAppendOptionsPrefix"
1218 /*@C
1219    PCAppendOptionsPrefix - Appends to the prefix used for searching for all
1220    PC options in the database.
1221 
1222    Logically Collective on PC
1223 
1224    Input Parameters:
1225 +  pc - the preconditioner context
1226 -  prefix - the prefix string to prepend to all PC option requests
1227 
1228    Notes:
1229    A hyphen (-) must NOT be given at the beginning of the prefix name.
1230    The first character of all runtime options is AUTOMATICALLY the
1231    hyphen.
1232 
1233    Level: advanced
1234 
1235 .keywords: PC, append, options, prefix, database
1236 
1237 .seealso: PCSetOptionsPrefix(), PCGetOptionsPrefix()
1238 @*/
1239 PetscErrorCode PETSCKSP_DLLEXPORT PCAppendOptionsPrefix(PC pc,const char prefix[])
1240 {
1241   PetscErrorCode ierr;
1242 
1243   PetscFunctionBegin;
1244   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1245   ierr = PetscObjectAppendOptionsPrefix((PetscObject)pc,prefix);CHKERRQ(ierr);
1246   PetscFunctionReturn(0);
1247 }
1248 
1249 #undef __FUNCT__
1250 #define __FUNCT__ "PCGetOptionsPrefix"
1251 /*@C
1252    PCGetOptionsPrefix - Gets the prefix used for searching for all
1253    PC options in the database.
1254 
1255    Not Collective
1256 
1257    Input Parameters:
1258 .  pc - the preconditioner context
1259 
1260    Output Parameters:
1261 .  prefix - pointer to the prefix string used, is returned
1262 
1263    Notes: On the fortran side, the user should pass in a string 'prifix' of
1264    sufficient length to hold the prefix.
1265 
1266    Level: advanced
1267 
1268 .keywords: PC, get, options, prefix, database
1269 
1270 .seealso: PCSetOptionsPrefix(), PCAppendOptionsPrefix()
1271 @*/
1272 PetscErrorCode PETSCKSP_DLLEXPORT PCGetOptionsPrefix(PC pc,const char *prefix[])
1273 {
1274   PetscErrorCode ierr;
1275 
1276   PetscFunctionBegin;
1277   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1278   PetscValidPointer(prefix,2);
1279   ierr = PetscObjectGetOptionsPrefix((PetscObject)pc,prefix);CHKERRQ(ierr);
1280   PetscFunctionReturn(0);
1281 }
1282 
1283 #undef __FUNCT__
1284 #define __FUNCT__ "PCPreSolve"
1285 /*@
1286    PCPreSolve - Optional pre-solve phase, intended for any
1287    preconditioner-specific actions that must be performed before
1288    the iterative solve itself.
1289 
1290    Collective on PC
1291 
1292    Input Parameters:
1293 +  pc - the preconditioner context
1294 -  ksp - the Krylov subspace context
1295 
1296    Level: developer
1297 
1298    Sample of Usage:
1299 .vb
1300     PCPreSolve(pc,ksp);
1301     KSPSolve(ksp,b,x);
1302     PCPostSolve(pc,ksp);
1303 .ve
1304 
1305    Notes:
1306    The pre-solve phase is distinct from the PCSetUp() phase.
1307 
1308    KSPSolve() calls this directly, so is rarely called by the user.
1309 
1310 .keywords: PC, pre-solve
1311 
1312 .seealso: PCPostSolve()
1313 @*/
1314 PetscErrorCode PETSCKSP_DLLEXPORT PCPreSolve(PC pc,KSP ksp)
1315 {
1316   PetscErrorCode ierr;
1317   Vec            x,rhs;
1318   Mat            A,B;
1319 
1320   PetscFunctionBegin;
1321   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1322   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
1323   ierr = KSPGetSolution(ksp,&x);CHKERRQ(ierr);
1324   ierr = KSPGetRhs(ksp,&rhs);CHKERRQ(ierr);
1325   /*
1326       Scale the system and have the matrices use the scaled form
1327     only if the two matrices are actually the same (and hence
1328     have the same scaling
1329   */
1330   ierr = PCGetOperators(pc,&A,&B,PETSC_NULL);CHKERRQ(ierr);
1331   if (A == B) {
1332     ierr = MatScaleSystem(pc->mat,rhs,x);CHKERRQ(ierr);
1333     ierr = MatUseScaledForm(pc->mat,PETSC_TRUE);CHKERRQ(ierr);
1334   }
1335 
1336   if (pc->ops->presolve) {
1337     ierr = (*pc->ops->presolve)(pc,ksp,rhs,x);CHKERRQ(ierr);
1338   }
1339   PetscFunctionReturn(0);
1340 }
1341 
1342 #undef __FUNCT__
1343 #define __FUNCT__ "PCPostSolve"
1344 /*@
1345    PCPostSolve - Optional post-solve phase, intended for any
1346    preconditioner-specific actions that must be performed after
1347    the iterative solve itself.
1348 
1349    Collective on PC
1350 
1351    Input Parameters:
1352 +  pc - the preconditioner context
1353 -  ksp - the Krylov subspace context
1354 
1355    Sample of Usage:
1356 .vb
1357     PCPreSolve(pc,ksp);
1358     KSPSolve(ksp,b,x);
1359     PCPostSolve(pc,ksp);
1360 .ve
1361 
1362    Note:
1363    KSPSolve() calls this routine directly, so it is rarely called by the user.
1364 
1365    Level: developer
1366 
1367 .keywords: PC, post-solve
1368 
1369 .seealso: PCPreSolve(), KSPSolve()
1370 @*/
1371 PetscErrorCode PETSCKSP_DLLEXPORT PCPostSolve(PC pc,KSP ksp)
1372 {
1373   PetscErrorCode ierr;
1374   Vec            x,rhs;
1375   Mat            A,B;
1376 
1377   PetscFunctionBegin;
1378   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1379   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
1380   ierr = KSPGetSolution(ksp,&x);CHKERRQ(ierr);
1381   ierr = KSPGetRhs(ksp,&rhs);CHKERRQ(ierr);
1382   if (pc->ops->postsolve) {
1383     ierr =  (*pc->ops->postsolve)(pc,ksp,rhs,x);CHKERRQ(ierr);
1384   }
1385   /*
1386       Scale the system and have the matrices use the scaled form
1387     only if the two matrices are actually the same (and hence
1388     have the same scaling
1389   */
1390   ierr = PCGetOperators(pc,&A,&B,PETSC_NULL);CHKERRQ(ierr);
1391   if (A == B) {
1392     ierr = MatUnScaleSystem(pc->mat,rhs,x);CHKERRQ(ierr);
1393     ierr = MatUseScaledForm(pc->mat,PETSC_FALSE);CHKERRQ(ierr);
1394   }
1395   PetscFunctionReturn(0);
1396 }
1397 
1398 #undef __FUNCT__
1399 #define __FUNCT__ "PCView"
1400 /*@C
1401    PCView - Prints the PC data structure.
1402 
1403    Collective on PC
1404 
1405    Input Parameters:
1406 +  PC - the PC context
1407 -  viewer - optional visualization context
1408 
1409    Note:
1410    The available visualization contexts include
1411 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
1412 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
1413          output where only the first processor opens
1414          the file.  All other processors send their
1415          data to the first processor to print.
1416 
1417    The user can open an alternative visualization contexts with
1418    PetscViewerASCIIOpen() (output to a specified file).
1419 
1420    Level: developer
1421 
1422 .keywords: PC, view
1423 
1424 .seealso: KSPView(), PetscViewerASCIIOpen()
1425 @*/
1426 PetscErrorCode PETSCKSP_DLLEXPORT PCView(PC pc,PetscViewer viewer)
1427 {
1428   const PCType      cstr;
1429   PetscErrorCode    ierr;
1430   PetscTruth        iascii,isstring;
1431   PetscViewerFormat format;
1432 
1433   PetscFunctionBegin;
1434   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1435   if (!viewer) {
1436     ierr = PetscViewerASCIIGetStdout(((PetscObject)pc)->comm,&viewer);CHKERRQ(ierr);
1437   }
1438   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1439   PetscCheckSameComm(pc,1,viewer,2);
1440 
1441   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1442   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
1443   if (iascii) {
1444     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1445     if (((PetscObject)pc)->prefix) {
1446       ierr = PetscViewerASCIIPrintf(viewer,"PC Object:(%s)\n",((PetscObject)pc)->prefix);CHKERRQ(ierr);
1447     } else {
1448       ierr = PetscViewerASCIIPrintf(viewer,"PC Object:\n");CHKERRQ(ierr);
1449     }
1450     ierr = PCGetType(pc,&cstr);CHKERRQ(ierr);
1451     if (cstr) {
1452       ierr = PetscViewerASCIIPrintf(viewer,"  type: %s\n",cstr);CHKERRQ(ierr);
1453     } else {
1454       ierr = PetscViewerASCIIPrintf(viewer,"  type: not yet set\n");CHKERRQ(ierr);
1455     }
1456     if (pc->ops->view) {
1457       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1458       ierr = (*pc->ops->view)(pc,viewer);CHKERRQ(ierr);
1459       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1460     }
1461     if (pc->mat) {
1462       ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
1463       if (pc->pmat == pc->mat) {
1464         ierr = PetscViewerASCIIPrintf(viewer,"  linear system matrix = precond matrix:\n");CHKERRQ(ierr);
1465         ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1466         ierr = MatView(pc->mat,viewer);CHKERRQ(ierr);
1467         ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1468       } else {
1469         if (pc->pmat) {
1470           ierr = PetscViewerASCIIPrintf(viewer,"  linear system matrix followed by preconditioner matrix:\n");CHKERRQ(ierr);
1471         } else {
1472           ierr = PetscViewerASCIIPrintf(viewer,"  linear system matrix:\n");CHKERRQ(ierr);
1473         }
1474         ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1475         ierr = MatView(pc->mat,viewer);CHKERRQ(ierr);
1476         if (pc->pmat) {ierr = MatView(pc->pmat,viewer);CHKERRQ(ierr);}
1477         ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1478       }
1479       ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
1480     }
1481   } else if (isstring) {
1482     ierr = PCGetType(pc,&cstr);CHKERRQ(ierr);
1483     ierr = PetscViewerStringSPrintf(viewer," %-7.7s",cstr);CHKERRQ(ierr);
1484     if (pc->ops->view) {ierr = (*pc->ops->view)(pc,viewer);CHKERRQ(ierr);}
1485   } else {
1486     SETERRQ1(((PetscObject)pc)->comm,PETSC_ERR_SUP,"Viewer type %s not supported by PC",((PetscObject)viewer)->type_name);
1487   }
1488   PetscFunctionReturn(0);
1489 }
1490 
1491 
1492 #undef __FUNCT__
1493 #define __FUNCT__ "PCSetInitialGuessNonzero"
1494 /*@
1495    PCSetInitialGuessNonzero - Tells the iterative solver that the
1496    initial guess is nonzero; otherwise PC assumes the initial guess
1497    is to be zero (and thus zeros it out before solving).
1498 
1499    Logically Collective on PC
1500 
1501    Input Parameters:
1502 +  pc - iterative context obtained from PCCreate()
1503 -  flg - PETSC_TRUE indicates the guess is non-zero, PETSC_FALSE indicates the guess is zero
1504 
1505    Level: Developer
1506 
1507    Notes:
1508     This is a weird function. Since PC's are linear operators on the right hand side they
1509     CANNOT use an initial guess. This function is for the "pass-through" preconditioners
1510     PCKSP, PCREDUNDANT and PCOPENMP and causes the inner KSP object to use the nonzero
1511     initial guess. Not currently working for PCREDUNDANT, that has to be rewritten to use KSP.
1512 
1513 
1514 .keywords: PC, set, initial guess, nonzero
1515 
1516 .seealso: PCGetInitialGuessNonzero(), PCSetInitialGuessKnoll(), PCGetInitialGuessKnoll()
1517 @*/
1518 PetscErrorCode PETSCKSP_DLLEXPORT PCSetInitialGuessNonzero(PC pc,PetscTruth flg)
1519 {
1520   PetscFunctionBegin;
1521   PetscValidLogicalCollectiveTruth(pc,flg,2);
1522   pc->nonzero_guess   = flg;
1523   PetscFunctionReturn(0);
1524 }
1525 
1526 #undef __FUNCT__
1527 #define __FUNCT__ "PCRegister"
1528 /*@C
1529   PCRegister - See PCRegisterDynamic()
1530 
1531   Level: advanced
1532 @*/
1533 PetscErrorCode PETSCKSP_DLLEXPORT PCRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(PC))
1534 {
1535   PetscErrorCode ierr;
1536   char           fullname[PETSC_MAX_PATH_LEN];
1537 
1538   PetscFunctionBegin;
1539 
1540   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
1541   ierr = PetscFListAdd(&PCList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
1542   PetscFunctionReturn(0);
1543 }
1544 
1545 #undef __FUNCT__
1546 #define __FUNCT__ "PCComputeExplicitOperator"
1547 /*@
1548     PCComputeExplicitOperator - Computes the explicit preconditioned operator.
1549 
1550     Collective on PC
1551 
1552     Input Parameter:
1553 .   pc - the preconditioner object
1554 
1555     Output Parameter:
1556 .   mat - the explict preconditioned operator
1557 
1558     Notes:
1559     This computation is done by applying the operators to columns of the
1560     identity matrix.
1561 
1562     Currently, this routine uses a dense matrix format when 1 processor
1563     is used and a sparse format otherwise.  This routine is costly in general,
1564     and is recommended for use only with relatively small systems.
1565 
1566     Level: advanced
1567 
1568 .keywords: PC, compute, explicit, operator
1569 
1570 .seealso: KSPComputeExplicitOperator()
1571 
1572 @*/
1573 PetscErrorCode PETSCKSP_DLLEXPORT PCComputeExplicitOperator(PC pc,Mat *mat)
1574 {
1575   Vec            in,out;
1576   PetscErrorCode ierr;
1577   PetscInt       i,M,m,*rows,start,end;
1578   PetscMPIInt    size;
1579   MPI_Comm       comm;
1580   PetscScalar    *array,one = 1.0;
1581 
1582   PetscFunctionBegin;
1583   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1584   PetscValidPointer(mat,2);
1585 
1586   comm = ((PetscObject)pc)->comm;
1587   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1588 
1589   if (!pc->pmat) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ORDER,"You must call KSPSetOperators() or PCSetOperators() before this call");
1590   ierr = MatGetVecs(pc->pmat,&in,0);CHKERRQ(ierr);
1591   ierr = VecDuplicate(in,&out);CHKERRQ(ierr);
1592   ierr = VecGetOwnershipRange(in,&start,&end);CHKERRQ(ierr);
1593   ierr = VecGetSize(in,&M);CHKERRQ(ierr);
1594   ierr = VecGetLocalSize(in,&m);CHKERRQ(ierr);
1595   ierr = PetscMalloc((m+1)*sizeof(PetscInt),&rows);CHKERRQ(ierr);
1596   for (i=0; i<m; i++) {rows[i] = start + i;}
1597 
1598   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
1599   ierr = MatSetSizes(*mat,m,m,M,M);CHKERRQ(ierr);
1600   if (size == 1) {
1601     ierr = MatSetType(*mat,MATSEQDENSE);CHKERRQ(ierr);
1602     ierr = MatSeqDenseSetPreallocation(*mat,PETSC_NULL);CHKERRQ(ierr);
1603   } else {
1604     ierr = MatSetType(*mat,MATMPIAIJ);CHKERRQ(ierr);
1605     ierr = MatMPIAIJSetPreallocation(*mat,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
1606   }
1607 
1608   for (i=0; i<M; i++) {
1609 
1610     ierr = VecSet(in,0.0);CHKERRQ(ierr);
1611     ierr = VecSetValues(in,1,&i,&one,INSERT_VALUES);CHKERRQ(ierr);
1612     ierr = VecAssemblyBegin(in);CHKERRQ(ierr);
1613     ierr = VecAssemblyEnd(in);CHKERRQ(ierr);
1614 
1615     /* should fix, allowing user to choose side */
1616     ierr = PCApply(pc,in,out);CHKERRQ(ierr);
1617 
1618     ierr = VecGetArray(out,&array);CHKERRQ(ierr);
1619     ierr = MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1620     ierr = VecRestoreArray(out,&array);CHKERRQ(ierr);
1621 
1622   }
1623   ierr = PetscFree(rows);CHKERRQ(ierr);
1624   ierr = VecDestroy(out);CHKERRQ(ierr);
1625   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1626   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1627   PetscFunctionReturn(0);
1628 }
1629 
1630