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