Date: 2015-10-02T22:17:50+00:00

Actual source code: shellpc.c
petsc-3.6.2 2015-10-02
Report Typos and Errors

      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 <petsc/private/pcimpl.h>        /*I "petscpc.h" I*/
      8: #include <petsc/private/vecimpl.h>

     10: typedef struct {
     11:   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*);

     23:   char *name;
     24: } 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 PCSetType(pc,shell)

     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

     44: .keywords: PC, shell, get, context

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

     56:   PetscObjectTypeCompare((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: PCShellGetContext(), PCSHELL
     80: @*/
     81: PetscErrorCode  PCShellSetContext(PC pc,void *ctx)
     82: {
     83:   PC_Shell       *shell = (PC_Shell*)pc->data;
     85:   PetscBool      flg;

     89:   PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&flg);
     90:   if (flg) shell->ctx = ctx;
     91:   return(0);
     92: }

     96: static PetscErrorCode PCSetUp_Shell(PC pc)
     97: {
     98:   PC_Shell       *shell = (PC_Shell*)pc->data;

    102:   if (!shell->setup) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No setup() routine provided to Shell PC");
    103:   PetscStackCall("PCSHELL user function setup()",(*shell->setup)(pc);CHKERRQ(ierr));
    104:   return(0);
    105: }

    109: static PetscErrorCode PCApply_Shell(PC pc,Vec x,Vec y)
    110: {
    111:   PC_Shell       *shell = (PC_Shell*)pc->data;

    115:   if (!shell->apply) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No apply() routine provided to Shell PC");
    116:   PetscStackCall("PCSHELL user function apply()",(*shell->apply)(pc,x,y);CHKERRQ(ierr));
    117:   return(0);
    118: }

    122: static PetscErrorCode PCApplyBA_Shell(PC pc,PCSide side,Vec x,Vec y,Vec w)
    123: {
    124:   PC_Shell       *shell = (PC_Shell*)pc->data;

    128:   if (!shell->applyBA) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No applyBA() routine provided to Shell PC");
    129:   PetscStackCall("PCSHELL user function applyBA()",(*shell->applyBA)(pc,side,x,y,w);CHKERRQ(ierr));
    130:   return(0);
    131: }

    135: static PetscErrorCode PCPreSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
    136: {
    137:   PC_Shell       *shell = (PC_Shell*)pc->data;

    141:   if (!shell->presolve) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No presolve() routine provided to Shell PC");
    142:   PetscStackCall("PCSHELL user function presolve()",(*shell->presolve)(pc,ksp,b,x);CHKERRQ(ierr));
    143:   return(0);
    144: }

    148: static PetscErrorCode PCPostSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
    149: {
    150:   PC_Shell       *shell = (PC_Shell*)pc->data;

    154:   if (!shell->postsolve) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No postsolve() routine provided to Shell PC");
    155:   PetscStackCall("PCSHELL user function postsolve()",(*shell->postsolve)(pc,ksp,b,x);CHKERRQ(ierr));
    156:   return(0);
    157: }

    161: static PetscErrorCode PCApplyTranspose_Shell(PC pc,Vec x,Vec y)
    162: {
    163:   PC_Shell       *shell = (PC_Shell*)pc->data;

    167:   if (!shell->applytranspose) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No applytranspose() routine provided to Shell PC");
    168:   PetscStackCall("PCSHELL user function applytranspose()",(*shell->applytranspose)(pc,x,y);CHKERRQ(ierr));
    169:   return(0);
    170: }

    174: 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)
    175: {
    177:   PC_Shell       *shell = (PC_Shell*)pc->data;

    180:   if (!shell->applyrich) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No applyrichardson() routine provided to Shell PC");
    181:   PetscStackCall("PCSHELL user function applyrichardson()",(*shell->applyrich)(pc,x,y,w,rtol,abstol,dtol,it,guesszero,outits,reason);CHKERRQ(ierr));
    182:   return(0);
    183: }

    187: static PetscErrorCode PCDestroy_Shell(PC pc)
    188: {
    189:   PC_Shell       *shell = (PC_Shell*)pc->data;

    193:   PetscFree(shell->name);
    194:   if (shell->destroy) PetscStackCall("PCSHELL user function destroy()",(*shell->destroy)(pc);CHKERRQ(ierr));
    195:   PetscFree(pc->data);
    196:   return(0);
    197: }

    201: static PetscErrorCode PCView_Shell(PC pc,PetscViewer viewer)
    202: {
    203:   PC_Shell       *shell = (PC_Shell*)pc->data;
    205:   PetscBool      iascii;

    208:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    209:   if (iascii) {
    210:     if (shell->name) {
    211:       PetscViewerASCIIPrintf(viewer,"  Shell: %s\n",shell->name);
    212:     } else {
    213:       PetscViewerASCIIPrintf(viewer,"  Shell: no name\n");
    214:     }
    215:   }
    216:   if (shell->view) {
    217:     PetscViewerASCIIPushTab(viewer);
    218:     (*shell->view)(pc,viewer);
    219:     PetscViewerASCIIPopTab(viewer);
    220:   }
    221:   return(0);
    222: }

    224: /* ------------------------------------------------------------------------------*/
    227: static PetscErrorCode  PCShellSetDestroy_Shell(PC pc, PetscErrorCode (*destroy)(PC))
    228: {
    229:   PC_Shell *shell= (PC_Shell*)pc->data;

    232:   shell->destroy = destroy;
    233:   return(0);
    234: }

    238: static PetscErrorCode  PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(PC))
    239: {
    240:   PC_Shell *shell = (PC_Shell*)pc->data;;

    243:   shell->setup = setup;
    244:   if (setup) pc->ops->setup = PCSetUp_Shell;
    245:   else       pc->ops->setup = 0;
    246:   return(0);
    247: }

    251: static PetscErrorCode  PCShellSetApply_Shell(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec))
    252: {
    253:   PC_Shell *shell = (PC_Shell*)pc->data;

    256:   shell->apply = apply;
    257:   return(0);
    258: }

    262: static PetscErrorCode  PCShellSetApplyBA_Shell(PC pc,PetscErrorCode (*applyBA)(PC,PCSide,Vec,Vec,Vec))
    263: {
    264:   PC_Shell *shell = (PC_Shell*)pc->data;

    267:   shell->applyBA = applyBA;
    268:   if (applyBA) pc->ops->applyBA  = PCApplyBA_Shell;
    269:   else         pc->ops->applyBA  = 0;
    270:   return(0);
    271: }

    275: static PetscErrorCode  PCShellSetPreSolve_Shell(PC pc,PetscErrorCode (*presolve)(PC,KSP,Vec,Vec))
    276: {
    277:   PC_Shell *shell = (PC_Shell*)pc->data;

    280:   shell->presolve = presolve;
    281:   if (presolve) pc->ops->presolve = PCPreSolve_Shell;
    282:   else          pc->ops->presolve = 0;
    283:   return(0);
    284: }

    288: static PetscErrorCode  PCShellSetPostSolve_Shell(PC pc,PetscErrorCode (*postsolve)(PC,KSP,Vec,Vec))
    289: {
    290:   PC_Shell *shell = (PC_Shell*)pc->data;

    293:   shell->postsolve = postsolve;
    294:   if (postsolve) pc->ops->postsolve = PCPostSolve_Shell;
    295:   else           pc->ops->postsolve = 0;
    296:   return(0);
    297: }

    301: static PetscErrorCode  PCShellSetView_Shell(PC pc,PetscErrorCode (*view)(PC,PetscViewer))
    302: {
    303:   PC_Shell *shell = (PC_Shell*)pc->data;

    306:   shell->view = view;
    307:   return(0);
    308: }

    312: static PetscErrorCode  PCShellSetApplyTranspose_Shell(PC pc,PetscErrorCode (*applytranspose)(PC,Vec,Vec))
    313: {
    314:   PC_Shell *shell = (PC_Shell*)pc->data;

    317:   shell->applytranspose = applytranspose;
    318:   if (applytranspose) pc->ops->applytranspose = PCApplyTranspose_Shell;
    319:   else                pc->ops->applytranspose = 0;
    320:   return(0);
    321: }

    325: static PetscErrorCode  PCShellSetApplyRichardson_Shell(PC pc,PetscErrorCode (*applyrich)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool ,PetscInt*,PCRichardsonConvergedReason*))
    326: {
    327:   PC_Shell *shell = (PC_Shell*)pc->data;

    330:   shell->applyrich = applyrich;
    331:   if (applyrich) pc->ops->applyrichardson = PCApplyRichardson_Shell;
    332:   else           pc->ops->applyrichardson = 0;
    333:   return(0);
    334: }

    338: static PetscErrorCode  PCShellSetName_Shell(PC pc,const char name[])
    339: {
    340:   PC_Shell       *shell = (PC_Shell*)pc->data;

    344:   PetscFree(shell->name);
    345:   PetscStrallocpy(name,&shell->name);
    346:   return(0);
    347: }

    351: static PetscErrorCode  PCShellGetName_Shell(PC pc,const char *name[])
    352: {
    353:   PC_Shell *shell = (PC_Shell*)pc->data;

    356:   *name = shell->name;
    357:   return(0);
    358: }

    360: /* -------------------------------------------------------------------------------*/

    364: /*@C
    365:    PCShellSetDestroy - Sets routine to use to destroy the user-provided
    366:    application context.

    368:    Logically Collective on PC

    370:    Input Parameters:
    371: +  pc - the preconditioner context
    372: .  destroy - the application-provided destroy routine

    374:    Calling sequence of destroy:
    375: .vb
    376:    PetscErrorCode destroy (PC)
    377: .ve

    379: .  ptr - the application context

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

    383:    Level: developer

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

    387: .seealso: PCShellSetApply(), PCShellSetContext()
    388: @*/
    389: PetscErrorCode  PCShellSetDestroy(PC pc,PetscErrorCode (*destroy)(PC))
    390: {

    395:   PetscTryMethod(pc,"PCShellSetDestroy_C",(PC,PetscErrorCode (*)(PC)),(pc,destroy));
    396:   return(0);
    397: }

    402: /*@C
    403:    PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
    404:    matrix operator is changed.

    406:    Logically Collective on PC

    408:    Input Parameters:
    409: +  pc - the preconditioner context
    410: .  setup - the application-provided setup routine

    412:    Calling sequence of setup:
    413: .vb
    414:    PetscErrorCode setup (PC pc)
    415: .ve

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

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

    421:    Level: developer

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

    425: .seealso: PCShellSetApplyRichardson(), PCShellSetApply(), PCShellSetContext()
    426: @*/
    427: PetscErrorCode  PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(PC))
    428: {

    433:   PetscTryMethod(pc,"PCShellSetSetUp_C",(PC,PetscErrorCode (*)(PC)),(pc,setup));
    434:   return(0);
    435: }

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

    443:    Logically Collective on PC

    445:    Input Parameters:
    446: +  pc - the preconditioner context
    447: -  view - the application-provided view routine

    449:    Calling sequence of apply:
    450: .vb
    451:    PetscErrorCode view(PC pc,PetscViewer v)
    452: .ve

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

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

    459:    Level: developer

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

    463: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
    464: @*/
    465: PetscErrorCode  PCShellSetView(PC pc,PetscErrorCode (*view)(PC,PetscViewer))
    466: {

    471:   PetscTryMethod(pc,"PCShellSetView_C",(PC,PetscErrorCode (*)(PC,PetscViewer)),(pc,view));
    472:   return(0);
    473: }

    477: /*@C
    478:    PCShellSetApply - Sets routine to use as preconditioner.

    480:    Logically Collective on PC

    482:    Input Parameters:
    483: +  pc - the preconditioner context
    484: -  apply - the application-provided preconditioning routine

    486:    Calling sequence of apply:
    487: .vb
    488:    PetscErrorCode apply (PC pc,Vec xin,Vec xout)
    489: .ve

    491: +  pc - the preconditioner, get the application context with PCShellGetContext()
    492: .  xin - input vector
    493: -  xout - output vector

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

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

    499:    Level: developer

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

    503: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApplyBA()
    504: @*/
    505: PetscErrorCode  PCShellSetApply(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec))
    506: {

    511:   PetscTryMethod(pc,"PCShellSetApply_C",(PC,PetscErrorCode (*)(PC,Vec,Vec)),(pc,apply));
    512:   return(0);
    513: }

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

    520:    Logically Collective on PC

    522:    Input Parameters:
    523: +  pc - the preconditioner context
    524: -  applyBA - the application-provided BA routine

    526:    Calling sequence of apply:
    527: .vb
    528:    PetscErrorCode applyBA (PC pc,Vec xin,Vec xout)
    529: .ve

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

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

    537:    Level: developer

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

    541: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApply()
    542: @*/
    543: PetscErrorCode  PCShellSetApplyBA(PC pc,PetscErrorCode (*applyBA)(PC,PCSide,Vec,Vec,Vec))
    544: {

    549:   PetscTryMethod(pc,"PCShellSetApplyBA_C",(PC,PetscErrorCode (*)(PC,PCSide,Vec,Vec,Vec)),(pc,applyBA));
    550:   return(0);
    551: }

    555: /*@C
    556:    PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.

    558:    Logically Collective on PC

    560:    Input Parameters:
    561: +  pc - the preconditioner context
    562: -  apply - the application-provided preconditioning transpose routine

    564:    Calling sequence of apply:
    565: .vb
    566:    PetscErrorCode applytranspose (PC pc,Vec xin,Vec xout)
    567: .ve

    569: +  pc - the preconditioner, get the application context with PCShellGetContext()
    570: .  xin - input vector
    571: -  xout - output vector

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

    575:    Level: developer

    577:    Notes:
    578:    Uses the same context variable as PCShellSetApply().

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

    582: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply(), PCSetContext(), PCShellSetApplyBA()
    583: @*/
    584: PetscErrorCode  PCShellSetApplyTranspose(PC pc,PetscErrorCode (*applytranspose)(PC,Vec,Vec))
    585: {

    590:   PetscTryMethod(pc,"PCShellSetApplyTranspose_C",(PC,PetscErrorCode (*)(PC,Vec,Vec)),(pc,applytranspose));
    591:   return(0);
    592: }

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

    601:    Logically Collective on PC

    603:    Input Parameters:
    604: +  pc - the preconditioner context
    605: -  presolve - the application-provided presolve routine

    607:    Calling sequence of presolve:
    608: .vb
    609:    PetscErrorCode presolve (PC,KSP ksp,Vec b,Vec x)
    610: .ve

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

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

    618:    Level: developer

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

    622: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPostSolve(), PCShellSetContext()
    623: @*/
    624: PetscErrorCode  PCShellSetPreSolve(PC pc,PetscErrorCode (*presolve)(PC,KSP,Vec,Vec))
    625: {

    630:   PetscTryMethod(pc,"PCShellSetPreSolve_C",(PC,PetscErrorCode (*)(PC,KSP,Vec,Vec)),(pc,presolve));
    631:   return(0);
    632: }

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

    641:    Logically Collective on PC

    643:    Input Parameters:
    644: +  pc - the preconditioner context
    645: -  postsolve - the application-provided presolve routine

    647:    Calling sequence of postsolve:
    648: .vb
    649:    PetscErrorCode postsolve(PC,KSP ksp,Vec b,Vec x)
    650: .ve

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

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

    658:    Level: developer

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

    662: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPreSolve(), PCShellSetContext()
    663: @*/
    664: PetscErrorCode  PCShellSetPostSolve(PC pc,PetscErrorCode (*postsolve)(PC,KSP,Vec,Vec))
    665: {

    670:   PetscTryMethod(pc,"PCShellSetPostSolve_C",(PC,PetscErrorCode (*)(PC,KSP,Vec,Vec)),(pc,postsolve));
    671:   return(0);
    672: }

    676: /*@C
    677:    PCShellSetName - Sets an optional name to associate with a shell
    678:    preconditioner.

    680:    Not Collective

    682:    Input Parameters:
    683: +  pc - the preconditioner context
    684: -  name - character string describing shell preconditioner

    686:    Level: developer

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

    690: .seealso: PCShellGetName()
    691: @*/
    692: PetscErrorCode  PCShellSetName(PC pc,const char name[])
    693: {

    698:   PetscTryMethod(pc,"PCShellSetName_C",(PC,const char []),(pc,name));
    699:   return(0);
    700: }

    704: /*@C
    705:    PCShellGetName - Gets an optional name that the user has set for a shell
    706:    preconditioner.

    708:    Not Collective

    710:    Input Parameter:
    711: .  pc - the preconditioner context

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

    716:    Level: developer

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

    720: .seealso: PCShellSetName()
    721: @*/
    722: PetscErrorCode  PCShellGetName(PC pc,const char *name[])
    723: {

    729:   PetscUseMethod(pc,"PCShellGetName_C",(PC,const char*[]),(pc,name));
    730:   return(0);
    731: }

    735: /*@C
    736:    PCShellSetApplyRichardson - Sets routine to use as preconditioner
    737:    in Richardson iteration.

    739:    Logically Collective on PC

    741:    Input Parameters:
    742: +  pc - the preconditioner context
    743: -  apply - the application-provided preconditioning routine

    745:    Calling sequence of apply:
    746: .vb
    747:    PetscErrorCode apply (PC pc,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits)
    748: .ve

    750: +  pc - the preconditioner, get the application context with PCShellGetContext()
    751: .  b - right-hand-side
    752: .  x - current iterate
    753: .  r - work space
    754: .  rtol - relative tolerance of residual norm to stop at
    755: .  abstol - absolute tolerance of residual norm to stop at
    756: .  dtol - if residual norm increases by this factor than return
    757: -  maxits - number of iterations to run

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

    761:    Level: developer

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

    765: .seealso: PCShellSetApply(), PCShellSetContext()
    766: @*/
    767: PetscErrorCode  PCShellSetApplyRichardson(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool,PetscInt*,PCRichardsonConvergedReason*))
    768: {

    773:   PetscTryMethod(pc,"PCShellSetApplyRichardson_C",(PC,PetscErrorCode (*)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool,PetscInt*,PCRichardsonConvergedReason*)),(pc,apply));
    774:   return(0);
    775: }

    777: /*MC
    778:    PCSHELL - Creates a new preconditioner class for use with your
    779:               own private data storage format.

    781:    Level: advanced
    782: >
    783:    Concepts: providing your own preconditioner

    785:   Usage:
    786: $             extern PetscErrorCode apply(PC,Vec,Vec);
    787: $             extern PetscErrorCode applyba(PC,PCSide,Vec,Vec,Vec);
    788: $             extern PetscErrorCode applytranspose(PC,Vec,Vec);
    789: $             extern PetscErrorCode setup(PC);
    790: $             extern PetscErrorCode destroy(PC);
    791: $
    792: $             PCCreate(comm,&pc);
    793: $             PCSetType(pc,PCSHELL);
    794: $             PCShellSetContext(pc,ctx)
    795: $             PCShellSetApply(pc,apply);
    796: $             PCShellSetApplyBA(pc,applyba);               (optional)
    797: $             PCShellSetApplyTranspose(pc,applytranspose); (optional)
    798: $             PCShellSetSetUp(pc,setup);                   (optional)
    799: $             PCShellSetDestroy(pc,destroy);               (optional)

    801: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
    802:            MATSHELL, PCShellSetSetUp(), PCShellSetApply(), PCShellSetView(),
    803:            PCShellSetApplyTranspose(), PCShellSetName(), PCShellSetApplyRichardson(),
    804:            PCShellGetName(), PCShellSetContext(), PCShellGetContext(), PCShellSetApplyBA()
    805: M*/

    809: PETSC_EXTERN PetscErrorCode PCCreate_Shell(PC pc)
    810: {
    812:   PC_Shell       *shell;

    815:   PetscNewLog(pc,&shell);
    816:   pc->data = (void*)shell;

    818:   pc->ops->destroy         = PCDestroy_Shell;
    819:   pc->ops->view            = PCView_Shell;
    820:   pc->ops->apply           = PCApply_Shell;
    821:   pc->ops->applytranspose  = 0;
    822:   pc->ops->applyrichardson = 0;
    823:   pc->ops->setup           = 0;
    824:   pc->ops->presolve        = 0;
    825:   pc->ops->postsolve       = 0;

    827:   shell->apply          = 0;
    828:   shell->applytranspose = 0;
    829:   shell->name           = 0;
    830:   shell->applyrich      = 0;
    831:   shell->presolve       = 0;
    832:   shell->postsolve      = 0;
    833:   shell->ctx            = 0;
    834:   shell->setup          = 0;
    835:   shell->view           = 0;
    836:   shell->destroy        = 0;

    838:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetDestroy_C",PCShellSetDestroy_Shell);
    839:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetSetUp_C",PCShellSetSetUp_Shell);
    840:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApply_C",PCShellSetApply_Shell);
    841:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApplyBA_C",PCShellSetApplyBA_Shell);
    842:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetPreSolve_C",PCShellSetPreSolve_Shell);
    843:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetPostSolve_C",PCShellSetPostSolve_Shell);
    844:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetView_C",PCShellSetView_Shell);
    845:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",PCShellSetApplyTranspose_Shell);
    846:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetName_C",PCShellSetName_Shell);
    847:   PetscObjectComposeFunction((PetscObject)pc,"PCShellGetName_C",PCShellGetName_Shell);
    848:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",PCShellSetApplyRichardson_Shell);
    849:   return(0);
    850: }