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