Actual source code: shellpc.c
1: /*$Id: shellpc.c,v 1.77 2001/08/21 21:03:18 bsmith Exp $*/
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 src/ksp/pc/pcimpl.h
9: #include vecimpl.h
11: EXTERN_C_BEGIN
12: typedef struct {
13: void *ctx,*ctxrich; /* user provided contexts for preconditioner */
14: int (*setup)(void *);
15: int (*apply)(void *,Vec,Vec);
16: int (*view)(void *,PetscViewer);
17: int (*applytranspose)(void *,Vec,Vec);
18: int (*applyrich)(void *,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int);
19: char *name;
20: } PC_Shell;
21: EXTERN_C_END
25: static int PCSetUp_Shell(PC pc)
26: {
27: PC_Shell *shell;
28: int ierr;
31: shell = (PC_Shell*)pc->data;
32: if (shell->setup) {
33: (*shell->setup)(shell->ctx);
34: }
35: return(0);
36: }
40: static int PCApply_Shell(PC pc,Vec x,Vec y)
41: {
42: PC_Shell *shell;
43: int ierr;
46: shell = (PC_Shell*)pc->data;
47: if (!shell->apply) SETERRQ(1,"No apply() routine provided to Shell PC");
48: (*shell->apply)(shell->ctx,x,y);
49: return(0);
50: }
54: static int PCApplyTranspose_Shell(PC pc,Vec x,Vec y)
55: {
56: PC_Shell *shell;
57: int ierr;
60: shell = (PC_Shell*)pc->data;
61: if (!shell->applytranspose) SETERRQ(1,"No applytranspose() routine provided to Shell PC");
62: (*shell->applytranspose)(shell->ctx,x,y);
63: return(0);
64: }
68: static int PCApplyRichardson_Shell(PC pc,Vec x,Vec y,Vec w,PetscReal rtol,PetscReal atol, PetscReal dtol,int it)
69: {
70: int ierr;
71: PC_Shell *shell;
74: shell = (PC_Shell*)pc->data;
75: (*shell->applyrich)(shell->ctxrich,x,y,w,rtol,atol,dtol,it);
76: return(0);
77: }
81: static int PCDestroy_Shell(PC pc)
82: {
83: PC_Shell *shell = (PC_Shell*)pc->data;
84: int ierr;
87: if (shell->name) {PetscFree(shell->name);}
88: PetscFree(shell);
89: return(0);
90: }
94: static int PCView_Shell(PC pc,PetscViewer viewer)
95: {
96: PC_Shell *shell = (PC_Shell*)pc->data;
97: int ierr;
98: PetscTruth isascii;
101: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
102: if (isascii) {
103: if (shell->name) {PetscViewerASCIIPrintf(viewer," Shell: %s\n",shell->name);}
104: else {PetscViewerASCIIPrintf(viewer," Shell: no name\n");}
105: }
106: if (shell->view) {
107: PetscViewerASCIIPushTab(viewer);
108: (*shell->view)(shell->ctx,viewer);
109: PetscViewerASCIIPopTab(viewer);
110: }
111: return(0);
112: }
114: /* ------------------------------------------------------------------------------*/
115: EXTERN_C_BEGIN
118: int PCShellSetSetUp_Shell(PC pc, int (*setup)(void*))
119: {
120: PC_Shell *shell;
123: shell = (PC_Shell*)pc->data;
124: shell->setup = setup;
125: return(0);
126: }
127: EXTERN_C_END
129: EXTERN_C_BEGIN
132: int PCShellSetApply_Shell(PC pc,int (*apply)(void*,Vec,Vec),void *ptr)
133: {
134: PC_Shell *shell;
137: shell = (PC_Shell*)pc->data;
138: shell->apply = apply;
139: shell->ctx = ptr;
140: return(0);
141: }
142: EXTERN_C_END
144: EXTERN_C_BEGIN
147: int PCShellSetView_Shell(PC pc,int (*view)(void*,PetscViewer))
148: {
149: PC_Shell *shell;
152: shell = (PC_Shell*)pc->data;
153: shell->view = view;
154: return(0);
155: }
156: EXTERN_C_END
158: EXTERN_C_BEGIN
161: int PCShellSetApplyTranspose_Shell(PC pc,int (*applytranspose)(void*,Vec,Vec))
162: {
163: PC_Shell *shell;
166: shell = (PC_Shell*)pc->data;
167: shell->applytranspose = applytranspose;
168: return(0);
169: }
170: EXTERN_C_END
172: EXTERN_C_BEGIN
175: int PCShellSetName_Shell(PC pc,const char name[])
176: {
177: PC_Shell *shell;
178: int ierr;
181: shell = (PC_Shell*)pc->data;
182: PetscStrallocpy(name,&shell->name);
183: return(0);
184: }
185: EXTERN_C_END
187: EXTERN_C_BEGIN
190: int PCShellGetName_Shell(PC pc,char *name[])
191: {
192: PC_Shell *shell;
195: shell = (PC_Shell*)pc->data;
196: *name = shell->name;
197: return(0);
198: }
199: EXTERN_C_END
201: EXTERN_C_BEGIN
204: int PCShellSetApplyRichardson_Shell(PC pc,int (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int),void *ptr)
205: {
206: PC_Shell *shell;
209: shell = (PC_Shell*)pc->data;
210: pc->ops->applyrichardson = PCApplyRichardson_Shell;
211: shell->applyrich = apply;
212: shell->ctxrich = ptr;
213: return(0);
214: }
215: EXTERN_C_END
217: /* -------------------------------------------------------------------------------*/
221: /*@C
222: PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
223: matrix operator is changed.
225: Collective on PC
227: Input Parameters:
228: + pc - the preconditioner context
229: . setup - the application-provided setup routine
231: Calling sequence of setup:
232: .vb
233: int setup (void *ptr)
234: .ve
236: . ptr - the application context
238: Level: developer
240: .keywords: PC, shell, set, setup, user-provided
242: .seealso: PCShellSetApplyRichardson(), PCShellSetApply()
243: @*/
244: int PCShellSetSetUp(PC pc,int (*setup)(void*))
245: {
246: int ierr,(*f)(PC,int (*)(void*));
250: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)(void))&f);
251: if (f) {
252: (*f)(pc,setup);
253: }
254: return(0);
255: }
260: /*@C
261: PCShellSetView - Sets routine to use as viewer of shell preconditioner
263: Collective on PC
265: Input Parameters:
266: + pc - the preconditioner context
267: - view - the application-provided view routine
269: Calling sequence of apply:
270: .vb
271: int view(void *ptr,PetscViewer v)
272: .ve
274: + ptr - the application context
275: - v - viewer
277: Level: developer
279: .keywords: PC, shell, set, apply, user-provided
281: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
282: @*/
283: int PCShellSetView(PC pc,int (*view)(void*,PetscViewer))
284: {
285: int ierr,(*f)(PC,int (*)(void*,PetscViewer));
289: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetView_C",(void (**)(void))&f);
290: if (f) {
291: (*f)(pc,view);
292: }
293: return(0);
294: }
298: /*@C
299: PCShellSetApply - Sets routine to use as preconditioner.
301: Collective on PC
303: Input Parameters:
304: + pc - the preconditioner context
305: . apply - the application-provided preconditioning routine
306: - ptr - pointer to data needed by this routine
308: Calling sequence of apply:
309: .vb
310: int apply (void *ptr,Vec xin,Vec xout)
311: .ve
313: + ptr - the application context
314: . xin - input vector
315: - xout - output vector
317: Level: developer
319: .keywords: PC, shell, set, apply, user-provided
321: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
322: @*/
323: int PCShellSetApply(PC pc,int (*apply)(void*,Vec,Vec),void *ptr)
324: {
325: int ierr,(*f)(PC,int (*)(void*,Vec,Vec),void *);
329: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)(void))&f);
330: if (f) {
331: (*f)(pc,apply,ptr);
332: }
333: return(0);
334: }
338: /*@C
339: PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
341: Collective on PC
343: Input Parameters:
344: + pc - the preconditioner context
345: - apply - the application-provided preconditioning transpose routine
347: Calling sequence of apply:
348: .vb
349: int applytranspose (void *ptr,Vec xin,Vec xout)
350: .ve
352: + ptr - the application context
353: . xin - input vector
354: - xout - output vector
356: Level: developer
358: Notes:
359: Uses the same context variable as PCShellSetApply().
361: .keywords: PC, shell, set, apply, user-provided
363: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply()
364: @*/
365: int PCShellSetApplyTranspose(PC pc,int (*applytranspose)(void*,Vec,Vec))
366: {
367: int ierr,(*f)(PC,int (*)(void*,Vec,Vec));
371: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)(void))&f);
372: if (f) {
373: (*f)(pc,applytranspose);
374: }
375: return(0);
376: }
380: /*@C
381: PCShellSetName - Sets an optional name to associate with a shell
382: preconditioner.
384: Not Collective
386: Input Parameters:
387: + pc - the preconditioner context
388: - name - character string describing shell preconditioner
390: Level: developer
392: .keywords: PC, shell, set, name, user-provided
394: .seealso: PCShellGetName()
395: @*/
396: int PCShellSetName(PC pc,const char name[])
397: {
398: int ierr,(*f)(PC,const char []);
402: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)(void))&f);
403: if (f) {
404: (*f)(pc,name);
405: }
406: return(0);
407: }
411: /*@C
412: PCShellGetName - Gets an optional name that the user has set for a shell
413: preconditioner.
415: Not Collective
417: Input Parameter:
418: . pc - the preconditioner context
420: Output Parameter:
421: . name - character string describing shell preconditioner (you should not free this)
423: Level: developer
425: .keywords: PC, shell, get, name, user-provided
427: .seealso: PCShellSetName()
428: @*/
429: int PCShellGetName(PC pc,char *name[])
430: {
431: int ierr,(*f)(PC,char *[]);
436: PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)(void))&f);
437: if (f) {
438: (*f)(pc,name);
439: } else {
440: SETERRQ(1,"Not shell preconditioner, cannot get name");
441: }
442: return(0);
443: }
447: /*@C
448: PCShellSetApplyRichardson - Sets routine to use as preconditioner
449: in Richardson iteration.
451: Collective on PC
453: Input Parameters:
454: + pc - the preconditioner context
455: . apply - the application-provided preconditioning routine
456: - ptr - pointer to data needed by this routine
458: Calling sequence of apply:
459: .vb
460: int apply (void *ptr,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal atol,PetscReal dtol,int maxits)
461: .ve
463: + ptr - the application context
464: . b - right-hand-side
465: . x - current iterate
466: . r - work space
467: . rtol - relative tolerance of residual norm to stop at
468: . atol - absolute tolerance of residual norm to stop at
469: . dtol - if residual norm increases by this factor than return
470: - maxits - number of iterations to run
472: Level: developer
474: .keywords: PC, shell, set, apply, Richardson, user-provided
476: .seealso: PCShellSetApply()
477: @*/
478: int PCShellSetApplyRichardson(PC pc,int (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int),void *ptr)
479: {
480: int ierr,(*f)(PC,int (*)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int),void *);
484: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)(void))&f);
485: if (f) {
486: (*f)(pc,apply,ptr);
487: }
488: return(0);
489: }
491: /*MC
492: PCSHELL - Creates a new preconditioner class for use with your
493: own private data storage format.
495: Level: advanced
497: Concepts: providing your own preconditioner
499: Usage:
500: $ int (*mult)(void *,Vec,Vec);
501: $ int (*setup)(void *);
502: $ PCCreate(comm,&pc);
503: $ PCSetType(pc,PCSHELL);
504: $ PCShellSetApply(pc,mult,ctx);
505: $ PCShellSetSetUp(pc,setup); (optional)
507: .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC,
508: KSPSHELL(), MATSHELL(), PCShellSetUp(), PCShellSetApply(), PCShellSetView(),
509: PCShellSetApplyTranpose(), PCShellSetName(), PCShellSetApplyRichardson(),
510: PCShellGetName()
511: M*/
513: EXTERN_C_BEGIN
516: int PCCreate_Shell(PC pc)
517: {
518: int ierr;
519: PC_Shell *shell;
522: pc->ops->destroy = PCDestroy_Shell;
523: PetscNew(PC_Shell,&shell);
524: PetscLogObjectMemory(pc,sizeof(PC_Shell));
526: pc->data = (void*)shell;
527: pc->name = 0;
529: pc->ops->apply = PCApply_Shell;
530: pc->ops->view = PCView_Shell;
531: pc->ops->applytranspose = PCApplyTranspose_Shell;
532: pc->ops->applyrichardson = 0;
533: pc->ops->setup = PCSetUp_Shell;
534: pc->ops->view = PCView_Shell;
536: shell->apply = 0;
537: shell->applytranspose = 0;
538: shell->name = 0;
539: shell->applyrich = 0;
540: shell->ctxrich = 0;
541: shell->ctx = 0;
542: shell->setup = 0;
543: shell->view = 0;
545: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell",
546: PCShellSetSetUp_Shell);
547: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell",
548: PCShellSetApply_Shell);
549: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell",
550: PCShellSetView_Shell);
551: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C",
552: "PCShellSetApplyTranspose_Shell",
553: PCShellSetApplyTranspose_Shell);
554: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell",
555: PCShellSetName_Shell);
556: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell",
557: PCShellGetName_Shell);
558: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C",
559: "PCShellSetApplyRichardson_Shell",
560: PCShellSetApplyRichardson_Shell);
562: return(0);
563: }
564: EXTERN_C_END