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: }