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: #undef __FUNCT__
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: ierr = (*shell->setup)(shell->ctx);
32: }
33: return(0);
34: }
36: #undef __FUNCT__
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: ierr = (*shell->apply)(shell->ctx,x,y);
47: return(0);
48: }
50: #undef __FUNCT__
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: ierr = (*shell->applytranspose)(shell->ctx,x,y);
61: return(0);
62: }
64: #undef __FUNCT__
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: ierr = (*shell->applyrich)(shell->ctxrich,x,y,w,rtol,atol,dtol,it);
74: return(0);
75: }
77: #undef __FUNCT__
79: static int PCDestroy_Shell(PC pc)
80: {
81: PC_Shell *shell = (PC_Shell*)pc->data;
82: int ierr;
85: PetscFree(shell);
86: return(0);
87: }
89: #undef __FUNCT__
91: static int PCView_Shell(PC pc,PetscViewer viewer)
92: {
93: PC_Shell *shell = (PC_Shell*)pc->data;
94: int ierr;
95: PetscTruth isascii;
98: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
99: if (isascii) {
100: if (shell->name) {PetscViewerASCIIPrintf(viewer," Shell: %sn",shell->name);}
101: else {PetscViewerASCIIPrintf(viewer," Shell: no namen");}
102: }
103: if (shell->view) {
104: PetscViewerASCIIPushTab(viewer);
105: ierr = (*shell->view)(shell->ctx,viewer);
106: PetscViewerASCIIPopTab(viewer);
107: }
108: return(0);
109: }
111: /* ------------------------------------------------------------------------------*/
112: EXTERN_C_BEGIN
113: #undef __FUNCT__
115: int PCShellSetSetUp_Shell(PC pc, int (*setup)(void*))
116: {
117: PC_Shell *shell;
120: shell = (PC_Shell*)pc->data;
121: shell->setup = setup;
122: return(0);
123: }
124: EXTERN_C_END
126: EXTERN_C_BEGIN
127: #undef __FUNCT__
129: int PCShellSetApply_Shell(PC pc,int (*apply)(void*,Vec,Vec),void *ptr)
130: {
131: PC_Shell *shell;
134: shell = (PC_Shell*)pc->data;
135: shell->apply = apply;
136: shell->ctx = ptr;
137: return(0);
138: }
139: EXTERN_C_END
141: EXTERN_C_BEGIN
142: #undef __FUNCT__
144: int PCShellSetView_Shell(PC pc,int (*view)(void*,PetscViewer))
145: {
146: PC_Shell *shell;
149: shell = (PC_Shell*)pc->data;
150: shell->view = view;
151: return(0);
152: }
153: EXTERN_C_END
155: EXTERN_C_BEGIN
156: #undef __FUNCT__
158: int PCShellSetApplyTranspose_Shell(PC pc,int (*applytranspose)(void*,Vec,Vec))
159: {
160: PC_Shell *shell;
163: shell = (PC_Shell*)pc->data;
164: shell->applytranspose = applytranspose;
165: return(0);
166: }
167: EXTERN_C_END
169: EXTERN_C_BEGIN
170: #undef __FUNCT__
172: int PCShellSetName_Shell(PC pc,char *name)
173: {
174: PC_Shell *shell;
177: shell = (PC_Shell*)pc->data;
178: shell->name = name;
179: return(0);
180: }
181: EXTERN_C_END
183: EXTERN_C_BEGIN
184: #undef __FUNCT__
186: int PCShellGetName_Shell(PC pc,char **name)
187: {
188: PC_Shell *shell;
191: shell = (PC_Shell*)pc->data;
192: *name = shell->name;
193: return(0);
194: }
195: EXTERN_C_END
197: EXTERN_C_BEGIN
198: #undef __FUNCT__
200: int PCShellSetApplyRichardson_Shell(PC pc,int (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int),void *ptr)
201: {
202: PC_Shell *shell;
205: shell = (PC_Shell*)pc->data;
206: pc->ops->applyrichardson = PCApplyRichardson_Shell;
207: shell->applyrich = apply;
208: shell->ctxrich = ptr;
209: return(0);
210: }
211: EXTERN_C_END
213: /* -------------------------------------------------------------------------------*/
215: #undef __FUNCT__
217: /*@C
218: PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
219: matrix operator is changed.
221: Collective on PC
223: Input Parameters:
224: + pc - the preconditioner context
225: . setup - the application-provided setup routine
227: Calling sequence of setup:
228: .vb
229: int setup (void *ptr)
230: .ve
232: . ptr - the application context
234: Level: developer
236: .keywords: PC, shell, set, setup, user-provided
238: .seealso: PCShellSetApplyRichardson(), PCShellSetApply()
239: @*/
240: int PCShellSetSetUp(PC pc,int (*setup)(void*))
241: {
242: int ierr,(*f)(PC,int (*)(void*));
246: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)(void))&f);
247: if (f) {
248: (*f)(pc,setup);
249: }
250: return(0);
251: }
254: #undef __FUNCT__
256: /*@C
257: PCShellSetView - Sets routine to use as viewer of shell preconditioner
259: Collective on PC
261: Input Parameters:
262: + pc - the preconditioner context
263: - view - the application-provided view routine
265: Calling sequence of apply:
266: .vb
267: int view(void *ptr,PetscViewer v)
268: .ve
270: + ptr - the application context
271: - v - viewer
273: Level: developer
275: .keywords: PC, shell, set, apply, user-provided
277: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
278: @*/
279: int PCShellSetView(PC pc,int (*view)(void*,PetscViewer))
280: {
281: int ierr,(*f)(PC,int (*)(void*,PetscViewer));
285: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetView_C",(void (**)(void))&f);
286: if (f) {
287: (*f)(pc,view);
288: }
289: return(0);
290: }
292: #undef __FUNCT__
294: /*@C
295: PCShellSetApply - Sets routine to use as preconditioner.
297: Collective on PC
299: Input Parameters:
300: + pc - the preconditioner context
301: . apply - the application-provided preconditioning routine
302: - ptr - pointer to data needed by this routine
304: Calling sequence of apply:
305: .vb
306: int apply (void *ptr,Vec xin,Vec xout)
307: .ve
309: + ptr - the application context
310: . xin - input vector
311: - xout - output vector
313: Level: developer
315: .keywords: PC, shell, set, apply, user-provided
317: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
318: @*/
319: int PCShellSetApply(PC pc,int (*apply)(void*,Vec,Vec),void *ptr)
320: {
321: int ierr,(*f)(PC,int (*)(void*,Vec,Vec),void *);
325: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)(void))&f);
326: if (f) {
327: (*f)(pc,apply,ptr);
328: }
329: return(0);
330: }
332: #undef __FUNCT__
334: /*@C
335: PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
337: Collective on PC
339: Input Parameters:
340: + pc - the preconditioner context
341: - apply - the application-provided preconditioning transpose routine
343: Calling sequence of apply:
344: .vb
345: int applytranspose (void *ptr,Vec xin,Vec xout)
346: .ve
348: + ptr - the application context
349: . xin - input vector
350: - xout - output vector
352: Level: developer
354: Notes:
355: Uses the same context variable as PCShellSetApply().
357: .keywords: PC, shell, set, apply, user-provided
359: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply()
360: @*/
361: int PCShellSetApplyTranspose(PC pc,int (*applytranspose)(void*,Vec,Vec))
362: {
363: int ierr,(*f)(PC,int (*)(void*,Vec,Vec));
367: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)(void))&f);
368: if (f) {
369: (*f)(pc,applytranspose);
370: }
371: return(0);
372: }
374: #undef __FUNCT__
376: /*@C
377: PCShellSetName - Sets an optional name to associate with a shell
378: preconditioner.
380: Not Collective
382: Input Parameters:
383: + pc - the preconditioner context
384: - name - character string describing shell preconditioner
386: Level: developer
388: .keywords: PC, shell, set, name, user-provided
390: .seealso: PCShellGetName()
391: @*/
392: int PCShellSetName(PC pc,char *name)
393: {
394: int ierr,(*f)(PC,char *);
398: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)(void))&f);
399: if (f) {
400: (*f)(pc,name);
401: }
402: return(0);
403: }
405: #undef __FUNCT__
407: /*@C
408: PCShellGetName - Gets an optional name that the user has set for a shell
409: preconditioner.
411: Not Collective
413: Input Parameter:
414: . pc - the preconditioner context
416: Output Parameter:
417: . name - character string describing shell preconditioner
419: Level: developer
421: .keywords: PC, shell, get, name, user-provided
423: .seealso: PCShellSetName()
424: @*/
425: int PCShellGetName(PC pc,char **name)
426: {
427: int ierr,(*f)(PC,char **);
431: PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)(void))&f);
432: if (f) {
433: (*f)(pc,name);
434: } else {
435: SETERRQ(1,"Not shell preconditioner, cannot get name");
436: }
437: return(0);
438: }
440: #undef __FUNCT__
442: /*@C
443: PCShellSetApplyRichardson - Sets routine to use as preconditioner
444: in Richardson iteration.
446: Collective on PC
448: Input Parameters:
449: + pc - the preconditioner context
450: . apply - the application-provided preconditioning routine
451: - ptr - pointer to data needed by this routine
453: Calling sequence of apply:
454: .vb
455: int apply (void *ptr,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal atol,PetscReal dtol,int maxits)
456: .ve
458: + ptr - the application context
459: . b - right-hand-side
460: . x - current iterate
461: . r - work space
462: . rtol - relative tolerance of residual norm to stop at
463: . atol - absolute tolerance of residual norm to stop at
464: . dtol - if residual norm increases by this factor than return
465: - maxits - number of iterations to run
467: Level: developer
469: .keywords: PC, shell, set, apply, Richardson, user-provided
471: .seealso: PCShellSetApply()
472: @*/
473: int PCShellSetApplyRichardson(PC pc,int (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int),void *ptr)
474: {
475: int ierr,(*f)(PC,int (*)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int),void *);
479: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)(void))&f);
480: if (f) {
481: (*f)(pc,apply,ptr);
482: }
483: return(0);
484: }
486: /*MC
487: PCSHELL - Creates a new preconditioner class for use with your
488: own private data storage format.
490: Level: advanced
492: Concepts: providing your own preconditioner
494: Usage:
495: $ int (*mult)(void *,Vec,Vec);
496: $ int (*setup)(void *);
497: $ PCCreate(comm,&pc);
498: $ PCSetType(pc,PCSHELL);
499: $ PCShellSetApply(pc,mult,ctx);
500: $ PCShellSetSetUp(pc,setup); (optional)
502: .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC,
503: KSPSHELL(), MATSHELL(), PCShellSetUp(), PCShellSetApply(), PCShellSetView(),
504: PCShellSetApplyTranpose(), PCShellSetName(), PCShellSetApplyRichardson(),
505: PCShellGetName()
506: M*/
508: EXTERN_C_BEGIN
509: #undef __FUNCT__
511: int PCCreate_Shell(PC pc)
512: {
513: int ierr;
514: PC_Shell *shell;
517: pc->ops->destroy = PCDestroy_Shell;
518: ierr = PetscNew(PC_Shell,&shell);
519: PetscLogObjectMemory(pc,sizeof(PC_Shell));
521: pc->data = (void*)shell;
522: pc->name = 0;
524: pc->ops->apply = PCApply_Shell;
525: pc->ops->view = PCView_Shell;
526: pc->ops->applytranspose = PCApplyTranspose_Shell;
527: pc->ops->applyrichardson = 0;
528: pc->ops->setup = PCSetUp_Shell;
529: pc->ops->view = PCView_Shell;
531: shell->apply = 0;
532: shell->applytranspose = 0;
533: shell->name = 0;
534: shell->applyrich = 0;
535: shell->ctxrich = 0;
536: shell->ctx = 0;
537: shell->setup = 0;
538: shell->view = 0;
540: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell",
541: PCShellSetSetUp_Shell);
542: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell",
543: PCShellSetApply_Shell);
544: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell",
545: PCShellSetView_Shell);
546: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C",
547: "PCShellSetApplyTranspose_Shell",
548: PCShellSetApplyTranspose_Shell);
549: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell",
550: PCShellSetName_Shell);
551: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell",
552: PCShellGetName_Shell);
553: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C",
554: "PCShellSetApplyRichardson_Shell",
555: PCShellSetApplyRichardson_Shell);
557: return(0);
558: }
559: EXTERN_C_END