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/sles/pc/pcimpl.h
9: #include src/vec/vecimpl.h
11: typedef struct {
12: void *ctx,*ctxrich; /* user provided contexts for preconditioner */
13: int (*setup)(void *);
14: int (*apply)(void *,Vec,Vec);
15: int (*view)(void *,PetscViewer);
16: int (*applytranspose)(void *,Vec,Vec);
17: int (*applyrich)(void *,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int);
18: char *name;
19: } PC_Shell;
23: static int PCSetUp_Shell(PC pc)
24: {
25: PC_Shell *shell;
26: int ierr;
29: shell = (PC_Shell*)pc->data;
30: if (shell->setup) {
31: (*shell->setup)(shell->ctx);
32: }
33: return(0);
34: }
38: static int PCApply_Shell(PC pc,Vec x,Vec y)
39: {
40: PC_Shell *shell;
41: int ierr;
44: shell = (PC_Shell*)pc->data;
45: if (!shell->apply) SETERRQ(1,"No apply() routine provided to Shell PC");
46: (*shell->apply)(shell->ctx,x,y);
47: return(0);
48: }
52: static int PCApplyTranspose_Shell(PC pc,Vec x,Vec y)
53: {
54: PC_Shell *shell;
55: int ierr;
58: shell = (PC_Shell*)pc->data;
59: if (!shell->applytranspose) SETERRQ(1,"No applytranspose() routine provided to Shell PC");
60: (*shell->applytranspose)(shell->ctx,x,y);
61: return(0);
62: }
66: static int PCApplyRichardson_Shell(PC pc,Vec x,Vec y,Vec w,PetscReal rtol,PetscReal atol, PetscReal dtol,int it)
67: {
68: int ierr;
69: PC_Shell *shell;
72: shell = (PC_Shell*)pc->data;
73: (*shell->applyrich)(shell->ctxrich,x,y,w,rtol,atol,dtol,it);
74: return(0);
75: }
79: static int PCDestroy_Shell(PC pc)
80: {
81: PC_Shell *shell = (PC_Shell*)pc->data;
82: int ierr;
85: if (shell->name) {PetscFree(shell->name);}
86: PetscFree(shell);
87: return(0);
88: }
92: static int PCView_Shell(PC pc,PetscViewer viewer)
93: {
94: PC_Shell *shell = (PC_Shell*)pc->data;
95: int ierr;
96: PetscTruth isascii;
99: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
100: if (isascii) {
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: /* ------------------------------------------------------------------------------*/
113: EXTERN_C_BEGIN
116: int PCShellSetSetUp_Shell(PC pc, int (*setup)(void*))
117: {
118: PC_Shell *shell;
121: shell = (PC_Shell*)pc->data;
122: shell->setup = setup;
123: return(0);
124: }
125: EXTERN_C_END
127: EXTERN_C_BEGIN
130: int PCShellSetApply_Shell(PC pc,int (*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: }
140: EXTERN_C_END
142: EXTERN_C_BEGIN
145: int PCShellSetView_Shell(PC pc,int (*view)(void*,PetscViewer))
146: {
147: PC_Shell *shell;
150: shell = (PC_Shell*)pc->data;
151: shell->view = view;
152: return(0);
153: }
154: EXTERN_C_END
156: EXTERN_C_BEGIN
159: int PCShellSetApplyTranspose_Shell(PC pc,int (*applytranspose)(void*,Vec,Vec))
160: {
161: PC_Shell *shell;
164: shell = (PC_Shell*)pc->data;
165: shell->applytranspose = applytranspose;
166: return(0);
167: }
168: EXTERN_C_END
170: EXTERN_C_BEGIN
173: int PCShellSetName_Shell(PC pc,const char name[])
174: {
175: PC_Shell *shell;
176: int ierr;
179: shell = (PC_Shell*)pc->data;
180: PetscStrallocpy(name,&shell->name);
181: return(0);
182: }
183: EXTERN_C_END
185: EXTERN_C_BEGIN
188: int 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: }
197: EXTERN_C_END
199: EXTERN_C_BEGIN
202: int PCShellSetApplyRichardson_Shell(PC pc,int (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int),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: }
213: EXTERN_C_END
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: int 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: int PCShellSetSetUp(PC pc,int (*setup)(void*))
243: {
244: int ierr,(*f)(PC,int (*)(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: int 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: int PCShellSetView(PC pc,int (*view)(void*,PetscViewer))
282: {
283: int ierr,(*f)(PC,int (*)(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: int 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: int PCShellSetApply(PC pc,int (*apply)(void*,Vec,Vec),void *ptr)
322: {
323: int ierr,(*f)(PC,int (*)(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: int 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: int PCShellSetApplyTranspose(PC pc,int (*applytranspose)(void*,Vec,Vec))
364: {
365: int ierr,(*f)(PC,int (*)(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: int PCShellSetName(PC pc,const char name[])
395: {
396: int 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: int PCShellGetName(PC pc,char *name[])
428: {
429: int ierr,(*f)(PC,char *[]);
433: PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)(void))&f);
434: if (f) {
435: (*f)(pc,name);
436: } else {
437: SETERRQ(1,"Not shell preconditioner, cannot get name");
438: }
439: return(0);
440: }
444: /*@C
445: PCShellSetApplyRichardson - Sets routine to use as preconditioner
446: in Richardson iteration.
448: Collective on PC
450: Input Parameters:
451: + pc - the preconditioner context
452: . apply - the application-provided preconditioning routine
453: - ptr - pointer to data needed by this routine
455: Calling sequence of apply:
456: .vb
457: int apply (void *ptr,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal atol,PetscReal dtol,int maxits)
458: .ve
460: + ptr - the application context
461: . b - right-hand-side
462: . x - current iterate
463: . r - work space
464: . rtol - relative tolerance of residual norm to stop at
465: . atol - absolute tolerance of residual norm to stop at
466: . dtol - if residual norm increases by this factor than return
467: - maxits - number of iterations to run
469: Level: developer
471: .keywords: PC, shell, set, apply, Richardson, user-provided
473: .seealso: PCShellSetApply()
474: @*/
475: int PCShellSetApplyRichardson(PC pc,int (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int),void *ptr)
476: {
477: int ierr,(*f)(PC,int (*)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int),void *);
481: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)(void))&f);
482: if (f) {
483: (*f)(pc,apply,ptr);
484: }
485: return(0);
486: }
488: /*MC
489: PCSHELL - Creates a new preconditioner class for use with your
490: own private data storage format.
492: Level: advanced
494: Concepts: providing your own preconditioner
496: Usage:
497: $ int (*mult)(void *,Vec,Vec);
498: $ int (*setup)(void *);
499: $ PCCreate(comm,&pc);
500: $ PCSetType(pc,PCSHELL);
501: $ PCShellSetApply(pc,mult,ctx);
502: $ PCShellSetSetUp(pc,setup); (optional)
504: .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC,
505: KSPSHELL(), MATSHELL(), PCShellSetUp(), PCShellSetApply(), PCShellSetView(),
506: PCShellSetApplyTranpose(), PCShellSetName(), PCShellSetApplyRichardson(),
507: PCShellGetName()
508: M*/
510: EXTERN_C_BEGIN
513: int PCCreate_Shell(PC pc)
514: {
515: int ierr;
516: PC_Shell *shell;
519: pc->ops->destroy = PCDestroy_Shell;
520: PetscNew(PC_Shell,&shell);
521: PetscLogObjectMemory(pc,sizeof(PC_Shell));
523: pc->data = (void*)shell;
524: pc->name = 0;
526: pc->ops->apply = PCApply_Shell;
527: pc->ops->view = PCView_Shell;
528: pc->ops->applytranspose = PCApplyTranspose_Shell;
529: pc->ops->applyrichardson = 0;
530: pc->ops->setup = PCSetUp_Shell;
531: pc->ops->view = PCView_Shell;
533: shell->apply = 0;
534: shell->applytranspose = 0;
535: shell->name = 0;
536: shell->applyrich = 0;
537: shell->ctxrich = 0;
538: shell->ctx = 0;
539: shell->setup = 0;
540: shell->view = 0;
542: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell",
543: PCShellSetSetUp_Shell);
544: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell",
545: PCShellSetApply_Shell);
546: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell",
547: PCShellSetView_Shell);
548: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C",
549: "PCShellSetApplyTranspose_Shell",
550: PCShellSetApplyTranspose_Shell);
551: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell",
552: PCShellSetName_Shell);
553: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell",
554: PCShellGetName_Shell);
555: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C",
556: "PCShellSetApplyRichardson_Shell",
557: PCShellSetApplyRichardson_Shell);
559: return(0);
560: }
561: EXTERN_C_END