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