Actual source code: shellpc.c
 
   petsc-3.7.7 2017-09-25
   
  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 (*applysymmetricleft)(PC,Vec,Vec);
 17:   PetscErrorCode (*applysymmetricright)(PC,Vec,Vec);
 18:   PetscErrorCode (*applyBA)(PC,PCSide,Vec,Vec,Vec);
 19:   PetscErrorCode (*presolve)(PC,KSP,Vec,Vec);
 20:   PetscErrorCode (*postsolve)(PC,KSP,Vec,Vec);
 21:   PetscErrorCode (*view)(PC,PetscViewer);
 22:   PetscErrorCode (*applytranspose)(PC,Vec,Vec);
 23:   PetscErrorCode (*applyrich)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool,PetscInt*,PCRichardsonConvergedReason*);
 25:   char *name;
 26: } PC_Shell;
 30: /*@C
 31:     PCShellGetContext - Returns the user-provided context associated with a shell PC
 33:     Not Collective
 35:     Input Parameter:
 36: .   pc - should have been created with PCSetType(pc,shell)
 38:     Output Parameter:
 39: .   ctx - the user provided context
 41:     Level: advanced
 43:     Notes:
 44:     This routine is intended for use within various shell routines
 46:    Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this
 47:     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
 49: .keywords: PC, shell, get, context
 51: .seealso: PCShellSetContext()
 52: @*/
 53: PetscErrorCode  PCShellGetContext(PC pc,void **ctx)
 54: {
 56:   PetscBool      flg;
 61:   PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&flg);
 62:   if (!flg) *ctx = 0;
 63:   else      *ctx = ((PC_Shell*)(pc->data))->ctx;
 64:   return(0);
 65: }
 69: /*@
 70:     PCShellSetContext - sets the context for a shell PC
 72:    Logically Collective on PC
 74:     Input Parameters:
 75: +   pc - the shell PC
 76: -   ctx - the context
 78:    Level: advanced
 80:    Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this
 81:     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
 85: .seealso: PCShellGetContext(), PCSHELL
 86: @*/
 87: PetscErrorCode  PCShellSetContext(PC pc,void *ctx)
 88: {
 89:   PC_Shell       *shell = (PC_Shell*)pc->data;
 91:   PetscBool      flg;
 95:   PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&flg);
 96:   if (flg) shell->ctx = ctx;
 97:   return(0);
 98: }
102: static PetscErrorCode PCSetUp_Shell(PC pc)
103: {
104:   PC_Shell       *shell = (PC_Shell*)pc->data;
108:   if (!shell->setup) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No setup() routine provided to Shell PC");
109:   PetscStackCall("PCSHELL user function setup()",(*shell->setup)(pc);CHKERRQ(ierr));
110:   return(0);
111: }
115: static PetscErrorCode PCApply_Shell(PC pc,Vec x,Vec y)
116: {
117:   PC_Shell         *shell = (PC_Shell*)pc->data;
118:   PetscErrorCode   ierr;
119:   PetscObjectState instate,outstate;
122:   if (!shell->apply) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No apply() routine provided to Shell PC");
123:   PetscObjectStateGet((PetscObject)y, &instate);
124:   PetscStackCall("PCSHELL user function apply()",(*shell->apply)(pc,x,y);CHKERRQ(ierr));
125:   PetscObjectStateGet((PetscObject)y, &outstate);
126:   if (instate == outstate) {
127:     /* increase the state of the output vector since the user did not update its state themselve as should have been done */
128:     PetscObjectStateIncrease((PetscObject)y);
129:   }
130:   return(0);
131: }
135: static PetscErrorCode PCApplySymmetricLeft_Shell(PC pc,Vec x,Vec y)
136: {
137:   PC_Shell       *shell = (PC_Shell*)pc->data;
141:   if (!shell->applysymmetricleft) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No apply() routine provided to Shell PC");
142:   PetscStackCall("PCSHELL user function apply()",(*shell->applysymmetricleft)(pc,x,y);CHKERRQ(ierr));
143:   return(0);
144: }
148: static PetscErrorCode PCApplySymmetricRight_Shell(PC pc,Vec x,Vec y)
149: {
150:   PC_Shell       *shell = (PC_Shell*)pc->data;
154:   if (!shell->applysymmetricright) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No apply() routine provided to Shell PC");
155:   PetscStackCall("PCSHELL user function apply()",(*shell->applysymmetricright)(pc,x,y);CHKERRQ(ierr));
156:   return(0);
157: }
161: static PetscErrorCode PCApplyBA_Shell(PC pc,PCSide side,Vec x,Vec y,Vec w)
162: {
163:   PC_Shell         *shell = (PC_Shell*)pc->data;
164:   PetscErrorCode   ierr;
165:   PetscObjectState instate,outstate;
168:   if (!shell->applyBA) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No applyBA() routine provided to Shell PC");
169:   PetscObjectStateGet((PetscObject)w, &instate);
170:   PetscStackCall("PCSHELL user function applyBA()",(*shell->applyBA)(pc,side,x,y,w);CHKERRQ(ierr));
171:   PetscObjectStateGet((PetscObject)w, &outstate);
172:   if (instate == outstate) {
173:     /* increase the state of the output vector since the user did not update its state themselve as should have been done */
174:     PetscObjectStateIncrease((PetscObject)w);
175:   }
176:   return(0);
177: }
181: static PetscErrorCode PCPreSolveChangeRHS_Shell(PC pc,PetscBool* change)
182: {
184:   *change = PETSC_TRUE;
185:   return(0);
186: }
190: static PetscErrorCode PCPreSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
191: {
192:   PC_Shell       *shell = (PC_Shell*)pc->data;
196:   if (!shell->presolve) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No presolve() routine provided to Shell PC");
197:   PetscStackCall("PCSHELL user function presolve()",(*shell->presolve)(pc,ksp,b,x);CHKERRQ(ierr));
198:   return(0);
199: }
203: static PetscErrorCode PCPostSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
204: {
205:   PC_Shell       *shell = (PC_Shell*)pc->data;
209:   if (!shell->postsolve) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No postsolve() routine provided to Shell PC");
210:   PetscStackCall("PCSHELL user function postsolve()",(*shell->postsolve)(pc,ksp,b,x);CHKERRQ(ierr));
211:   return(0);
212: }
216: static PetscErrorCode PCApplyTranspose_Shell(PC pc,Vec x,Vec y)
217: {
218:   PC_Shell         *shell = (PC_Shell*)pc->data;
219:   PetscErrorCode   ierr;
220:   PetscObjectState instate,outstate;
223:   if (!shell->applytranspose) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No applytranspose() routine provided to Shell PC");
224:   PetscObjectStateGet((PetscObject)y, &instate);
225:   PetscStackCall("PCSHELL user function applytranspose()",(*shell->applytranspose)(pc,x,y);CHKERRQ(ierr));
226:   PetscObjectStateGet((PetscObject)y, &outstate);
227:   if (instate == outstate) {
228:     /* increase the state of the output vector since the user did not update its state themself as should have been done */
229:     PetscObjectStateIncrease((PetscObject)y);
230:   }
231:   return(0);
232: }
236: 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)
237: {
238:   PetscErrorCode   ierr;
239:   PC_Shell         *shell = (PC_Shell*)pc->data;
240:   PetscObjectState instate,outstate;
243:   if (!shell->applyrich) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"No applyrichardson() routine provided to Shell PC");
244:   PetscObjectStateGet((PetscObject)y, &instate);
245:   PetscStackCall("PCSHELL user function applyrichardson()",(*shell->applyrich)(pc,x,y,w,rtol,abstol,dtol,it,guesszero,outits,reason);CHKERRQ(ierr));
246:   PetscObjectStateGet((PetscObject)y, &outstate);
247:   if (instate == outstate) {
248:     /* increase the state of the output vector since the user did not update its state themself as should have been done */
249:     PetscObjectStateIncrease((PetscObject)y);
250:   }
251:   return(0);
252: }
256: static PetscErrorCode PCDestroy_Shell(PC pc)
257: {
258:   PC_Shell       *shell = (PC_Shell*)pc->data;
262:   PetscFree(shell->name);
263:   if (shell->destroy) PetscStackCall("PCSHELL user function destroy()",(*shell->destroy)(pc);CHKERRQ(ierr));
264:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetDestroy_C",NULL);
265:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetSetUp_C",NULL);
266:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApply_C",NULL);
267:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApplySymmetricLeft_C",NULL);
268:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApplySymmetricRight_C",NULL);
269:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApplyBA_C",NULL);
270:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetPreSolve_C",NULL);
271:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetPostSolve_C",NULL);
272:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetView_C",NULL);
273:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",NULL);
274:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetName_C",NULL);
275:   PetscObjectComposeFunction((PetscObject)pc,"PCShellGetName_C",NULL);
276:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",NULL);
277:   PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",NULL);
278:   PetscFree(pc->data);
279:   return(0);
280: }
284: static PetscErrorCode PCView_Shell(PC pc,PetscViewer viewer)
285: {
286:   PC_Shell       *shell = (PC_Shell*)pc->data;
288:   PetscBool      iascii;
291:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
292:   if (iascii) {
293:     if (shell->name) {
294:       PetscViewerASCIIPrintf(viewer,"  Shell: %s\n",shell->name);
295:     } else {
296:       PetscViewerASCIIPrintf(viewer,"  Shell: no name\n");
297:     }
298:   }
299:   if (shell->view) {
300:     PetscViewerASCIIPushTab(viewer);
301:     (*shell->view)(pc,viewer);
302:     PetscViewerASCIIPopTab(viewer);
303:   }
304:   return(0);
305: }
307: /* ------------------------------------------------------------------------------*/
310: static PetscErrorCode  PCShellSetDestroy_Shell(PC pc, PetscErrorCode (*destroy)(PC))
311: {
312:   PC_Shell *shell= (PC_Shell*)pc->data;
315:   shell->destroy = destroy;
316:   return(0);
317: }
321: static PetscErrorCode  PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(PC))
322: {
323:   PC_Shell *shell = (PC_Shell*)pc->data;;
326:   shell->setup = setup;
327:   if (setup) pc->ops->setup = PCSetUp_Shell;
328:   else       pc->ops->setup = 0;
329:   return(0);
330: }
334: static PetscErrorCode  PCShellSetApply_Shell(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec))
335: {
336:   PC_Shell *shell = (PC_Shell*)pc->data;
339:   shell->apply = apply;
340:   return(0);
341: }
345: static PetscErrorCode  PCShellSetApplySymmetricLeft_Shell(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec))
346: {
347:   PC_Shell *shell = (PC_Shell*)pc->data;
350:   shell->applysymmetricleft = apply;
351:   return(0);
352: }
356: static PetscErrorCode  PCShellSetApplySymmetricRight_Shell(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec))
357: {
358:   PC_Shell *shell = (PC_Shell*)pc->data;
361:   shell->applysymmetricright = apply;
362:   return(0);
363: }
367: static PetscErrorCode  PCShellSetApplyBA_Shell(PC pc,PetscErrorCode (*applyBA)(PC,PCSide,Vec,Vec,Vec))
368: {
369:   PC_Shell *shell = (PC_Shell*)pc->data;
372:   shell->applyBA = applyBA;
373:   if (applyBA) pc->ops->applyBA  = PCApplyBA_Shell;
374:   else         pc->ops->applyBA  = 0;
375:   return(0);
376: }
380: static PetscErrorCode  PCShellSetPreSolve_Shell(PC pc,PetscErrorCode (*presolve)(PC,KSP,Vec,Vec))
381: {
382:   PC_Shell       *shell = (PC_Shell*)pc->data;
386:   shell->presolve = presolve;
387:   if (presolve) {
388:     pc->ops->presolve = PCPreSolve_Shell;
389:     PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",PCPreSolveChangeRHS_Shell);
390:   } else {
391:     pc->ops->presolve = 0;
392:     PetscObjectComposeFunction((PetscObject)pc,"PCPreSolveChangeRHS_C",NULL);
393:   }
394:   return(0);
395: }
399: static PetscErrorCode  PCShellSetPostSolve_Shell(PC pc,PetscErrorCode (*postsolve)(PC,KSP,Vec,Vec))
400: {
401:   PC_Shell *shell = (PC_Shell*)pc->data;
404:   shell->postsolve = postsolve;
405:   if (postsolve) pc->ops->postsolve = PCPostSolve_Shell;
406:   else           pc->ops->postsolve = 0;
407:   return(0);
408: }
412: static PetscErrorCode  PCShellSetView_Shell(PC pc,PetscErrorCode (*view)(PC,PetscViewer))
413: {
414:   PC_Shell *shell = (PC_Shell*)pc->data;
417:   shell->view = view;
418:   return(0);
419: }
423: static PetscErrorCode  PCShellSetApplyTranspose_Shell(PC pc,PetscErrorCode (*applytranspose)(PC,Vec,Vec))
424: {
425:   PC_Shell *shell = (PC_Shell*)pc->data;
428:   shell->applytranspose = applytranspose;
429:   if (applytranspose) pc->ops->applytranspose = PCApplyTranspose_Shell;
430:   else                pc->ops->applytranspose = 0;
431:   return(0);
432: }
436: static PetscErrorCode  PCShellSetApplyRichardson_Shell(PC pc,PetscErrorCode (*applyrich)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool ,PetscInt*,PCRichardsonConvergedReason*))
437: {
438:   PC_Shell *shell = (PC_Shell*)pc->data;
441:   shell->applyrich = applyrich;
442:   if (applyrich) pc->ops->applyrichardson = PCApplyRichardson_Shell;
443:   else           pc->ops->applyrichardson = 0;
444:   return(0);
445: }
449: static PetscErrorCode  PCShellSetName_Shell(PC pc,const char name[])
450: {
451:   PC_Shell       *shell = (PC_Shell*)pc->data;
455:   PetscFree(shell->name);
456:   PetscStrallocpy(name,&shell->name);
457:   return(0);
458: }
462: static PetscErrorCode  PCShellGetName_Shell(PC pc,const char *name[])
463: {
464:   PC_Shell *shell = (PC_Shell*)pc->data;
467:   *name = shell->name;
468:   return(0);
469: }
471: /* -------------------------------------------------------------------------------*/
475: /*@C
476:    PCShellSetDestroy - Sets routine to use to destroy the user-provided
477:    application context.
479:    Logically Collective on PC
481:    Input Parameters:
482: +  pc - the preconditioner context
483: .  destroy - the application-provided destroy routine
485:    Calling sequence of destroy:
486: .vb
487:    PetscErrorCode destroy (PC)
488: .ve
490: .  ptr - the application context
492:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
494:    Level: developer
496: .keywords: PC, shell, set, destroy, user-provided
498: .seealso: PCShellSetApply(), PCShellSetContext()
499: @*/
500: PetscErrorCode  PCShellSetDestroy(PC pc,PetscErrorCode (*destroy)(PC))
501: {
506:   PetscTryMethod(pc,"PCShellSetDestroy_C",(PC,PetscErrorCode (*)(PC)),(pc,destroy));
507:   return(0);
508: }
513: /*@C
514:    PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
515:    matrix operator is changed.
517:    Logically Collective on PC
519:    Input Parameters:
520: +  pc - the preconditioner context
521: .  setup - the application-provided setup routine
523:    Calling sequence of setup:
524: .vb
525:    PetscErrorCode setup (PC pc)
526: .ve
528: .  pc - the preconditioner, get the application context with PCShellGetContext()
530:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
532:    Level: developer
534: .keywords: PC, shell, set, setup, user-provided
536: .seealso: PCShellSetApplyRichardson(), PCShellSetApply(), PCShellSetContext()
537: @*/
538: PetscErrorCode  PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(PC))
539: {
544:   PetscTryMethod(pc,"PCShellSetSetUp_C",(PC,PetscErrorCode (*)(PC)),(pc,setup));
545:   return(0);
546: }
551: /*@C
552:    PCShellSetView - Sets routine to use as viewer of shell preconditioner
554:    Logically Collective on PC
556:    Input Parameters:
557: +  pc - the preconditioner context
558: -  view - the application-provided view routine
560:    Calling sequence of apply:
561: .vb
562:    PetscErrorCode view(PC pc,PetscViewer v)
563: .ve
565: +  pc - the preconditioner, get the application context with PCShellGetContext()
566: -  v   - viewer
568:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
570:    Level: developer
572: .keywords: PC, shell, set, apply, user-provided
574: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
575: @*/
576: PetscErrorCode  PCShellSetView(PC pc,PetscErrorCode (*view)(PC,PetscViewer))
577: {
582:   PetscTryMethod(pc,"PCShellSetView_C",(PC,PetscErrorCode (*)(PC,PetscViewer)),(pc,view));
583:   return(0);
584: }
588: /*@C
589:    PCShellSetApply - Sets routine to use as preconditioner.
591:    Logically Collective on PC
593:    Input Parameters:
594: +  pc - the preconditioner context
595: -  apply - the application-provided preconditioning routine
597:    Calling sequence of apply:
598: .vb
599:    PetscErrorCode apply (PC pc,Vec xin,Vec xout)
600: .ve
602: +  pc - the preconditioner, get the application context with PCShellGetContext()
603: .  xin - input vector
604: -  xout - output vector
606:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
608:    Level: developer
610: .keywords: PC, shell, set, apply, user-provided
612: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApplyBA(), PCShellSetApplySymmetricRight(),PCShellSetApplySymmetricLeft()
613: @*/
614: PetscErrorCode  PCShellSetApply(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec))
615: {
620:   PetscTryMethod(pc,"PCShellSetApply_C",(PC,PetscErrorCode (*)(PC,Vec,Vec)),(pc,apply));
621:   return(0);
622: }
626: /*@C
627:    PCShellSetApplySymmetricLeft - Sets routine to use as left preconditioner (when the PC_SYMMETRIC is used).
629:    Logically Collective on PC
631:    Input Parameters:
632: +  pc - the preconditioner context
633: -  apply - the application-provided left preconditioning routine
635:    Calling sequence of apply:
636: .vb
637:    PetscErrorCode apply (PC pc,Vec xin,Vec xout)
638: .ve
640: +  pc - the preconditioner, get the application context with PCShellGetContext()
641: .  xin - input vector
642: -  xout - output vector
644:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
646:    Level: developer
648: .keywords: PC, shell, set, apply, user-provided
650: .seealso: PCShellSetApply(), PCShellSetApplySymmetricLeft(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext()
651: @*/
652: PetscErrorCode  PCShellSetApplySymmetricLeft(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec))
653: {
658:   PetscTryMethod(pc,"PCShellSetApplySymmetricLeft_C",(PC,PetscErrorCode (*)(PC,Vec,Vec)),(pc,apply));
659:   return(0);
660: }
664: /*@C
665:    PCShellSetApplySymmetricRight - Sets routine to use as right preconditioner (when the PC_SYMMETRIC is used).
667:    Logically Collective on PC
669:    Input Parameters:
670: +  pc - the preconditioner context
671: -  apply - the application-provided right preconditioning routine
673:    Calling sequence of apply:
674: .vb
675:    PetscErrorCode apply (PC pc,Vec xin,Vec xout)
676: .ve
678: +  pc - the preconditioner, get the application context with PCShellGetContext()
679: .  xin - input vector
680: -  xout - output vector
682:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
684:    Level: developer
686: .keywords: PC, shell, set, apply, user-provided
688: .seealso: PCShellSetApply(), PCShellSetApplySymmetricLeft(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext()
689: @*/
690: PetscErrorCode  PCShellSetApplySymmetricRight(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec))
691: {
696:   PetscTryMethod(pc,"PCShellSetApplySymmetricRight_C",(PC,PetscErrorCode (*)(PC,Vec,Vec)),(pc,apply));
697:   return(0);
698: }
702: /*@C
703:    PCShellSetApplyBA - Sets routine to use as preconditioner times operator.
705:    Logically Collective on PC
707:    Input Parameters:
708: +  pc - the preconditioner context
709: -  applyBA - the application-provided BA routine
711:    Calling sequence of apply:
712: .vb
713:    PetscErrorCode applyBA (PC pc,Vec xin,Vec xout)
714: .ve
716: +  pc - the preconditioner, get the application context with PCShellGetContext()
717: .  xin - input vector
718: -  xout - output vector
720:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
722:    Level: developer
724: .keywords: PC, shell, set, apply, user-provided
726: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApply()
727: @*/
728: PetscErrorCode  PCShellSetApplyBA(PC pc,PetscErrorCode (*applyBA)(PC,PCSide,Vec,Vec,Vec))
729: {
734:   PetscTryMethod(pc,"PCShellSetApplyBA_C",(PC,PetscErrorCode (*)(PC,PCSide,Vec,Vec,Vec)),(pc,applyBA));
735:   return(0);
736: }
740: /*@C
741:    PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
743:    Logically Collective on PC
745:    Input Parameters:
746: +  pc - the preconditioner context
747: -  apply - the application-provided preconditioning transpose routine
749:    Calling sequence of apply:
750: .vb
751:    PetscErrorCode applytranspose (PC pc,Vec xin,Vec xout)
752: .ve
754: +  pc - the preconditioner, get the application context with PCShellGetContext()
755: .  xin - input vector
756: -  xout - output vector
758:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
760:    Level: developer
762:    Notes:
763:    Uses the same context variable as PCShellSetApply().
765: .keywords: PC, shell, set, apply, user-provided
767: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply(), PCSetContext(), PCShellSetApplyBA()
768: @*/
769: PetscErrorCode  PCShellSetApplyTranspose(PC pc,PetscErrorCode (*applytranspose)(PC,Vec,Vec))
770: {
775:   PetscTryMethod(pc,"PCShellSetApplyTranspose_C",(PC,PetscErrorCode (*)(PC,Vec,Vec)),(pc,applytranspose));
776:   return(0);
777: }
781: /*@C
782:    PCShellSetPreSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
783:       applied. This usually does something like scale the linear system in some application
784:       specific way.
786:    Logically Collective on PC
788:    Input Parameters:
789: +  pc - the preconditioner context
790: -  presolve - the application-provided presolve routine
792:    Calling sequence of presolve:
793: .vb
794:    PetscErrorCode presolve (PC,KSP ksp,Vec b,Vec x)
795: .ve
797: +  pc - the preconditioner, get the application context with PCShellGetContext()
798: .  xin - input vector
799: -  xout - output vector
801:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
803:    Level: developer
805: .keywords: PC, shell, set, apply, user-provided
807: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPostSolve(), PCShellSetContext()
808: @*/
809: PetscErrorCode  PCShellSetPreSolve(PC pc,PetscErrorCode (*presolve)(PC,KSP,Vec,Vec))
810: {
815:   PetscTryMethod(pc,"PCShellSetPreSolve_C",(PC,PetscErrorCode (*)(PC,KSP,Vec,Vec)),(pc,presolve));
816:   return(0);
817: }
821: /*@C
822:    PCShellSetPostSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
823:       applied. This usually does something like scale the linear system in some application
824:       specific way.
826:    Logically Collective on PC
828:    Input Parameters:
829: +  pc - the preconditioner context
830: -  postsolve - the application-provided presolve routine
832:    Calling sequence of postsolve:
833: .vb
834:    PetscErrorCode postsolve(PC,KSP ksp,Vec b,Vec x)
835: .ve
837: +  pc - the preconditioner, get the application context with PCShellGetContext()
838: .  xin - input vector
839: -  xout - output vector
841:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
843:    Level: developer
845: .keywords: PC, shell, set, apply, user-provided
847: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPreSolve(), PCShellSetContext()
848: @*/
849: PetscErrorCode  PCShellSetPostSolve(PC pc,PetscErrorCode (*postsolve)(PC,KSP,Vec,Vec))
850: {
855:   PetscTryMethod(pc,"PCShellSetPostSolve_C",(PC,PetscErrorCode (*)(PC,KSP,Vec,Vec)),(pc,postsolve));
856:   return(0);
857: }
861: /*@C
862:    PCShellSetName - Sets an optional name to associate with a shell
863:    preconditioner.
865:    Not Collective
867:    Input Parameters:
868: +  pc - the preconditioner context
869: -  name - character string describing shell preconditioner
871:    Level: developer
873: .keywords: PC, shell, set, name, user-provided
875: .seealso: PCShellGetName()
876: @*/
877: PetscErrorCode  PCShellSetName(PC pc,const char name[])
878: {
883:   PetscTryMethod(pc,"PCShellSetName_C",(PC,const char []),(pc,name));
884:   return(0);
885: }
889: /*@C
890:    PCShellGetName - Gets an optional name that the user has set for a shell
891:    preconditioner.
893:    Not Collective
895:    Input Parameter:
896: .  pc - the preconditioner context
898:    Output Parameter:
899: .  name - character string describing shell preconditioner (you should not free this)
901:    Level: developer
903: .keywords: PC, shell, get, name, user-provided
905: .seealso: PCShellSetName()
906: @*/
907: PetscErrorCode  PCShellGetName(PC pc,const char *name[])
908: {
914:   PetscUseMethod(pc,"PCShellGetName_C",(PC,const char*[]),(pc,name));
915:   return(0);
916: }
920: /*@C
921:    PCShellSetApplyRichardson - Sets routine to use as preconditioner
922:    in Richardson iteration.
924:    Logically Collective on PC
926:    Input Parameters:
927: +  pc - the preconditioner context
928: -  apply - the application-provided preconditioning routine
930:    Calling sequence of apply:
931: .vb
932:    PetscErrorCode apply (PC pc,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits)
933: .ve
935: +  pc - the preconditioner, get the application context with PCShellGetContext()
936: .  b - right-hand-side
937: .  x - current iterate
938: .  r - work space
939: .  rtol - relative tolerance of residual norm to stop at
940: .  abstol - absolute tolerance of residual norm to stop at
941: .  dtol - if residual norm increases by this factor than return
942: -  maxits - number of iterations to run
944:    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
946:    Level: developer
948: .keywords: PC, shell, set, apply, Richardson, user-provided
950: .seealso: PCShellSetApply(), PCShellSetContext()
951: @*/
952: PetscErrorCode  PCShellSetApplyRichardson(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool,PetscInt*,PCRichardsonConvergedReason*))
953: {
958:   PetscTryMethod(pc,"PCShellSetApplyRichardson_C",(PC,PetscErrorCode (*)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool,PetscInt*,PCRichardsonConvergedReason*)),(pc,apply));
959:   return(0);
960: }
962: /*MC
963:    PCSHELL - Creates a new preconditioner class for use with your
964:               own private data storage format.
966:    Level: advanced
967: >
968:    Concepts: providing your own preconditioner
970:   Usage:
971: $             extern PetscErrorCode apply(PC,Vec,Vec);
972: $             extern PetscErrorCode applyba(PC,PCSide,Vec,Vec,Vec);
973: $             extern PetscErrorCode applytranspose(PC,Vec,Vec);
974: $             extern PetscErrorCode setup(PC);
975: $             extern PetscErrorCode destroy(PC);
976: $
977: $             PCCreate(comm,&pc);
978: $             PCSetType(pc,PCSHELL);
979: $             PCShellSetContext(pc,ctx)
980: $             PCShellSetApply(pc,apply);
981: $             PCShellSetApplyBA(pc,applyba);               (optional)
982: $             PCShellSetApplyTranspose(pc,applytranspose); (optional)
983: $             PCShellSetSetUp(pc,setup);                   (optional)
984: $             PCShellSetDestroy(pc,destroy);               (optional)
986: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
987:            MATSHELL, PCShellSetSetUp(), PCShellSetApply(), PCShellSetView(),
988:            PCShellSetApplyTranspose(), PCShellSetName(), PCShellSetApplyRichardson(),
989:            PCShellGetName(), PCShellSetContext(), PCShellGetContext(), PCShellSetApplyBA()
990: M*/
994: PETSC_EXTERN PetscErrorCode PCCreate_Shell(PC pc)
995: {
997:   PC_Shell       *shell;
1000:   PetscNewLog(pc,&shell);
1001:   pc->data = (void*)shell;
1003:   pc->ops->destroy         = PCDestroy_Shell;
1004:   pc->ops->view            = PCView_Shell;
1005:   pc->ops->apply           = PCApply_Shell;
1006:   pc->ops->applysymmetricleft  = PCApplySymmetricLeft_Shell;
1007:   pc->ops->applysymmetricright = PCApplySymmetricRight_Shell;
1008:   pc->ops->applytranspose  = 0;
1009:   pc->ops->applyrichardson = 0;
1010:   pc->ops->setup           = 0;
1011:   pc->ops->presolve        = 0;
1012:   pc->ops->postsolve       = 0;
1014:   shell->apply          = 0;
1015:   shell->applytranspose = 0;
1016:   shell->name           = 0;
1017:   shell->applyrich      = 0;
1018:   shell->presolve       = 0;
1019:   shell->postsolve      = 0;
1020:   shell->ctx            = 0;
1021:   shell->setup          = 0;
1022:   shell->view           = 0;
1023:   shell->destroy        = 0;
1024:   shell->applysymmetricleft  = 0;
1025:   shell->applysymmetricright = 0;
1027:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetDestroy_C",PCShellSetDestroy_Shell);
1028:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetSetUp_C",PCShellSetSetUp_Shell);
1029:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApply_C",PCShellSetApply_Shell);
1030:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApplySymmetricLeft_C",PCShellSetApplySymmetricLeft_Shell);
1031:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApplySymmetricRight_C",PCShellSetApplySymmetricRight_Shell);
1032:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApplyBA_C",PCShellSetApplyBA_Shell);
1033:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetPreSolve_C",PCShellSetPreSolve_Shell);
1034:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetPostSolve_C",PCShellSetPostSolve_Shell);
1035:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetView_C",PCShellSetView_Shell);
1036:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",PCShellSetApplyTranspose_Shell);
1037:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetName_C",PCShellSetName_Shell);
1038:   PetscObjectComposeFunction((PetscObject)pc,"PCShellGetName_C",PCShellGetName_Shell);
1039:   PetscObjectComposeFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",PCShellSetApplyRichardson_Shell);
1040:   return(0);
1041: }