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;
 85:   PetscTruth     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(PETSC_ERR_USER,"No setup() routine provided to Shell PC");
107:   PetscStackPush("PCSHELL user function setup()");
108:   CHKMEMQ;
109:   (*shell->setup)(shell->ctx);
110:   CHKMEMQ;
111:   PetscStackPop;
112:   return(0);
113: }

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

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

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

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

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

159:   shell = (PC_Shell*)pc->data;
160:   if (!shell->presolve) SETERRQ(PETSC_ERR_USER,"No presolve() routine provided to Shell PC");
161:   PetscStackPush("PCSHELL user function presolve()");
162:   CHKMEMQ;
163:   (*shell->presolve)(shell->ctx,ksp,b,x);
164:   CHKMEMQ;
165:   PetscStackPop;
166:   return(0);
167: }

171: static PetscErrorCode PCPostSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
172: {
173:   PC_Shell       *shell;

177:   shell = (PC_Shell*)pc->data;
178:   if (!shell->postsolve) SETERRQ(PETSC_ERR_USER,"No postsolve() routine provided to Shell PC");
179:   PetscStackPush("PCSHELL user function postsolve()");
180:   CHKMEMQ;
181:   (*shell->postsolve)(shell->ctx,ksp,b,x);
182:   CHKMEMQ;
183:   PetscStackPop;
184:   return(0);
185: }

189: static PetscErrorCode PCApplyTranspose_Shell(PC pc,Vec x,Vec y)
190: {
191:   PC_Shell       *shell;

195:   shell = (PC_Shell*)pc->data;
196:   if (!shell->applytranspose) SETERRQ(PETSC_ERR_USER,"No applytranspose() routine provided to Shell PC");
197:   PetscStackPush("PCSHELL user function applytranspose()");
198:   CHKMEMQ;
199:   (*shell->applytranspose)(shell->ctx,x,y);
200:   CHKMEMQ;
201:   PetscStackPop;
202:   return(0);
203: }

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

213:   shell = (PC_Shell*)pc->data;
214:   if (!shell->applyrich) SETERRQ(PETSC_ERR_USER,"No applyrichardson() routine provided to Shell PC");
215:   PetscStackPush("PCSHELL user function applyrichardson()");
216:   CHKMEMQ;
217:   (*shell->applyrich)(shell->ctx,x,y,w,rtol,abstol,dtol,it);
218:   CHKMEMQ;
219:   PetscStackPop;
220:   return(0);
221: }

225: static PetscErrorCode PCDestroy_Shell(PC pc)
226: {
227:   PC_Shell       *shell = (PC_Shell*)pc->data;

231:   PetscStrfree(shell->name);
232:   if (shell->destroy) {
233:     (*shell->destroy)(shell->ctx);
234:   }
235:   PetscFree(shell);
236:   return(0);
237: }

241: static PetscErrorCode PCView_Shell(PC pc,PetscViewer viewer)
242: {
243:   PC_Shell       *shell = (PC_Shell*)pc->data;
245:   PetscTruth     iascii;

248:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
249:   if (iascii) {
250:     if (shell->name) {PetscViewerASCIIPrintf(viewer,"  Shell: %s\n",shell->name);}
251:     else             {PetscViewerASCIIPrintf(viewer,"  Shell: no name\n");}
252:   }
253:   if (shell->view) {
254:     PetscViewerASCIIPushTab(viewer);
255:     (*shell->view)(shell->ctx,viewer);
256:     PetscViewerASCIIPopTab(viewer);
257:   }
258:   return(0);
259: }

261: /* ------------------------------------------------------------------------------*/
265: PetscErrorCode  PCShellSetDestroy_Shell(PC pc, PetscErrorCode (*destroy)(void*))
266: {
267:   PC_Shell *shell;

270:   shell          = (PC_Shell*)pc->data;
271:   shell->destroy = destroy;
272:   return(0);
273: }

279: PetscErrorCode  PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(void*))
280: {
281:   PC_Shell *shell;

284:   shell        = (PC_Shell*)pc->data;
285:   shell->setup = setup;
286:   if (setup) pc->ops->setup = PCSetUp_Shell;
287:   else       pc->ops->setup = 0;
288:   return(0);
289: }

295: PetscErrorCode  PCShellSetApply_Shell(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec))
296: {
297:   PC_Shell *shell;

300:   shell        = (PC_Shell*)pc->data;
301:   shell->apply = apply;
302:   return(0);
303: }

309: PetscErrorCode  PCShellSetApplyBA_Shell(PC pc,PetscErrorCode (*applyBA)(void*,PCSide,Vec,Vec,Vec))
310: {
311:   PC_Shell *shell;

314:   shell          = (PC_Shell*)pc->data;
315:   shell->applyBA = applyBA;
316:   if (applyBA) pc->ops->applyBA  = PCApplyBA_Shell;
317:   else         pc->ops->applyBA  = 0;
318:   return(0);
319: }

325: PetscErrorCode  PCShellSetPreSolve_Shell(PC pc,PetscErrorCode (*presolve)(void*,KSP,Vec,Vec))
326: {
327:   PC_Shell *shell;

330:   shell           = (PC_Shell*)pc->data;
331:   shell->presolve = presolve;
332:   if (presolve) pc->ops->presolve = PCPreSolve_Shell;
333:   else          pc->ops->presolve = 0;
334:   return(0);
335: }

341: PetscErrorCode  PCShellSetPostSolve_Shell(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec))
342: {
343:   PC_Shell *shell;

346:   shell            = (PC_Shell*)pc->data;
347:   shell->postsolve = postsolve;
348:   if (postsolve) pc->ops->postsolve = PCPostSolve_Shell;
349:   else           pc->ops->postsolve = 0;
350:   return(0);
351: }

357: PetscErrorCode  PCShellSetView_Shell(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
358: {
359:   PC_Shell *shell;

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

371: PetscErrorCode  PCShellSetApplyTranspose_Shell(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
372: {
373:   PC_Shell *shell;

376:   shell                 = (PC_Shell*)pc->data;
377:   shell->applytranspose = applytranspose;
378:   if (applytranspose) pc->ops->applytranspose = PCApplyTranspose_Shell;
379:   else                pc->ops->applytranspose = 0;
380:   return(0);
381: }

387: PetscErrorCode  PCShellSetApplyRichardson_Shell(PC pc,PetscErrorCode (*applyrich)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt))
388: {
389:   PC_Shell *shell;

392:   shell            = (PC_Shell*)pc->data;
393:   shell->applyrich = applyrich;
394:   if (applyrich) pc->ops->applyrichardson  = PCApplyRichardson_Shell;
395:   else           pc->ops->applyrichardson  = 0;
396:   return(0);
397: }

403: PetscErrorCode  PCShellSetName_Shell(PC pc,const char name[])
404: {
405:   PC_Shell       *shell;

409:   shell = (PC_Shell*)pc->data;
410:   PetscStrfree(shell->name);
411:   PetscStrallocpy(name,&shell->name);
412:   return(0);
413: }

419: PetscErrorCode  PCShellGetName_Shell(PC pc,char *name[])
420: {
421:   PC_Shell *shell;

424:   shell  = (PC_Shell*)pc->data;
425:   *name  = shell->name;
426:   return(0);
427: }

430: /* -------------------------------------------------------------------------------*/

434: /*@C
435:    PCShellSetDestroy - Sets routine to use to destroy the user-provided 
436:    application context.

438:    Collective on PC

440:    Input Parameters:
441: +  pc - the preconditioner context
442: .  destroy - the application-provided destroy routine

444:    Calling sequence of destroy:
445: .vb
446:    PetscErrorCode destroy (void *ptr)
447: .ve

449: .  ptr - the application context

451:    Level: developer

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

455: .seealso: PCShellSetApply(), PCShellSetContext()
456: @*/
457: PetscErrorCode  PCShellSetDestroy(PC pc,PetscErrorCode (*destroy)(void*))
458: {
459:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*));

463:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetDestroy_C",(void (**)(void))&f);
464:   if (f) {
465:     (*f)(pc,destroy);
466:   }
467:   return(0);
468: }


473: /*@C
474:    PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the 
475:    matrix operator is changed.

477:    Collective on PC

479:    Input Parameters:
480: +  pc - the preconditioner context
481: .  setup - the application-provided setup routine

483:    Calling sequence of setup:
484: .vb
485:    PetscErrorCode setup (void *ptr)
486: .ve

488: .  ptr - the application context

490:    Level: developer

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

494: .seealso: PCShellSetApplyRichardson(), PCShellSetApply(), PCShellSetContext()
495: @*/
496: PetscErrorCode  PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(void*))
497: {
498:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*));

502:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)(void))&f);
503:   if (f) {
504:     (*f)(pc,setup);
505:   }
506:   return(0);
507: }


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

515:    Collective on PC

517:    Input Parameters:
518: +  pc - the preconditioner context
519: -  view - the application-provided view routine

521:    Calling sequence of apply:
522: .vb
523:    PetscErrorCode view(void *ptr,PetscViewer v)
524: .ve

526: +  ptr - the application context
527: -  v   - viewer

529:    Level: developer

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

533: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
534: @*/
535: PetscErrorCode  PCShellSetView(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
536: {
537:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PetscViewer));

541:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetView_C",(void (**)(void))&f);
542:   if (f) {
543:     (*f)(pc,view);
544:   }
545:   return(0);
546: }

550: /*@C
551:    PCShellSetApply - Sets routine to use as preconditioner.

553:    Collective on PC

555:    Input Parameters:
556: +  pc - the preconditioner context
557: -  apply - the application-provided preconditioning routine

559:    Calling sequence of apply:
560: .vb
561:    PetscErrorCode apply (void *ptr,Vec xin,Vec xout)
562: .ve

564: +  ptr - the application context
565: .  xin - input vector
566: -  xout - output vector

568:    Level: developer

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

572: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApplyBA()
573: @*/
574: PetscErrorCode  PCShellSetApply(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec))
575: {
576:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));

580:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)(void))&f);
581:   if (f) {
582:     (*f)(pc,apply);
583:   }
584:   return(0);
585: }

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

592:    Collective on PC

594:    Input Parameters:
595: +  pc - the preconditioner context
596: -  applyBA - the application-provided BA routine

598:    Calling sequence of apply:
599: .vb
600:    PetscErrorCode applyBA (void *ptr,Vec xin,Vec xout)
601: .ve

603: +  ptr - the application context
604: .  xin - input vector
605: -  xout - output vector

607:    Level: developer

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

611: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApply()
612: @*/
613: PetscErrorCode  PCShellSetApplyBA(PC pc,PetscErrorCode (*applyBA)(void*,PCSide,Vec,Vec,Vec))
614: {
615:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PCSide,Vec,Vec,Vec));

619:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyBA_C",(void (**)(void))&f);
620:   if (f) {
621:     (*f)(pc,applyBA);
622:   }
623:   return(0);
624: }

628: /*@C
629:    PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.

631:    Collective on PC

633:    Input Parameters:
634: +  pc - the preconditioner context
635: -  apply - the application-provided preconditioning transpose routine

637:    Calling sequence of apply:
638: .vb
639:    PetscErrorCode applytranspose (void *ptr,Vec xin,Vec xout)
640: .ve

642: +  ptr - the application context
643: .  xin - input vector
644: -  xout - output vector

646:    Level: developer

648:    Notes: 
649:    Uses the same context variable as PCShellSetApply().

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

653: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply(), PCSetContext(), PCShellSetApplyBA()
654: @*/
655: PetscErrorCode  PCShellSetApplyTranspose(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
656: {
657:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));

661:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)(void))&f);
662:   if (f) {
663:     (*f)(pc,applytranspose);
664:   }
665:   return(0);
666: }

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

675:    Collective on PC

677:    Input Parameters:
678: +  pc - the preconditioner context
679: -  presolve - the application-provided presolve routine

681:    Calling sequence of presolve:
682: .vb
683:    PetscErrorCode presolve (void *ptr,KSP ksp,Vec b,Vec x)
684: .ve

686: +  ptr - the application context
687: .  xin - input vector
688: -  xout - output vector

690:    Level: developer

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

694: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPostSolve(), PCShellSetContext()
695: @*/
696: PetscErrorCode  PCShellSetPreSolve(PC pc,PetscErrorCode (*presolve)(void*,KSP,Vec,Vec))
697: {
698:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));

702:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPreSolve_C",(void (**)(void))&f);
703:   if (f) {
704:     (*f)(pc,presolve);
705:   }
706:   return(0);
707: }

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

716:    Collective on PC

718:    Input Parameters:
719: +  pc - the preconditioner context
720: -  postsolve - the application-provided presolve routine

722:    Calling sequence of postsolve:
723: .vb
724:    PetscErrorCode postsolve(void *ptr,KSP ksp,Vec b,Vec x)
725: .ve

727: +  ptr - the application context
728: .  xin - input vector
729: -  xout - output vector

731:    Level: developer

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

735: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPreSolve(), PCShellSetContext()
736: @*/
737: PetscErrorCode  PCShellSetPostSolve(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec))
738: {
739:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));

743:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPostSolve_C",(void (**)(void))&f);
744:   if (f) {
745:     (*f)(pc,postsolve);
746:   }
747:   return(0);
748: }

752: /*@C
753:    PCShellSetName - Sets an optional name to associate with a shell
754:    preconditioner.

756:    Not Collective

758:    Input Parameters:
759: +  pc - the preconditioner context
760: -  name - character string describing shell preconditioner

762:    Level: developer

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

766: .seealso: PCShellGetName()
767: @*/
768: PetscErrorCode  PCShellSetName(PC pc,const char name[])
769: {
770:   PetscErrorCode ierr,(*f)(PC,const char []);

774:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)(void))&f);
775:   if (f) {
776:     (*f)(pc,name);
777:   }
778:   return(0);
779: }

783: /*@C
784:    PCShellGetName - Gets an optional name that the user has set for a shell
785:    preconditioner.

787:    Not Collective

789:    Input Parameter:
790: .  pc - the preconditioner context

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

795:    Level: developer

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

799: .seealso: PCShellSetName()
800: @*/
801: PetscErrorCode  PCShellGetName(PC pc,char *name[])
802: {
803:   PetscErrorCode ierr,(*f)(PC,char *[]);

808:   PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)(void))&f);
809:   if (f) {
810:     (*f)(pc,name);
811:   } else {
812:     SETERRQ(PETSC_ERR_ARG_WRONG,"Not shell preconditioner, cannot get name");
813:   }
814:   return(0);
815: }

819: /*@C
820:    PCShellSetApplyRichardson - Sets routine to use as preconditioner
821:    in Richardson iteration.

823:    Collective on PC

825:    Input Parameters:
826: +  pc - the preconditioner context
827: -  apply - the application-provided preconditioning routine

829:    Calling sequence of apply:
830: .vb
831:    PetscErrorCode apply (void *ptr,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits)
832: .ve

834: +  ptr - the application context
835: .  b - right-hand-side
836: .  x - current iterate
837: .  r - work space
838: .  rtol - relative tolerance of residual norm to stop at
839: .  abstol - absolute tolerance of residual norm to stop at
840: .  dtol - if residual norm increases by this factor than return
841: -  maxits - number of iterations to run

843:    Level: developer

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

847: .seealso: PCShellSetApply(), PCShellSetContext()
848: @*/
849: PetscErrorCode  PCShellSetApplyRichardson(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt))
850: {
851:   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt));

855:   PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)(void))&f);
856:   if (f) {
857:     (*f)(pc,apply);
858:   }
859:   return(0);
860: }

862: /*MC
863:    PCSHELL - Creates a new preconditioner class for use with your 
864:               own private data storage format.

866:    Level: advanced
867: >
868:    Concepts: providing your own preconditioner

870:   Usage:
871: $             PetscErrorCode (*mult)(void*,Vec,Vec);
872: $             PetscErrorCode (*setup)(void*);
873: $             PCCreate(comm,&pc);
874: $             PCSetType(pc,PCSHELL);
875: $             PCShellSetApply(pc,apply);
876: $             PCShellSetApplyBA(pc,apply); (optional)
877: $             PCShellSetApplyTranspose(pc,apply); (optional)
878: $             PCShellSetContext(pc,ctx)
879: $             PCShellSetSetUp(pc,setup); (optional)
880: $             PCShellSetDestroy(pc,destroy); (optional)

882: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
883:            MATSHELL, PCShellSetSetUp(), PCShellSetApply(), PCShellSetView(), 
884:            PCShellSetApplyTranspose(), PCShellSetName(), PCShellSetApplyRichardson(), 
885:            PCShellGetName(), PCShellSetContext(), PCShellGetContext(), PCShellSetApplyBA()
886: M*/

891: PetscErrorCode  PCCreate_Shell(PC pc)
892: {
894:   PC_Shell       *shell;

897:   PetscNew(PC_Shell,&shell);
898:   PetscLogObjectMemory(pc,sizeof(PC_Shell));
899:   pc->data         = (void*)shell;
900:   pc->name         = 0;

902:   pc->ops->destroy         = PCDestroy_Shell;
903:   pc->ops->view            = PCView_Shell;
904:   pc->ops->apply           = PCApply_Shell;
905:   pc->ops->applytranspose  = 0;
906:   pc->ops->applyrichardson = 0;
907:   pc->ops->setup           = 0;
908:   pc->ops->presolve        = 0;
909:   pc->ops->postsolve       = 0;

911:   shell->apply          = 0;
912:   shell->applytranspose = 0;
913:   shell->name           = 0;
914:   shell->applyrich      = 0;
915:   shell->presolve       = 0;
916:   shell->postsolve      = 0;
917:   shell->ctx            = 0;
918:   shell->setup          = 0;
919:   shell->view           = 0;
920:   shell->destroy        = 0;

922:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetDestroy_C","PCShellSetDestroy_Shell",
923:                     PCShellSetDestroy_Shell);
924:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell",
925:                     PCShellSetSetUp_Shell);
926:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell",
927:                     PCShellSetApply_Shell);
928:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyBA_C","PCShellSetApplyBA_Shell",
929:                     PCShellSetApplyBA_Shell);
930:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPreSolve_C","PCShellSetPreSolve_Shell",
931:                     PCShellSetPreSolve_Shell);
932:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPostSolve_C","PCShellSetPostSolve_Shell",
933:                     PCShellSetPostSolve_Shell);
934:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell",
935:                     PCShellSetView_Shell);
936:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C","PCShellSetApplyTranspose_Shell",
937:                     PCShellSetApplyTranspose_Shell);
938:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell",
939:                     PCShellSetName_Shell);
940:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell",
941:                     PCShellGetName_Shell);
942:   PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C","PCShellSetApplyRichardson_Shell",
943:                     PCShellSetApplyRichardson_Shell);
944:   return(0);
945: }