xref: /petsc/src/ksp/pc/impls/shell/shellpc.c (revision 593a00ba379f3e4c24722dd323a07a7f06866c96)
1 #define PETSCKSP_DLL
2 
3 /*
4    This provides a simple shell for Fortran (and C programmers) to
5   create their own preconditioner without writing much interface code.
6 */
7 
8 #include "src/ksp/pc/pcimpl.h"        /*I "petscpc.h" I*/
9 #include "vecimpl.h"
10 
11 EXTERN_C_BEGIN
12 typedef struct {
13   void           *ctx;                     /* user provided contexts for preconditioner */
14   PetscErrorCode (*destroy)(void*);
15   PetscErrorCode (*setup)(void*);
16   PetscErrorCode (*apply)(void*,Vec,Vec);
17   PetscErrorCode (*presolve)(void*,KSP,Vec,Vec);
18   PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec);
19   PetscErrorCode (*view)(void*,PetscViewer);
20   PetscErrorCode (*applytranspose)(void*,Vec,Vec);
21   PetscErrorCode (*applyrich)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt);
22   char           *name;
23 } PC_Shell;
24 EXTERN_C_END
25 
26 #undef __FUNCT__
27 #define __FUNCT__ "PCShellGetContext"
28 /*@
29     PCShellGetContext - Returns the user-provided context associated with a shell PC
30 
31     Not Collective
32 
33     Input Parameter:
34 .   pc - should have been created with PCCreateShell()
35 
36     Output Parameter:
37 .   ctx - the user provided context
38 
39     Level: advanced
40 
41     Notes:
42     This routine is intended for use within various shell routines
43 
44 .keywords: PC, shell, get, context
45 
46 .seealso: PCCreateShell(), PCShellSetContext()
47 @*/
48 PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetContext(PC pc,void **ctx)
49 {
50   PetscErrorCode ierr;
51   PetscTruth     flg;
52 
53   PetscFunctionBegin;
54   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
55   PetscValidPointer(ctx,2);
56   ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);CHKERRQ(ierr);
57   if (!flg) *ctx = 0;
58   else      *ctx = ((PC_Shell*)(pc->data))->ctx;
59   PetscFunctionReturn(0);
60 }
61 
62 #undef __FUNCT__
63 #define __FUNCT__ "PCShellSetContext"
64 /*@C
65     PCShellSetContext - sets the context for a shell PC
66 
67    Collective on PC
68 
69     Input Parameters:
70 +   pc - the shell PC
71 -   ctx - the context
72 
73    Level: advanced
74 
75    Fortran Notes: The context can only be an integer or a PetscObject
76       unfortunately it cannot be a Fortran array or derived type.
77 
78 .seealso: PCCreateShell(), PCShellGetContext()
79 @*/
80 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetContext(PC pc,void *ctx)
81 {
82   PC_Shell      *shell = (PC_Shell*)pc->data;
83   PetscErrorCode ierr;
84   PetscTruth     flg;
85 
86   PetscFunctionBegin;
87   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
88   ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);CHKERRQ(ierr);
89   if (flg) {
90     shell->ctx = ctx;
91   }
92   PetscFunctionReturn(0);
93 }
94 
95 #undef __FUNCT__
96 #define __FUNCT__ "PCSetUp_Shell"
97 static PetscErrorCode PCSetUp_Shell(PC pc)
98 {
99   PC_Shell       *shell;
100   PetscErrorCode ierr;
101 
102   PetscFunctionBegin;
103   shell = (PC_Shell*)pc->data;
104   if (shell->setup) {
105     ierr  = (*shell->setup)(shell->ctx);CHKERRQ(ierr);
106   }
107   PetscFunctionReturn(0);
108 }
109 
110 #undef __FUNCT__
111 #define __FUNCT__ "PCApply_Shell"
112 static PetscErrorCode PCApply_Shell(PC pc,Vec x,Vec y)
113 {
114   PC_Shell       *shell;
115   PetscErrorCode ierr;
116 
117   PetscFunctionBegin;
118   shell = (PC_Shell*)pc->data;
119   if (!shell->apply) SETERRQ(PETSC_ERR_USER,"No apply() routine provided to Shell PC");
120   ierr  = (*shell->apply)(shell->ctx,x,y);CHKERRQ(ierr);
121   PetscFunctionReturn(0);
122 }
123 
124 #undef __FUNCT__
125 #define __FUNCT__ "PCPreSolve_Shell"
126 static PetscErrorCode PCPreSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
127 {
128   PC_Shell       *shell;
129   PetscErrorCode ierr;
130 
131   PetscFunctionBegin;
132   shell = (PC_Shell*)pc->data;
133   if (!shell->presolve) SETERRQ(PETSC_ERR_USER,"No presolve() routine provided to Shell PC");
134   ierr  = (*shell->presolve)(shell->ctx,ksp,b,x);CHKERRQ(ierr);
135   PetscFunctionReturn(0);
136 }
137 
138 #undef __FUNCT__
139 #define __FUNCT__ "PCPostSolve_Shell"
140 static PetscErrorCode PCPostSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
141 {
142   PC_Shell       *shell;
143   PetscErrorCode ierr;
144 
145   PetscFunctionBegin;
146   shell = (PC_Shell*)pc->data;
147   if (!shell->postsolve) SETERRQ(PETSC_ERR_USER,"No postsolve() routine provided to Shell PC");
148   ierr  = (*shell->postsolve)(shell->ctx,ksp,b,x);CHKERRQ(ierr);
149   PetscFunctionReturn(0);
150 }
151 
152 #undef __FUNCT__
153 #define __FUNCT__ "PCApplyTranspose_Shell"
154 static PetscErrorCode PCApplyTranspose_Shell(PC pc,Vec x,Vec y)
155 {
156   PC_Shell       *shell;
157   PetscErrorCode ierr;
158 
159   PetscFunctionBegin;
160   shell = (PC_Shell*)pc->data;
161   if (!shell->applytranspose) SETERRQ(PETSC_ERR_USER,"No applytranspose() routine provided to Shell PC");
162   ierr  = (*shell->applytranspose)(shell->ctx,x,y);CHKERRQ(ierr);
163   PetscFunctionReturn(0);
164 }
165 
166 #undef __FUNCT__
167 #define __FUNCT__ "PCApplyRichardson_Shell"
168 static PetscErrorCode PCApplyRichardson_Shell(PC pc,Vec x,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt it)
169 {
170   PetscErrorCode ierr;
171   PC_Shell       *shell;
172 
173   PetscFunctionBegin;
174   shell = (PC_Shell*)pc->data;
175   ierr  = (*shell->applyrich)(shell->ctx,x,y,w,rtol,abstol,dtol,it);CHKERRQ(ierr);
176   PetscFunctionReturn(0);
177 }
178 
179 #undef __FUNCT__
180 #define __FUNCT__ "PCDestroy_Shell"
181 static PetscErrorCode PCDestroy_Shell(PC pc)
182 {
183   PC_Shell       *shell = (PC_Shell*)pc->data;
184   PetscErrorCode ierr;
185 
186   PetscFunctionBegin;
187   if (shell->name) {ierr = PetscFree(shell->name);CHKERRQ(ierr);}
188   if (shell->destroy) {
189     ierr  = (*shell->destroy)(shell->ctx);CHKERRQ(ierr);
190   }
191   ierr = PetscFree(shell);CHKERRQ(ierr);
192   PetscFunctionReturn(0);
193 }
194 
195 #undef __FUNCT__
196 #define __FUNCT__ "PCView_Shell"
197 static PetscErrorCode PCView_Shell(PC pc,PetscViewer viewer)
198 {
199   PC_Shell       *shell = (PC_Shell*)pc->data;
200   PetscErrorCode ierr;
201   PetscTruth     iascii;
202 
203   PetscFunctionBegin;
204   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
205   if (iascii) {
206     if (shell->name) {ierr = PetscViewerASCIIPrintf(viewer,"  Shell: %s\n",shell->name);CHKERRQ(ierr);}
207     else             {ierr = PetscViewerASCIIPrintf(viewer,"  Shell: no name\n");CHKERRQ(ierr);}
208   }
209   if (shell->view) {
210     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
211     ierr  = (*shell->view)(shell->ctx,viewer);CHKERRQ(ierr);
212     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
213   }
214   PetscFunctionReturn(0);
215 }
216 
217 /* ------------------------------------------------------------------------------*/
218 EXTERN_C_BEGIN
219 #undef __FUNCT__
220 #define __FUNCT__ "PCShellSetDestroy_Shell"
221 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetDestroy_Shell(PC pc, PetscErrorCode (*destroy)(void*))
222 {
223   PC_Shell *shell;
224 
225   PetscFunctionBegin;
226   shell          = (PC_Shell*)pc->data;
227   shell->destroy = destroy;
228   PetscFunctionReturn(0);
229 }
230 EXTERN_C_END
231 
232 EXTERN_C_BEGIN
233 #undef __FUNCT__
234 #define __FUNCT__ "PCShellSetSetUp_Shell"
235 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(void*))
236 {
237   PC_Shell *shell;
238 
239   PetscFunctionBegin;
240   shell        = (PC_Shell*)pc->data;
241   shell->setup = setup;
242   PetscFunctionReturn(0);
243 }
244 EXTERN_C_END
245 
246 EXTERN_C_BEGIN
247 #undef __FUNCT__
248 #define __FUNCT__ "PCShellSetApply_Shell"
249 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApply_Shell(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec))
250 {
251   PC_Shell *shell;
252 
253   PetscFunctionBegin;
254   shell        = (PC_Shell*)pc->data;
255   shell->apply = apply;
256   PetscFunctionReturn(0);
257 }
258 EXTERN_C_END
259 
260 EXTERN_C_BEGIN
261 #undef __FUNCT__
262 #define __FUNCT__ "PCShellSetPreSolve_Shell"
263 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPreSolve_Shell(PC pc,PetscErrorCode (*presolve)(void*,KSP,Vec,Vec))
264 {
265   PC_Shell *shell;
266 
267   PetscFunctionBegin;
268   shell             = (PC_Shell*)pc->data;
269   shell->presolve   = presolve;
270   if (presolve) {
271     pc->ops->presolve = PCPreSolve_Shell;
272   } else {
273     pc->ops->presolve = 0;
274   }
275   PetscFunctionReturn(0);
276 }
277 EXTERN_C_END
278 
279 EXTERN_C_BEGIN
280 #undef __FUNCT__
281 #define __FUNCT__ "PCShellSetPostSolve_Shell"
282 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPostSolve_Shell(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec))
283 {
284   PC_Shell *shell;
285 
286   PetscFunctionBegin;
287   shell           = (PC_Shell*)pc->data;
288   shell->postsolve = postsolve;
289   if (postsolve) {
290     pc->ops->postsolve = PCPostSolve_Shell;
291   } else {
292     pc->ops->postsolve = 0;
293   }
294   PetscFunctionReturn(0);
295 }
296 EXTERN_C_END
297 
298 EXTERN_C_BEGIN
299 #undef __FUNCT__
300 #define __FUNCT__ "PCShellSetView_Shell"
301 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetView_Shell(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
302 {
303   PC_Shell *shell;
304 
305   PetscFunctionBegin;
306   shell        = (PC_Shell*)pc->data;
307   shell->view = view;
308   PetscFunctionReturn(0);
309 }
310 EXTERN_C_END
311 
312 EXTERN_C_BEGIN
313 #undef __FUNCT__
314 #define __FUNCT__ "PCShellSetApplyTranspose_Shell"
315 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyTranspose_Shell(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
316 {
317   PC_Shell *shell;
318 
319   PetscFunctionBegin;
320   shell                 = (PC_Shell*)pc->data;
321   shell->applytranspose = applytranspose;
322   PetscFunctionReturn(0);
323 }
324 EXTERN_C_END
325 
326 EXTERN_C_BEGIN
327 #undef __FUNCT__
328 #define __FUNCT__ "PCShellSetName_Shell"
329 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetName_Shell(PC pc,const char name[])
330 {
331   PC_Shell       *shell;
332   PetscErrorCode ierr;
333 
334   PetscFunctionBegin;
335   shell = (PC_Shell*)pc->data;
336   ierr  = PetscStrfree(shell->name);CHKERRQ(ierr);
337   ierr  = PetscStrallocpy(name,&shell->name);CHKERRQ(ierr);
338   PetscFunctionReturn(0);
339 }
340 EXTERN_C_END
341 
342 EXTERN_C_BEGIN
343 #undef __FUNCT__
344 #define __FUNCT__ "PCShellGetName_Shell"
345 PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetName_Shell(PC pc,char *name[])
346 {
347   PC_Shell *shell;
348 
349   PetscFunctionBegin;
350   shell  = (PC_Shell*)pc->data;
351   *name  = shell->name;
352   PetscFunctionReturn(0);
353 }
354 EXTERN_C_END
355 
356 EXTERN_C_BEGIN
357 #undef __FUNCT__
358 #define __FUNCT__ "PCShellSetApplyRichardson_Shell"
359 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyRichardson_Shell(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt))
360 {
361   PC_Shell *shell;
362 
363   PetscFunctionBegin;
364   shell                     = (PC_Shell*)pc->data;
365   pc->ops->applyrichardson  = PCApplyRichardson_Shell;
366   shell->applyrich          = apply;
367   PetscFunctionReturn(0);
368 }
369 EXTERN_C_END
370 
371 /* -------------------------------------------------------------------------------*/
372 
373 #undef __FUNCT__
374 #define __FUNCT__ "PCShellSetDestroy"
375 /*@C
376    PCShellSetDestroy - Sets routine to use to destroy the user-provided
377    application context.
378 
379    Collective on PC
380 
381    Input Parameters:
382 +  pc - the preconditioner context
383 .  destroy - the application-provided destroy routine
384 
385    Calling sequence of destroy:
386 .vb
387    PetscErrorCode destroy (void *ptr)
388 .ve
389 
390 .  ptr - the application context
391 
392    Level: developer
393 
394 .keywords: PC, shell, set, destroy, user-provided
395 
396 .seealso: PCShellSetApply(), PCShellSetContext()
397 @*/
398 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetDestroy(PC pc,PetscErrorCode (*destroy)(void*))
399 {
400   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*));
401 
402   PetscFunctionBegin;
403   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
404   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetDestroy_C",(void (**)(void))&f);CHKERRQ(ierr);
405   if (f) {
406     ierr = (*f)(pc,destroy);CHKERRQ(ierr);
407   }
408   PetscFunctionReturn(0);
409 }
410 
411 
412 #undef __FUNCT__
413 #define __FUNCT__ "PCShellSetSetUp"
414 /*@C
415    PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
416    matrix operator is changed.
417 
418    Collective on PC
419 
420    Input Parameters:
421 +  pc - the preconditioner context
422 .  setup - the application-provided setup routine
423 
424    Calling sequence of setup:
425 .vb
426    PetscErrorCode setup (void *ptr)
427 .ve
428 
429 .  ptr - the application context
430 
431    Level: developer
432 
433 .keywords: PC, shell, set, setup, user-provided
434 
435 .seealso: PCShellSetApplyRichardson(), PCShellSetApply(), PCShellSetContext()
436 @*/
437 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(void*))
438 {
439   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*));
440 
441   PetscFunctionBegin;
442   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
443   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)(void))&f);CHKERRQ(ierr);
444   if (f) {
445     ierr = (*f)(pc,setup);CHKERRQ(ierr);
446   }
447   PetscFunctionReturn(0);
448 }
449 
450 
451 #undef __FUNCT__
452 #define __FUNCT__ "PCShellSetView"
453 /*@C
454    PCShellSetView - Sets routine to use as viewer of shell preconditioner
455 
456    Collective on PC
457 
458    Input Parameters:
459 +  pc - the preconditioner context
460 -  view - the application-provided view routine
461 
462    Calling sequence of apply:
463 .vb
464    PetscErrorCode view(void *ptr,PetscViewer v)
465 .ve
466 
467 +  ptr - the application context
468 -  v   - viewer
469 
470    Level: developer
471 
472 .keywords: PC, shell, set, apply, user-provided
473 
474 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
475 @*/
476 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetView(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
477 {
478   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PetscViewer));
479 
480   PetscFunctionBegin;
481   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
482   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetView_C",(void (**)(void))&f);CHKERRQ(ierr);
483   if (f) {
484     ierr = (*f)(pc,view);CHKERRQ(ierr);
485   }
486   PetscFunctionReturn(0);
487 }
488 
489 #undef __FUNCT__
490 #define __FUNCT__ "PCShellSetApply"
491 /*@C
492    PCShellSetApply - Sets routine to use as preconditioner.
493 
494    Collective on PC
495 
496    Input Parameters:
497 +  pc - the preconditioner context
498 -  apply - the application-provided preconditioning routine
499 
500    Calling sequence of apply:
501 .vb
502    PetscErrorCode apply (void *ptr,Vec xin,Vec xout)
503 .ve
504 
505 +  ptr - the application context
506 .  xin - input vector
507 -  xout - output vector
508 
509    Level: developer
510 
511 .keywords: PC, shell, set, apply, user-provided
512 
513 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext()
514 @*/
515 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApply(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec))
516 {
517   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));
518 
519   PetscFunctionBegin;
520   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
521   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)(void))&f);CHKERRQ(ierr);
522   if (f) {
523     ierr = (*f)(pc,apply);CHKERRQ(ierr);
524   }
525   PetscFunctionReturn(0);
526 }
527 
528 #undef __FUNCT__
529 #define __FUNCT__ "PCShellSetApplyTranspose"
530 /*@C
531    PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
532 
533    Collective on PC
534 
535    Input Parameters:
536 +  pc - the preconditioner context
537 -  apply - the application-provided preconditioning transpose routine
538 
539    Calling sequence of apply:
540 .vb
541    PetscErrorCode applytranspose (void *ptr,Vec xin,Vec xout)
542 .ve
543 
544 +  ptr - the application context
545 .  xin - input vector
546 -  xout - output vector
547 
548    Level: developer
549 
550    Notes:
551    Uses the same context variable as PCShellSetApply().
552 
553 .keywords: PC, shell, set, apply, user-provided
554 
555 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply(), PCSetContext()
556 @*/
557 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyTranspose(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
558 {
559   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));
560 
561   PetscFunctionBegin;
562   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
563   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
564   if (f) {
565     ierr = (*f)(pc,applytranspose);CHKERRQ(ierr);
566   }
567   PetscFunctionReturn(0);
568 }
569 
570 #undef __FUNCT__
571 #define __FUNCT__ "PCShellSetPreSolve"
572 /*@C
573    PCShellSetPreSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
574       applied. This usually does something like scale the linear system in some application
575       specific way.
576 
577    Collective on PC
578 
579    Input Parameters:
580 +  pc - the preconditioner context
581 -  presolve - the application-provided presolve routine
582 
583    Calling sequence of presolve:
584 .vb
585    PetscErrorCode presolve (void *ptr,KSP ksp,Vec b,Vec x)
586 .ve
587 
588 +  ptr - the application context
589 .  xin - input vector
590 -  xout - output vector
591 
592    Level: developer
593 
594 .keywords: PC, shell, set, apply, user-provided
595 
596 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPostSolve(), PCShellSetContext()
597 @*/
598 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPreSolve(PC pc,PetscErrorCode (*presolve)(void*,KSP,Vec,Vec))
599 {
600   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));
601 
602   PetscFunctionBegin;
603   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
604   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPreSolve_C",(void (**)(void))&f);CHKERRQ(ierr);
605   if (f) {
606     ierr = (*f)(pc,presolve);CHKERRQ(ierr);
607   }
608   PetscFunctionReturn(0);
609 }
610 
611 #undef __FUNCT__
612 #define __FUNCT__ "PCShellSetPostSolve"
613 /*@C
614    PCShellSetPostSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
615       applied. This usually does something like scale the linear system in some application
616       specific way.
617 
618    Collective on PC
619 
620    Input Parameters:
621 +  pc - the preconditioner context
622 -  postsolve - the application-provided presolve routine
623 
624    Calling sequence of postsolve:
625 .vb
626    PetscErrorCode postsolve(void *ptr,KSP ksp,Vec b,Vec x)
627 .ve
628 
629 +  ptr - the application context
630 .  xin - input vector
631 -  xout - output vector
632 
633    Level: developer
634 
635 .keywords: PC, shell, set, apply, user-provided
636 
637 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPreSolve(), PCShellSetContext()
638 @*/
639 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPostSolve(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec))
640 {
641   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));
642 
643   PetscFunctionBegin;
644   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
645   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPostSolve_C",(void (**)(void))&f);CHKERRQ(ierr);
646   if (f) {
647     ierr = (*f)(pc,postsolve);CHKERRQ(ierr);
648   }
649   PetscFunctionReturn(0);
650 }
651 
652 #undef __FUNCT__
653 #define __FUNCT__ "PCShellSetName"
654 /*@C
655    PCShellSetName - Sets an optional name to associate with a shell
656    preconditioner.
657 
658    Not Collective
659 
660    Input Parameters:
661 +  pc - the preconditioner context
662 -  name - character string describing shell preconditioner
663 
664    Level: developer
665 
666 .keywords: PC, shell, set, name, user-provided
667 
668 .seealso: PCShellGetName()
669 @*/
670 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetName(PC pc,const char name[])
671 {
672   PetscErrorCode ierr,(*f)(PC,const char []);
673 
674   PetscFunctionBegin;
675   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
676   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)(void))&f);CHKERRQ(ierr);
677   if (f) {
678     ierr = (*f)(pc,name);CHKERRQ(ierr);
679   }
680   PetscFunctionReturn(0);
681 }
682 
683 #undef __FUNCT__
684 #define __FUNCT__ "PCShellGetName"
685 /*@C
686    PCShellGetName - Gets an optional name that the user has set for a shell
687    preconditioner.
688 
689    Not Collective
690 
691    Input Parameter:
692 .  pc - the preconditioner context
693 
694    Output Parameter:
695 .  name - character string describing shell preconditioner (you should not free this)
696 
697    Level: developer
698 
699 .keywords: PC, shell, get, name, user-provided
700 
701 .seealso: PCShellSetName()
702 @*/
703 PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetName(PC pc,char *name[])
704 {
705   PetscErrorCode ierr,(*f)(PC,char *[]);
706 
707   PetscFunctionBegin;
708   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
709   PetscValidPointer(name,2);
710   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)(void))&f);CHKERRQ(ierr);
711   if (f) {
712     ierr = (*f)(pc,name);CHKERRQ(ierr);
713   } else {
714     SETERRQ(PETSC_ERR_ARG_WRONG,"Not shell preconditioner, cannot get name");
715   }
716   PetscFunctionReturn(0);
717 }
718 
719 #undef __FUNCT__
720 #define __FUNCT__ "PCShellSetApplyRichardson"
721 /*@C
722    PCShellSetApplyRichardson - Sets routine to use as preconditioner
723    in Richardson iteration.
724 
725    Collective on PC
726 
727    Input Parameters:
728 +  pc - the preconditioner context
729 -  apply - the application-provided preconditioning routine
730 
731    Calling sequence of apply:
732 .vb
733    PetscErrorCode apply (void *ptr,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits)
734 .ve
735 
736 +  ptr - the application context
737 .  b - right-hand-side
738 .  x - current iterate
739 .  r - work space
740 .  rtol - relative tolerance of residual norm to stop at
741 .  abstol - absolute tolerance of residual norm to stop at
742 .  dtol - if residual norm increases by this factor than return
743 -  maxits - number of iterations to run
744 
745    Level: developer
746 
747 .keywords: PC, shell, set, apply, Richardson, user-provided
748 
749 .seealso: PCShellSetApply(), PCShellSetContext()
750 @*/
751 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyRichardson(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt))
752 {
753   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt));
754 
755   PetscFunctionBegin;
756   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
757   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)(void))&f);CHKERRQ(ierr);
758   if (f) {
759     ierr = (*f)(pc,apply);CHKERRQ(ierr);
760   }
761   PetscFunctionReturn(0);
762 }
763 
764 /*MC
765    PCSHELL - Creates a new preconditioner class for use with your
766               own private data storage format.
767 
768    Level: advanced
769 
770    Concepts: providing your own preconditioner
771 
772   Usage:
773 $             PetscErrorCode (*mult)(void*,Vec,Vec);
774 $             PetscErrorCode (*setup)(void*);
775 $             PCCreate(comm,&pc);
776 $             PCSetType(pc,PCSHELL);
777 $             PCShellSetApply(pc,mult);
778 $             PCShellSetContext(pc,ctx)
779 $             PCShellSetSetUp(pc,setup);       (optional)
780 
781 .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
782            MATSHELL, PCShellSetUp(), PCShellSetApply(), PCShellSetView(),
783            PCShellSetApplyTranpose(), PCShellSetName(), PCShellSetApplyRichardson(),
784            PCShellGetName(), PCShellSetContext(), PCShellGetContext()
785 M*/
786 
787 EXTERN_C_BEGIN
788 #undef __FUNCT__
789 #define __FUNCT__ "PCCreate_Shell"
790 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_Shell(PC pc)
791 {
792   PetscErrorCode ierr;
793   PC_Shell       *shell;
794 
795   PetscFunctionBegin;
796   pc->ops->destroy    = PCDestroy_Shell;
797   ierr                = PetscNew(PC_Shell,&shell);CHKERRQ(ierr);
798   ierr = PetscLogObjectMemory(pc,sizeof(PC_Shell));CHKERRQ(ierr);
799   pc->data         = (void*)shell;
800   pc->name         = 0;
801 
802   pc->ops->apply           = PCApply_Shell;
803   pc->ops->view            = PCView_Shell;
804   pc->ops->applytranspose  = PCApplyTranspose_Shell;
805   pc->ops->applyrichardson = 0;
806   pc->ops->setup           = PCSetUp_Shell;
807   pc->ops->presolve        = 0;
808   pc->ops->postsolve       = 0;
809   pc->ops->view            = PCView_Shell;
810 
811   shell->apply          = 0;
812   shell->applytranspose = 0;
813   shell->name           = 0;
814   shell->applyrich      = 0;
815   shell->presolve       = 0;
816   shell->postsolve      = 0;
817   shell->ctx            = 0;
818   shell->setup          = 0;
819   shell->view           = 0;
820   shell->destroy        = 0;
821 
822   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetDestroy_C","PCShellSetDestroy_Shell",
823                     PCShellSetDestroy_Shell);CHKERRQ(ierr);
824   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell",
825                     PCShellSetSetUp_Shell);CHKERRQ(ierr);
826   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell",
827                     PCShellSetApply_Shell);CHKERRQ(ierr);
828   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPreSolve_C","PCShellSetPreSolve_Shell",
829                     PCShellSetPreSolve_Shell);CHKERRQ(ierr);
830   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPostSolve_C","PCShellSetPostSolve_Shell",
831                     PCShellSetPostSolve_Shell);CHKERRQ(ierr);
832   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell",
833                     PCShellSetView_Shell);CHKERRQ(ierr);
834   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C","PCShellSetApplyTranspose_Shell",
835                     PCShellSetApplyTranspose_Shell);CHKERRQ(ierr);
836   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell",
837                     PCShellSetName_Shell);CHKERRQ(ierr);
838   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell",
839                     PCShellGetName_Shell);CHKERRQ(ierr);
840   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C","PCShellSetApplyRichardson_Shell",
841                     PCShellSetApplyRichardson_Shell);CHKERRQ(ierr);
842   PetscFunctionReturn(0);
843 }
844 EXTERN_C_END
845 
846 
847 
848 
849 
850 
851