Actual source code: shellpc.c
1: /*$Id: shellpc.c,v 1.75 2001/04/10 19:36:09 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 (*applytranspose)(void *,Vec,Vec);
16: int (*applyrich)(void *,Vec,Vec,Vec,int);
17: char *name;
18: } PC_Shell;
20: static int PCSetUp_Shell(PC pc)
21: {
22: PC_Shell *shell;
23: int ierr;
26: shell = (PC_Shell*)pc->data;
27: if (shell->setup) {
28: ierr = (*shell->setup)(shell->ctx);
29: }
30: return(0);
31: }
33: static int PCApply_Shell(PC pc,Vec x,Vec y)
34: {
35: PC_Shell *shell;
36: int ierr;
39: shell = (PC_Shell*)pc->data;
40: if (!shell->apply) SETERRQ(1,"No apply() routine provided to Shell PC");
41: ierr = (*shell->apply)(shell->ctx,x,y);
42: return(0);
43: }
45: static int PCApplyTranspose_Shell(PC pc,Vec x,Vec y)
46: {
47: PC_Shell *shell;
48: int ierr;
51: shell = (PC_Shell*)pc->data;
52: if (!shell->applytranspose) SETERRQ(1,"No applytranspose() routine provided to Shell PC");
53: ierr = (*shell->applytranspose)(shell->ctx,x,y);
54: return(0);
55: }
57: static int PCApplyRichardson_Shell(PC pc,Vec x,Vec y,Vec w,int it)
58: {
59: int ierr;
60: PC_Shell *shell;
63: shell = (PC_Shell*)pc->data;
64: ierr = (*shell->applyrich)(shell->ctxrich,x,y,w,it);
65: return(0);
66: }
68: static int PCDestroy_Shell(PC pc)
69: {
70: PC_Shell *shell = (PC_Shell*)pc->data;
71: int ierr;
74: PetscFree(shell);
75: return(0);
76: }
78: static int PCView_Shell(PC pc,PetscViewer viewer)
79: {
80: PC_Shell *jac = (PC_Shell*)pc->data;
81: int ierr;
82: PetscTruth isascii;
85: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
86: if (isascii) {
87: if (jac->name) {PetscViewerASCIIPrintf(viewer," Shell: %sn",jac->name);}
88: else {PetscViewerASCIIPrintf(viewer," Shell: no namen");}
89: } else {
90: SETERRQ1(1,"Viewer type %s not supported for PCShell",((PetscObject)viewer)->type_name);
91: }
92: return(0);
93: }
95: /* ------------------------------------------------------------------------------*/
96: EXTERN_C_BEGIN
97: int PCShellSetSetUp_Shell(PC pc, int (*setup)(void*))
98: {
99: PC_Shell *shell;
102: shell = (PC_Shell*)pc->data;
103: shell->setup = setup;
104: return(0);
105: }
106: EXTERN_C_END
108: EXTERN_C_BEGIN
109: int PCShellSetApply_Shell(PC pc,int (*apply)(void*,Vec,Vec),void *ptr)
110: {
111: PC_Shell *shell;
114: shell = (PC_Shell*)pc->data;
115: shell->apply = apply;
116: shell->ctx = ptr;
117: return(0);
118: }
119: EXTERN_C_END
121: EXTERN_C_BEGIN
122: int PCShellSetApplyTranspose_Shell(PC pc,int (*applytranspose)(void*,Vec,Vec))
123: {
124: PC_Shell *shell;
127: shell = (PC_Shell*)pc->data;
128: shell->applytranspose = applytranspose;
129: return(0);
130: }
131: EXTERN_C_END
133: EXTERN_C_BEGIN
134: int PCShellSetName_Shell(PC pc,char *name)
135: {
136: PC_Shell *shell;
139: shell = (PC_Shell*)pc->data;
140: shell->name = name;
141: return(0);
142: }
143: EXTERN_C_END
145: EXTERN_C_BEGIN
146: int PCShellGetName_Shell(PC pc,char **name)
147: {
148: PC_Shell *shell;
151: shell = (PC_Shell*)pc->data;
152: *name = shell->name;
153: return(0);
154: }
155: EXTERN_C_END
157: EXTERN_C_BEGIN
158: int PCShellSetApplyRichardson_Shell(PC pc,int (*apply)(void*,Vec,Vec,Vec,int),void *ptr)
159: {
160: PC_Shell *shell;
163: shell = (PC_Shell*)pc->data;
164: pc->ops->applyrichardson = PCApplyRichardson_Shell;
165: shell->applyrich = apply;
166: shell->ctxrich = ptr;
167: return(0);
168: }
169: EXTERN_C_END
171: /* -------------------------------------------------------------------------------*/
173: /*@C
174: PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
175: matrix operator is changed.
177: Collective on PC
179: Input Parameters:
180: + pc - the preconditioner context
181: . setup - the application-provided setup routine
183: Calling sequence of setup:
184: .vb
185: int setup (void *ptr)
186: .ve
188: . ptr - the application context
190: Level: developer
192: .keywords: PC, shell, set, setup, user-provided
194: .seealso: PCShellSetApplyRichardson(), PCShellSetApply()
195: @*/
196: int PCShellSetSetUp(PC pc,int (*setup)(void*))
197: {
198: int ierr,(*f)(PC,int (*)(void*));
202: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)())&f);
203: if (f) {
204: (*f)(pc,setup);
205: }
206: return(0);
207: }
209: /*@C
210: PCShellSetApply - Sets routine to use as preconditioner.
212: Collective on PC
214: Input Parameters:
215: + pc - the preconditioner context
216: . apply - the application-provided preconditioning routine
217: - ptr - pointer to data needed by this routine
219: Calling sequence of apply:
220: .vb
221: int apply (void *ptr,Vec xin,Vec xout)
222: .ve
224: + ptr - the application context
225: . xin - input vector
226: - xout - output vector
228: Level: developer
230: .keywords: PC, shell, set, apply, user-provided
232: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
233: @*/
234: int PCShellSetApply(PC pc,int (*apply)(void*,Vec,Vec),void *ptr)
235: {
236: int ierr,(*f)(PC,int (*)(void*,Vec,Vec),void *);
240: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)())&f);
241: if (f) {
242: (*f)(pc,apply,ptr);
243: }
244: return(0);
245: }
247: /*@C
248: PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
250: Collective on PC
252: Input Parameters:
253: + pc - the preconditioner context
254: - apply - the application-provided preconditioning transpose routine
256: Calling sequence of apply:
257: .vb
258: int applytranspose (void *ptr,Vec xin,Vec xout)
259: .ve
261: + ptr - the application context
262: . xin - input vector
263: - xout - output vector
265: Level: developer
267: Notes:
268: Uses the same context variable as PCShellSetApply().
270: .keywords: PC, shell, set, apply, user-provided
272: .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply()
273: @*/
274: int PCShellSetApplyTranspose(PC pc,int (*applytranspose)(void*,Vec,Vec))
275: {
276: int ierr,(*f)(PC,int (*)(void*,Vec,Vec));
280: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)())&f);
281: if (f) {
282: (*f)(pc,applytranspose);
283: }
284: return(0);
285: }
287: /*@C
288: PCShellSetName - Sets an optional name to associate with a shell
289: preconditioner.
291: Not Collective
293: Input Parameters:
294: + pc - the preconditioner context
295: - name - character string describing shell preconditioner
297: Level: developer
299: .keywords: PC, shell, set, name, user-provided
301: .seealso: PCShellGetName()
302: @*/
303: int PCShellSetName(PC pc,char *name)
304: {
305: int ierr,(*f)(PC,char *);
309: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)())&f);
310: if (f) {
311: (*f)(pc,name);
312: }
313: return(0);
314: }
316: /*@C
317: PCShellGetName - Gets an optional name that the user has set for a shell
318: preconditioner.
320: Not Collective
322: Input Parameter:
323: . pc - the preconditioner context
325: Output Parameter:
326: . name - character string describing shell preconditioner
328: Level: developer
330: .keywords: PC, shell, get, name, user-provided
332: .seealso: PCShellSetName()
333: @*/
334: int PCShellGetName(PC pc,char **name)
335: {
336: int ierr,(*f)(PC,char **);
340: PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)())&f);
341: if (f) {
342: (*f)(pc,name);
343: } else {
344: SETERRQ(1,"Not shell preconditioner, cannot get name");
345: }
346: return(0);
347: }
349: /*@C
350: PCShellSetApplyRichardson - Sets routine to use as preconditioner
351: in Richardson iteration.
353: Collective on PC
355: Input Parameters:
356: + pc - the preconditioner context
357: . apply - the application-provided preconditioning routine
358: - ptr - pointer to data needed by this routine
360: Calling sequence of apply:
361: .vb
362: int apply (void *ptr,Vec b,Vec x,Vec r,int maxits)
363: .ve
365: + ptr - the application context
366: . b - right-hand-side
367: . x - current iterate
368: . r - work space
369: - maxits - number of iterations to run
371: Level: developer
373: .keywords: PC, shell, set, apply, Richardson, user-provided
375: .seealso: PCShellSetApply()
376: @*/
377: int PCShellSetApplyRichardson(PC pc,int (*apply)(void*,Vec,Vec,Vec,int),void *ptr)
378: {
379: int ierr,(*f)(PC,int (*)(void*,Vec,Vec,Vec,int),void *);
383: PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)())&f);
384: if (f) {
385: (*f)(pc,apply,ptr);
386: }
387: return(0);
388: }
390: /*
391: PCCreate_Shell - creates a new preconditioner class for use with your
392: own private data storage format. This is intended to
393: provide a simple class to use with KSP. You should
394: not use this if you plan to make a complete class.
397: Usage:
398: $ int (*mult)(void *,Vec,Vec);
399: $ int (*setup)(void *);
400: $ PCCreate(comm,&pc);
401: $ PCSetType(pc,PC_Shell);
402: $ PCShellSetApply(pc,mult,ctx);
403: $ PCShellSetSetUp(pc,setup); (optional)
405: */
406: EXTERN_C_BEGIN
407: int PCCreate_Shell(PC pc)
408: {
409: int ierr;
410: PC_Shell *shell;
413: pc->ops->destroy = PCDestroy_Shell;
414: ierr = PetscNew(PC_Shell,&shell);
415: PetscLogObjectMemory(pc,sizeof(PC_Shell));
417: pc->data = (void*)shell;
418: pc->name = 0;
420: pc->ops->apply = PCApply_Shell;
421: pc->ops->applytranspose = PCApplyTranspose_Shell;
422: pc->ops->applyrichardson = 0;
423: pc->ops->setup = PCSetUp_Shell;
424: pc->ops->view = PCView_Shell;
426: shell->apply = 0;
427: shell->applytranspose = 0;
428: shell->name = 0;
429: shell->applyrich = 0;
430: shell->ctxrich = 0;
431: shell->ctx = 0;
432: shell->setup = 0;
434: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell",
435: PCShellSetSetUp_Shell);
436: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell",
437: PCShellSetApply_Shell);
438: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C",
439: "PCShellSetApplyTranspose_Shell",
440: PCShellSetApplyTranspose_Shell);
441: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell",
442: PCShellSetName_Shell);
443: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell",
444: PCShellGetName_Shell);
445: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C",
446: "PCShellSetApplyRichardson_Shell",
447: PCShellSetApplyRichardson_Shell);
449: return(0);
450: }
451: EXTERN_C_END