Actual source code: shellpc.c

  2: /*
  3:    This provides a simple shell for Fortran (and C programmers) to 
  4:   create their own preconditioner without writing much interface code.
  5: */

  7: #include <private/pcimpl.h>        /*I "petscpc.h" I*/
  8: #include <private/vecimpl.h>  

 11: typedef struct {
 12:   void           *ctx;                     /* user provided contexts for preconditioner */
 13:   PetscErrorCode (*destroy)(PC);
 14:   PetscErrorCode (*setup)(PC);
 15:   PetscErrorCode (*apply)(PC,Vec,Vec);
 16:   PetscErrorCode (*applyBA)(PC,PCSide,Vec,Vec,Vec);
 17:   PetscErrorCode (*presolve)(PC,KSP,Vec,Vec);
 18:   PetscErrorCode (*postsolve)(PC,KSP,Vec,Vec);
 19:   PetscErrorCode (*view)(PC,PetscViewer);
 20:   PetscErrorCode (*applytranspose)(PC,Vec,Vec);
 21:   PetscErrorCode (*applyrich)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool ,PetscInt*,PCRichardsonConvergedReason*);
 22:   char           *name;
 23: } PC_Shell;

 28: /*@C
 29:     PCShellGetContext - Returns the user-provided context associated with a shell PC

 31:     Not Collective

 33:     Input Parameter:
 34: .   pc - should have been created with PCCreateShell()

 36:     Output Parameter:
 37: .   ctx - the user provided context

 39:     Level: advanced

 41:     Notes:
 42:     This routine is intended for use within various shell routines
 43:     
 44: .keywords: PC, shell, get, context

 46: .seealso: PCCreateShell(), PCShellSetContext()
 47: @*/
 48: PetscErrorCode  PCShellGetContext(PC pc,void **ctx)
 49: {
 51:   PetscBool      flg;

 56:   PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);
 57:   if (!flg) *ctx = 0;
 58:   else      *ctx = ((PC_Shell*)(pc->data))->ctx;
 59:   return(0);
 60: }

 64: /*@
 65:     PCShellSetContext - sets the context for a shell PC

 67:    Logically Collective on PC

 69:     Input Parameters:
 70: +   pc - the shell PC
 71: -   ctx - the context

 73:    Level: advanced

 75:    Fortran Notes: The context can only be an integer or a PetscObject
 76:       unfortunately it cannot be a Fortran array or derived type.


 79: .seealso: PCCreateShell(), PCShellGetContext()
 80: @*/
 81: PetscErrorCode  PCShellSetContext(PC pc,void *ctx)
 82: {
 83:   PC_Shell      *shell;
 85:   PetscBool      flg;

 89:   shell = (PC_Shell*)pc->data;
 90:   PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);
 91:   if (flg) {
 92:     shell->ctx = ctx;
 93:   }
 94:   return(0);
 95: }

 99: static PetscErrorCode PCSetUp_Shell(PC pc)
100: {
101:   PC_Shell       *shell;

105:   shell = (PC_Shell*)pc->data;
106:   if (!shell->setup) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_USER,"No setup() routine provided to Shell PC");
107:   PetscStackCall("PCSHELL user function setup()",(*shell->setup)(pc);CHKERRQ(ierr));
108:   return(0);
109: }

113: static PetscErrorCode PCApply_Shell(PC pc,Vec x,Vec y)
114: {
115:   PC_Shell       *shell;

119:   shell = (PC_Shell*)pc->data;
120:   if (!shell->apply) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_USER,"No apply() routine provided to Shell PC");
121:   PetscStackCall("PCSHELL user function apply()",(*shell->apply)(pc,x,y);CHKERRQ(ierr));
122:   return(0);
123: }

127: static PetscErrorCode PCApplyBA_Shell(PC pc,PCSide side,Vec x,Vec y,Vec w)
128: {
129:   PC_Shell       *shell;

133:   shell = (PC_Shell*)pc->data;
134:   if (!shell->applyBA) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_USER,"No applyBA() routine provided to Shell PC");
135:   PetscStackCall("PCSHELL user function applyBA()",(*shell->applyBA)(pc,side,x,y,w);CHKERRQ(ierr));
136:   return(0);
137: }

141: static PetscErrorCode PCPreSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
142: {
143:   PC_Shell       *shell;

147:   shell = (PC_Shell*)pc->data;
148:   if (!shell->presolve) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_USER,"No presolve() routine provided to Shell PC");
149:   PetscStackCall("PCSHELL user function presolve()",(*shell->presolve)(pc,ksp,b,x);CHKERRQ(ierr));
150:   return(0);
151: }

155: static PetscErrorCode PCPostSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
156: {
157:   PC_Shell       *shell;

161:   shell = (PC_Shell*)pc->data;
162:   if (!shell->postsolve) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_USER,"No postsolve() routine provided to Shell PC");
163:   PetscStackCall("PCSHELL user function postsolve()",(*shell->postsolve)(pc,ksp,b,x);CHKERRQ(ierr));
164:   return(0);
165: }

169: static PetscErrorCode PCApplyTranspose_Shell(PC pc,Vec x,Vec y)
170: {
171:   PC_Shell       *shell;

175:   shell = (PC_Shell*)pc->data;
176:   if (!shell->applytranspose) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_USER,"No applytranspose() routine provided to Shell PC");
177:   PetscStackCall("PCSHELL user function applytranspose()",(*shell->applytranspose)(pc,x,y);CHKERRQ(ierr));
178:   return(0);
179: }

183: static PetscErrorCode PCApplyRichardson_Shell(PC pc,Vec x,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt it,PetscBool  guesszero,PetscInt *outits,PCRichardsonConvergedReason *reason)
184: {
186:   PC_Shell       *shell;

189:   shell = (PC_Shell*)pc->data;
190:   if (!shell->applyrich) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_USER,"No applyrichardson() routine provided to Shell PC");
191:   PetscStackCall("PCSHELL user function applyrichardson()",(*shell->applyrich)(pc,x,y,w,rtol,abstol,dtol,it,guesszero,outits,reason);CHKERRQ(ierr));
192:   return(0);
193: }

197: static PetscErrorCode PCDestroy_Shell(PC pc)
198: {
199:   PC_Shell       *shell = (PC_Shell*)pc->data;

203:   PetscFree(shell->name);
204:   if (shell->destroy) {
205:     PetscStackCall("PCSHELL user function destroy()",(*shell->destroy)(pc);CHKERRQ(ierr));
206:   }
207:   PetscFree(pc->data);
208:   return(0);
209: }

213: static PetscErrorCode PCView_Shell(PC pc,PetscViewer viewer)
214: {
215:   PC_Shell       *shell = (PC_Shell*)pc->data;
217:   PetscBool      iascii;

220:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
221:   if (iascii) {
222:     if (shell->name) {PetscViewerASCIIPrintf(viewer,"  Shell: %s\n",shell->name);}
223:     else             {PetscViewerASCIIPrintf(viewer,"  Shell: no name\n");}
224:   }
225:   if (shell->view) {
226:     PetscViewerASCIIPushTab(viewer);
227:     (*shell->view)(pc,viewer);
228:     PetscViewerASCIIPopTab(viewer);
229:   }
230:   return(0);
231: }

233: /* ------------------------------------------------------------------------------*/
237: PetscErrorCode  PCShellSetDestroy_Shell(PC pc, PetscErrorCode (*destroy)(PC))
238: {
239:   PC_Shell *shell;

242:   shell          = (PC_Shell*)pc->data;
243:   shell->destroy = destroy;
244:   return(0);
245: }

251: PetscErrorCode  PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(PC))
252: {
253:   PC_Shell *shell;

256:   shell        = (PC_Shell*)pc->data;
257:   shell->setup = setup;
258:   if (setup) pc->ops->setup = PCSetUp_Shell;
259:   else       pc->ops->setup = 0;
260:   return(0);
261: }

267: PetscErrorCode  PCShellSetApply_Shell(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec))
268: {
269:   PC_Shell *shell;

272:   shell        = (PC_Shell*)pc->data;
273:   shell->apply = apply;
274:   return(0);
275: }

281: PetscErrorCode  PCShellSetApplyBA_Shell(PC pc,PetscErrorCode (*applyBA)(PC,PCSide,Vec,Vec,Vec))
282: {
283:   PC_Shell *shell;

286:   shell          = (PC_Shell*)pc->data;
287:   shell->applyBA = applyBA;
288:   if (applyBA) pc->ops->applyBA  = PCApplyBA_Shell;
289:   else         pc->ops->applyBA  = 0;
290:   return(0);
291: }

297: PetscErrorCode  PCShellSetPreSolve_Shell(PC pc,PetscErrorCode (*presolve)(PC,KSP,Vec,Vec))
298: {
299:   PC_Shell *shell;

302:   shell           = (PC_Shell*)pc->data;
303:   shell->presolve = presolve;
304:   if (presolve) pc->ops->presolve = PCPreSolve_Shell;
305:   else          pc->ops->presolve = 0;
306:   return(0);
307: }

313: PetscErrorCode  PCShellSetPostSolve_Shell(PC pc,PetscErrorCode (*postsolve)(PC,KSP,Vec,Vec))
314: {
315:   PC_Shell *shell;

318:   shell            = (PC_Shell*)pc->data;
319:   shell->postsolve = postsolve;
320:   if (postsolve) pc->ops->postsolve = PCPostSolve_Shell;
321:   else           pc->ops->postsolve = 0;
322:   return(0);
323: }

329: PetscErrorCode  PCShellSetView_Shell(PC pc,PetscErrorCode (*view)(PC,PetscViewer))
330: {
331:   PC_Shell *shell;

334:   shell        = (PC_Shell*)pc->data;
335:   shell->view = view;
336:   return(0);
337: }

343: PetscErrorCode  PCShellSetApplyTranspose_Shell(PC pc,PetscErrorCode (*applytranspose)(PC,Vec,Vec))
344: {
345:   PC_Shell *shell;

348:   shell                 = (PC_Shell*)pc->data;
349:   shell->applytranspose = applytranspose;
350:   if (applytranspose) pc->ops->applytranspose = PCApplyTranspose_Shell;
351:   else                pc->ops->applytranspose = 0;
352:   return(0);
353: }

359: PetscErrorCode  PCShellSetApplyRichardson_Shell(PC pc,PetscErrorCode (*applyrich)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool ,PetscInt*,PCRichardsonConvergedReason*))
360: {
361:   PC_Shell *shell;

364:   shell            = (PC_Shell*)pc->data;
365:   shell->applyrich = applyrich;
366:   if (applyrich) pc->ops->applyrichardson  = PCApplyRichardson_Shell;
367:   else           pc->ops->applyrichardson  = 0;
368:   return(0);
369: }

375: PetscErrorCode  PCShellSetName_Shell(PC pc,const char name[])
376: {
377:   PC_Shell       *shell;

381:   shell = (PC_Shell*)pc->data;
382:   PetscFree(shell->name);
383:   PetscStrallocpy(name,&shell->name);
384:   return(0);
385: }

391: PetscErrorCode  PCShellGetName_Shell(PC pc,char *name[])
392: {
393:   PC_Shell *shell;

396:   shell  = (PC_Shell*)pc->data;
397:   *name  = shell->name;
398:   return(0);
399: }

402: /* -------------------------------------------------------------------------------*/

406: /*@C
407:    PCShellSetDestroy - Sets routine to use to destroy the user-provided 
408:    application context.

410:    Logically Collective on PC

412:    Input Parameters:
413: +  pc - the preconditioner context
414: .  destroy - the application-provided destroy routine

416:    Calling sequence of destroy:
417: .vb
418:    PetscErrorCode destroy (PC)
419: .ve

421: .  ptr - the application context

423:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.

425:    Level: developer

427: .keywords: PC, shell, set, destroy, user-provided

429: .seealso: PCShellSetApply(), PCShellSetContext()
430: @*/
431: PetscErrorCode  PCShellSetDestroy(PC pc,PetscErrorCode (*destroy)(PC))
432: {

437:   PetscTryMethod(pc,"PCShellSetDestroy_C",(PC,PetscErrorCode (*)(PC)),(pc,destroy));
438:   return(0);
439: }


444: /*@C
445:    PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the 
446:    matrix operator is changed.

448:    Logically Collective on PC

450:    Input Parameters:
451: +  pc - the preconditioner context
452: .  setup - the application-provided setup routine

454:    Calling sequence of setup:
455: .vb
456:    PetscErrorCode setup (PC pc)
457: .ve

459: .  pc - the preconditioner, get the application context with PCShellGetContext()

461:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.

463:    Level: developer

465: .keywords: PC, shell, set, setup, user-provided

467: .seealso: PCShellSetApplyRichardson(), PCShellSetApply(), PCShellSetContext()
468: @*/
469: PetscErrorCode  PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(PC))
470: {

475:   PetscTryMethod(pc,"PCShellSetSetUp_C",(PC,PetscErrorCode (*)(PC)),(pc,setup));
476:   return(0);
477: }


482: /*@C
483:    PCShellSetView - Sets routine to use as viewer of shell preconditioner

485:    Logically Collective on PC

487:    Input Parameters:
488: +  pc - the preconditioner context
489: -  view - the application-provided view routine

491:    Calling sequence of apply:
492: .vb
493:    PetscErrorCode view(PC pc,PetscViewer v)
494: .ve

496: +  pc - the preconditioner, get the application context with PCShellGetContext()
497: -  v   - viewer

499:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.

501:    Level: developer

503: .keywords: PC, shell, set, apply, user-provided

505: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
506: @*/
507: PetscErrorCode  PCShellSetView(PC pc,PetscErrorCode (*view)(PC,PetscViewer))
508: {

513:   PetscTryMethod(pc,"PCShellSetView_C",(PC,PetscErrorCode (*)(PC,PetscViewer)),(pc,view));
514:   return(0);
515: }

519: /*@C
520:    PCShellSetApply - Sets routine to use as preconditioner.

522:    Logically Collective on PC

524:    Input Parameters:
525: +  pc - the preconditioner context
526: -  apply - the application-provided preconditioning routine

528:    Calling sequence of apply:
529: .vb
530:    PetscErrorCode apply (PC pc,Vec xin,Vec xout)
531: .ve

533: +  pc - the preconditioner, get the application context with PCShellGetContext()
534: .  xin - input vector
535: -  xout - output vector

537:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.

539:    Developer Notes: There should also be a PCShellSetApplySymmetricRight() and PCShellSetApplySymmetricLeft().

541:    Level: developer

543: .keywords: PC, shell, set, apply, user-provided

545: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApplyBA()
546: @*/
547: PetscErrorCode  PCShellSetApply(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec))
548: {

553:   PetscTryMethod(pc,"PCShellSetApply_C",(PC,PetscErrorCode (*)(PC,Vec,Vec)),(pc,apply));
554:   return(0);
555: }

559: /*@C
560:    PCShellSetApplyBA - Sets routine to use as preconditioner times operator.

562:    Logically Collective on PC

564:    Input Parameters:
565: +  pc - the preconditioner context
566: -  applyBA - the application-provided BA routine

568:    Calling sequence of apply:
569: .vb
570:    PetscErrorCode applyBA (PC pc,Vec xin,Vec xout)
571: .ve

573: +  pc - the preconditioner, get the application context with PCShellGetContext()
574: .  xin - input vector
575: -  xout - output vector

577:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.

579:    Level: developer

581: .keywords: PC, shell, set, apply, user-provided

583: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApply()
584: @*/
585: PetscErrorCode  PCShellSetApplyBA(PC pc,PetscErrorCode (*applyBA)(PC,PCSide,Vec,Vec,Vec))
586: {

591:   PetscTryMethod(pc,"PCShellSetApplyBA_C",(PC,PetscErrorCode (*)(PC,PCSide,Vec,Vec,Vec)),(pc,applyBA));
592:   return(0);
593: }

597: /*@C
598:    PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.

600:    Logically Collective on PC

602:    Input Parameters:
603: +  pc - the preconditioner context
604: -  apply - the application-provided preconditioning transpose routine

606:    Calling sequence of apply:
607: .vb
608:    PetscErrorCode applytranspose (PC pc,Vec xin,Vec xout)
609: .ve

611: +  pc - the preconditioner, get the application context with PCShellGetContext()
612: .  xin - input vector
613: -  xout - output vector

615:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.

617:    Level: developer

619:    Notes: 
620:    Uses the same context variable as PCShellSetApply().

622: .keywords: PC, shell, set, apply, user-provided

624: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply(), PCSetContext(), PCShellSetApplyBA()
625: @*/
626: PetscErrorCode  PCShellSetApplyTranspose(PC pc,PetscErrorCode (*applytranspose)(PC,Vec,Vec))
627: {

632:   PetscTryMethod(pc,"PCShellSetApplyTranspose_C",(PC,PetscErrorCode (*)(PC,Vec,Vec)),(pc,applytranspose));
633:   return(0);
634: }

638: /*@C
639:    PCShellSetPreSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
640:       applied. This usually does something like scale the linear system in some application 
641:       specific way.

643:    Logically Collective on PC

645:    Input Parameters:
646: +  pc - the preconditioner context
647: -  presolve - the application-provided presolve routine

649:    Calling sequence of presolve:
650: .vb
651:    PetscErrorCode presolve (PC,KSP ksp,Vec b,Vec x)
652: .ve

654: +  pc - the preconditioner, get the application context with PCShellGetContext()
655: .  xin - input vector
656: -  xout - output vector

658:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.

660:    Level: developer

662: .keywords: PC, shell, set, apply, user-provided

664: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPostSolve(), PCShellSetContext()
665: @*/
666: PetscErrorCode  PCShellSetPreSolve(PC pc,PetscErrorCode (*presolve)(PC,KSP,Vec,Vec))
667: {

672:   PetscTryMethod(pc,"PCShellSetPreSolve_C",(PC,PetscErrorCode (*)(PC,KSP,Vec,Vec)),(pc,presolve));
673:   return(0);
674: }

678: /*@C
679:    PCShellSetPostSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
680:       applied. This usually does something like scale the linear system in some application 
681:       specific way.

683:    Logically Collective on PC

685:    Input Parameters:
686: +  pc - the preconditioner context
687: -  postsolve - the application-provided presolve routine

689:    Calling sequence of postsolve:
690: .vb
691:    PetscErrorCode postsolve(PC,KSP ksp,Vec b,Vec x)
692: .ve

694: +  pc - the preconditioner, get the application context with PCShellGetContext()
695: .  xin - input vector
696: -  xout - output vector

698:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.

700:    Level: developer

702: .keywords: PC, shell, set, apply, user-provided

704: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPreSolve(), PCShellSetContext()
705: @*/
706: PetscErrorCode  PCShellSetPostSolve(PC pc,PetscErrorCode (*postsolve)(PC,KSP,Vec,Vec))
707: {

712:   PetscTryMethod(pc,"PCShellSetPostSolve_C",(PC,PetscErrorCode (*)(PC,KSP,Vec,Vec)),(pc,postsolve));
713:   return(0);
714: }

718: /*@C
719:    PCShellSetName - Sets an optional name to associate with a shell
720:    preconditioner.

722:    Not Collective

724:    Input Parameters:
725: +  pc - the preconditioner context
726: -  name - character string describing shell preconditioner

728:    Level: developer

730: .keywords: PC, shell, set, name, user-provided

732: .seealso: PCShellGetName()
733: @*/
734: PetscErrorCode  PCShellSetName(PC pc,const char name[])
735: {

740:   PetscTryMethod(pc,"PCShellSetName_C",(PC,const char []),(pc,name));
741:   return(0);
742: }

746: /*@C
747:    PCShellGetName - Gets an optional name that the user has set for a shell
748:    preconditioner.

750:    Not Collective

752:    Input Parameter:
753: .  pc - the preconditioner context

755:    Output Parameter:
756: .  name - character string describing shell preconditioner (you should not free this)

758:    Level: developer

760: .keywords: PC, shell, get, name, user-provided

762: .seealso: PCShellSetName()
763: @*/
764: PetscErrorCode  PCShellGetName(PC pc,char *name[])
765: {

771:   PetscUseMethod(pc,"PCShellGetName_C",(PC,char *[]),(pc,name));
772:   return(0);
773: }

777: /*@C
778:    PCShellSetApplyRichardson - Sets routine to use as preconditioner
779:    in Richardson iteration.

781:    Logically Collective on PC

783:    Input Parameters:
784: +  pc - the preconditioner context
785: -  apply - the application-provided preconditioning routine

787:    Calling sequence of apply:
788: .vb
789:    PetscErrorCode apply (PC pc,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits)
790: .ve

792: +  pc - the preconditioner, get the application context with PCShellGetContext()
793: .  b - right-hand-side
794: .  x - current iterate
795: .  r - work space
796: .  rtol - relative tolerance of residual norm to stop at
797: .  abstol - absolute tolerance of residual norm to stop at
798: .  dtol - if residual norm increases by this factor than return
799: -  maxits - number of iterations to run

801:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.

803:    Level: developer

805: .keywords: PC, shell, set, apply, Richardson, user-provided

807: .seealso: PCShellSetApply(), PCShellSetContext()
808: @*/
809: PetscErrorCode  PCShellSetApplyRichardson(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool ,PetscInt*,PCRichardsonConvergedReason*))
810: {

815:   PetscTryMethod(pc,"PCShellSetApplyRichardson_C",(PC,PetscErrorCode (*)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool ,PetscInt*,PCRichardsonConvergedReason*)),(pc,apply));
816:   return(0);
817: }

819: /*MC
820:    PCSHELL - Creates a new preconditioner class for use with your 
821:               own private data storage format.

823:    Level: advanced
824: >
825:    Concepts: providing your own preconditioner

827:   Usage:
833: $
834: $             PCCreate(comm,&pc);
835: $             PCSetType(pc,PCSHELL);
836: $             PCShellSetContext(pc,ctx)
837: $             PCShellSetApply(pc,apply);
838: $             PCShellSetApplyBA(pc,applyba);               (optional)
839: $             PCShellSetApplyTranspose(pc,applytranspose); (optional)
840: $             PCShellSetSetUp(pc,setup);                   (optional)
841: $             PCShellSetDestroy(pc,destroy);               (optional)

843: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
844:            MATSHELL, PCShellSetSetUp(), PCShellSetApply(), PCShellSetView(), 
845:            PCShellSetApplyTranspose(), PCShellSetName(), PCShellSetApplyRichardson(), 
846:            PCShellGetName(), PCShellSetContext(), PCShellGetContext(), PCShellSetApplyBA()
847: M*/

852: PetscErrorCode  PCCreate_Shell(PC pc)
853: {
855:   PC_Shell       *shell;

858:   PetscNewLog(pc,PC_Shell,&shell);
859:   pc->data  = (void*)shell;

861:   pc->ops->destroy         = PCDestroy_Shell;
862:   pc->ops->view            = PCView_Shell;
863:   pc->ops->apply           = PCApply_Shell;
864:   pc->ops->applytranspose  = 0;
865:   pc->ops->applyrichardson = 0;
866:   pc->ops->setup           = 0;
867:   pc->ops->presolve        = 0;
868:   pc->ops->postsolve       = 0;

870:   shell->apply          = 0;
871:   shell->applytranspose = 0;
872:   shell->name           = 0;
873:   shell->applyrich      = 0;
874:   shell->presolve       = 0;
875:   shell->postsolve      = 0;
876:   shell->ctx            = 0;
877:   shell->setup          = 0;
878:   shell->view           = 0;
879:   shell->destroy        = 0;

881:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetDestroy_C","PCShellSetDestroy_Shell",
882:                     PCShellSetDestroy_Shell);
883:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell",
884:                     PCShellSetSetUp_Shell);
885:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell",
886:                     PCShellSetApply_Shell);
887:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyBA_C","PCShellSetApplyBA_Shell",
888:                     PCShellSetApplyBA_Shell);
889:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPreSolve_C","PCShellSetPreSolve_Shell",
890:                     PCShellSetPreSolve_Shell);
891:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPostSolve_C","PCShellSetPostSolve_Shell",
892:                     PCShellSetPostSolve_Shell);
893:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell",
894:                     PCShellSetView_Shell);
895:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C","PCShellSetApplyTranspose_Shell",
896:                     PCShellSetApplyTranspose_Shell);
897:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell",
898:                     PCShellSetName_Shell);
899:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell",
900:                     PCShellGetName_Shell);
901:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C","PCShellSetApplyRichardson_Shell",
902:                     PCShellSetApplyRichardson_Shell);
903:   return(0);
904: }