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;
21: static int PCSetUp_Shell(PC pc)
22: {
23: PC_Shell *shell;
24: int ierr;
27: shell = (PC_Shell*)pc->data;
28: if (shell->setup) {
29: ierr = (*shell->setup)(shell->ctx);
30: }
31: return(0);
32: }
34: static int PCApply_Shell(PC pc,Vec x,Vec y)
35: {
36: PC_Shell *shell;
37: int ierr;
40: shell = (PC_Shell*)pc->data;
41: if (!shell->apply) SETERRQ(1,"No apply() routine provided to Shell PC");
42: ierr = (*shell->apply)(shell->ctx,x,y);
43: return(0);
44: }
46: static int PCApplyTranspose_Shell(PC pc,Vec x,Vec y)
47: {
48: PC_Shell *shell;
49: int ierr;
52: shell = (PC_Shell*)pc->data;
53: if (!shell->applytranspose) SETERRQ(1,"No applytranspose() routine provided to Shell PC");
54: ierr = (*shell->applytranspose)(shell->ctx,x,y);
55: return(0);
56: }
58: static int PCApplyRichardson_Shell(PC pc,Vec x,Vec y,Vec w,PetscReal rtol,PetscReal atol, PetscReal dtol,int it)
59: {
60: int ierr;
61: PC_Shell *shell;
64: shell = (PC_Shell*)pc->data;
65: ierr = (*shell->applyrich)(shell->ctxrich,x,y,w,rtol,atol,dtol,it);
66: return(0);
67: }
69: static int PCDestroy_Shell(PC pc)
70: {
71: PC_Shell *shell = (PC_Shell*)pc->data;
72: int ierr;
75: PetscFree(shell);
76: return(0);
77: }
79: static int PCView_Shell(PC pc,PetscViewer viewer)
80: {
81: PC_Shell *shell = (PC_Shell*)pc->data;
82: int ierr;
83: PetscTruth isascii;
86: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
87: if (isascii) {
88: if (shell->name) {PetscViewerASCIIPrintf(viewer," Shell: %sn",shell->name);}
89: else {PetscViewerASCIIPrintf(viewer," Shell: no namen");}
90: }
91: if (shell->view) {
92: PetscViewerASCIIPushTab(viewer);
93: ierr = (*shell->view)(shell->ctx,viewer);
94: PetscViewerASCIIPopTab(viewer);
95: }
96: return(0);
97: }
99: /* ------------------------------------------------------------------------------*/
100: EXTERN_C_BEGIN
101: int PCShellSetSetUp_Shell(PC pc, int (*setup)(void*))
102: {
103: PC_Shell *shell;
106: shell = (PC_Shell*)pc->data;
107: shell->setup = setup;
108: return(0);
109: }
110: EXTERN_C_END
112: EXTERN_C_BEGIN
113: int PCShellSetApply_Shell(PC pc,int (*apply)(void*,Vec,Vec),void *ptr)
114: {
115: PC_Shell *shell;
118: shell = (PC_Shell*)pc->data;
119: shell->apply = apply;
120: shell->ctx = ptr;
121: return(0);
122: }
123: EXTERN_C_END
125: EXTERN_C_BEGIN
126: int PCShellSetView_Shell(PC pc,int (*view)(void*,PetscViewer))
127: {
128: PC_Shell *shell;
131: shell = (PC_Shell*)pc->data;
132: shell->view = view;
133: return(0);
134: }
135: EXTERN_C_END
137: EXTERN_C_BEGIN
138: int PCShellSetApplyTranspose_Shell(PC pc,int (*applytranspose)(void*,Vec,Vec))
139: {
140: PC_Shell *shell;
143: shell = (PC_Shell*)pc->data;
144: shell->applytranspose = applytranspose;
145: return(0);
146: }
147: EXTERN_C_END
149: EXTERN_C_BEGIN
150: int PCShellSetName_Shell(PC pc,char *name)
151: {
152: PC_Shell *shell;
155: shell = (PC_Shell*)pc->data;
156: shell->name = name;
157: return(0);
158: }
159: EXTERN_C_END
161: EXTERN_C_BEGIN
162: int PCShellGetName_Shell(PC pc,char **name)
163: {
164: PC_Shell *shell;
167: shell = (PC_Shell*)pc->data;
168: *name = shell->name;
169: return(0);
170: }
171: EXTERN_C_END
173: EXTERN_C_BEGIN
174: int PCShellSetApplyRichardson_Shell(PC pc,int (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int),void *ptr)
175: {
176: PC_Shell *shell;
179: shell = (PC_Shell*)pc->data;
180: pc->ops->applyrichardson = PCApplyRichardson_Shell;
181: shell->applyrich = apply;
182: shell->ctxrich = ptr;
183: return(0);
184: }
185: EXTERN_C_END
187: /* -------------------------------------------------------------------------------*/
189: /*@C
190: PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
191: matrix operator is changed.
193: Collective on PC
195: Input Parameters:
196: + pc - the preconditioner context
197: . setup - the application-provided setup routine
199: Calling sequence of setup:
200: .vb
201: int setup (void *ptr)
202: .ve
204: . ptr - the application context
206: Level: developer
208: .keywords: PC, shell, set, setup, user-provided
210: .seealso: PCShellSetApplyRichardson(), PCShellSetApply()
211: @*/
212: int PCShellSetSetUp(PC pc,int (*setup)(void*))
213: {
214: int ierr,(*f)(PC,int (*)(void*));
218: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)(void))&f);
219: if (f) {
220: (*f)(pc,setup);
221: }
222: return(0);
223: }
226: /*@C
227: PCShellSetView - Sets routine to use as viewer of shell preconditioner
229: Collective on PC
231: Input Parameters:
232: + pc - the preconditioner context
233: - view - the application-provided view routine
235: Calling sequence of apply:
236: .vb
237: int view(void *ptr,PetscViewer v)
238: .ve
240: + ptr - the application context
241: - v - viewer
243: Level: developer
245: .keywords: PC, shell, set, apply, user-provided
247: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
248: @*/
249: int PCShellSetView(PC pc,int (*view)(void*,PetscViewer))
250: {
251: int ierr,(*f)(PC,int (*)(void*,PetscViewer));
255: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetView_C",(void (**)(void))&f);
256: if (f) {
257: (*f)(pc,view);
258: }
259: return(0);
260: }
262: /*@C
263: PCShellSetApply - Sets routine to use as preconditioner.
265: Collective on PC
267: Input Parameters:
268: + pc - the preconditioner context
269: . apply - the application-provided preconditioning routine
270: - ptr - pointer to data needed by this routine
272: Calling sequence of apply:
273: .vb
274: int apply (void *ptr,Vec xin,Vec xout)
275: .ve
277: + ptr - the application context
278: . xin - input vector
279: - xout - output vector
281: Level: developer
283: .keywords: PC, shell, set, apply, user-provided
285: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
286: @*/
287: int PCShellSetApply(PC pc,int (*apply)(void*,Vec,Vec),void *ptr)
288: {
289: int ierr,(*f)(PC,int (*)(void*,Vec,Vec),void *);
293: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)(void))&f);
294: if (f) {
295: (*f)(pc,apply,ptr);
296: }
297: return(0);
298: }
300: /*@C
301: PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
303: Collective on PC
305: Input Parameters:
306: + pc - the preconditioner context
307: - apply - the application-provided preconditioning transpose routine
309: Calling sequence of apply:
310: .vb
311: int applytranspose (void *ptr,Vec xin,Vec xout)
312: .ve
314: + ptr - the application context
315: . xin - input vector
316: - xout - output vector
318: Level: developer
320: Notes:
321: Uses the same context variable as PCShellSetApply().
323: .keywords: PC, shell, set, apply, user-provided
325: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply()
326: @*/
327: int PCShellSetApplyTranspose(PC pc,int (*applytranspose)(void*,Vec,Vec))
328: {
329: int ierr,(*f)(PC,int (*)(void*,Vec,Vec));
333: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)(void))&f);
334: if (f) {
335: (*f)(pc,applytranspose);
336: }
337: return(0);
338: }
340: /*@C
341: PCShellSetName - Sets an optional name to associate with a shell
342: preconditioner.
344: Not Collective
346: Input Parameters:
347: + pc - the preconditioner context
348: - name - character string describing shell preconditioner
350: Level: developer
352: .keywords: PC, shell, set, name, user-provided
354: .seealso: PCShellGetName()
355: @*/
356: int PCShellSetName(PC pc,char *name)
357: {
358: int ierr,(*f)(PC,char *);
362: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)(void))&f);
363: if (f) {
364: (*f)(pc,name);
365: }
366: return(0);
367: }
369: /*@C
370: PCShellGetName - Gets an optional name that the user has set for a shell
371: preconditioner.
373: Not Collective
375: Input Parameter:
376: . pc - the preconditioner context
378: Output Parameter:
379: . name - character string describing shell preconditioner
381: Level: developer
383: .keywords: PC, shell, get, name, user-provided
385: .seealso: PCShellSetName()
386: @*/
387: int PCShellGetName(PC pc,char **name)
388: {
389: int ierr,(*f)(PC,char **);
393: PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)(void))&f);
394: if (f) {
395: (*f)(pc,name);
396: } else {
397: SETERRQ(1,"Not shell preconditioner, cannot get name");
398: }
399: return(0);
400: }
402: /*@C
403: PCShellSetApplyRichardson - Sets routine to use as preconditioner
404: in Richardson iteration.
406: Collective on PC
408: Input Parameters:
409: + pc - the preconditioner context
410: . apply - the application-provided preconditioning routine
411: - ptr - pointer to data needed by this routine
413: Calling sequence of apply:
414: .vb
415: int apply (void *ptr,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal atol,PetscReal dtol,int maxits)
416: .ve
418: + ptr - the application context
419: . b - right-hand-side
420: . x - current iterate
421: . r - work space
422: . rtol - relative tolerance of residual norm to stop at
423: . atol - absolute tolerance of residual norm to stop at
424: . dtol - if residual norm increases by this factor than return
425: - maxits - number of iterations to run
427: Level: developer
429: .keywords: PC, shell, set, apply, Richardson, user-provided
431: .seealso: PCShellSetApply()
432: @*/
433: int PCShellSetApplyRichardson(PC pc,int (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int),void *ptr)
434: {
435: int ierr,(*f)(PC,int (*)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int),void *);
439: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)(void))&f);
440: if (f) {
441: (*f)(pc,apply,ptr);
442: }
443: return(0);
444: }
446: /*
447: PCCreate_Shell - creates a new preconditioner class for use with your
448: own private data storage format. This is intended to
449: provide a simple class to use with KSP. You should
450: not use this if you plan to make a complete class.
453: Usage:
454: $ int (*mult)(void *,Vec,Vec);
455: $ int (*setup)(void *);
456: $ PCCreate(comm,&pc);
457: $ PCSetType(pc,PC_Shell);
458: $ PCShellSetApply(pc,mult,ctx);
459: $ PCShellSetSetUp(pc,setup); (optional)
461: */
462: EXTERN_C_BEGIN
463: int PCCreate_Shell(PC pc)
464: {
465: int ierr;
466: PC_Shell *shell;
469: pc->ops->destroy = PCDestroy_Shell;
470: ierr = PetscNew(PC_Shell,&shell);
471: PetscLogObjectMemory(pc,sizeof(PC_Shell));
473: pc->data = (void*)shell;
474: pc->name = 0;
476: pc->ops->apply = PCApply_Shell;
477: pc->ops->view = PCView_Shell;
478: pc->ops->applytranspose = PCApplyTranspose_Shell;
479: pc->ops->applyrichardson = 0;
480: pc->ops->setup = PCSetUp_Shell;
481: pc->ops->view = PCView_Shell;
483: shell->apply = 0;
484: shell->applytranspose = 0;
485: shell->name = 0;
486: shell->applyrich = 0;
487: shell->ctxrich = 0;
488: shell->ctx = 0;
489: shell->setup = 0;
490: shell->view = 0;
492: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell",
493: PCShellSetSetUp_Shell);
494: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell",
495: PCShellSetApply_Shell);
496: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell",
497: PCShellSetView_Shell);
498: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C",
499: "PCShellSetApplyTranspose_Shell",
500: PCShellSetApplyTranspose_Shell);
501: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell",
502: PCShellSetName_Shell);
503: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell",
504: PCShellGetName_Shell);
505: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C",
506: "PCShellSetApplyRichardson_Shell",
507: PCShellSetApplyRichardson_Shell);
509: return(0);
510: }
511: EXTERN_C_END