Actual source code: precon.c

  1: #define PETSCKSP_DLL

  3: /*
  4:     The PC (preconditioner) interface routines, callable by users.
  5: */
 6:  #include private/pcimpl.h

  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;

 15: PetscErrorCode PCGetDefaultType_Private(PC pc,const char* type[])
 16: {
 18:   PetscMPIInt    size;
 19:   PetscTruth     flg1,flg2,set,flg3;

 22:   MPI_Comm_size(pc->comm,&size);
 23:   if (pc->pmat) {
 24:     PetscErrorCode (*f)(Mat,PetscTruth*,MatReuse,Mat*);
 25:     PetscObjectQueryFunction((PetscObject)pc->pmat,"MatGetDiagonalBlock_C",(void (**)(void))&f);
 26:     if (size == 1) {
 27:       MatHasOperation(pc->pmat,MATOP_ICCFACTOR_SYMBOLIC,&flg1);
 28:       MatHasOperation(pc->pmat,MATOP_ILUFACTOR_SYMBOLIC,&flg2);
 29:       MatIsSymmetricKnown(pc->pmat,&set,&flg3);
 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:   return(0);
 54: }

 58: /*@
 59:    PCDestroy - Destroys PC context that was created with PCCreate().

 61:    Collective on PC

 63:    Input Parameter:
 64: .  pc - the preconditioner context

 66:    Level: developer

 68: .keywords: PC, destroy

 70: .seealso: PCCreate(), PCSetUp()
 71: @*/
 72: PetscErrorCode PETSCKSP_DLLEXPORT PCDestroy(PC pc)
 73: {

 78:   if (--pc->refct > 0) return(0);

 80:   /* if memory was published with AMS then destroy it */
 81:   PetscObjectDepublish(pc);

 83:   if (pc->ops->destroy)       { (*pc->ops->destroy)(pc);}
 84:   if (pc->diagonalscaleright) {VecDestroy(pc->diagonalscaleright);}
 85:   if (pc->diagonalscaleleft)  {VecDestroy(pc->diagonalscaleleft);}

 87:   PetscHeaderDestroy(pc);
 88:   return(0);
 89: }

 93: /*@C
 94:    PCDiagonalScale - Indicates if the preconditioner applies an additional left and right
 95:       scaling as needed by certain time-stepping codes.

 97:    Collective on PC

 99:    Input Parameter:
100: .  pc - the preconditioner context

102:    Output Parameter:
103: .  flag - PETSC_TRUE if it applies the scaling

105:    Level: developer

107:    Notes: If this returns PETSC_TRUE then the system solved via the Krylov method is
108: $           D M A D^{-1} y = D M b  for left preconditioning or
109: $           D A M D^{-1} z = D b for right preconditioning

111: .keywords: PC

113: .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleLeft(), PCDiagonalScaleRight(), PCDiagonalScaleSet()
114: @*/
115: PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScale(PC pc,PetscTruth *flag)
116: {
120:   *flag = pc->diagonalscale;
121:   return(0);
122: }

126: /*@
127:    PCDiagonalScaleSet - Indicates the left scaling to use to apply an additional left and right
128:       scaling as needed by certain time-stepping codes.

130:    Collective on PC

132:    Input Parameters:
133: +  pc - the preconditioner context
134: -  s - scaling vector

136:    Level: intermediate

138:    Notes: The system solved via the Krylov method is
139: $           D M A D^{-1} y = D M b  for left preconditioning or
140: $           D A M D^{-1} z = D b for right preconditioning

142:    PCDiagonalScaleLeft() scales a vector by D. PCDiagonalScaleRight() scales a vector by D^{-1}.

144: .keywords: PC

146: .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleLeft(), PCDiagonalScaleRight(), PCDiagonalScale()
147: @*/
148: PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScaleSet(PC pc,Vec s)
149: {

155:   pc->diagonalscale     = PETSC_TRUE;
156:   if (pc->diagonalscaleleft) {
157:     VecDestroy(pc->diagonalscaleleft);
158:   }
159:   pc->diagonalscaleleft = s;
160:   PetscObjectReference((PetscObject)s);
161:   if (!pc->diagonalscaleright) {
162:     VecDuplicate(s,&pc->diagonalscaleright);
163:   }
164:   VecCopy(s,pc->diagonalscaleright);
165:   VecReciprocal(pc->diagonalscaleright);
166:   return(0);
167: }

171: /*@C
172:    PCDiagonalScaleLeft - Indicates the left scaling to use to apply an additional left and right
173:       scaling as needed by certain time-stepping codes.

175:    Collective on PC

177:    Input Parameters:
178: +  pc - the preconditioner context
179: .  in - input vector
180: +  out - scaled vector (maybe the same as in)

182:    Level: intermediate

184:    Notes: The system solved via the Krylov method is
185: $           D M A D^{-1} y = D M b  for left preconditioning or
186: $           D A M D^{-1} z = D b for right preconditioning

188:    PCDiagonalScaleLeft() scales a vector by D. PCDiagonalScaleRight() scales a vector by D^{-1}.

190:    If diagonal scaling is turned off and in is not out then in is copied to out

192: .keywords: PC

194: .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleSet(), PCDiagonalScaleRight(), PCDiagonalScale()
195: @*/
196: PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScaleLeft(PC pc,Vec in,Vec out)
197: {

204:   if (pc->diagonalscale) {
205:     VecPointwiseMult(out,pc->diagonalscaleleft,in);
206:   } else if (in != out) {
207:     VecCopy(in,out);
208:   }
209:   return(0);
210: }

214: /*@C
215:    PCDiagonalScaleRight - Scales a vector by the right scaling as needed by certain time-stepping codes.

217:    Collective on PC

219:    Input Parameters:
220: +  pc - the preconditioner context
221: .  in - input vector
222: +  out - scaled vector (maybe the same as in)

224:    Level: intermediate

226:    Notes: The system solved via the Krylov method is
227: $           D M A D^{-1} y = D M b  for left preconditioning or
228: $           D A M D^{-1} z = D b for right preconditioning

230:    PCDiagonalScaleLeft() scales a vector by D. PCDiagonalScaleRight() scales a vector by D^{-1}.

232:    If diagonal scaling is turned off and in is not out then in is copied to out

234: .keywords: PC

236: .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleLeft(), PCDiagonalScaleSet(), PCDiagonalScale()
237: @*/
238: PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScaleRight(PC pc,Vec in,Vec out)
239: {

246:   if (pc->diagonalscale) {
247:     VecPointwiseMult(out,pc->diagonalscaleright,in);
248:   } else if (in != out) {
249:     VecCopy(in,out);
250:   }
251:   return(0);
252: }

256: static PetscErrorCode PCPublish_Petsc(PetscObject obj)
257: {
259:   return(0);
260: }

264: /*@
265:    PCCreate - Creates a preconditioner context.

267:    Collective on MPI_Comm

269:    Input Parameter:
270: .  comm - MPI communicator 

272:    Output Parameter:
273: .  pc - location to put the preconditioner context

275:    Notes:
276:    The default preconditioner on one processor is PCILU with 0 fill on more 
277:    then one it is PCBJACOBI with ILU() on each processor.

279:    Level: developer

281: .keywords: PC, create, context

283: .seealso: PCSetUp(), PCApply(), PCDestroy()
284: @*/
285: PetscErrorCode PETSCKSP_DLLEXPORT PCCreate(MPI_Comm comm,PC *newpc)
286: {
287:   PC             pc;

292:   *newpc = 0;
293: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
294:   PCInitializePackage(PETSC_NULL);
295: #endif

297:   PetscHeaderCreate(pc,_p_PC,struct _PCOps,PC_COOKIE,-1,"PC",comm,PCDestroy,PCView);
298:   pc->bops->publish      = PCPublish_Petsc;
299:   pc->mat                = 0;
300:   pc->pmat               = 0;
301:   pc->setupcalled        = 0;
302:   pc->data               = 0;
303:   pc->diagonalscale      = PETSC_FALSE;
304:   pc->diagonalscaleleft  = 0;
305:   pc->diagonalscaleright = 0;

307:   pc->ops->destroy             = 0;
308:   pc->ops->apply               = 0;
309:   pc->ops->applytranspose      = 0;
310:   pc->ops->applyBA             = 0;
311:   pc->ops->applyBAtranspose    = 0;
312:   pc->ops->applyrichardson     = 0;
313:   pc->ops->view                = 0;
314:   pc->ops->getfactoredmatrix   = 0;
315:   pc->ops->applysymmetricright = 0;
316:   pc->ops->applysymmetricleft  = 0;
317:   pc->ops->setuponblocks       = 0;

319:   pc->modifysubmatrices   = 0;
320:   pc->modifysubmatricesP  = 0;
321:   *newpc                  = pc;
322:   PetscPublishAll(pc);
323:   return(0);

325: }

327: /* -------------------------------------------------------------------------------*/

331: /*@
332:    PCApply - Applies the preconditioner to a vector.

334:    Collective on PC and Vec

336:    Input Parameters:
337: +  pc - the preconditioner context
338: -  x - input vector

340:    Output Parameter:
341: .  y - output vector

343:    Level: developer

345: .keywords: PC, apply

347: .seealso: PCApplyTranspose(), PCApplyBAorAB()
348: @*/
349: PetscErrorCode PETSCKSP_DLLEXPORT PCApply(PC pc,Vec x,Vec y)
350: {

357:   if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different vectors");

359:   if (pc->setupcalled < 2) {
360:     PCSetUp(pc);
361:   }
362:   PetscLogEventBegin(PC_Apply,pc,x,y,0);
363:   (*pc->ops->apply)(pc,x,y);
364:   PetscLogEventEnd(PC_Apply,pc,x,y,0);
365:   return(0);
366: }

370: /*@
371:    PCApplySymmetricLeft - Applies the left part of a symmetric preconditioner to a vector.

373:    Collective on PC and Vec

375:    Input Parameters:
376: +  pc - the preconditioner context
377: -  x - input vector

379:    Output Parameter:
380: .  y - output vector

382:    Notes:
383:    Currently, this routine is implemented only for PCICC and PCJACOBI preconditioners.

385:    Level: developer

387: .keywords: PC, apply, symmetric, left

389: .seealso: PCApply(), PCApplySymmetricRight()
390: @*/
391: PetscErrorCode PETSCKSP_DLLEXPORT PCApplySymmetricLeft(PC pc,Vec x,Vec y)
392: {

399:   if (!pc->ops->applysymmetricleft) SETERRQ(PETSC_ERR_SUP,"PC does not have left symmetric apply");

401:   if (pc->setupcalled < 2) {
402:     PCSetUp(pc);
403:   }

405:   PetscLogEventBegin(PC_ApplySymmetricLeft,pc,x,y,0);
406:   (*pc->ops->applysymmetricleft)(pc,x,y);
407:   PetscLogEventEnd(PC_ApplySymmetricLeft,pc,x,y,0);
408:   return(0);
409: }

413: /*@
414:    PCApplySymmetricRight - Applies the right part of a symmetric preconditioner to a vector.

416:    Collective on PC and Vec

418:    Input Parameters:
419: +  pc - the preconditioner context
420: -  x - input vector

422:    Output Parameter:
423: .  y - output vector

425:    Level: developer

427:    Notes:
428:    Currently, this routine is implemented only for PCICC and PCJACOBI preconditioners.

430: .keywords: PC, apply, symmetric, right

432: .seealso: PCApply(), PCApplySymmetricLeft()
433: @*/
434: PetscErrorCode PETSCKSP_DLLEXPORT PCApplySymmetricRight(PC pc,Vec x,Vec y)
435: {

442:   if (!pc->ops->applysymmetricright) SETERRQ(PETSC_ERR_SUP,"PC does not have left symmetric apply");

444:   if (pc->setupcalled < 2) {
445:     PCSetUp(pc);
446:   }

448:   PetscLogEventBegin(PC_ApplySymmetricRight,pc,x,y,0);
449:   (*pc->ops->applysymmetricright)(pc,x,y);
450:   PetscLogEventEnd(PC_ApplySymmetricRight,pc,x,y,0);
451:   return(0);
452: }

456: /*@
457:    PCApplyTranspose - Applies the transpose of preconditioner to a vector.

459:    Collective on PC and Vec

461:    Input Parameters:
462: +  pc - the preconditioner context
463: -  x - input vector

465:    Output Parameter:
466: .  y - output vector

468:    Level: developer

470: .keywords: PC, apply, transpose

472: .seealso: PCApply(), PCApplyBAorAB(), PCApplyBAorABTranspose(), PCHasApplyTranspose()
473: @*/
474: PetscErrorCode PETSCKSP_DLLEXPORT PCApplyTranspose(PC pc,Vec x,Vec y)
475: {

482:   if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different vectors");
483:   if (!pc->ops->applytranspose) SETERRQ(PETSC_ERR_SUP," ");

485:   if (pc->setupcalled < 2) {
486:     PCSetUp(pc);
487:   }

489:   PetscLogEventBegin(PC_Apply,pc,x,y,0);
490:   (*pc->ops->applytranspose)(pc,x,y);
491:   PetscLogEventEnd(PC_Apply,pc,x,y,0);
492:   return(0);
493: }

497: /*@
498:    PCHasApplyTranspose - Test whether the preconditioner has a transpose apply operation

500:    Collective on PC and Vec

502:    Input Parameters:
503: .  pc - the preconditioner context

505:    Output Parameter:
506: .  flg - PETSC_TRUE if a transpose operation is defined

508:    Level: developer

510: .keywords: PC, apply, transpose

512: .seealso: PCApplyTranspose()
513: @*/
514: PetscErrorCode PETSCKSP_DLLEXPORT PCHasApplyTranspose(PC pc,PetscTruth *flg)
515: {
519:   *flg = (PetscTruth) (pc->ops->applytranspose == 0);
520:   return(0);
521: }

525: /*@
526:    PCApplyBAorAB - Applies the preconditioner and operator to a vector. 

528:    Collective on PC and Vec

530:    Input Parameters:
531: +  pc - the preconditioner context
532: .  side - indicates the preconditioner side, one of PC_LEFT, PC_RIGHT, or PC_SYMMETRIC
533: .  x - input vector
534: -  work - work vector

536:    Output Parameter:
537: .  y - output vector

539:    Level: developer

541: .keywords: PC, apply, operator

543: .seealso: PCApply(), PCApplyTranspose(), PCApplyBAorABTranspose()
544: @*/
545: PetscErrorCode PETSCKSP_DLLEXPORT PCApplyBAorAB(PC pc,PCSide side,Vec x,Vec y,Vec work)
546: {

554:   if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different vectors");
555:   if (side != PC_LEFT && side != PC_SYMMETRIC && side != PC_RIGHT) {
556:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Side must be right, left, or symmetric");
557:   }
558:   if (pc->diagonalscale && side == PC_SYMMETRIC) {
559:     SETERRQ(PETSC_ERR_SUP,"Cannot include diagonal scaling with symmetric preconditioner application");
560:   }

562:   if (pc->setupcalled < 2) {
563:     PCSetUp(pc);
564:   }

566:   if (pc->diagonalscale) {
567:     if (pc->ops->applyBA) {
568:       Vec work2; /* this is expensive, but to fix requires a second work vector argument to PCApplyBAorAB() */
569:       VecDuplicate(x,&work2);
570:       PCDiagonalScaleRight(pc,x,work2);
571:       (*pc->ops->applyBA)(pc,side,work2,y,work);
572:       PCDiagonalScaleLeft(pc,y,y);
573:       VecDestroy(work2);
574:     } else if (side == PC_RIGHT) {
575:       PCDiagonalScaleRight(pc,x,y);
576:       PCApply(pc,y,work);
577:       MatMult(pc->mat,work,y);
578:       PCDiagonalScaleLeft(pc,y,y);
579:     } else if (side == PC_LEFT) {
580:       PCDiagonalScaleRight(pc,x,y);
581:       MatMult(pc->mat,y,work);
582:       PCApply(pc,work,y);
583:       PCDiagonalScaleLeft(pc,y,y);
584:     } else if (side == PC_SYMMETRIC) {
585:       SETERRQ(PETSC_ERR_SUP,"Cannot provide diagonal scaling with symmetric application of preconditioner");
586:     }
587:   } else {
588:     if (pc->ops->applyBA) {
589:       (*pc->ops->applyBA)(pc,side,x,y,work);
590:     } else if (side == PC_RIGHT) {
591:       PCApply(pc,x,work);
592:       MatMult(pc->mat,work,y);
593:     } else if (side == PC_LEFT) {
594:       MatMult(pc->mat,x,work);
595:       PCApply(pc,work,y);
596:     } else if (side == PC_SYMMETRIC) {
597:       /* There's an extra copy here; maybe should provide 2 work vectors instead? */
598:       PCApplySymmetricRight(pc,x,work);
599:       MatMult(pc->mat,work,y);
600:       VecCopy(y,work);
601:       PCApplySymmetricLeft(pc,work,y);
602:     }
603:   }
604:   return(0);
605: }

609: /*@ 
610:    PCApplyBAorABTranspose - Applies the transpose of the preconditioner
611:    and operator to a vector. That is, applies tr(B) * tr(A) with left preconditioning,
612:    not tr(B*A) = tr(A)*tr(B).

614:    Collective on PC and Vec

616:    Input Parameters:
617: +  pc - the preconditioner context
618: .  side - indicates the preconditioner side, one of PC_LEFT, PC_RIGHT, or PC_SYMMETRIC
619: .  x - input vector
620: -  work - work vector

622:    Output Parameter:
623: .  y - output vector

625:    Level: developer

627: .keywords: PC, apply, operator, transpose

629: .seealso: PCApply(), PCApplyTranspose(), PCApplyBAorAB()
630: @*/
631: PetscErrorCode PETSCKSP_DLLEXPORT PCApplyBAorABTranspose(PC pc,PCSide side,Vec x,Vec y,Vec work)
632: {

640:   if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different vectors");
641:   if (pc->ops->applyBAtranspose) {
642:     (*pc->ops->applyBAtranspose)(pc,side,x,y,work);
643:     return(0);
644:   }
645:   if (side != PC_LEFT && side != PC_RIGHT) {
646:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Side must be right or left");
647:   }

649:   if (pc->setupcalled < 2) {
650:     PCSetUp(pc);
651:   }

653:   if (side == PC_RIGHT) {
654:     PCApplyTranspose(pc,x,work);
655:     MatMultTranspose(pc->mat,work,y);
656:   } else if (side == PC_LEFT) {
657:     MatMultTranspose(pc->mat,x,work);
658:     PCApplyTranspose(pc,work,y);
659:   }
660:   /* add support for PC_SYMMETRIC */
661:   return(0); /* actually will never get here */
662: }

664: /* -------------------------------------------------------------------------------*/

668: /*@
669:    PCApplyRichardsonExists - Determines whether a particular preconditioner has a 
670:    built-in fast application of Richardson's method.

672:    Not Collective

674:    Input Parameter:
675: .  pc - the preconditioner

677:    Output Parameter:
678: .  exists - PETSC_TRUE or PETSC_FALSE

680:    Level: developer

682: .keywords: PC, apply, Richardson, exists

684: .seealso: PCApplyRichardson()
685: @*/
686: PetscErrorCode PETSCKSP_DLLEXPORT PCApplyRichardsonExists(PC pc,PetscTruth *exists)
687: {
691:   if (pc->ops->applyrichardson) *exists = PETSC_TRUE;
692:   else                    *exists = PETSC_FALSE;
693:   return(0);
694: }

698: /*@
699:    PCApplyRichardson - Applies several steps of Richardson iteration with 
700:    the particular preconditioner. This routine is usually used by the 
701:    Krylov solvers and not the application code directly.

703:    Collective on PC

705:    Input Parameters:
706: +  pc  - the preconditioner context
707: .  x   - the initial guess 
708: .  w   - one work vector
709: .  rtol - relative decrease in residual norm convergence criteria
710: .  abstol - absolute residual norm convergence criteria
711: .  dtol - divergence residual norm increase criteria
712: -  its - the number of iterations to apply.

714:    Output Parameter:
715: .  y - the solution

717:    Notes: 
718:    Most preconditioners do not support this function. Use the command
719:    PCApplyRichardsonExists() to determine if one does.

721:    Except for the multigrid PC this routine ignores the convergence tolerances
722:    and always runs for the number of iterations
723:  
724:    Level: developer

726: .keywords: PC, apply, Richardson

728: .seealso: PCApplyRichardsonExists()
729: @*/
730: PetscErrorCode PETSCKSP_DLLEXPORT PCApplyRichardson(PC pc,Vec x,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt its)
731: {

739:   if (!pc->ops->applyrichardson) SETERRQ(PETSC_ERR_SUP," ");

741:   if (pc->setupcalled < 2) {
742:     PCSetUp(pc);
743:   }

745:   (*pc->ops->applyrichardson)(pc,x,y,w,rtol,abstol,dtol,its);
746:   return(0);
747: }

749: /* 
750:       a setupcall of 0 indicates never setup, 
751:                      1 needs to be resetup,
752:                      2 does not need any changes.
753: */
756: /*@
757:    PCSetUp - Prepares for the use of a preconditioner.

759:    Collective on PC

761:    Input Parameter:
762: .  pc - the preconditioner context

764:    Level: developer

766: .keywords: PC, setup

768: .seealso: PCCreate(), PCApply(), PCDestroy()
769: @*/
770: PetscErrorCode PETSCKSP_DLLEXPORT PCSetUp(PC pc)
771: {
773:   const char     *def;


778:   if (pc->setupcalled > 1) {
779:     PetscInfo(pc,"Setting PC with identical preconditioner\n");
780:     return(0);
781:   } else if (!pc->setupcalled) {
782:     PetscInfo(pc,"Setting up new PC\n");
783:   } else if (pc->flag == SAME_NONZERO_PATTERN) {
784:     PetscInfo(pc,"Setting up PC with same nonzero pattern\n");
785:   } else {
786:     PetscInfo(pc,"Setting up PC with different nonzero pattern\n");
787:   }

789:   PetscLogEventBegin(PC_SetUp,pc,0,0,0);
790:   if (!pc->mat) {SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be set first");}

792:   if (!pc->type_name) {
793:     PCGetDefaultType_Private(pc,&def);
794:     PCSetType(pc,def);
795:   }

797:   if (pc->ops->setup) {
798:     (*pc->ops->setup)(pc);
799:   }
800:   pc->setupcalled = 2;
801:   PetscLogEventEnd(PC_SetUp,pc,0,0,0);
802:   return(0);
803: }

807: /*@
808:    PCSetUpOnBlocks - Sets up the preconditioner for each block in
809:    the block Jacobi, block Gauss-Seidel, and overlapping Schwarz 
810:    methods.

812:    Collective on PC

814:    Input Parameters:
815: .  pc - the preconditioner context

817:    Level: developer

819: .keywords: PC, setup, blocks

821: .seealso: PCCreate(), PCApply(), PCDestroy(), PCSetUp()
822: @*/
823: PetscErrorCode PETSCKSP_DLLEXPORT PCSetUpOnBlocks(PC pc)
824: {

829:   if (!pc->ops->setuponblocks) return(0);
830:   PetscLogEventBegin(PC_SetUpOnBlocks,pc,0,0,0);
831:   (*pc->ops->setuponblocks)(pc);
832:   PetscLogEventEnd(PC_SetUpOnBlocks,pc,0,0,0);
833:   return(0);
834: }

838: /*@C
839:    PCSetModifySubMatrices - Sets a user-defined routine for modifying the
840:    submatrices that arise within certain subdomain-based preconditioners.
841:    The basic submatrices are extracted from the preconditioner matrix as
842:    usual; the user can then alter these (for example, to set different boundary
843:    conditions for each submatrix) before they are used for the local solves.

845:    Collective on PC

847:    Input Parameters:
848: +  pc - the preconditioner context
849: .  func - routine for modifying the submatrices
850: -  ctx - optional user-defined context (may be null)

852:    Calling sequence of func:
853: $     func (PC pc,PetscInt nsub,IS *row,IS *col,Mat *submat,void *ctx);

855: .  row - an array of index sets that contain the global row numbers
856:          that comprise each local submatrix
857: .  col - an array of index sets that contain the global column numbers
858:          that comprise each local submatrix
859: .  submat - array of local submatrices
860: -  ctx - optional user-defined context for private data for the 
861:          user-defined func routine (may be null)

863:    Notes:
864:    PCSetModifySubMatrices() MUST be called before KSPSetUp() and
865:    KSPSolve().

867:    A routine set by PCSetModifySubMatrices() is currently called within
868:    the block Jacobi (PCBJACOBI) and additive Schwarz (PCASM)
869:    preconditioners.  All other preconditioners ignore this routine.

871:    Level: advanced

873: .keywords: PC, set, modify, submatrices

875: .seealso: PCModifySubMatrices()
876: @*/
877: PetscErrorCode PETSCKSP_DLLEXPORT PCSetModifySubMatrices(PC pc,PetscErrorCode (*func)(PC,PetscInt,const IS[],const IS[],Mat[],void*),void *ctx)
878: {
881:   pc->modifysubmatrices  = func;
882:   pc->modifysubmatricesP = ctx;
883:   return(0);
884: }

888: /*@C
889:    PCModifySubMatrices - Calls an optional user-defined routine within 
890:    certain preconditioners if one has been set with PCSetModifySubMarices().

892:    Collective on PC

894:    Input Parameters:
895: +  pc - the preconditioner context
896: .  nsub - the number of local submatrices
897: .  row - an array of index sets that contain the global row numbers
898:          that comprise each local submatrix
899: .  col - an array of index sets that contain the global column numbers
900:          that comprise each local submatrix
901: .  submat - array of local submatrices
902: -  ctx - optional user-defined context for private data for the 
903:          user-defined routine (may be null)

905:    Output Parameter:
906: .  submat - array of local submatrices (the entries of which may
907:             have been modified)

909:    Notes:
910:    The user should NOT generally call this routine, as it will
911:    automatically be called within certain preconditioners (currently
912:    block Jacobi, additive Schwarz) if set.

914:    The basic submatrices are extracted from the preconditioner matrix
915:    as usual; the user can then alter these (for example, to set different
916:    boundary conditions for each submatrix) before they are used for the
917:    local solves.

919:    Level: developer

921: .keywords: PC, modify, submatrices

923: .seealso: PCSetModifySubMatrices()
924: @*/
925: PetscErrorCode PETSCKSP_DLLEXPORT PCModifySubMatrices(PC pc,PetscInt nsub,const IS row[],const IS col[],Mat submat[],void *ctx)
926: {

930:   if (!pc->modifysubmatrices) return(0);
931:   PetscLogEventBegin(PC_ModifySubMatrices,pc,0,0,0);
932:   (*pc->modifysubmatrices)(pc,nsub,row,col,submat,ctx);
933:   PetscLogEventEnd(PC_ModifySubMatrices,pc,0,0,0);
934:   return(0);
935: }

939: /*@
940:    PCSetOperators - Sets the matrix associated with the linear system and 
941:    a (possibly) different one associated with the preconditioner.

943:    Collective on PC and Mat

945:    Input Parameters:
946: +  pc - the preconditioner context
947: .  Amat - the matrix associated with the linear system
948: .  Pmat - the matrix to be used in constructing the preconditioner, usually
949:           the same as Amat. 
950: -  flag - flag indicating information about the preconditioner matrix structure
951:    during successive linear solves.  This flag is ignored the first time a
952:    linear system is solved, and thus is irrelevant when solving just one linear
953:    system.

955:    Notes: 
956:    The flag can be used to eliminate unnecessary work in the preconditioner 
957:    during the repeated solution of linear systems of the same size.  The 
958:    available options are
959: +    SAME_PRECONDITIONER -
960:        Pmat is identical during successive linear solves.
961:        This option is intended for folks who are using
962:        different Amat and Pmat matrices and wish to reuse the
963:        same preconditioner matrix.  For example, this option
964:        saves work by not recomputing incomplete factorization
965:        for ILU/ICC preconditioners.
966: .     SAME_NONZERO_PATTERN -
967:        Pmat has the same nonzero structure during
968:        successive linear solves. 
969: -     DIFFERENT_NONZERO_PATTERN -
970:        Pmat does not have the same nonzero structure.

972:    Caution:
973:    If you specify SAME_NONZERO_PATTERN, PETSc believes your assertion
974:    and does not check the structure of the matrix.  If you erroneously
975:    claim that the structure is the same when it actually is not, the new
976:    preconditioner will not function correctly.  Thus, use this optimization
977:    feature carefully!

979:    If in doubt about whether your preconditioner matrix has changed
980:    structure or not, use the flag DIFFERENT_NONZERO_PATTERN.

982:    More Notes about Repeated Solution of Linear Systems:
983:    PETSc does NOT reset the matrix entries of either Amat or Pmat
984:    to zero after a linear solve; the user is completely responsible for
985:    matrix assembly.  See the routine MatZeroEntries() if desiring to
986:    zero all elements of a matrix.

988:    Level: intermediate

990: .keywords: PC, set, operators, matrix, linear system

992: .seealso: PCGetOperators(), MatZeroEntries()
993:  @*/
994: PetscErrorCode PETSCKSP_DLLEXPORT PCSetOperators(PC pc,Mat Amat,Mat Pmat,MatStructure flag)
995: {
997:   PetscTruth     isbjacobi,isrowbs;


1006:   /*
1007:       BlockSolve95 cannot use default BJacobi preconditioning
1008:   */
1009:   if (Amat) {
1010:     PetscTypeCompare((PetscObject)Amat,MATMPIROWBS,&isrowbs);
1011:     if (isrowbs) {
1012:       PetscTypeCompare((PetscObject)pc,PCBJACOBI,&isbjacobi);
1013:       if (isbjacobi) {
1014:         PCSetType(pc,PCILU);
1015:         PetscInfo(pc,"Switching default PC to PCILU since BS95 doesn't support PCBJACOBI\n");
1016:       }
1017:     }
1018:   }

1020:   pc->mat  = Amat;
1021:   pc->pmat = Pmat;
1022:   if (pc->setupcalled == 2 && flag != SAME_PRECONDITIONER) {
1023:     pc->setupcalled = 1;
1024:   }
1025:   pc->flag = flag;
1026:   return(0);
1027: }

1031: /*@C
1032:    PCGetOperators - Gets the matrix associated with the linear system and
1033:    possibly a different one associated with the preconditioner.

1035:    Not collective, though parallel Mats are returned if the PC is parallel

1037:    Input Parameter:
1038: .  pc - the preconditioner context

1040:    Output Parameters:
1041: +  mat - the matrix associated with the linear system
1042: .  pmat - matrix associated with the preconditioner, usually the same
1043:           as mat. 
1044: -  flag - flag indicating information about the preconditioner
1045:           matrix structure.  See PCSetOperators() for details.

1047:    Level: intermediate

1049: .keywords: PC, get, operators, matrix, linear system

1051: .seealso: PCSetOperators()
1052: @*/
1053: PetscErrorCode PETSCKSP_DLLEXPORT PCGetOperators(PC pc,Mat *mat,Mat *pmat,MatStructure *flag)
1054: {
1057:   if (mat)  *mat  = pc->mat;
1058:   if (pmat) *pmat = pc->pmat;
1059:   if (flag) *flag = pc->flag;
1060:   return(0);
1061: }

1065: /*@
1066:    PCGetFactoredMatrix - Gets the factored matrix from the
1067:    preconditioner context.  This routine is valid only for the LU, 
1068:    incomplete LU, Cholesky, and incomplete Cholesky methods.

1070:    Not Collective on PC though Mat is parallel if PC is parallel

1072:    Input Parameters:
1073: .  pc - the preconditioner context

1075:    Output parameters:
1076: .  mat - the factored matrix

1078:    Level: advanced

1080:    Notes: Does not increase the reference count for the matrix so DO NOT destroy it

1082: .keywords: PC, get, factored, matrix
1083: @*/
1084: PetscErrorCode PETSCKSP_DLLEXPORT PCGetFactoredMatrix(PC pc,Mat *mat)
1085: {

1091:   if (pc->ops->getfactoredmatrix) {
1092:     (*pc->ops->getfactoredmatrix)(pc,mat);
1093:   }
1094:   return(0);
1095: }

1099: /*@C
1100:    PCSetOptionsPrefix - Sets the prefix used for searching for all 
1101:    PC options in the database.

1103:    Collective on PC

1105:    Input Parameters:
1106: +  pc - the preconditioner context
1107: -  prefix - the prefix string to prepend to all PC option requests

1109:    Notes:
1110:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1111:    The first character of all runtime options is AUTOMATICALLY the
1112:    hyphen.

1114:    Level: advanced

1116: .keywords: PC, set, options, prefix, database

1118: .seealso: PCAppendOptionsPrefix(), PCGetOptionsPrefix()
1119: @*/
1120: PetscErrorCode PETSCKSP_DLLEXPORT PCSetOptionsPrefix(PC pc,const char prefix[])
1121: {

1126:   PetscObjectSetOptionsPrefix((PetscObject)pc,prefix);
1127:   return(0);
1128: }

1132: /*@C
1133:    PCAppendOptionsPrefix - Appends to the prefix used for searching for all 
1134:    PC options in the database.

1136:    Collective on PC

1138:    Input Parameters:
1139: +  pc - the preconditioner context
1140: -  prefix - the prefix string to prepend to all PC option requests

1142:    Notes:
1143:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1144:    The first character of all runtime options is AUTOMATICALLY the
1145:    hyphen.

1147:    Level: advanced

1149: .keywords: PC, append, options, prefix, database

1151: .seealso: PCSetOptionsPrefix(), PCGetOptionsPrefix()
1152: @*/
1153: PetscErrorCode PETSCKSP_DLLEXPORT PCAppendOptionsPrefix(PC pc,const char prefix[])
1154: {

1159:   PetscObjectAppendOptionsPrefix((PetscObject)pc,prefix);
1160:   return(0);
1161: }

1165: /*@C
1166:    PCGetOptionsPrefix - Gets the prefix used for searching for all 
1167:    PC options in the database.

1169:    Not Collective

1171:    Input Parameters:
1172: .  pc - the preconditioner context

1174:    Output Parameters:
1175: .  prefix - pointer to the prefix string used, is returned

1177:    Notes: On the fortran side, the user should pass in a string 'prifix' of
1178:    sufficient length to hold the prefix.

1180:    Level: advanced

1182: .keywords: PC, get, options, prefix, database

1184: .seealso: PCSetOptionsPrefix(), PCAppendOptionsPrefix()
1185: @*/
1186: PetscErrorCode PETSCKSP_DLLEXPORT PCGetOptionsPrefix(PC pc,const char *prefix[])
1187: {

1193:   PetscObjectGetOptionsPrefix((PetscObject)pc,prefix);
1194:   return(0);
1195: }

1199: /*@
1200:    PCPreSolve - Optional pre-solve phase, intended for any
1201:    preconditioner-specific actions that must be performed before 
1202:    the iterative solve itself.

1204:    Collective on PC

1206:    Input Parameters:
1207: +  pc - the preconditioner context
1208: -  ksp - the Krylov subspace context

1210:    Level: developer

1212:    Sample of Usage:
1213: .vb
1214:     PCPreSolve(pc,ksp);
1215:     KSPSolve(ksp,b,x);
1216:     PCPostSolve(pc,ksp);
1217: .ve

1219:    Notes:
1220:    The pre-solve phase is distinct from the PCSetUp() phase.

1222:    KSPSolve() calls this directly, so is rarely called by the user.

1224: .keywords: PC, pre-solve

1226: .seealso: PCPostSolve()
1227: @*/
1228: PetscErrorCode PETSCKSP_DLLEXPORT PCPreSolve(PC pc,KSP ksp)
1229: {
1231:   Vec            x,rhs;
1232:   Mat            A,B;

1237:   KSPGetSolution(ksp,&x);
1238:   KSPGetRhs(ksp,&rhs);
1239:   /*
1240:       Scale the system and have the matrices use the scaled form
1241:     only if the two matrices are actually the same (and hence
1242:     have the same scaling
1243:   */
1244:   PCGetOperators(pc,&A,&B,PETSC_NULL);
1245:   if (A == B) {
1246:     MatScaleSystem(pc->mat,rhs,x);
1247:     MatUseScaledForm(pc->mat,PETSC_TRUE);
1248:   }

1250:   if (pc->ops->presolve) {
1251:     (*pc->ops->presolve)(pc,ksp,rhs,x);
1252:   }
1253:   return(0);
1254: }

1258: /*@
1259:    PCPostSolve - Optional post-solve phase, intended for any
1260:    preconditioner-specific actions that must be performed after
1261:    the iterative solve itself.

1263:    Collective on PC

1265:    Input Parameters:
1266: +  pc - the preconditioner context
1267: -  ksp - the Krylov subspace context

1269:    Sample of Usage:
1270: .vb
1271:     PCPreSolve(pc,ksp);
1272:     KSPSolve(ksp,b,x);
1273:     PCPostSolve(pc,ksp);
1274: .ve

1276:    Note:
1277:    KSPSolve() calls this routine directly, so it is rarely called by the user.

1279:    Level: developer

1281: .keywords: PC, post-solve

1283: .seealso: PCPreSolve(), KSPSolve()
1284: @*/
1285: PetscErrorCode PETSCKSP_DLLEXPORT PCPostSolve(PC pc,KSP ksp)
1286: {
1288:   Vec            x,rhs;
1289:   Mat            A,B;

1294:   KSPGetSolution(ksp,&x);
1295:   KSPGetRhs(ksp,&rhs);
1296:   if (pc->ops->postsolve) {
1297:      (*pc->ops->postsolve)(pc,ksp,rhs,x);
1298:   }

1300:   /*
1301:       Scale the system and have the matrices use the scaled form
1302:     only if the two matrices are actually the same (and hence
1303:     have the same scaling
1304:   */
1305:   PCGetOperators(pc,&A,&B,PETSC_NULL);
1306:   if (A == B) {
1307:     MatUnScaleSystem(pc->mat,rhs,x);
1308:     MatUseScaledForm(pc->mat,PETSC_FALSE);
1309:   }
1310:   return(0);
1311: }

1315: /*@C
1316:    PCView - Prints the PC data structure.

1318:    Collective on PC

1320:    Input Parameters:
1321: +  PC - the PC context
1322: -  viewer - optional visualization context

1324:    Note:
1325:    The available visualization contexts include
1326: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
1327: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
1328:          output where only the first processor opens
1329:          the file.  All other processors send their 
1330:          data to the first processor to print. 

1332:    The user can open an alternative visualization contexts with
1333:    PetscViewerASCIIOpen() (output to a specified file).

1335:    Level: developer

1337: .keywords: PC, view

1339: .seealso: KSPView(), PetscViewerASCIIOpen()
1340: @*/
1341: PetscErrorCode PETSCKSP_DLLEXPORT PCView(PC pc,PetscViewer viewer)
1342: {
1343:   PCType            cstr;
1344:   PetscErrorCode    ierr;
1345:   PetscTruth        mat_exists,iascii,isstring;
1346:   PetscViewerFormat format;

1350:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(pc->comm);

1354:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
1355:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
1356:   if (iascii) {
1357:     PetscViewerGetFormat(viewer,&format);
1358:     if (pc->prefix) {
1359:       PetscViewerASCIIPrintf(viewer,"PC Object:(%s)\n",pc->prefix);
1360:     } else {
1361:       PetscViewerASCIIPrintf(viewer,"PC Object:\n");
1362:     }
1363:     PCGetType(pc,&cstr);
1364:     if (cstr) {
1365:       PetscViewerASCIIPrintf(viewer,"  type: %s\n",cstr);
1366:     } else {
1367:       PetscViewerASCIIPrintf(viewer,"  type: not yet set\n");
1368:     }
1369:     if (pc->ops->view) {
1370:       PetscViewerASCIIPushTab(viewer);
1371:       (*pc->ops->view)(pc,viewer);
1372:       PetscViewerASCIIPopTab(viewer);
1373:     }
1374:     PetscObjectExists((PetscObject)pc->mat,&mat_exists);
1375:     if (mat_exists) {
1376:       PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
1377:       if (pc->pmat == pc->mat) {
1378:         PetscViewerASCIIPrintf(viewer,"  linear system matrix = precond matrix:\n");
1379:         PetscViewerASCIIPushTab(viewer);
1380:         MatView(pc->mat,viewer);
1381:         PetscViewerASCIIPopTab(viewer);
1382:       } else {
1383:         PetscObjectExists((PetscObject)pc->pmat,&mat_exists);
1384:         if (mat_exists) {
1385:           PetscViewerASCIIPrintf(viewer,"  linear system matrix followed by preconditioner matrix:\n");
1386:         } else {
1387:           PetscViewerASCIIPrintf(viewer,"  linear system matrix:\n");
1388:         }
1389:         PetscViewerASCIIPushTab(viewer);
1390:         MatView(pc->mat,viewer);
1391:         if (mat_exists) {MatView(pc->pmat,viewer);}
1392:         PetscViewerASCIIPopTab(viewer);
1393:       }
1394:       PetscViewerPopFormat(viewer);
1395:     }
1396:   } else if (isstring) {
1397:     PCGetType(pc,&cstr);
1398:     PetscViewerStringSPrintf(viewer," %-7.7s",cstr);
1399:     if (pc->ops->view) {(*pc->ops->view)(pc,viewer);}
1400:   } else {
1401:     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by PC",((PetscObject)viewer)->type_name);
1402:   }
1403:   return(0);
1404: }

1408: /*@C
1409:   PCRegister - See PCRegisterDynamic()

1411:   Level: advanced
1412: @*/
1413: PetscErrorCode PETSCKSP_DLLEXPORT PCRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(PC))
1414: {
1416:   char           fullname[PETSC_MAX_PATH_LEN];


1420:   PetscFListConcat(path,name,fullname);
1421:   PetscFListAdd(&PCList,sname,fullname,(void (*)(void))function);
1422:   return(0);
1423: }

1427: /*@
1428:     PCComputeExplicitOperator - Computes the explicit preconditioned operator.  

1430:     Collective on PC

1432:     Input Parameter:
1433: .   pc - the preconditioner object

1435:     Output Parameter:
1436: .   mat - the explict preconditioned operator

1438:     Notes:
1439:     This computation is done by applying the operators to columns of the 
1440:     identity matrix.

1442:     Currently, this routine uses a dense matrix format when 1 processor
1443:     is used and a sparse format otherwise.  This routine is costly in general,
1444:     and is recommended for use only with relatively small systems.

1446:     Level: advanced
1447:    
1448: .keywords: PC, compute, explicit, operator

1450: @*/
1451: PetscErrorCode PETSCKSP_DLLEXPORT PCComputeExplicitOperator(PC pc,Mat *mat)
1452: {
1453:   Vec            in,out;
1455:   PetscInt       i,M,m,*rows,start,end;
1456:   PetscMPIInt    size;
1457:   MPI_Comm       comm;
1458:   PetscScalar    *array,one = 1.0;
1459: 

1464:   comm = pc->comm;
1465:   MPI_Comm_size(comm,&size);

1467:   if (!pc->pmat) SETERRQ(PETSC_ERR_ORDER,"You must call KSPSetOperators() or PCSetOperators() before this call");
1468:   MatGetVecs(pc->pmat,&in,0);
1469:   VecDuplicate(in,&out);
1470:   VecGetOwnershipRange(in,&start,&end);
1471:   VecGetSize(in,&M);
1472:   VecGetLocalSize(in,&m);
1473:   PetscMalloc((m+1)*sizeof(PetscInt),&rows);
1474:   for (i=0; i<m; i++) {rows[i] = start + i;}

1476:   MatCreate(comm,mat);
1477:   MatSetSizes(*mat,m,m,M,M);
1478:   if (size == 1) {
1479:     MatSetType(*mat,MATSEQDENSE);
1480:     MatSeqDenseSetPreallocation(*mat,PETSC_NULL);
1481:   } else {
1482:     MatSetType(*mat,MATMPIAIJ);
1483:     MatMPIAIJSetPreallocation(*mat,0,PETSC_NULL,0,PETSC_NULL);
1484:   }

1486:   for (i=0; i<M; i++) {

1488:     VecSet(in,0.0);
1489:     VecSetValues(in,1,&i,&one,INSERT_VALUES);
1490:     VecAssemblyBegin(in);
1491:     VecAssemblyEnd(in);

1493:     /* should fix, allowing user to choose side */
1494:     PCApply(pc,in,out);
1495: 
1496:     VecGetArray(out,&array);
1497:     MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);
1498:     VecRestoreArray(out,&array);

1500:   }
1501:   PetscFree(rows);
1502:   VecDestroy(out);
1503:   MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);
1504:   MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);
1505:   return(0);
1506: }