Actual source code: shellpc.c

petsc-3.5.4 2015-05-23
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: }