Actual source code: shellpc.c

  1: #define PETSCKSP_DLL

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

 8:  #include private/pcimpl.h
 9:  #include private/vecimpl.h

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

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

 32:     Not Collective

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

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

 40:     Level: advanced

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

 47: .seealso: PCCreateShell(), PCShellSetContext()
 48: @*/
 49: PetscErrorCode  PCShellGetContext(PC pc,void **ctx)
 50: {
 52:   PetscTruth     flg;

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

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

 68:    Collective on PC

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

 74:    Level: advanced

 76:    Fortran Notes: The context can only be an integer or a PetscObject
 77:       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 = (PC_Shell*)pc->data;
 85:   PetscTruth     flg;

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

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

104:   shell = (PC_Shell*)pc->data;
105:   if (shell->setup) {
106:     CHKMEMQ;
107:     (*shell->setup)(shell->ctx);
108:     CHKMEMQ;
109:   }
110:   return(0);
111: }

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

121:   shell = (PC_Shell*)pc->data;
122:   if (!shell->apply) SETERRQ(PETSC_ERR_USER,"No apply() routine provided to Shell PC");
123:   PetscStackPush("PCSHELL user function");
124:   CHKMEMQ;
125:   (*shell->apply)(shell->ctx,x,y);
126:   CHKMEMQ;
127:   PetscStackPop;
128:   return(0);
129: }

133: static PetscErrorCode PCApplyBA_Shell(PC pc,PCSide side,Vec x,Vec y,Vec w)
134: {
135:   PC_Shell       *shell;

139:   shell = (PC_Shell*)pc->data;
140:   if (!shell->applyBA) SETERRQ(PETSC_ERR_USER,"No applyBA() routine provided to Shell PC");
141:   PetscStackPush("PCSHELL user function BA");
142:   CHKMEMQ;
143:   (*shell->applyBA)(shell->ctx,side,x,y,w);
144:   CHKMEMQ;
145:   PetscStackPop;
146:   return(0);
147: }

151: static PetscErrorCode PCPreSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
152: {
153:   PC_Shell       *shell;

157:   shell = (PC_Shell*)pc->data;
158:   if (!shell->presolve) SETERRQ(PETSC_ERR_USER,"No presolve() routine provided to Shell PC");
159:   (*shell->presolve)(shell->ctx,ksp,b,x);
160:   return(0);
161: }

165: static PetscErrorCode PCPostSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
166: {
167:   PC_Shell       *shell;

171:   shell = (PC_Shell*)pc->data;
172:   if (!shell->postsolve) SETERRQ(PETSC_ERR_USER,"No postsolve() routine provided to Shell PC");
173:   (*shell->postsolve)(shell->ctx,ksp,b,x);
174:   return(0);
175: }

179: static PetscErrorCode PCApplyTranspose_Shell(PC pc,Vec x,Vec y)
180: {
181:   PC_Shell       *shell;

185:   shell = (PC_Shell*)pc->data;
186:   if (!shell->applytranspose) SETERRQ(PETSC_ERR_USER,"No applytranspose() routine provided to Shell PC");
187:   (*shell->applytranspose)(shell->ctx,x,y);
188:   return(0);
189: }

193: static PetscErrorCode PCApplyRichardson_Shell(PC pc,Vec x,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt it)
194: {
196:   PC_Shell       *shell;

199:   shell = (PC_Shell*)pc->data;
200:   (*shell->applyrich)(shell->ctx,x,y,w,rtol,abstol,dtol,it);
201:   return(0);
202: }

206: static PetscErrorCode PCDestroy_Shell(PC pc)
207: {
208:   PC_Shell       *shell = (PC_Shell*)pc->data;

212:   PetscStrfree(shell->name);
213:   if (shell->destroy) {
214:     (*shell->destroy)(shell->ctx);
215:   }
216:   PetscFree(shell);
217:   return(0);
218: }

222: static PetscErrorCode PCView_Shell(PC pc,PetscViewer viewer)
223: {
224:   PC_Shell       *shell = (PC_Shell*)pc->data;
226:   PetscTruth     iascii;

229:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
230:   if (iascii) {
231:     if (shell->name) {PetscViewerASCIIPrintf(viewer,"  Shell: %s\n",shell->name);}
232:     else             {PetscViewerASCIIPrintf(viewer,"  Shell: no name\n");}
233:   }
234:   if (shell->view) {
235:     PetscViewerASCIIPushTab(viewer);
236:     (*shell->view)(shell->ctx,viewer);
237:     PetscViewerASCIIPopTab(viewer);
238:   }
239:   return(0);
240: }

242: /* ------------------------------------------------------------------------------*/
246: PetscErrorCode  PCShellSetDestroy_Shell(PC pc, PetscErrorCode (*destroy)(void*))
247: {
248:   PC_Shell *shell;

251:   shell          = (PC_Shell*)pc->data;
252:   shell->destroy = destroy;
253:   return(0);
254: }

260: PetscErrorCode  PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(void*))
261: {
262:   PC_Shell *shell;

265:   shell        = (PC_Shell*)pc->data;
266:   shell->setup = setup;
267:   return(0);
268: }

274: PetscErrorCode  PCShellSetApply_Shell(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec))
275: {
276:   PC_Shell *shell;

279:   shell        = (PC_Shell*)pc->data;
280:   shell->apply = apply;
281:   return(0);
282: }

288: PetscErrorCode  PCShellSetApplyBA_Shell(PC pc,PetscErrorCode (*apply)(void*,PCSide,Vec,Vec,Vec))
289: {
290:   PC_Shell *shell;

293:   shell          = (PC_Shell*)pc->data;
294:   if (apply) pc->ops->applyBA  = PCApplyBA_Shell;
295:   else       pc->ops->applyBA  = 0;
296:   shell->applyBA = apply;
297:   return(0);
298: }

304: PetscErrorCode  PCShellSetPreSolve_Shell(PC pc,PetscErrorCode (*presolve)(void*,KSP,Vec,Vec))
305: {
306:   PC_Shell *shell;

309:   shell             = (PC_Shell*)pc->data;
310:   shell->presolve   = presolve;
311:   if (presolve) {
312:     pc->ops->presolve = PCPreSolve_Shell;
313:   } else {
314:     pc->ops->presolve = 0;
315:   }
316:   return(0);
317: }

323: PetscErrorCode  PCShellSetPostSolve_Shell(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec))
324: {
325:   PC_Shell *shell;

328:   shell           = (PC_Shell*)pc->data;
329:   shell->postsolve = postsolve;
330:   if (postsolve) {
331:     pc->ops->postsolve = PCPostSolve_Shell;
332:   } else {
333:     pc->ops->postsolve = 0;
334:   }
335:   return(0);
336: }

342: PetscErrorCode  PCShellSetView_Shell(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
343: {
344:   PC_Shell *shell;

347:   shell        = (PC_Shell*)pc->data;
348:   shell->view = view;
349:   return(0);
350: }

356: PetscErrorCode  PCShellSetApplyTranspose_Shell(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
357: {
358:   PC_Shell *shell;

361:   shell                 = (PC_Shell*)pc->data;
362:   shell->applytranspose = applytranspose;
363:   return(0);
364: }

370: PetscErrorCode  PCShellSetName_Shell(PC pc,const char name[])
371: {
372:   PC_Shell       *shell;

376:   shell = (PC_Shell*)pc->data;
377:   PetscStrfree(shell->name);
378:   PetscStrallocpy(name,&shell->name);
379:   return(0);
380: }

386: PetscErrorCode  PCShellGetName_Shell(PC pc,char *name[])
387: {
388:   PC_Shell *shell;

391:   shell  = (PC_Shell*)pc->data;
392:   *name  = shell->name;
393:   return(0);
394: }

400: PetscErrorCode  PCShellSetApplyRichardson_Shell(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt))
401: {
402:   PC_Shell *shell;

405:   shell                     = (PC_Shell*)pc->data;
406:   pc->ops->applyrichardson  = PCApplyRichardson_Shell;
407:   shell->applyrich          = apply;
408:   return(0);
409: }

412: /* -------------------------------------------------------------------------------*/

416: /*@C
417:    PCShellSetDestroy - Sets routine to use to destroy the user-provided 
418:    application context.

420:    Collective on PC

422:    Input Parameters:
423: +  pc - the preconditioner context
424: .  destroy - the application-provided destroy routine

426:    Calling sequence of destroy:
427: .vb
428:    PetscErrorCode destroy (void *ptr)
429: .ve

431: .  ptr - the application context

433:    Level: developer

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

437: .seealso: PCShellSetApply(), PCShellSetContext()
438: @*/
439: PetscErrorCode  PCShellSetDestroy(PC pc,PetscErrorCode (*destroy)(void*))
440: {
441:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*));

445:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetDestroy_C",(void (**)(void))&f);
446:   if (f) {
447:     (*f)(pc,destroy);
448:   }
449:   return(0);
450: }


455: /*@C
456:    PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the 
457:    matrix operator is changed.

459:    Collective on PC

461:    Input Parameters:
462: +  pc - the preconditioner context
463: .  setup - the application-provided setup routine

465:    Calling sequence of setup:
466: .vb
467:    PetscErrorCode setup (void *ptr)
468: .ve

470: .  ptr - the application context

472:    Level: developer

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

476: .seealso: PCShellSetApplyRichardson(), PCShellSetApply(), PCShellSetContext()
477: @*/
478: PetscErrorCode  PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(void*))
479: {
480:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*));

484:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)(void))&f);
485:   if (f) {
486:     (*f)(pc,setup);
487:   }
488:   return(0);
489: }


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

497:    Collective on PC

499:    Input Parameters:
500: +  pc - the preconditioner context
501: -  view - the application-provided view routine

503:    Calling sequence of apply:
504: .vb
505:    PetscErrorCode view(void *ptr,PetscViewer v)
506: .ve

508: +  ptr - the application context
509: -  v   - viewer

511:    Level: developer

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

515: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
516: @*/
517: PetscErrorCode  PCShellSetView(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
518: {
519:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PetscViewer));

523:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetView_C",(void (**)(void))&f);
524:   if (f) {
525:     (*f)(pc,view);
526:   }
527:   return(0);
528: }

532: /*@C
533:    PCShellSetApply - Sets routine to use as preconditioner.

535:    Collective on PC

537:    Input Parameters:
538: +  pc - the preconditioner context
539: -  apply - the application-provided preconditioning routine

541:    Calling sequence of apply:
542: .vb
543:    PetscErrorCode apply (void *ptr,Vec xin,Vec xout)
544: .ve

546: +  ptr - the application context
547: .  xin - input vector
548: -  xout - output vector

550:    Level: developer

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

554: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApplyBA()
555: @*/
556: PetscErrorCode  PCShellSetApply(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec))
557: {
558:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));

562:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)(void))&f);
563:   if (f) {
564:     (*f)(pc,apply);
565:   }
566:   return(0);
567: }

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

574:    Collective on PC

576:    Input Parameters:
577: +  pc - the preconditioner context
578: -  applyBA - the application-provided BA routine

580:    Calling sequence of apply:
581: .vb
582:    PetscErrorCode applyBA (void *ptr,Vec xin,Vec xout)
583: .ve

585: +  ptr - the application context
586: .  xin - input vector
587: -  xout - output vector

589:    Level: developer

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

593: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApply()
594: @*/
595: PetscErrorCode  PCShellSetApplyBA(PC pc,PetscErrorCode (*applyBA)(void*,PCSide,Vec,Vec,Vec))
596: {
597:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PCSide,Vec,Vec,Vec));

601:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyBA_C",(void (**)(void))&f);
602:   if (f) {
603:     (*f)(pc,applyBA);
604:   }
605:   return(0);
606: }

610: /*@C
611:    PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.

613:    Collective on PC

615:    Input Parameters:
616: +  pc - the preconditioner context
617: -  apply - the application-provided preconditioning transpose routine

619:    Calling sequence of apply:
620: .vb
621:    PetscErrorCode applytranspose (void *ptr,Vec xin,Vec xout)
622: .ve

624: +  ptr - the application context
625: .  xin - input vector
626: -  xout - output vector

628:    Level: developer

630:    Notes: 
631:    Uses the same context variable as PCShellSetApply().

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

635: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply(), PCSetContext(), PCShellSetApplyBA()
636: @*/
637: PetscErrorCode  PCShellSetApplyTranspose(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
638: {
639:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));

643:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)(void))&f);
644:   if (f) {
645:     (*f)(pc,applytranspose);
646:   }
647:   return(0);
648: }

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

657:    Collective on PC

659:    Input Parameters:
660: +  pc - the preconditioner context
661: -  presolve - the application-provided presolve routine

663:    Calling sequence of presolve:
664: .vb
665:    PetscErrorCode presolve (void *ptr,KSP ksp,Vec b,Vec x)
666: .ve

668: +  ptr - the application context
669: .  xin - input vector
670: -  xout - output vector

672:    Level: developer

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

676: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPostSolve(), PCShellSetContext()
677: @*/
678: PetscErrorCode  PCShellSetPreSolve(PC pc,PetscErrorCode (*presolve)(void*,KSP,Vec,Vec))
679: {
680:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));

684:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPreSolve_C",(void (**)(void))&f);
685:   if (f) {
686:     (*f)(pc,presolve);
687:   }
688:   return(0);
689: }

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

698:    Collective on PC

700:    Input Parameters:
701: +  pc - the preconditioner context
702: -  postsolve - the application-provided presolve routine

704:    Calling sequence of postsolve:
705: .vb
706:    PetscErrorCode postsolve(void *ptr,KSP ksp,Vec b,Vec x)
707: .ve

709: +  ptr - the application context
710: .  xin - input vector
711: -  xout - output vector

713:    Level: developer

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

717: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPreSolve(), PCShellSetContext()
718: @*/
719: PetscErrorCode  PCShellSetPostSolve(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec))
720: {
721:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));

725:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPostSolve_C",(void (**)(void))&f);
726:   if (f) {
727:     (*f)(pc,postsolve);
728:   }
729:   return(0);
730: }

734: /*@C
735:    PCShellSetName - Sets an optional name to associate with a shell
736:    preconditioner.

738:    Not Collective

740:    Input Parameters:
741: +  pc - the preconditioner context
742: -  name - character string describing shell preconditioner

744:    Level: developer

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

748: .seealso: PCShellGetName()
749: @*/
750: PetscErrorCode  PCShellSetName(PC pc,const char name[])
751: {
752:   PetscErrorCode ierr,(*f)(PC,const char []);

756:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)(void))&f);
757:   if (f) {
758:     (*f)(pc,name);
759:   }
760:   return(0);
761: }

765: /*@C
766:    PCShellGetName - Gets an optional name that the user has set for a shell
767:    preconditioner.

769:    Not Collective

771:    Input Parameter:
772: .  pc - the preconditioner context

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

777:    Level: developer

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

781: .seealso: PCShellSetName()
782: @*/
783: PetscErrorCode  PCShellGetName(PC pc,char *name[])
784: {
785:   PetscErrorCode ierr,(*f)(PC,char *[]);

790:   PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)(void))&f);
791:   if (f) {
792:     (*f)(pc,name);
793:   } else {
794:     SETERRQ(PETSC_ERR_ARG_WRONG,"Not shell preconditioner, cannot get name");
795:   }
796:   return(0);
797: }

801: /*@C
802:    PCShellSetApplyRichardson - Sets routine to use as preconditioner
803:    in Richardson iteration.

805:    Collective on PC

807:    Input Parameters:
808: +  pc - the preconditioner context
809: -  apply - the application-provided preconditioning routine

811:    Calling sequence of apply:
812: .vb
813:    PetscErrorCode apply (void *ptr,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits)
814: .ve

816: +  ptr - the application context
817: .  b - right-hand-side
818: .  x - current iterate
819: .  r - work space
820: .  rtol - relative tolerance of residual norm to stop at
821: .  abstol - absolute tolerance of residual norm to stop at
822: .  dtol - if residual norm increases by this factor than return
823: -  maxits - number of iterations to run

825:    Level: developer

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

829: .seealso: PCShellSetApply(), PCShellSetContext()
830: @*/
831: PetscErrorCode  PCShellSetApplyRichardson(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt))
832: {
833:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt));

837:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)(void))&f);
838:   if (f) {
839:     (*f)(pc,apply);
840:   }
841:   return(0);
842: }

844: /*MC
845:    PCSHELL - Creates a new preconditioner class for use with your 
846:               own private data storage format.

848:    Level: advanced

850:    Concepts: providing your own preconditioner

852:   Usage:
853: $             PetscErrorCode (*mult)(void*,Vec,Vec);
854: $             PetscErrorCode (*setup)(void*);
855: $             PCCreate(comm,&pc);
856: $             PCSetType(pc,PCSHELL);
857: $             PCShellSetApply(pc,mult);
858: $             PCShellSetApplyBA(pc,mult);      (optional)
859: $             PCShellSetApplyTranspose(pc,mult); (optional)
860: $             PCShellSetContext(pc,ctx)
861: $             PCShellSetSetUp(pc,setup);       (optional)

863: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
864:            MATSHELL, PCShellSetSetUp(), PCShellSetApply(), PCShellSetView(), 
865:            PCShellSetApplyTranspose(), PCShellSetName(), PCShellSetApplyRichardson(), 
866:            PCShellGetName(), PCShellSetContext(), PCShellGetContext(), PCShellSetApplyBA()
867: M*/

872: PetscErrorCode  PCCreate_Shell(PC pc)
873: {
875:   PC_Shell       *shell;

878:   pc->ops->destroy    = PCDestroy_Shell;
879:   PetscNew(PC_Shell,&shell);
880:   PetscLogObjectMemory(pc,sizeof(PC_Shell));
881:   pc->data         = (void*)shell;
882:   pc->name         = 0;

884:   pc->ops->apply           = PCApply_Shell;
885:   pc->ops->view            = PCView_Shell;
886:   pc->ops->applytranspose  = PCApplyTranspose_Shell;
887:   pc->ops->applyrichardson = 0;
888:   pc->ops->setup           = PCSetUp_Shell;
889:   pc->ops->presolve        = 0;
890:   pc->ops->postsolve       = 0;
891:   pc->ops->view            = PCView_Shell;

893:   shell->apply          = 0;
894:   shell->applytranspose = 0;
895:   shell->name           = 0;
896:   shell->applyrich      = 0;
897:   shell->presolve       = 0;
898:   shell->postsolve      = 0;
899:   shell->ctx            = 0;
900:   shell->setup          = 0;
901:   shell->view           = 0;
902:   shell->destroy        = 0;

904:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetDestroy_C","PCShellSetDestroy_Shell",
905:                     PCShellSetDestroy_Shell);
906:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell",
907:                     PCShellSetSetUp_Shell);
908:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell",
909:                     PCShellSetApply_Shell);
910:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyBA_C","PCShellSetApplyBA_Shell",
911:                     PCShellSetApplyBA_Shell);
912:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPreSolve_C","PCShellSetPreSolve_Shell",
913:                     PCShellSetPreSolve_Shell);
914:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPostSolve_C","PCShellSetPostSolve_Shell",
915:                     PCShellSetPostSolve_Shell);
916:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell",
917:                     PCShellSetView_Shell);
918:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C","PCShellSetApplyTranspose_Shell",
919:                     PCShellSetApplyTranspose_Shell);
920:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell",
921:                     PCShellSetName_Shell);
922:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell",
923:                     PCShellGetName_Shell);
924:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C","PCShellSetApplyRichardson_Shell",
925:                     PCShellSetApplyRichardson_Shell);
926:   return(0);
927: }