Actual source code: shellpc.c
1: /*
2: This provides a simple shell for Fortran (and C programmers) to
3: create their own preconditioner without writing much interface code.
4: */
6: #include src/ksp/pc/pcimpl.h
7: #include vecimpl.h
10: typedef struct {
11: void *ctx,*ctxrich; /* user provided contexts for preconditioner */
12: PetscErrorCode (*setup)(void*);
13: PetscErrorCode (*apply)(void*,Vec,Vec);
14: PetscErrorCode (*view)(void*,PetscViewer);
15: PetscErrorCode (*applytranspose)(void*,Vec,Vec);
16: PetscErrorCode (*applyrich)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt);
17: char *name;
18: } PC_Shell;
23: static PetscErrorCode PCSetUp_Shell(PC pc)
24: {
25: PC_Shell *shell;
29: shell = (PC_Shell*)pc->data;
30: if (shell->setup) {
31: (*shell->setup)(shell->ctx);
32: }
33: return(0);
34: }
38: static PetscErrorCode PCApply_Shell(PC pc,Vec x,Vec y)
39: {
40: PC_Shell *shell;
44: shell = (PC_Shell*)pc->data;
45: if (!shell->apply) SETERRQ(PETSC_ERR_USER,"No apply() routine provided to Shell PC");
46: (*shell->apply)(shell->ctx,x,y);
47: return(0);
48: }
52: static PetscErrorCode PCApplyTranspose_Shell(PC pc,Vec x,Vec y)
53: {
54: PC_Shell *shell;
58: shell = (PC_Shell*)pc->data;
59: if (!shell->applytranspose) SETERRQ(PETSC_ERR_USER,"No applytranspose() routine provided to Shell PC");
60: (*shell->applytranspose)(shell->ctx,x,y);
61: return(0);
62: }
66: static PetscErrorCode PCApplyRichardson_Shell(PC pc,Vec x,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt it)
67: {
69: PC_Shell *shell;
72: shell = (PC_Shell*)pc->data;
73: (*shell->applyrich)(shell->ctxrich,x,y,w,rtol,abstol,dtol,it);
74: return(0);
75: }
79: static PetscErrorCode PCDestroy_Shell(PC pc)
80: {
81: PC_Shell *shell = (PC_Shell*)pc->data;
85: if (shell->name) {PetscFree(shell->name);}
86: PetscFree(shell);
87: return(0);
88: }
92: static PetscErrorCode PCView_Shell(PC pc,PetscViewer viewer)
93: {
94: PC_Shell *shell = (PC_Shell*)pc->data;
96: PetscTruth iascii;
99: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
100: if (iascii) {
101: if (shell->name) {PetscViewerASCIIPrintf(viewer," Shell: %s\n",shell->name);}
102: else {PetscViewerASCIIPrintf(viewer," Shell: no name\n");}
103: }
104: if (shell->view) {
105: PetscViewerASCIIPushTab(viewer);
106: (*shell->view)(shell->ctx,viewer);
107: PetscViewerASCIIPopTab(viewer);
108: }
109: return(0);
110: }
112: /* ------------------------------------------------------------------------------*/
116: PetscErrorCode PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(void*))
117: {
118: PC_Shell *shell;
121: shell = (PC_Shell*)pc->data;
122: shell->setup = setup;
123: return(0);
124: }
130: PetscErrorCode PCShellSetApply_Shell(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec),void *ptr)
131: {
132: PC_Shell *shell;
135: shell = (PC_Shell*)pc->data;
136: shell->apply = apply;
137: shell->ctx = ptr;
138: return(0);
139: }
145: PetscErrorCode PCShellSetView_Shell(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
146: {
147: PC_Shell *shell;
150: shell = (PC_Shell*)pc->data;
151: shell->view = view;
152: return(0);
153: }
159: PetscErrorCode PCShellSetApplyTranspose_Shell(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
160: {
161: PC_Shell *shell;
164: shell = (PC_Shell*)pc->data;
165: shell->applytranspose = applytranspose;
166: return(0);
167: }
173: PetscErrorCode PCShellSetName_Shell(PC pc,const char name[])
174: {
175: PC_Shell *shell;
179: shell = (PC_Shell*)pc->data;
180: PetscStrallocpy(name,&shell->name);
181: return(0);
182: }
188: PetscErrorCode PCShellGetName_Shell(PC pc,char *name[])
189: {
190: PC_Shell *shell;
193: shell = (PC_Shell*)pc->data;
194: *name = shell->name;
195: return(0);
196: }
202: PetscErrorCode PCShellSetApplyRichardson_Shell(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt),void *ptr)
203: {
204: PC_Shell *shell;
207: shell = (PC_Shell*)pc->data;
208: pc->ops->applyrichardson = PCApplyRichardson_Shell;
209: shell->applyrich = apply;
210: shell->ctxrich = ptr;
211: return(0);
212: }
215: /* -------------------------------------------------------------------------------*/
219: /*@C
220: PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
221: matrix operator is changed.
223: Collective on PC
225: Input Parameters:
226: + pc - the preconditioner context
227: . setup - the application-provided setup routine
229: Calling sequence of setup:
230: .vb
231: PetscErrorCode setup (void *ptr)
232: .ve
234: . ptr - the application context
236: Level: developer
238: .keywords: PC, shell, set, setup, user-provided
240: .seealso: PCShellSetApplyRichardson(), PCShellSetApply()
241: @*/
242: PetscErrorCode PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(void*))
243: {
244: PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*));
248: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)(void))&f);
249: if (f) {
250: (*f)(pc,setup);
251: }
252: return(0);
253: }
258: /*@C
259: PCShellSetView - Sets routine to use as viewer of shell preconditioner
261: Collective on PC
263: Input Parameters:
264: + pc - the preconditioner context
265: - view - the application-provided view routine
267: Calling sequence of apply:
268: .vb
269: PetscErrorCode view(void *ptr,PetscViewer v)
270: .ve
272: + ptr - the application context
273: - v - viewer
275: Level: developer
277: .keywords: PC, shell, set, apply, user-provided
279: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
280: @*/
281: PetscErrorCode PCShellSetView(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
282: {
283: PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PetscViewer));
287: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetView_C",(void (**)(void))&f);
288: if (f) {
289: (*f)(pc,view);
290: }
291: return(0);
292: }
296: /*@C
297: PCShellSetApply - Sets routine to use as preconditioner.
299: Collective on PC
301: Input Parameters:
302: + pc - the preconditioner context
303: . apply - the application-provided preconditioning routine
304: - ptr - pointer to data needed by this routine
306: Calling sequence of apply:
307: .vb
308: PetscErrorCode apply (void *ptr,Vec xin,Vec xout)
309: .ve
311: + ptr - the application context
312: . xin - input vector
313: - xout - output vector
315: Level: developer
317: .keywords: PC, shell, set, apply, user-provided
319: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
320: @*/
321: PetscErrorCode PCShellSetApply(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec),void *ptr)
322: {
323: PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec),void *);
327: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)(void))&f);
328: if (f) {
329: (*f)(pc,apply,ptr);
330: }
331: return(0);
332: }
336: /*@C
337: PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
339: Collective on PC
341: Input Parameters:
342: + pc - the preconditioner context
343: - apply - the application-provided preconditioning transpose routine
345: Calling sequence of apply:
346: .vb
347: PetscErrorCode applytranspose (void *ptr,Vec xin,Vec xout)
348: .ve
350: + ptr - the application context
351: . xin - input vector
352: - xout - output vector
354: Level: developer
356: Notes:
357: Uses the same context variable as PCShellSetApply().
359: .keywords: PC, shell, set, apply, user-provided
361: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply()
362: @*/
363: PetscErrorCode PCShellSetApplyTranspose(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
364: {
365: PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));
369: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)(void))&f);
370: if (f) {
371: (*f)(pc,applytranspose);
372: }
373: return(0);
374: }
378: /*@C
379: PCShellSetName - Sets an optional name to associate with a shell
380: preconditioner.
382: Not Collective
384: Input Parameters:
385: + pc - the preconditioner context
386: - name - character string describing shell preconditioner
388: Level: developer
390: .keywords: PC, shell, set, name, user-provided
392: .seealso: PCShellGetName()
393: @*/
394: PetscErrorCode PCShellSetName(PC pc,const char name[])
395: {
396: PetscErrorCode ierr,(*f)(PC,const char []);
400: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)(void))&f);
401: if (f) {
402: (*f)(pc,name);
403: }
404: return(0);
405: }
409: /*@C
410: PCShellGetName - Gets an optional name that the user has set for a shell
411: preconditioner.
413: Not Collective
415: Input Parameter:
416: . pc - the preconditioner context
418: Output Parameter:
419: . name - character string describing shell preconditioner (you should not free this)
421: Level: developer
423: .keywords: PC, shell, get, name, user-provided
425: .seealso: PCShellSetName()
426: @*/
427: PetscErrorCode PCShellGetName(PC pc,char *name[])
428: {
429: PetscErrorCode ierr,(*f)(PC,char *[]);
434: PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)(void))&f);
435: if (f) {
436: (*f)(pc,name);
437: } else {
438: SETERRQ(PETSC_ERR_ARG_WRONG,"Not shell preconditioner, cannot get name");
439: }
440: return(0);
441: }
445: /*@C
446: PCShellSetApplyRichardson - Sets routine to use as preconditioner
447: in Richardson iteration.
449: Collective on PC
451: Input Parameters:
452: + pc - the preconditioner context
453: . apply - the application-provided preconditioning routine
454: - ptr - pointer to data needed by this routine
456: Calling sequence of apply:
457: .vb
458: PetscErrorCode apply (void *ptr,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits)
459: .ve
461: + ptr - the application context
462: . b - right-hand-side
463: . x - current iterate
464: . r - work space
465: . rtol - relative tolerance of residual norm to stop at
466: . abstol - absolute tolerance of residual norm to stop at
467: . dtol - if residual norm increases by this factor than return
468: - maxits - number of iterations to run
470: Level: developer
472: .keywords: PC, shell, set, apply, Richardson, user-provided
474: .seealso: PCShellSetApply()
475: @*/
476: PetscErrorCode PCShellSetApplyRichardson(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt),void *ptr)
477: {
478: PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt),void *);
482: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)(void))&f);
483: if (f) {
484: (*f)(pc,apply,ptr);
485: }
486: return(0);
487: }
489: /*MC
490: PCSHELL - Creates a new preconditioner class for use with your
491: own private data storage format.
493: Level: advanced
495: Concepts: providing your own preconditioner
497: Usage:
498: $ PetscErrorCode (*mult)(void*,Vec,Vec);
499: $ PetscErrorCode (*setup)(void*);
500: $ PCCreate(comm,&pc);
501: $ PCSetType(pc,PCSHELL);
502: $ PCShellSetApply(pc,mult,ctx);
503: $ PCShellSetSetUp(pc,setup); (optional)
505: .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC,
506: MATSHELL, PCShellSetUp(), PCShellSetApply(), PCShellSetView(),
507: PCShellSetApplyTranpose(), PCShellSetName(), PCShellSetApplyRichardson(),
508: PCShellGetName()
509: M*/
514: PetscErrorCode PCCreate_Shell(PC pc)
515: {
517: PC_Shell *shell;
520: pc->ops->destroy = PCDestroy_Shell;
521: PetscNew(PC_Shell,&shell);
522: PetscLogObjectMemory(pc,sizeof(PC_Shell));
524: pc->data = (void*)shell;
525: pc->name = 0;
527: pc->ops->apply = PCApply_Shell;
528: pc->ops->view = PCView_Shell;
529: pc->ops->applytranspose = PCApplyTranspose_Shell;
530: pc->ops->applyrichardson = 0;
531: pc->ops->setup = PCSetUp_Shell;
532: pc->ops->view = PCView_Shell;
534: shell->apply = 0;
535: shell->applytranspose = 0;
536: shell->name = 0;
537: shell->applyrich = 0;
538: shell->ctxrich = 0;
539: shell->ctx = 0;
540: shell->setup = 0;
541: shell->view = 0;
543: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell",
544: PCShellSetSetUp_Shell);
545: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell",
546: PCShellSetApply_Shell);
547: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell",
548: PCShellSetView_Shell);
549: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C",
550: "PCShellSetApplyTranspose_Shell",
551: PCShellSetApplyTranspose_Shell);
552: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell",
553: PCShellSetName_Shell);
554: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell",
555: PCShellGetName_Shell);
556: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C",
557: "PCShellSetApplyRichardson_Shell",
558: PCShellSetApplyRichardson_Shell);
560: return(0);
561: }