Actual source code: precon.c


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

  8: /* Logging support */
  9: PetscClassId  PC_CLASSID;
 10: PetscLogEvent PC_SetUp, PC_SetUpOnBlocks, PC_Apply, PC_MatApply, PC_ApplyCoarse, PC_ApplyMultiple, PC_ApplySymmetricLeft;
 11: PetscLogEvent PC_ApplySymmetricRight, PC_ModifySubMatrices, PC_ApplyOnBlocks, PC_ApplyTransposeOnBlocks;
 12: PetscInt      PetscMGLevelId;

 14: PetscErrorCode PCGetDefaultType_Private(PC pc,const char *type[])
 15: {
 16:   PetscMPIInt    size;
 17:   PetscBool      hasop,flg1,flg2,set,flg3;

 19:   MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);
 20:   if (pc->pmat) {
 21:     MatHasOperation(pc->pmat,MATOP_GET_DIAGONAL_BLOCK,&hasop);
 22:     if (size == 1) {
 23:       MatGetFactorAvailable(pc->pmat,"petsc",MAT_FACTOR_ICC,&flg1);
 24:       MatGetFactorAvailable(pc->pmat,"petsc",MAT_FACTOR_ILU,&flg2);
 25:       MatIsSymmetricKnown(pc->pmat,&set,&flg3);
 26:       if (flg1 && (!flg2 || (set && flg3))) {
 27:         *type = PCICC;
 28:       } else if (flg2) {
 29:         *type = PCILU;
 30:       } else if (hasop) { /* likely is a parallel matrix run on one processor */
 31:         *type = PCBJACOBI;
 32:       } else {
 33:         *type = PCNONE;
 34:       }
 35:     } else {
 36:        if (hasop) {
 37:         *type = PCBJACOBI;
 38:       } else {
 39:         *type = PCNONE;
 40:       }
 41:     }
 42:   } else {
 43:     if (size == 1) {
 44:       *type = PCILU;
 45:     } else {
 46:       *type = PCBJACOBI;
 47:     }
 48:   }
 49:   return 0;
 50: }

 52: /*@
 53:    PCReset - Resets a PC context to the pcsetupcalled = 0 state and removes any allocated Vecs and Mats

 55:    Collective on PC

 57:    Input Parameter:
 58: .  pc - the preconditioner context

 60:    Level: developer

 62:    Notes:
 63:     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

 65: .seealso: PCCreate(), PCSetUp()
 66: @*/
 67: PetscErrorCode  PCReset(PC pc)
 68: {
 70:   if (pc->ops->reset) {
 71:     (*pc->ops->reset)(pc);
 72:   }
 73:   VecDestroy(&pc->diagonalscaleright);
 74:   VecDestroy(&pc->diagonalscaleleft);
 75:   MatDestroy(&pc->pmat);
 76:   MatDestroy(&pc->mat);

 78:   pc->setupcalled = 0;
 79:   return 0;
 80: }

 82: /*@C
 83:    PCDestroy - Destroys PC context that was created with PCCreate().

 85:    Collective on PC

 87:    Input Parameter:
 88: .  pc - the preconditioner context

 90:    Level: developer

 92: .seealso: PCCreate(), PCSetUp()
 93: @*/
 94: PetscErrorCode  PCDestroy(PC *pc)
 95: {
 96:   if (!*pc) return 0;
 98:   if (--((PetscObject)(*pc))->refct > 0) {*pc = NULL; return 0;}

100:   PCReset(*pc);

102:   /* if memory was published with SAWs then destroy it */
103:   PetscObjectSAWsViewOff((PetscObject)*pc);
104:   if ((*pc)->ops->destroy) (*(*pc)->ops->destroy)((*pc));
105:   DMDestroy(&(*pc)->dm);
106:   PetscHeaderDestroy(pc);
107:   return 0;
108: }

110: /*@C
111:    PCGetDiagonalScale - Indicates if the preconditioner applies an additional left and right
112:       scaling as needed by certain time-stepping codes.

114:    Logically Collective on PC

116:    Input Parameter:
117: .  pc - the preconditioner context

119:    Output Parameter:
120: .  flag - PETSC_TRUE if it applies the scaling

122:    Level: developer

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

129: .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleLeft(), PCDiagonalScaleRight(), PCSetDiagonalScale()
130: @*/
131: PetscErrorCode  PCGetDiagonalScale(PC pc,PetscBool  *flag)
132: {
135:   *flag = pc->diagonalscale;
136:   return 0;
137: }

139: /*@
140:    PCSetDiagonalScale - Indicates the left scaling to use to apply an additional left and right
141:       scaling as needed by certain time-stepping codes.

143:    Logically Collective on PC

145:    Input Parameters:
146: +  pc - the preconditioner context
147: -  s - scaling vector

149:    Level: intermediate

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

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

158: .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleLeft(), PCDiagonalScaleRight(), PCGetDiagonalScale()
159: @*/
160: PetscErrorCode  PCSetDiagonalScale(PC pc,Vec s)
161: {
164:   pc->diagonalscale     = PETSC_TRUE;

166:   PetscObjectReference((PetscObject)s);
167:   VecDestroy(&pc->diagonalscaleleft);

169:   pc->diagonalscaleleft = s;

171:   VecDuplicate(s,&pc->diagonalscaleright);
172:   VecCopy(s,pc->diagonalscaleright);
173:   VecReciprocal(pc->diagonalscaleright);
174:   return 0;
175: }

177: /*@
178:    PCDiagonalScaleLeft - Scales a vector by the left scaling as needed by certain time-stepping codes.

180:    Logically Collective on PC

182:    Input Parameters:
183: +  pc - the preconditioner context
184: .  in - input vector
185: -  out - scaled vector (maybe the same as in)

187:    Level: intermediate

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

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

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

198: .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleSet(), PCDiagonalScaleRight(), PCDiagonalScale()
199: @*/
200: PetscErrorCode  PCDiagonalScaleLeft(PC pc,Vec in,Vec out)
201: {
205:   if (pc->diagonalscale) {
206:     VecPointwiseMult(out,pc->diagonalscaleleft,in);
207:   } else if (in != out) {
208:     VecCopy(in,out);
209:   }
210:   return 0;
211: }

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

216:    Logically Collective on PC

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

223:    Level: intermediate

225:    Notes:
226:     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: .seealso: PCCreate(), PCSetUp(), PCDiagonalScaleLeft(), PCDiagonalScaleSet(), PCDiagonalScale()
235: @*/
236: PetscErrorCode  PCDiagonalScaleRight(PC pc,Vec in,Vec out)
237: {
241:   if (pc->diagonalscale) {
242:     VecPointwiseMult(out,pc->diagonalscaleright,in);
243:   } else if (in != out) {
244:     VecCopy(in,out);
245:   }
246:   return 0;
247: }

249: /*@
250:    PCSetUseAmat - Sets a flag to indicate that when the preconditioner needs to apply (part of) the
251:    operator during the preconditioning process it applies the Amat provided to TSSetRHSJacobian(),
252:    TSSetIJacobian(), SNESSetJacobian(), KSPSetOperators() or PCSetOperators() not the Pmat.

254:    Logically Collective on PC

256:    Input Parameters:
257: +  pc - the preconditioner context
258: -  flg - PETSC_TRUE to use the Amat, PETSC_FALSE to use the Pmat (default is false)

260:    Options Database Key:
261: .  -pc_use_amat <true,false> - use the amat to apply the operator

263:    Notes:
264:    For the common case in which the linear system matrix and the matrix used to construct the
265:    preconditioner are identical, this routine is does nothing.

267:    Level: intermediate

269: .seealso: PCGetUseAmat(), PCBJACOBI, PGMG, PCFIELDSPLIT, PCCOMPOSITE
270: @*/
271: PetscErrorCode  PCSetUseAmat(PC pc,PetscBool flg)
272: {
274:   pc->useAmat = flg;
275:   return 0;
276: }

278: /*@
279:    PCSetErrorIfFailure - Causes PC to generate an error if a FPE, for example a zero pivot, is detected.

281:    Logically Collective on PC

283:    Input Parameters:
284: +  pc - iterative context obtained from PCCreate()
285: -  flg - PETSC_TRUE indicates you want the error generated

287:    Level: advanced

289:    Notes:
290:     Normally PETSc continues if a linear solver fails due to a failed setup of a preconditioner, you can call KSPGetConvergedReason() after a KSPSolve()
291:     to determine if it has converged or failed. Or use -ksp_error_if_not_converged to cause the program to terminate as soon as lack of convergence is
292:     detected.

294:     This is propagated into KSPs used by this PC, which then propagate it into PCs used by those KSPs

296: .seealso: PCGetInitialGuessNonzero(), PCSetInitialGuessKnoll(), PCGetInitialGuessKnoll()
297: @*/
298: PetscErrorCode  PCSetErrorIfFailure(PC pc,PetscBool flg)
299: {
302:   pc->erroriffailure = flg;
303:   return 0;
304: }

306: /*@
307:    PCGetUseAmat - Gets a flag to indicate that when the preconditioner needs to apply (part of) the
308:    operator during the preconditioning process it applies the Amat provided to TSSetRHSJacobian(),
309:    TSSetIJacobian(), SNESSetJacobian(), KSPSetOperators() or PCSetOperators() not the Pmat.

311:    Logically Collective on PC

313:    Input Parameter:
314: .  pc - the preconditioner context

316:    Output Parameter:
317: .  flg - PETSC_TRUE to use the Amat, PETSC_FALSE to use the Pmat (default is false)

319:    Notes:
320:    For the common case in which the linear system matrix and the matrix used to construct the
321:    preconditioner are identical, this routine is does nothing.

323:    Level: intermediate

325: .seealso: PCSetUseAmat(), PCBJACOBI, PGMG, PCFIELDSPLIT, PCCOMPOSITE
326: @*/
327: PetscErrorCode  PCGetUseAmat(PC pc,PetscBool *flg)
328: {
330:   *flg = pc->useAmat;
331:   return 0;
332: }

334: /*@
335:    PCCreate - Creates a preconditioner context.

337:    Collective

339:    Input Parameter:
340: .  comm - MPI communicator

342:    Output Parameter:
343: .  pc - location to put the preconditioner context

345:    Notes:
346:    The default preconditioner for sparse matrices is PCILU or PCICC with 0 fill on one process and block Jacobi with PCILU or PCICC
347:    in parallel. For dense matrices it is always PCNONE.

349:    Level: developer

351: .seealso: PCSetUp(), PCApply(), PCDestroy()
352: @*/
353: PetscErrorCode  PCCreate(MPI_Comm comm,PC *newpc)
354: {
355:   PC             pc;

358:   *newpc = NULL;
359:   PCInitializePackage();

361:   PetscHeaderCreate(pc,PC_CLASSID,"PC","Preconditioner","PC",comm,PCDestroy,PCView);

363:   pc->mat                  = NULL;
364:   pc->pmat                 = NULL;
365:   pc->setupcalled          = 0;
366:   pc->setfromoptionscalled = 0;
367:   pc->data                 = NULL;
368:   pc->diagonalscale        = PETSC_FALSE;
369:   pc->diagonalscaleleft    = NULL;
370:   pc->diagonalscaleright   = NULL;

372:   pc->modifysubmatrices  = NULL;
373:   pc->modifysubmatricesP = NULL;

375:   *newpc = pc;
376:   return 0;

378: }

380: /* -------------------------------------------------------------------------------*/

382: /*@
383:    PCApply - Applies the preconditioner to a vector.

385:    Collective on PC

387:    Input Parameters:
388: +  pc - the preconditioner context
389: -  x - input vector

391:    Output Parameter:
392: .  y - output vector

394:    Level: developer

396: .seealso: PCApplyTranspose(), PCApplyBAorAB()
397: @*/
398: PetscErrorCode  PCApply(PC pc,Vec x,Vec y)
399: {
400:   PetscInt       m,n,mv,nv;

406:   if (pc->erroriffailure) VecValidValues(x,2,PETSC_TRUE);
407:   /* use pmat to check vector sizes since for KSPLSQR the pmat may be of a different size than mat */
408:   MatGetLocalSize(pc->pmat,&m,&n);
409:   VecGetLocalSize(x,&mv);
410:   VecGetLocalSize(y,&nv);
411:   /* check pmat * y = x is feasible */
414:   VecSetErrorIfLocked(y,3);

416:   PCSetUp(pc);
418:   VecLockReadPush(x);
419:   PetscLogEventBegin(PC_Apply,pc,x,y,0);
420:   (*pc->ops->apply)(pc,x,y);
421:   PetscLogEventEnd(PC_Apply,pc,x,y,0);
422:   if (pc->erroriffailure) VecValidValues(y,3,PETSC_FALSE);
423:   VecLockReadPop(x);
424:   return 0;
425: }

427: /*@
428:    PCMatApply - Applies the preconditioner to multiple vectors stored as a MATDENSE. Like PCApply(), Y and X must be different matrices.

430:    Collective on PC

432:    Input Parameters:
433: +  pc - the preconditioner context
434: -  X - block of input vectors

436:    Output Parameter:
437: .  Y - block of output vectors

439:    Level: developer

441: .seealso: PCApply(), KSPMatSolve()
442: @*/
443: PetscErrorCode  PCMatApply(PC pc,Mat X,Mat Y)
444: {
445:   Mat            A;
446:   Vec            cy, cx;
447:   PetscInt       m1, M1, m2, M2, n1, N1, n2, N2, m3, M3, n3, N3;
448:   PetscBool      match;

456:   PCGetOperators(pc, NULL, &A);
457:   MatGetLocalSize(A, &m3, &n3);
458:   MatGetLocalSize(X, &m2, &n2);
459:   MatGetLocalSize(Y, &m1, &n1);
460:   MatGetSize(A, &M3, &N3);
461:   MatGetSize(X, &M2, &N2);
462:   MatGetSize(Y, &M1, &N1);
466:   PetscObjectBaseTypeCompareAny((PetscObject)Y, &match, MATSEQDENSE, MATMPIDENSE, "");
468:   PetscObjectBaseTypeCompareAny((PetscObject)X, &match, MATSEQDENSE, MATMPIDENSE, "");
470:   PCSetUp(pc);
471:   if (pc->ops->matapply) {
472:     PetscLogEventBegin(PC_MatApply, pc, X, Y, 0);
473:     (*pc->ops->matapply)(pc, X, Y);
474:     PetscLogEventEnd(PC_MatApply, pc, X, Y, 0);
475:   } else {
476:     PetscInfo(pc, "PC type %s applying column by column\n", ((PetscObject)pc)->type_name);
477:     for (n1 = 0; n1 < N1; ++n1) {
478:       MatDenseGetColumnVecRead(X, n1, &cx);
479:       MatDenseGetColumnVecWrite(Y, n1, &cy);
480:       PCApply(pc, cx, cy);
481:       MatDenseRestoreColumnVecWrite(Y, n1, &cy);
482:       MatDenseRestoreColumnVecRead(X, n1, &cx);
483:     }
484:   }
485:   return 0;
486: }

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

491:    Collective on PC

493:    Input Parameters:
494: +  pc - the preconditioner context
495: -  x - input vector

497:    Output Parameter:
498: .  y - output vector

500:    Notes:
501:    Currently, this routine is implemented only for PCICC and PCJACOBI preconditioners.

503:    Level: developer

505: .seealso: PCApply(), PCApplySymmetricRight()
506: @*/
507: PetscErrorCode  PCApplySymmetricLeft(PC pc,Vec x,Vec y)
508: {
513:   if (pc->erroriffailure) VecValidValues(x,2,PETSC_TRUE);
514:   PCSetUp(pc);
516:   VecLockReadPush(x);
517:   PetscLogEventBegin(PC_ApplySymmetricLeft,pc,x,y,0);
518:   (*pc->ops->applysymmetricleft)(pc,x,y);
519:   PetscLogEventEnd(PC_ApplySymmetricLeft,pc,x,y,0);
520:   VecLockReadPop(x);
521:   if (pc->erroriffailure) VecValidValues(y,3,PETSC_FALSE);
522:   return 0;
523: }

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

528:    Collective on PC

530:    Input Parameters:
531: +  pc - the preconditioner context
532: -  x - input vector

534:    Output Parameter:
535: .  y - output vector

537:    Level: developer

539:    Notes:
540:    Currently, this routine is implemented only for PCICC and PCJACOBI preconditioners.

542: .seealso: PCApply(), PCApplySymmetricLeft()
543: @*/
544: PetscErrorCode  PCApplySymmetricRight(PC pc,Vec x,Vec y)
545: {
550:   if (pc->erroriffailure) VecValidValues(x,2,PETSC_TRUE);
551:   PCSetUp(pc);
553:   VecLockReadPush(x);
554:   PetscLogEventBegin(PC_ApplySymmetricRight,pc,x,y,0);
555:   (*pc->ops->applysymmetricright)(pc,x,y);
556:   PetscLogEventEnd(PC_ApplySymmetricRight,pc,x,y,0);
557:   VecLockReadPop(x);
558:   if (pc->erroriffailure) VecValidValues(y,3,PETSC_FALSE);
559:   return 0;
560: }

562: /*@
563:    PCApplyTranspose - Applies the transpose of preconditioner to a vector.

565:    Collective on PC

567:    Input Parameters:
568: +  pc - the preconditioner context
569: -  x - input vector

571:    Output Parameter:
572: .  y - output vector

574:    Notes:
575:     For complex numbers this applies the non-Hermitian transpose.

577:    Developer Notes:
578:     We need to implement a PCApplyHermitianTranspose()

580:    Level: developer

582: .seealso: PCApply(), PCApplyBAorAB(), PCApplyBAorABTranspose(), PCApplyTransposeExists()
583: @*/
584: PetscErrorCode  PCApplyTranspose(PC pc,Vec x,Vec y)
585: {
590:   if (pc->erroriffailure) VecValidValues(x,2,PETSC_TRUE);
591:   PCSetUp(pc);
593:   VecLockReadPush(x);
594:   PetscLogEventBegin(PC_Apply,pc,x,y,0);
595:   (*pc->ops->applytranspose)(pc,x,y);
596:   PetscLogEventEnd(PC_Apply,pc,x,y,0);
597:   VecLockReadPop(x);
598:   if (pc->erroriffailure) VecValidValues(y,3,PETSC_FALSE);
599:   return 0;
600: }

602: /*@
603:    PCApplyTransposeExists - Test whether the preconditioner has a transpose apply operation

605:    Collective on PC

607:    Input Parameters:
608: .  pc - the preconditioner context

610:    Output Parameter:
611: .  flg - PETSC_TRUE if a transpose operation is defined

613:    Level: developer

615: .seealso: PCApplyTranspose()
616: @*/
617: PetscErrorCode  PCApplyTransposeExists(PC pc,PetscBool  *flg)
618: {
621:   if (pc->ops->applytranspose) *flg = PETSC_TRUE;
622:   else *flg = PETSC_FALSE;
623:   return 0;
624: }

626: /*@
627:    PCApplyBAorAB - Applies the preconditioner and operator to a vector. y = B*A*x or y = A*B*x.

629:    Collective on PC

631:    Input Parameters:
632: +  pc - the preconditioner context
633: .  side - indicates the preconditioner side, one of PC_LEFT, PC_RIGHT, or PC_SYMMETRIC
634: .  x - input vector
635: -  work - work vector

637:    Output Parameter:
638: .  y - output vector

640:    Level: developer

642:    Notes:
643:     If the PC has had PCSetDiagonalScale() set then D M A D^{-1} for left preconditioning or  D A M D^{-1} is actually applied. Note that the
644:    specific KSPSolve() method must also be written to handle the post-solve "correction" for the diagonal scaling.

646: .seealso: PCApply(), PCApplyTranspose(), PCApplyBAorABTranspose()
647: @*/
648: PetscErrorCode  PCApplyBAorAB(PC pc,PCSide side,Vec x,Vec y,Vec work)
649: {
661:   if (pc->erroriffailure) VecValidValues(x,3,PETSC_TRUE);

663:   PCSetUp(pc);
664:   if (pc->diagonalscale) {
665:     if (pc->ops->applyBA) {
666:       Vec work2; /* this is expensive, but to fix requires a second work vector argument to PCApplyBAorAB() */
667:       VecDuplicate(x,&work2);
668:       PCDiagonalScaleRight(pc,x,work2);
669:       (*pc->ops->applyBA)(pc,side,work2,y,work);
670:       PCDiagonalScaleLeft(pc,y,y);
671:       VecDestroy(&work2);
672:     } else if (side == PC_RIGHT) {
673:       PCDiagonalScaleRight(pc,x,y);
674:       PCApply(pc,y,work);
675:       MatMult(pc->mat,work,y);
676:       PCDiagonalScaleLeft(pc,y,y);
677:     } else if (side == PC_LEFT) {
678:       PCDiagonalScaleRight(pc,x,y);
679:       MatMult(pc->mat,y,work);
680:       PCApply(pc,work,y);
681:       PCDiagonalScaleLeft(pc,y,y);
683:   } else {
684:     if (pc->ops->applyBA) {
685:       (*pc->ops->applyBA)(pc,side,x,y,work);
686:     } else if (side == PC_RIGHT) {
687:       PCApply(pc,x,work);
688:       MatMult(pc->mat,work,y);
689:     } else if (side == PC_LEFT) {
690:       MatMult(pc->mat,x,work);
691:       PCApply(pc,work,y);
692:     } else if (side == PC_SYMMETRIC) {
693:       /* There's an extra copy here; maybe should provide 2 work vectors instead? */
694:       PCApplySymmetricRight(pc,x,work);
695:       MatMult(pc->mat,work,y);
696:       VecCopy(y,work);
697:       PCApplySymmetricLeft(pc,work,y);
698:     }
699:   }
700:   if (pc->erroriffailure) VecValidValues(y,4,PETSC_FALSE);
701:   return 0;
702: }

704: /*@
705:    PCApplyBAorABTranspose - Applies the transpose of the preconditioner
706:    and operator to a vector. That is, applies tr(B) * tr(A) with left preconditioning,
707:    NOT tr(B*A) = tr(A)*tr(B).

709:    Collective on PC

711:    Input Parameters:
712: +  pc - the preconditioner context
713: .  side - indicates the preconditioner side, one of PC_LEFT, PC_RIGHT, or PC_SYMMETRIC
714: .  x - input vector
715: -  work - work vector

717:    Output Parameter:
718: .  y - output vector

720:    Notes:
721:     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
722:       defined by B'. This is why this has the funny form that it computes tr(B) * tr(A)

724:     Level: developer

726: .seealso: PCApply(), PCApplyTranspose(), PCApplyBAorAB()
727: @*/
728: PetscErrorCode  PCApplyBAorABTranspose(PC pc,PCSide side,Vec x,Vec y,Vec work)
729: {
735:   if (pc->erroriffailure) VecValidValues(x,3,PETSC_TRUE);
736:   if (pc->ops->applyBAtranspose) {
737:     (*pc->ops->applyBAtranspose)(pc,side,x,y,work);
738:     if (pc->erroriffailure) VecValidValues(y,4,PETSC_FALSE);
739:     return 0;
740:   }

743:   PCSetUp(pc);
744:   if (side == PC_RIGHT) {
745:     PCApplyTranspose(pc,x,work);
746:     MatMultTranspose(pc->mat,work,y);
747:   } else if (side == PC_LEFT) {
748:     MatMultTranspose(pc->mat,x,work);
749:     PCApplyTranspose(pc,work,y);
750:   }
751:   /* add support for PC_SYMMETRIC */
752:   if (pc->erroriffailure) VecValidValues(y,4,PETSC_FALSE);
753:   return 0;
754: }

756: /* -------------------------------------------------------------------------------*/

758: /*@
759:    PCApplyRichardsonExists - Determines whether a particular preconditioner has a
760:    built-in fast application of Richardson's method.

762:    Not Collective

764:    Input Parameter:
765: .  pc - the preconditioner

767:    Output Parameter:
768: .  exists - PETSC_TRUE or PETSC_FALSE

770:    Level: developer

772: .seealso: PCApplyRichardson()
773: @*/
774: PetscErrorCode  PCApplyRichardsonExists(PC pc,PetscBool  *exists)
775: {
778:   if (pc->ops->applyrichardson) *exists = PETSC_TRUE;
779:   else *exists = PETSC_FALSE;
780:   return 0;
781: }

783: /*@
784:    PCApplyRichardson - Applies several steps of Richardson iteration with
785:    the particular preconditioner. This routine is usually used by the
786:    Krylov solvers and not the application code directly.

788:    Collective on PC

790:    Input Parameters:
791: +  pc  - the preconditioner context
792: .  b   - the right hand side
793: .  w   - one work vector
794: .  rtol - relative decrease in residual norm convergence criteria
795: .  abstol - absolute residual norm convergence criteria
796: .  dtol - divergence residual norm increase criteria
797: .  its - the number of iterations to apply.
798: -  guesszero - if the input x contains nonzero initial guess

800:    Output Parameters:
801: +  outits - number of iterations actually used (for SOR this always equals its)
802: .  reason - the reason the apply terminated
803: -  y - the solution (also contains initial guess if guesszero is PETSC_FALSE

805:    Notes:
806:    Most preconditioners do not support this function. Use the command
807:    PCApplyRichardsonExists() to determine if one does.

809:    Except for the multigrid PC this routine ignores the convergence tolerances
810:    and always runs for the number of iterations

812:    Level: developer

814: .seealso: PCApplyRichardsonExists()
815: @*/
816: PetscErrorCode  PCApplyRichardson(PC pc,Vec b,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt its,PetscBool guesszero,PetscInt *outits,PCRichardsonConvergedReason *reason)
817: {
823:   PCSetUp(pc);
825:   (*pc->ops->applyrichardson)(pc,b,y,w,rtol,abstol,dtol,its,guesszero,outits,reason);
826:   return 0;
827: }

829: /*@
830:    PCSetFailedReason - Sets the reason a PCSetUp() failed or PC_NOERROR if it did not fail

832:    Logically Collective on PC

834:    Input Parameters:
835: +  pc - the preconditioner context
836: -  reason - the reason it failedx

838:    Level: advanced

840: .seealso: PCCreate(), PCApply(), PCDestroy(), PCFailedReason
841: @*/
842: PetscErrorCode PCSetFailedReason(PC pc,PCFailedReason reason)
843: {
844:   pc->failedreason = reason;
845:   return 0;
846: }

848: /*@
849:    PCGetFailedReason - Gets the reason a PCSetUp() failed or PC_NOERROR if it did not fail

851:    Logically Collective on PC

853:    Input Parameter:
854: .  pc - the preconditioner context

856:    Output Parameter:
857: .  reason - the reason it failed

859:    Level: advanced

861:    Notes: This is the maximum over reason over all ranks in the PC communicator. It is only valid after
862:    a call KSPCheckDot() or  KSPCheckNorm() inside a KSPSolve(). It is not valid immediately after a PCSetUp()
863:    or PCApply(), then use PCGetFailedReasonRank()

865: .seealso: PCCreate(), PCApply(), PCDestroy(), PCGetFailedReasonRank(), PCSetFailedReason()
866: @*/
867: PetscErrorCode PCGetFailedReason(PC pc,PCFailedReason *reason)
868: {
869:   if (pc->setupcalled < 0) *reason = (PCFailedReason)pc->setupcalled;
870:   else *reason = pc->failedreason;
871:   return 0;
872: }

874: /*@
875:    PCGetFailedReasonRank - Gets the reason a PCSetUp() failed or PC_NOERROR if it did not fail on this MPI rank

877:   Not Collective on PC

879:    Input Parameter:
880: .  pc - the preconditioner context

882:    Output Parameter:
883: .  reason - the reason it failed

885:    Notes:
886:      Different ranks may have different reasons or no reason, see PCGetFailedReason()

888:    Level: advanced

890: .seealso: PCCreate(), PCApply(), PCDestroy(), PCGetFailedReason(), PCSetFailedReason()
891: @*/
892: PetscErrorCode PCGetFailedReasonRank(PC pc,PCFailedReason *reason)
893: {
894:   if (pc->setupcalled < 0) *reason = (PCFailedReason)pc->setupcalled;
895:   else *reason = pc->failedreason;
896:   return 0;
897: }

899: /*  Next line needed to deactivate KSP_Solve logging */
900: #include <petsc/private/kspimpl.h>

902: /*
903:       a setupcall of 0 indicates never setup,
904:                      1 indicates has been previously setup
905:                     -1 indicates a PCSetUp() was attempted and failed
906: */
907: /*@
908:    PCSetUp - Prepares for the use of a preconditioner.

910:    Collective on PC

912:    Input Parameter:
913: .  pc - the preconditioner context

915:    Level: developer

917: .seealso: PCCreate(), PCApply(), PCDestroy()
918: @*/
919: PetscErrorCode  PCSetUp(PC pc)
920: {
921:   const char       *def;
922:   PetscObjectState matstate, matnonzerostate;


927:   if (pc->setupcalled && pc->reusepreconditioner) {
928:     PetscInfo(pc,"Leaving PC with identical preconditioner since reuse preconditioner is set\n");
929:     return 0;
930:   }

932:   PetscObjectStateGet((PetscObject)pc->pmat,&matstate);
933:   MatGetNonzeroState(pc->pmat,&matnonzerostate);
934:   if (!pc->setupcalled) {
935:     PetscInfo(pc,"Setting up PC for first time\n");
936:     pc->flag = DIFFERENT_NONZERO_PATTERN;
937:   } else if (matstate == pc->matstate) {
938:     PetscInfo(pc,"Leaving PC with identical preconditioner since operator is unchanged\n");
939:     return 0;
940:   } else {
941:     if (matnonzerostate > pc->matnonzerostate) {
942:       PetscInfo(pc,"Setting up PC with different nonzero pattern\n");
943:       pc->flag = DIFFERENT_NONZERO_PATTERN;
944:     } else {
945:       PetscInfo(pc,"Setting up PC with same nonzero pattern\n");
946:       pc->flag = SAME_NONZERO_PATTERN;
947:     }
948:   }
949:   pc->matstate        = matstate;
950:   pc->matnonzerostate = matnonzerostate;

952:   if (!((PetscObject)pc)->type_name) {
953:     PCGetDefaultType_Private(pc,&def);
954:     PCSetType(pc,def);
955:   }

957:   MatSetErrorIfFailure(pc->pmat,pc->erroriffailure);
958:   MatSetErrorIfFailure(pc->mat,pc->erroriffailure);
959:   PetscLogEventBegin(PC_SetUp,pc,0,0,0);
960:   if (pc->ops->setup) {
961:     /* do not log solves and applications of preconditioners while constructing preconditioners; perhaps they should be logged separately from the regular solves */
962:     KSPInitializePackage();
963:     PetscLogEventDeactivatePush(KSP_Solve);
964:     PetscLogEventDeactivatePush(PC_Apply);
965:     (*pc->ops->setup)(pc);
966:     PetscLogEventDeactivatePop(KSP_Solve);
967:     PetscLogEventDeactivatePop(PC_Apply);
968:   }
969:   PetscLogEventEnd(PC_SetUp,pc,0,0,0);
970:   if (!pc->setupcalled) pc->setupcalled = 1;
971:   return 0;
972: }

974: /*@
975:    PCSetUpOnBlocks - Sets up the preconditioner for each block in
976:    the block Jacobi, block Gauss-Seidel, and overlapping Schwarz
977:    methods.

979:    Collective on PC

981:    Input Parameters:
982: .  pc - the preconditioner context

984:    Level: developer

986: .seealso: PCCreate(), PCApply(), PCDestroy(), PCSetUp()
987: @*/
988: PetscErrorCode  PCSetUpOnBlocks(PC pc)
989: {
991:   if (!pc->ops->setuponblocks) return 0;
992:   PetscLogEventBegin(PC_SetUpOnBlocks,pc,0,0,0);
993:   (*pc->ops->setuponblocks)(pc);
994:   PetscLogEventEnd(PC_SetUpOnBlocks,pc,0,0,0);
995:   return 0;
996: }

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

1005:    Logically Collective on PC

1007:    Input Parameters:
1008: +  pc - the preconditioner context
1009: .  func - routine for modifying the submatrices
1010: -  ctx - optional user-defined context (may be null)

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

1015: +  row - an array of index sets that contain the global row numbers
1016:          that comprise each local submatrix
1017: .  col - an array of index sets that contain the global column numbers
1018:          that comprise each local submatrix
1019: .  submat - array of local submatrices
1020: -  ctx - optional user-defined context for private data for the
1021:          user-defined func routine (may be null)

1023:    Notes:
1024:    PCSetModifySubMatrices() MUST be called before KSPSetUp() and
1025:    KSPSolve().

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

1031:    Level: advanced

1033: .seealso: PCModifySubMatrices()
1034: @*/
1035: PetscErrorCode  PCSetModifySubMatrices(PC pc,PetscErrorCode (*func)(PC,PetscInt,const IS[],const IS[],Mat[],void*),void *ctx)
1036: {
1038:   pc->modifysubmatrices  = func;
1039:   pc->modifysubmatricesP = ctx;
1040:   return 0;
1041: }

1043: /*@C
1044:    PCModifySubMatrices - Calls an optional user-defined routine within
1045:    certain preconditioners if one has been set with PCSetModifySubMatrices().

1047:    Collective on PC

1049:    Input Parameters:
1050: +  pc - the preconditioner context
1051: .  nsub - the number of local submatrices
1052: .  row - an array of index sets that contain the global row numbers
1053:          that comprise each local submatrix
1054: .  col - an array of index sets that contain the global column numbers
1055:          that comprise each local submatrix
1056: .  submat - array of local submatrices
1057: -  ctx - optional user-defined context for private data for the
1058:          user-defined routine (may be null)

1060:    Output Parameter:
1061: .  submat - array of local submatrices (the entries of which may
1062:             have been modified)

1064:    Notes:
1065:    The user should NOT generally call this routine, as it will
1066:    automatically be called within certain preconditioners (currently
1067:    block Jacobi, additive Schwarz) if set.

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

1074:    Level: developer

1076: .seealso: PCSetModifySubMatrices()
1077: @*/
1078: PetscErrorCode  PCModifySubMatrices(PC pc,PetscInt nsub,const IS row[],const IS col[],Mat submat[],void *ctx)
1079: {
1081:   if (!pc->modifysubmatrices) return 0;
1082:   PetscLogEventBegin(PC_ModifySubMatrices,pc,0,0,0);
1083:   (*pc->modifysubmatrices)(pc,nsub,row,col,submat,ctx);
1084:   PetscLogEventEnd(PC_ModifySubMatrices,pc,0,0,0);
1085:   return 0;
1086: }

1088: /*@
1089:    PCSetOperators - Sets the matrix associated with the linear system and
1090:    a (possibly) different one associated with the preconditioner.

1092:    Logically Collective on PC

1094:    Input Parameters:
1095: +  pc - the preconditioner context
1096: .  Amat - the matrix that defines the linear system
1097: -  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.

1099:    Notes:
1100:     Passing a NULL for Amat or Pmat removes the matrix that is currently used.

1102:     If you wish to replace either Amat or Pmat but leave the other one untouched then
1103:     first call KSPGetOperators() to get the one you wish to keep, call PetscObjectReference()
1104:     on it and then pass it back in in your call to KSPSetOperators().

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

1112:    Level: intermediate

1114: .seealso: PCGetOperators(), MatZeroEntries()
1115:  @*/
1116: PetscErrorCode  PCSetOperators(PC pc,Mat Amat,Mat Pmat)
1117: {
1118:   PetscInt         m1,n1,m2,n2;

1125:   if (pc->setupcalled && pc->mat && pc->pmat && Amat && Pmat) {
1126:     MatGetLocalSize(Amat,&m1,&n1);
1127:     MatGetLocalSize(pc->mat,&m2,&n2);
1129:     MatGetLocalSize(Pmat,&m1,&n1);
1130:     MatGetLocalSize(pc->pmat,&m2,&n2);
1132:   }

1134:   if (Pmat != pc->pmat) {
1135:     /* changing the operator that defines the preconditioner thus reneed to clear current states so new preconditioner is built */
1136:     pc->matnonzerostate = -1;
1137:     pc->matstate        = -1;
1138:   }

1140:   /* reference first in case the matrices are the same */
1141:   if (Amat) PetscObjectReference((PetscObject)Amat);
1142:   MatDestroy(&pc->mat);
1143:   if (Pmat) PetscObjectReference((PetscObject)Pmat);
1144:   MatDestroy(&pc->pmat);
1145:   pc->mat  = Amat;
1146:   pc->pmat = Pmat;
1147:   return 0;
1148: }

1150: /*@
1151:    PCSetReusePreconditioner - reuse the current preconditioner even if the operator in the preconditioner has changed.

1153:    Logically Collective on PC

1155:    Input Parameters:
1156: +  pc - the preconditioner context
1157: -  flag - PETSC_TRUE do not compute a new preconditioner, PETSC_FALSE do compute a new preconditioner

1159:     Level: intermediate

1161: .seealso: PCGetOperators(), MatZeroEntries(), PCGetReusePreconditioner(), KSPSetReusePreconditioner()
1162:  @*/
1163: PetscErrorCode  PCSetReusePreconditioner(PC pc,PetscBool flag)
1164: {
1167:   pc->reusepreconditioner = flag;
1168:   return 0;
1169: }

1171: /*@
1172:    PCGetReusePreconditioner - Determines if the PC reuses the current preconditioner even if the operator in the preconditioner has changed.

1174:    Not Collective

1176:    Input Parameter:
1177: .  pc - the preconditioner context

1179:    Output Parameter:
1180: .  flag - PETSC_TRUE do not compute a new preconditioner, PETSC_FALSE do compute a new preconditioner

1182:    Level: intermediate

1184: .seealso: PCGetOperators(), MatZeroEntries(), PCSetReusePreconditioner()
1185:  @*/
1186: PetscErrorCode  PCGetReusePreconditioner(PC pc,PetscBool *flag)
1187: {
1190:   *flag = pc->reusepreconditioner;
1191:   return 0;
1192: }

1194: /*@
1195:    PCGetOperators - Gets the matrix associated with the linear system and
1196:    possibly a different one associated with the preconditioner.

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

1200:    Input Parameter:
1201: .  pc - the preconditioner context

1203:    Output Parameters:
1204: +  Amat - the matrix defining the linear system
1205: -  Pmat - the matrix from which the preconditioner is constructed, usually the same as Amat.

1207:    Level: intermediate

1209:    Notes:
1210:     Does not increase the reference count of the matrices, so you should not destroy them

1212:    Alternative usage: If the operators have NOT been set with KSP/PCSetOperators() then the operators
1213:       are created in PC and returned to the user. In this case, if both operators
1214:       mat and pmat are requested, two DIFFERENT operators will be returned. If
1215:       only one is requested both operators in the PC will be the same (i.e. as
1216:       if one had called KSP/PCSetOperators() with the same argument for both Mats).
1217:       The user must set the sizes of the returned matrices and their type etc just
1218:       as if the user created them with MatCreate(). For example,

1220: $         KSP/PCGetOperators(ksp/pc,&Amat,NULL); is equivalent to
1221: $           set size, type, etc of Amat

1223: $         MatCreate(comm,&mat);
1224: $         KSP/PCSetOperators(ksp/pc,Amat,Amat);
1225: $         PetscObjectDereference((PetscObject)mat);
1226: $           set size, type, etc of Amat

1228:      and

1230: $         KSP/PCGetOperators(ksp/pc,&Amat,&Pmat); is equivalent to
1231: $           set size, type, etc of Amat and Pmat

1233: $         MatCreate(comm,&Amat);
1234: $         MatCreate(comm,&Pmat);
1235: $         KSP/PCSetOperators(ksp/pc,Amat,Pmat);
1236: $         PetscObjectDereference((PetscObject)Amat);
1237: $         PetscObjectDereference((PetscObject)Pmat);
1238: $           set size, type, etc of Amat and Pmat

1240:     The rational for this support is so that when creating a TS, SNES, or KSP the hierarchy
1241:     of underlying objects (i.e. SNES, KSP, PC, Mat) and their livespans can be completely
1242:     managed by the top most level object (i.e. the TS, SNES, or KSP). Another way to look
1243:     at this is when you create a SNES you do not NEED to create a KSP and attach it to
1244:     the SNES object (the SNES object manages it for you). Similarly when you create a KSP
1245:     you do not need to attach a PC to it (the KSP object manages the PC object for you).
1246:     Thus, why should YOU have to create the Mat and attach it to the SNES/KSP/PC, when
1247:     it can be created for you?

1249: .seealso: PCSetOperators(), KSPGetOperators(), KSPSetOperators(), PCGetOperatorsSet()
1250: @*/
1251: PetscErrorCode  PCGetOperators(PC pc,Mat *Amat,Mat *Pmat)
1252: {
1254:   if (Amat) {
1255:     if (!pc->mat) {
1256:       if (pc->pmat && !Pmat) {  /* Apmat has been set, but user did not request it, so use for Amat */
1257:         pc->mat = pc->pmat;
1258:         PetscObjectReference((PetscObject)pc->mat);
1259:       } else {                  /* both Amat and Pmat are empty */
1260:         MatCreate(PetscObjectComm((PetscObject)pc),&pc->mat);
1261:         if (!Pmat) { /* user did NOT request Pmat, so make same as Amat */
1262:           pc->pmat = pc->mat;
1263:           PetscObjectReference((PetscObject)pc->pmat);
1264:         }
1265:       }
1266:     }
1267:     *Amat = pc->mat;
1268:   }
1269:   if (Pmat) {
1270:     if (!pc->pmat) {
1271:       if (pc->mat && !Amat) {    /* Amat has been set but was not requested, so use for pmat */
1272:         pc->pmat = pc->mat;
1273:         PetscObjectReference((PetscObject)pc->pmat);
1274:       } else {
1275:         MatCreate(PetscObjectComm((PetscObject)pc),&pc->pmat);
1276:         if (!Amat) { /* user did NOT request Amat, so make same as Pmat */
1277:           pc->mat = pc->pmat;
1278:           PetscObjectReference((PetscObject)pc->mat);
1279:         }
1280:       }
1281:     }
1282:     *Pmat = pc->pmat;
1283:   }
1284:   return 0;
1285: }

1287: /*@C
1288:    PCGetOperatorsSet - Determines if the matrix associated with the linear system and
1289:    possibly a different one associated with the preconditioner have been set in the PC.

1291:    Not collective, though the results on all processes should be the same

1293:    Input Parameter:
1294: .  pc - the preconditioner context

1296:    Output Parameters:
1297: +  mat - the matrix associated with the linear system was set
1298: -  pmat - matrix associated with the preconditioner was set, usually the same

1300:    Level: intermediate

1302: .seealso: PCSetOperators(), KSPGetOperators(), KSPSetOperators(), PCGetOperators()
1303: @*/
1304: PetscErrorCode  PCGetOperatorsSet(PC pc,PetscBool  *mat,PetscBool  *pmat)
1305: {
1307:   if (mat) *mat = (pc->mat)  ? PETSC_TRUE : PETSC_FALSE;
1308:   if (pmat) *pmat = (pc->pmat) ? PETSC_TRUE : PETSC_FALSE;
1309:   return 0;
1310: }

1312: /*@
1313:    PCFactorGetMatrix - Gets the factored matrix from the
1314:    preconditioner context.  This routine is valid only for the LU,
1315:    incomplete LU, Cholesky, and incomplete Cholesky methods.

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

1319:    Input Parameters:
1320: .  pc - the preconditioner context

1322:    Output parameters:
1323: .  mat - the factored matrix

1325:    Level: advanced

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

1330: @*/
1331: PetscErrorCode  PCFactorGetMatrix(PC pc,Mat *mat)
1332: {
1335:   if (pc->ops->getfactoredmatrix) {
1336:     (*pc->ops->getfactoredmatrix)(pc,mat);
1337:   } else SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PC type does not support getting factor matrix");
1338:   return 0;
1339: }

1341: /*@C
1342:    PCSetOptionsPrefix - Sets the prefix used for searching for all
1343:    PC options in the database.

1345:    Logically Collective on PC

1347:    Input Parameters:
1348: +  pc - the preconditioner context
1349: -  prefix - the prefix string to prepend to all PC option requests

1351:    Notes:
1352:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1353:    The first character of all runtime options is AUTOMATICALLY the
1354:    hyphen.

1356:    Level: advanced

1358: .seealso: PCAppendOptionsPrefix(), PCGetOptionsPrefix()
1359: @*/
1360: PetscErrorCode  PCSetOptionsPrefix(PC pc,const char prefix[])
1361: {
1363:   PetscObjectSetOptionsPrefix((PetscObject)pc,prefix);
1364:   return 0;
1365: }

1367: /*@C
1368:    PCAppendOptionsPrefix - Appends to the prefix used for searching for all
1369:    PC options in the database.

1371:    Logically Collective on PC

1373:    Input Parameters:
1374: +  pc - the preconditioner context
1375: -  prefix - the prefix string to prepend to all PC option requests

1377:    Notes:
1378:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1379:    The first character of all runtime options is AUTOMATICALLY the
1380:    hyphen.

1382:    Level: advanced

1384: .seealso: PCSetOptionsPrefix(), PCGetOptionsPrefix()
1385: @*/
1386: PetscErrorCode  PCAppendOptionsPrefix(PC pc,const char prefix[])
1387: {
1389:   PetscObjectAppendOptionsPrefix((PetscObject)pc,prefix);
1390:   return 0;
1391: }

1393: /*@C
1394:    PCGetOptionsPrefix - Gets the prefix used for searching for all
1395:    PC options in the database.

1397:    Not Collective

1399:    Input Parameters:
1400: .  pc - the preconditioner context

1402:    Output Parameters:
1403: .  prefix - pointer to the prefix string used, is returned

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

1409:    Level: advanced

1411: .seealso: PCSetOptionsPrefix(), PCAppendOptionsPrefix()
1412: @*/
1413: PetscErrorCode  PCGetOptionsPrefix(PC pc,const char *prefix[])
1414: {
1417:   PetscObjectGetOptionsPrefix((PetscObject)pc,prefix);
1418:   return 0;
1419: }

1421: /*
1422:    Indicates the right hand side will be changed by KSPSolve(), this occurs for a few
1423:   preconditioners including BDDC and Eisentat that transform the equations before applying
1424:   the Krylov methods
1425: */
1426: PETSC_INTERN PetscErrorCode  PCPreSolveChangeRHS(PC pc,PetscBool *change)
1427: {
1430:   *change = PETSC_FALSE;
1431:   PetscTryMethod(pc,"PCPreSolveChangeRHS_C",(PC,PetscBool*),(pc,change));
1432:   return 0;
1433: }

1435: /*@
1436:    PCPreSolve - Optional pre-solve phase, intended for any
1437:    preconditioner-specific actions that must be performed before
1438:    the iterative solve itself.

1440:    Collective on PC

1442:    Input Parameters:
1443: +  pc - the preconditioner context
1444: -  ksp - the Krylov subspace context

1446:    Level: developer

1448:    Sample of Usage:
1449: .vb
1450:     PCPreSolve(pc,ksp);
1451:     KSPSolve(ksp,b,x);
1452:     PCPostSolve(pc,ksp);
1453: .ve

1455:    Notes:
1456:    The pre-solve phase is distinct from the PCSetUp() phase.

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

1460: .seealso: PCPostSolve()
1461: @*/
1462: PetscErrorCode PCPreSolve(PC pc,KSP ksp)
1463: {
1464:   Vec            x,rhs;

1468:   pc->presolvedone++;
1470:   KSPGetSolution(ksp,&x);
1471:   KSPGetRhs(ksp,&rhs);

1473:   if (pc->ops->presolve) {
1474:     (*pc->ops->presolve)(pc,ksp,rhs,x);
1475:   } else if (pc->presolve) {
1476:     (pc->presolve)(pc,ksp);
1477:   }
1478:   return 0;
1479: }

1481: /*@C
1482:    PCSetPreSolve - Sets function PCPreSolve() which is intended for any
1483:    preconditioner-specific actions that must be performed before
1484:    the iterative solve itself.

1486:    Logically Collective on pc

1488:    Input Parameters:
1489: +   pc - the preconditioner object
1490: -   presolve - the function to call before the solve

1492:    Calling sequence of presolve:
1493: $  func(PC pc,KSP ksp)

1495: +  pc - the PC context
1496: -  ksp - the KSP context

1498:    Level: developer

1500: .seealso: PC, PCSetUp(), PCPreSolve()
1501: @*/
1502: PetscErrorCode PCSetPreSolve(PC pc,PetscErrorCode (*presolve)(PC,KSP))
1503: {
1505:   pc->presolve = presolve;
1506:   return 0;
1507: }

1509: /*@
1510:    PCPostSolve - Optional post-solve phase, intended for any
1511:    preconditioner-specific actions that must be performed after
1512:    the iterative solve itself.

1514:    Collective on PC

1516:    Input Parameters:
1517: +  pc - the preconditioner context
1518: -  ksp - the Krylov subspace context

1520:    Sample of Usage:
1521: .vb
1522:     PCPreSolve(pc,ksp);
1523:     KSPSolve(ksp,b,x);
1524:     PCPostSolve(pc,ksp);
1525: .ve

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

1530:    Level: developer

1532: .seealso: PCPreSolve(), KSPSolve()
1533: @*/
1534: PetscErrorCode  PCPostSolve(PC pc,KSP ksp)
1535: {
1536:   Vec            x,rhs;

1540:   pc->presolvedone--;
1541:   KSPGetSolution(ksp,&x);
1542:   KSPGetRhs(ksp,&rhs);
1543:   if (pc->ops->postsolve) {
1544:     (*pc->ops->postsolve)(pc,ksp,rhs,x);
1545:   }
1546:   return 0;
1547: }

1549: /*@C
1550:   PCLoad - Loads a PC that has been stored in binary  with PCView().

1552:   Collective on PetscViewer

1554:   Input Parameters:
1555: + newdm - the newly loaded PC, this needs to have been created with PCCreate() or
1556:            some related function before a call to PCLoad().
1557: - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()

1559:    Level: intermediate

1561:   Notes:
1562:    The type is determined by the data in the file, any type set into the PC before this call is ignored.

1564:   Notes for advanced users:
1565:   Most users should not need to know the details of the binary storage
1566:   format, since PCLoad() and PCView() completely hide these details.
1567:   But for anyone who's interested, the standard binary matrix storage
1568:   format is
1569: .vb
1570:      has not yet been determined
1571: .ve

1573: .seealso: PetscViewerBinaryOpen(), PCView(), MatLoad(), VecLoad()
1574: @*/
1575: PetscErrorCode  PCLoad(PC newdm, PetscViewer viewer)
1576: {
1577:   PetscBool      isbinary;
1578:   PetscInt       classid;
1579:   char           type[256];

1583:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);

1586:   PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);
1588:   PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);
1589:   PCSetType(newdm, type);
1590:   if (newdm->ops->load) {
1591:     (*newdm->ops->load)(newdm,viewer);
1592:   }
1593:   return 0;
1594: }

1596: #include <petscdraw.h>
1597: #if defined(PETSC_HAVE_SAWS)
1598: #include <petscviewersaws.h>
1599: #endif

1601: /*@C
1602:    PCViewFromOptions - View from Options

1604:    Collective on PC

1606:    Input Parameters:
1607: +  A - the PC context
1608: .  obj - Optional object
1609: -  name - command line option

1611:    Level: intermediate
1612: .seealso:  PC, PCView, PetscObjectViewFromOptions(), PCCreate()
1613: @*/
1614: PetscErrorCode  PCViewFromOptions(PC A,PetscObject obj,const char name[])
1615: {
1617:   PetscObjectViewFromOptions((PetscObject)A,obj,name);
1618:   return 0;
1619: }

1621: /*@C
1622:    PCView - Prints the PC data structure.

1624:    Collective on PC

1626:    Input Parameters:
1627: +  PC - the PC context
1628: -  viewer - optional visualization context

1630:    Note:
1631:    The available visualization contexts include
1632: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
1633: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
1634:          output where only the first processor opens
1635:          the file.  All other processors send their
1636:          data to the first processor to print.

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

1641:    Level: developer

1643: .seealso: KSPView(), PetscViewerASCIIOpen()
1644: @*/
1645: PetscErrorCode  PCView(PC pc,PetscViewer viewer)
1646: {
1647:   PCType         cstr;
1648:   PetscBool      iascii,isstring,isbinary,isdraw;
1649: #if defined(PETSC_HAVE_SAWS)
1650:   PetscBool      issaws;
1651: #endif

1654:   if (!viewer) {
1655:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pc),&viewer);
1656:   }

1660:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
1661:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
1662:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
1663:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
1664: #if defined(PETSC_HAVE_SAWS)
1665:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
1666: #endif

1668:   if (iascii) {
1669:     PetscObjectPrintClassNamePrefixType((PetscObject)pc,viewer);
1670:     if (!pc->setupcalled) {
1671:       PetscViewerASCIIPrintf(viewer,"  PC has not been set up so information may be incomplete\n");
1672:     }
1673:     if (pc->ops->view) {
1674:       PetscViewerASCIIPushTab(viewer);
1675:       (*pc->ops->view)(pc,viewer);
1676:       PetscViewerASCIIPopTab(viewer);
1677:     }
1678:     if (pc->mat) {
1679:       PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
1680:       if (pc->pmat == pc->mat) {
1681:         PetscViewerASCIIPrintf(viewer,"  linear system matrix = precond matrix:\n");
1682:         PetscViewerASCIIPushTab(viewer);
1683:         MatView(pc->mat,viewer);
1684:         PetscViewerASCIIPopTab(viewer);
1685:       } else {
1686:         if (pc->pmat) {
1687:           PetscViewerASCIIPrintf(viewer,"  linear system matrix followed by preconditioner matrix:\n");
1688:         } else {
1689:           PetscViewerASCIIPrintf(viewer,"  linear system matrix:\n");
1690:         }
1691:         PetscViewerASCIIPushTab(viewer);
1692:         MatView(pc->mat,viewer);
1693:         if (pc->pmat) MatView(pc->pmat,viewer);
1694:         PetscViewerASCIIPopTab(viewer);
1695:       }
1696:       PetscViewerPopFormat(viewer);
1697:     }
1698:   } else if (isstring) {
1699:     PCGetType(pc,&cstr);
1700:     PetscViewerStringSPrintf(viewer," PCType: %-7.7s",cstr);
1701:     if (pc->ops->view) (*pc->ops->view)(pc,viewer);
1702:     if (pc->mat) MatView(pc->mat,viewer);
1703:     if (pc->pmat && pc->pmat != pc->mat) MatView(pc->pmat,viewer);
1704:   } else if (isbinary) {
1705:     PetscInt    classid = PC_FILE_CLASSID;
1706:     MPI_Comm    comm;
1707:     PetscMPIInt rank;
1708:     char        type[256];

1710:     PetscObjectGetComm((PetscObject)pc,&comm);
1711:     MPI_Comm_rank(comm,&rank);
1712:     if (rank == 0) {
1713:       PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT);
1714:       PetscStrncpy(type,((PetscObject)pc)->type_name,256);
1715:       PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR);
1716:     }
1717:     if (pc->ops->view) {
1718:       (*pc->ops->view)(pc,viewer);
1719:     }
1720:   } else if (isdraw) {
1721:     PetscDraw draw;
1722:     char      str[25];
1723:     PetscReal x,y,bottom,h;
1724:     PetscInt  n;

1726:     PetscViewerDrawGetDraw(viewer,0,&draw);
1727:     PetscDrawGetCurrentPoint(draw,&x,&y);
1728:     if (pc->mat) {
1729:       MatGetSize(pc->mat,&n,NULL);
1730:       PetscSNPrintf(str,25,"PC: %s (%D)",((PetscObject)pc)->type_name,n);
1731:     } else {
1732:       PetscSNPrintf(str,25,"PC: %s",((PetscObject)pc)->type_name);
1733:     }
1734:     PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_RED,PETSC_DRAW_BLACK,str,NULL,&h);
1735:     bottom = y - h;
1736:     PetscDrawPushCurrentPoint(draw,x,bottom);
1737:     if (pc->ops->view) {
1738:       (*pc->ops->view)(pc,viewer);
1739:     }
1740:     PetscDrawPopCurrentPoint(draw);
1741: #if defined(PETSC_HAVE_SAWS)
1742:   } else if (issaws) {
1743:     PetscMPIInt rank;

1745:     PetscObjectName((PetscObject)pc);
1746:     MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
1747:     if (!((PetscObject)pc)->amsmem && rank == 0) {
1748:       PetscObjectViewSAWs((PetscObject)pc,viewer);
1749:     }
1750:     if (pc->mat) MatView(pc->mat,viewer);
1751:     if (pc->pmat && pc->pmat != pc->mat) MatView(pc->pmat,viewer);
1752: #endif
1753:   }
1754:   return 0;
1755: }

1757: /*@C
1758:   PCRegister -  Adds a method to the preconditioner package.

1760:    Not collective

1762:    Input Parameters:
1763: +  name_solver - name of a new user-defined solver
1764: -  routine_create - routine to create method context

1766:    Notes:
1767:    PCRegister() may be called multiple times to add several user-defined preconditioners.

1769:    Sample usage:
1770: .vb
1771:    PCRegister("my_solver", MySolverCreate);
1772: .ve

1774:    Then, your solver can be chosen with the procedural interface via
1775: $     PCSetType(pc,"my_solver")
1776:    or at runtime via the option
1777: $     -pc_type my_solver

1779:    Level: advanced

1781: .seealso: PCRegisterAll()
1782: @*/
1783: PetscErrorCode  PCRegister(const char sname[],PetscErrorCode (*function)(PC))
1784: {
1785:   PCInitializePackage();
1786:   PetscFunctionListAdd(&PCList,sname,function);
1787:   return 0;
1788: }

1790: static PetscErrorCode MatMult_PC(Mat A,Vec X,Vec Y)
1791: {
1792:   PC             pc;

1794:   MatShellGetContext(A,&pc);
1795:   PCApply(pc,X,Y);
1796:   return 0;
1797: }

1799: /*@
1800:     PCComputeOperator - Computes the explicit preconditioned operator.

1802:     Collective on PC

1804:     Input Parameters:
1805: +   pc - the preconditioner object
1806: -   mattype - the matrix type to be used for the operator

1808:     Output Parameter:
1809: .   mat - the explicit preconditioned operator

1811:     Notes:
1812:     This computation is done by applying the operators to columns of the identity matrix.
1813:     This routine is costly in general, and is recommended for use only with relatively small systems.
1814:     Currently, this routine uses a dense matrix format when mattype == NULL

1816:     Level: advanced

1818: .seealso: KSPComputeOperator(), MatType

1820: @*/
1821: PetscErrorCode  PCComputeOperator(PC pc,MatType mattype,Mat *mat)
1822: {
1823:   PetscInt       N,M,m,n;
1824:   Mat            A,Apc;

1828:   PCGetOperators(pc,&A,NULL);
1829:   MatGetLocalSize(A,&m,&n);
1830:   MatGetSize(A,&M,&N);
1831:   MatCreateShell(PetscObjectComm((PetscObject)pc),m,n,M,N,pc,&Apc);
1832:   MatShellSetOperation(Apc,MATOP_MULT,(void (*)(void))MatMult_PC);
1833:   MatComputeOperator(Apc,mattype,mat);
1834:   MatDestroy(&Apc);
1835:   return 0;
1836: }

1838: /*@
1839:    PCSetCoordinates - sets the coordinates of all the nodes on the local process

1841:    Collective on PC

1843:    Input Parameters:
1844: +  pc - the solver context
1845: .  dim - the dimension of the coordinates 1, 2, or 3
1846: .  nloc - the blocked size of the coordinates array
1847: -  coords - the coordinates array

1849:    Level: intermediate

1851:    Notes:
1852:    coords is an array of the dim coordinates for the nodes on
1853:    the local processor, of size dim*nloc.
1854:    If there are 108 equation on a processor
1855:    for a displacement finite element discretization of elasticity (so
1856:    that there are nloc = 36 = 108/3 nodes) then the array must have 108
1857:    double precision values (ie, 3 * 36).  These x y z coordinates
1858:    should be ordered for nodes 0 to N-1 like so: [ 0.x, 0.y, 0.z, 1.x,
1859:    ... , N-1.z ].

1861: .seealso: MatSetNearNullSpace()
1862: @*/
1863: PetscErrorCode PCSetCoordinates(PC pc, PetscInt dim, PetscInt nloc, PetscReal coords[])
1864: {
1867:   PetscTryMethod(pc,"PCSetCoordinates_C",(PC,PetscInt,PetscInt,PetscReal*),(pc,dim,nloc,coords));
1868:   return 0;
1869: }

1871: /*@
1872:    PCGetInterpolations - Gets interpolation matrices for all levels (except level 0)

1874:    Logically Collective on PC

1876:    Input Parameter:
1877: .  pc - the precondition context

1879:    Output Parameters:
1880: +  num_levels - the number of levels
1881: -  interpolations - the interpolation matrices (size of num_levels-1)

1883:    Level: advanced

1885: .keywords: MG, GAMG, BoomerAMG, multigrid, interpolation, level

1887: .seealso: PCMGGetRestriction(), PCMGSetInterpolation(), PCMGGetInterpolation(), PCGetCoarseOperators()
1888: @*/
1889: PetscErrorCode PCGetInterpolations(PC pc,PetscInt *num_levels,Mat *interpolations[])
1890: {
1894:   PetscUseMethod(pc,"PCGetInterpolations_C",(PC,PetscInt*,Mat*[]),(pc,num_levels,interpolations));
1895:   return 0;
1896: }

1898: /*@
1899:    PCGetCoarseOperators - Gets coarse operator matrices for all levels (except the finest level)

1901:    Logically Collective on PC

1903:    Input Parameter:
1904: .  pc - the precondition context

1906:    Output Parameters:
1907: +  num_levels - the number of levels
1908: -  coarseOperators - the coarse operator matrices (size of num_levels-1)

1910:    Level: advanced

1912: .keywords: MG, GAMG, BoomerAMG, get, multigrid, interpolation, level

1914: .seealso: PCMGGetRestriction(), PCMGSetInterpolation(), PCMGGetRScale(), PCMGGetInterpolation(), PCGetInterpolations()
1915: @*/
1916: PetscErrorCode PCGetCoarseOperators(PC pc,PetscInt *num_levels,Mat *coarseOperators[])
1917: {
1921:   PetscUseMethod(pc,"PCGetCoarseOperators_C",(PC,PetscInt*,Mat*[]),(pc,num_levels,coarseOperators));
1922:   return 0;
1923: }