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