xref: /petsc/src/ksp/pc/impls/shell/shellpc.c (revision 91ad83363f870b3b4a1e6ad0ca0354b4ceda2c92)
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->presolve) 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->postsolve) SETERRQ(PETSC_ERR_USER,"No postsolve() routine provided to Shell PC");
78   ierr  = (*shell->postsolve)(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   if (presolve) {
185     pc->ops->presolve = PCPreSolve_Shell;
186   } else {
187     pc->ops->presolve = 0;
188   }
189   PetscFunctionReturn(0);
190 }
191 EXTERN_C_END
192 
193 EXTERN_C_BEGIN
194 #undef __FUNCT__
195 #define __FUNCT__ "PCShellSetPostSolve_Shell"
196 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPostSolve_Shell(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec),void *ptr)
197 {
198   PC_Shell *shell;
199 
200   PetscFunctionBegin;
201   shell           = (PC_Shell*)pc->data;
202   shell->postsolve = postsolve;
203   if (postsolve) {
204     pc->ops->postsolve = PCPostSolve_Shell;
205   } else {
206     pc->ops->postsolve = 0;
207   }
208   PetscFunctionReturn(0);
209 }
210 EXTERN_C_END
211 
212 EXTERN_C_BEGIN
213 #undef __FUNCT__
214 #define __FUNCT__ "PCShellSetView_Shell"
215 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetView_Shell(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
216 {
217   PC_Shell *shell;
218 
219   PetscFunctionBegin;
220   shell        = (PC_Shell*)pc->data;
221   shell->view = view;
222   PetscFunctionReturn(0);
223 }
224 EXTERN_C_END
225 
226 EXTERN_C_BEGIN
227 #undef __FUNCT__
228 #define __FUNCT__ "PCShellSetApplyTranspose_Shell"
229 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyTranspose_Shell(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
230 {
231   PC_Shell *shell;
232 
233   PetscFunctionBegin;
234   shell                 = (PC_Shell*)pc->data;
235   shell->applytranspose = applytranspose;
236   PetscFunctionReturn(0);
237 }
238 EXTERN_C_END
239 
240 EXTERN_C_BEGIN
241 #undef __FUNCT__
242 #define __FUNCT__ "PCShellSetName_Shell"
243 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetName_Shell(PC pc,const char name[])
244 {
245   PC_Shell       *shell;
246   PetscErrorCode ierr;
247 
248   PetscFunctionBegin;
249   shell = (PC_Shell*)pc->data;
250   ierr  = PetscStrallocpy(name,&shell->name);CHKERRQ(ierr);
251   PetscFunctionReturn(0);
252 }
253 EXTERN_C_END
254 
255 EXTERN_C_BEGIN
256 #undef __FUNCT__
257 #define __FUNCT__ "PCShellGetName_Shell"
258 PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetName_Shell(PC pc,char *name[])
259 {
260   PC_Shell *shell;
261 
262   PetscFunctionBegin;
263   shell  = (PC_Shell*)pc->data;
264   *name  = shell->name;
265   PetscFunctionReturn(0);
266 }
267 EXTERN_C_END
268 
269 EXTERN_C_BEGIN
270 #undef __FUNCT__
271 #define __FUNCT__ "PCShellSetApplyRichardson_Shell"
272 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyRichardson_Shell(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt),void *ptr)
273 {
274   PC_Shell *shell;
275 
276   PetscFunctionBegin;
277   shell                     = (PC_Shell*)pc->data;
278   pc->ops->applyrichardson  = PCApplyRichardson_Shell;
279   shell->applyrich          = apply;
280   shell->ctxrich            = ptr;
281   PetscFunctionReturn(0);
282 }
283 EXTERN_C_END
284 
285 /* -------------------------------------------------------------------------------*/
286 
287 #undef __FUNCT__
288 #define __FUNCT__ "PCShellSetSetUp"
289 /*@C
290    PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
291    matrix operator is changed.
292 
293    Collective on PC
294 
295    Input Parameters:
296 +  pc - the preconditioner context
297 .  setup - the application-provided setup routine
298 
299    Calling sequence of setup:
300 .vb
301    PetscErrorCode setup (void *ptr)
302 .ve
303 
304 .  ptr - the application context
305 
306    Level: developer
307 
308 .keywords: PC, shell, set, setup, user-provided
309 
310 .seealso: PCShellSetApplyRichardson(), PCShellSetApply()
311 @*/
312 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(void*))
313 {
314   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*));
315 
316   PetscFunctionBegin;
317   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
318   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)(void))&f);CHKERRQ(ierr);
319   if (f) {
320     ierr = (*f)(pc,setup);CHKERRQ(ierr);
321   }
322   PetscFunctionReturn(0);
323 }
324 
325 
326 #undef __FUNCT__
327 #define __FUNCT__ "PCShellSetView"
328 /*@C
329    PCShellSetView - Sets routine to use as viewer of shell preconditioner
330 
331    Collective on PC
332 
333    Input Parameters:
334 +  pc - the preconditioner context
335 -  view - the application-provided view routine
336 
337    Calling sequence of apply:
338 .vb
339    PetscErrorCode view(void *ptr,PetscViewer v)
340 .ve
341 
342 +  ptr - the application context
343 -  v   - viewer
344 
345    Level: developer
346 
347 .keywords: PC, shell, set, apply, user-provided
348 
349 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
350 @*/
351 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetView(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
352 {
353   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PetscViewer));
354 
355   PetscFunctionBegin;
356   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
357   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetView_C",(void (**)(void))&f);CHKERRQ(ierr);
358   if (f) {
359     ierr = (*f)(pc,view);CHKERRQ(ierr);
360   }
361   PetscFunctionReturn(0);
362 }
363 
364 #undef __FUNCT__
365 #define __FUNCT__ "PCShellSetApply"
366 /*@C
367    PCShellSetApply - Sets routine to use as preconditioner.
368 
369    Collective on PC
370 
371    Input Parameters:
372 +  pc - the preconditioner context
373 .  apply - the application-provided preconditioning routine
374 -  ptr - pointer to data needed by this routine
375 
376    Calling sequence of apply:
377 .vb
378    PetscErrorCode apply (void *ptr,Vec xin,Vec xout)
379 .ve
380 
381 +  ptr - the application context
382 .  xin - input vector
383 -  xout - output vector
384 
385    Level: developer
386 
387 .keywords: PC, shell, set, apply, user-provided
388 
389 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
390 @*/
391 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApply(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec),void *ptr)
392 {
393   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec),void *);
394 
395   PetscFunctionBegin;
396   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
397   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)(void))&f);CHKERRQ(ierr);
398   if (f) {
399     ierr = (*f)(pc,apply,ptr);CHKERRQ(ierr);
400   }
401   PetscFunctionReturn(0);
402 }
403 
404 #undef __FUNCT__
405 #define __FUNCT__ "PCShellSetApplyTranspose"
406 /*@C
407    PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
408 
409    Collective on PC
410 
411    Input Parameters:
412 +  pc - the preconditioner context
413 -  apply - the application-provided preconditioning transpose routine
414 
415    Calling sequence of apply:
416 .vb
417    PetscErrorCode applytranspose (void *ptr,Vec xin,Vec xout)
418 .ve
419 
420 +  ptr - the application context
421 .  xin - input vector
422 -  xout - output vector
423 
424    Level: developer
425 
426    Notes:
427    Uses the same context variable as PCShellSetApply().
428 
429 .keywords: PC, shell, set, apply, user-provided
430 
431 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply()
432 @*/
433 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyTranspose(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
434 {
435   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));
436 
437   PetscFunctionBegin;
438   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
439   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
440   if (f) {
441     ierr = (*f)(pc,applytranspose);CHKERRQ(ierr);
442   }
443   PetscFunctionReturn(0);
444 }
445 
446 #undef __FUNCT__
447 #define __FUNCT__ "PCShellSetPreSolve"
448 /*@C
449    PCShellSetPreSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
450       applied. This usually does something like scale the linear system in some application
451       specific way.
452 
453    Collective on PC
454 
455    Input Parameters:
456 +  pc - the preconditioner context
457 -  presolve - the application-provided presolve routine
458 
459    Calling sequence of presolve:
460 .vb
461    PetscErrorCode presolve (void *ptr,KSP ksp,Vec b,Vec x)
462 .ve
463 
464 +  ptr - the application context
465 .  xin - input vector
466 -  xout - output vector
467 
468    Level: developer
469 
470 .keywords: PC, shell, set, apply, user-provided
471 
472 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPostSolve()
473 @*/
474 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPreSolve(PC pc,PetscErrorCode (*presolve)(void*,KSP,Vec,Vec))
475 {
476   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));
477 
478   PetscFunctionBegin;
479   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
480   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPreSolve_C",(void (**)(void))&f);CHKERRQ(ierr);
481   if (f) {
482     ierr = (*f)(pc,presolve);CHKERRQ(ierr);
483   }
484   PetscFunctionReturn(0);
485 }
486 
487 #undef __FUNCT__
488 #define __FUNCT__ "PCShellSetPostSolve"
489 /*@C
490    PCShellSetPostSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
491       applied. This usually does something like scale the linear system in some application
492       specific way.
493 
494    Collective on PC
495 
496    Input Parameters:
497 +  pc - the preconditioner context
498 -  postsolve - the application-provided presolve routine
499 
500    Calling sequence of postsolve:
501 .vb
502    PetscErrorCode postsolve(void *ptr,KSP ksp,Vec b,Vec x)
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(), PCShellSetPreSolve()
514 @*/
515 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPostSolve(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec))
516 {
517   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));
518 
519   PetscFunctionBegin;
520   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
521   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPostSolve_C",(void (**)(void))&f);CHKERRQ(ierr);
522   if (f) {
523     ierr = (*f)(pc,postsolve);CHKERRQ(ierr);
524   }
525   PetscFunctionReturn(0);
526 }
527 
528 #undef __FUNCT__
529 #define __FUNCT__ "PCShellSetName"
530 /*@C
531    PCShellSetName - Sets an optional name to associate with a shell
532    preconditioner.
533 
534    Not Collective
535 
536    Input Parameters:
537 +  pc - the preconditioner context
538 -  name - character string describing shell preconditioner
539 
540    Level: developer
541 
542 .keywords: PC, shell, set, name, user-provided
543 
544 .seealso: PCShellGetName()
545 @*/
546 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetName(PC pc,const char name[])
547 {
548   PetscErrorCode ierr,(*f)(PC,const char []);
549 
550   PetscFunctionBegin;
551   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
552   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)(void))&f);CHKERRQ(ierr);
553   if (f) {
554     ierr = (*f)(pc,name);CHKERRQ(ierr);
555   }
556   PetscFunctionReturn(0);
557 }
558 
559 #undef __FUNCT__
560 #define __FUNCT__ "PCShellGetName"
561 /*@C
562    PCShellGetName - Gets an optional name that the user has set for a shell
563    preconditioner.
564 
565    Not Collective
566 
567    Input Parameter:
568 .  pc - the preconditioner context
569 
570    Output Parameter:
571 .  name - character string describing shell preconditioner (you should not free this)
572 
573    Level: developer
574 
575 .keywords: PC, shell, get, name, user-provided
576 
577 .seealso: PCShellSetName()
578 @*/
579 PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetName(PC pc,char *name[])
580 {
581   PetscErrorCode ierr,(*f)(PC,char *[]);
582 
583   PetscFunctionBegin;
584   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
585   PetscValidPointer(name,2);
586   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)(void))&f);CHKERRQ(ierr);
587   if (f) {
588     ierr = (*f)(pc,name);CHKERRQ(ierr);
589   } else {
590     SETERRQ(PETSC_ERR_ARG_WRONG,"Not shell preconditioner, cannot get name");
591   }
592   PetscFunctionReturn(0);
593 }
594 
595 #undef __FUNCT__
596 #define __FUNCT__ "PCShellSetApplyRichardson"
597 /*@C
598    PCShellSetApplyRichardson - Sets routine to use as preconditioner
599    in Richardson iteration.
600 
601    Collective on PC
602 
603    Input Parameters:
604 +  pc - the preconditioner context
605 .  apply - the application-provided preconditioning routine
606 -  ptr - pointer to data needed by this routine
607 
608    Calling sequence of apply:
609 .vb
610    PetscErrorCode apply (void *ptr,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits)
611 .ve
612 
613 +  ptr - the application context
614 .  b - right-hand-side
615 .  x - current iterate
616 .  r - work space
617 .  rtol - relative tolerance of residual norm to stop at
618 .  abstol - absolute tolerance of residual norm to stop at
619 .  dtol - if residual norm increases by this factor than return
620 -  maxits - number of iterations to run
621 
622    Level: developer
623 
624 .keywords: PC, shell, set, apply, Richardson, user-provided
625 
626 .seealso: PCShellSetApply()
627 @*/
628 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyRichardson(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt),void *ptr)
629 {
630   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt),void *);
631 
632   PetscFunctionBegin;
633   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
634   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)(void))&f);CHKERRQ(ierr);
635   if (f) {
636     ierr = (*f)(pc,apply,ptr);CHKERRQ(ierr);
637   }
638   PetscFunctionReturn(0);
639 }
640 
641 /*MC
642    PCSHELL - Creates a new preconditioner class for use with your
643               own private data storage format.
644 
645    Level: advanced
646 
647    Concepts: providing your own preconditioner
648 
649   Usage:
650 $             PetscErrorCode (*mult)(void*,Vec,Vec);
651 $             PetscErrorCode (*setup)(void*);
652 $             PCCreate(comm,&pc);
653 $             PCSetType(pc,PCSHELL);
654 $             PCShellSetApply(pc,mult,ctx);
655 $             PCShellSetSetUp(pc,setup);       (optional)
656 
657 .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
658            MATSHELL, PCShellSetUp(), PCShellSetApply(), PCShellSetView(),
659            PCShellSetApplyTranpose(), PCShellSetName(), PCShellSetApplyRichardson(),
660            PCShellGetName()
661 M*/
662 
663 EXTERN_C_BEGIN
664 #undef __FUNCT__
665 #define __FUNCT__ "PCCreate_Shell"
666 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_Shell(PC pc)
667 {
668   PetscErrorCode ierr;
669   PC_Shell       *shell;
670 
671   PetscFunctionBegin;
672   pc->ops->destroy    = PCDestroy_Shell;
673   ierr                = PetscNew(PC_Shell,&shell);CHKERRQ(ierr);
674   ierr = PetscLogObjectMemory(pc,sizeof(PC_Shell));CHKERRQ(ierr);
675   pc->data         = (void*)shell;
676   pc->name         = 0;
677 
678   pc->ops->apply           = PCApply_Shell;
679   pc->ops->view            = PCView_Shell;
680   pc->ops->applytranspose  = PCApplyTranspose_Shell;
681   pc->ops->applyrichardson = 0;
682   pc->ops->setup           = PCSetUp_Shell;
683   pc->ops->presolve        = 0;
684   pc->ops->postsolve       = 0;
685   pc->ops->view            = PCView_Shell;
686 
687   shell->apply          = 0;
688   shell->applytranspose = 0;
689   shell->name           = 0;
690   shell->applyrich      = 0;
691   shell->presolve       = 0;
692   shell->postsolve      = 0;
693   shell->ctxrich        = 0;
694   shell->ctx            = 0;
695   shell->setup          = 0;
696   shell->view           = 0;
697 
698   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell",
699                     PCShellSetSetUp_Shell);CHKERRQ(ierr);
700   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell",
701                     PCShellSetApply_Shell);CHKERRQ(ierr);
702   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPreSolve_C","PCShellSetPreSolve_Shell",
703                     PCShellSetPreSolve_Shell);CHKERRQ(ierr);
704   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPostSolve_C","PCShellSetPostSolve_Shell",
705                     PCShellSetPostSolve_Shell);CHKERRQ(ierr);
706   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell",
707                     PCShellSetView_Shell);CHKERRQ(ierr);
708   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C",
709                     "PCShellSetApplyTranspose_Shell",
710                     PCShellSetApplyTranspose_Shell);CHKERRQ(ierr);
711   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell",
712                     PCShellSetName_Shell);CHKERRQ(ierr);
713   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell",
714                     PCShellGetName_Shell);CHKERRQ(ierr);
715   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C",
716                     "PCShellSetApplyRichardson_Shell",
717                     PCShellSetApplyRichardson_Shell);CHKERRQ(ierr);
718 
719   PetscFunctionReturn(0);
720 }
721 EXTERN_C_END
722 
723 
724 
725 
726 
727 
728