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