xref: /petsc/src/ksp/pc/impls/shell/shellpc.c (revision f259bd47db2537c0c1948ca59840a8a8f5c67e64)
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 = PetscStrfree(shell->name);CHKERRQ(ierr);
325   ierr = PetscStrallocpy(name,&shell->name);CHKERRQ(ierr);
326   PetscFunctionReturn(0);
327 }
328 EXTERN_C_END
329 
330 EXTERN_C_BEGIN
331 #undef __FUNCT__
332 #define __FUNCT__ "PCShellGetName_Shell"
333 PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetName_Shell(PC pc,char *name[])
334 {
335   PC_Shell *shell;
336 
337   PetscFunctionBegin;
338   shell  = (PC_Shell*)pc->data;
339   *name  = shell->name;
340   PetscFunctionReturn(0);
341 }
342 EXTERN_C_END
343 
344 EXTERN_C_BEGIN
345 #undef __FUNCT__
346 #define __FUNCT__ "PCShellSetApplyRichardson_Shell"
347 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyRichardson_Shell(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt))
348 {
349   PC_Shell *shell;
350 
351   PetscFunctionBegin;
352   shell                     = (PC_Shell*)pc->data;
353   pc->ops->applyrichardson  = PCApplyRichardson_Shell;
354   shell->applyrich          = apply;
355   PetscFunctionReturn(0);
356 }
357 EXTERN_C_END
358 
359 /* -------------------------------------------------------------------------------*/
360 
361 #undef __FUNCT__
362 #define __FUNCT__ "PCShellSetSetUp"
363 /*@C
364    PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
365    matrix operator is changed.
366 
367    Collective on PC
368 
369    Input Parameters:
370 +  pc - the preconditioner context
371 .  setup - the application-provided setup routine
372 
373    Calling sequence of setup:
374 .vb
375    PetscErrorCode setup (void *ptr)
376 .ve
377 
378 .  ptr - the application context
379 
380    Level: developer
381 
382 .keywords: PC, shell, set, setup, user-provided
383 
384 .seealso: PCShellSetApplyRichardson(), PCShellSetApply(), PCShellSetContext()
385 @*/
386 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(void*))
387 {
388   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*));
389 
390   PetscFunctionBegin;
391   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
392   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)(void))&f);CHKERRQ(ierr);
393   if (f) {
394     ierr = (*f)(pc,setup);CHKERRQ(ierr);
395   }
396   PetscFunctionReturn(0);
397 }
398 
399 
400 #undef __FUNCT__
401 #define __FUNCT__ "PCShellSetView"
402 /*@C
403    PCShellSetView - Sets routine to use as viewer of shell preconditioner
404 
405    Collective on PC
406 
407    Input Parameters:
408 +  pc - the preconditioner context
409 -  view - the application-provided view routine
410 
411    Calling sequence of apply:
412 .vb
413    PetscErrorCode view(void *ptr,PetscViewer v)
414 .ve
415 
416 +  ptr - the application context
417 -  v   - viewer
418 
419    Level: developer
420 
421 .keywords: PC, shell, set, apply, user-provided
422 
423 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
424 @*/
425 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetView(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
426 {
427   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PetscViewer));
428 
429   PetscFunctionBegin;
430   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
431   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetView_C",(void (**)(void))&f);CHKERRQ(ierr);
432   if (f) {
433     ierr = (*f)(pc,view);CHKERRQ(ierr);
434   }
435   PetscFunctionReturn(0);
436 }
437 
438 #undef __FUNCT__
439 #define __FUNCT__ "PCShellSetApply"
440 /*@C
441    PCShellSetApply - Sets routine to use as preconditioner.
442 
443    Collective on PC
444 
445    Input Parameters:
446 +  pc - the preconditioner context
447 -  apply - the application-provided preconditioning routine
448 
449    Calling sequence of apply:
450 .vb
451    PetscErrorCode apply (void *ptr,Vec xin,Vec xout)
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(), PCShellSetContext()
463 @*/
464 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApply(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec))
465 {
466   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));
467 
468   PetscFunctionBegin;
469   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
470   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)(void))&f);CHKERRQ(ierr);
471   if (f) {
472     ierr = (*f)(pc,apply);CHKERRQ(ierr);
473   }
474   PetscFunctionReturn(0);
475 }
476 
477 #undef __FUNCT__
478 #define __FUNCT__ "PCShellSetApplyTranspose"
479 /*@C
480    PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
481 
482    Collective on PC
483 
484    Input Parameters:
485 +  pc - the preconditioner context
486 -  apply - the application-provided preconditioning transpose routine
487 
488    Calling sequence of apply:
489 .vb
490    PetscErrorCode applytranspose (void *ptr,Vec xin,Vec xout)
491 .ve
492 
493 +  ptr - the application context
494 .  xin - input vector
495 -  xout - output vector
496 
497    Level: developer
498 
499    Notes:
500    Uses the same context variable as PCShellSetApply().
501 
502 .keywords: PC, shell, set, apply, user-provided
503 
504 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply(), PCSetContext()
505 @*/
506 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyTranspose(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
507 {
508   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));
509 
510   PetscFunctionBegin;
511   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
512   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
513   if (f) {
514     ierr = (*f)(pc,applytranspose);CHKERRQ(ierr);
515   }
516   PetscFunctionReturn(0);
517 }
518 
519 #undef __FUNCT__
520 #define __FUNCT__ "PCShellSetPreSolve"
521 /*@C
522    PCShellSetPreSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
523       applied. This usually does something like scale the linear system in some application
524       specific way.
525 
526    Collective on PC
527 
528    Input Parameters:
529 +  pc - the preconditioner context
530 -  presolve - the application-provided presolve routine
531 
532    Calling sequence of presolve:
533 .vb
534    PetscErrorCode presolve (void *ptr,KSP ksp,Vec b,Vec x)
535 .ve
536 
537 +  ptr - the application context
538 .  xin - input vector
539 -  xout - output vector
540 
541    Level: developer
542 
543 .keywords: PC, shell, set, apply, user-provided
544 
545 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPostSolve(), PCShellSetContext()
546 @*/
547 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPreSolve(PC pc,PetscErrorCode (*presolve)(void*,KSP,Vec,Vec))
548 {
549   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));
550 
551   PetscFunctionBegin;
552   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
553   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPreSolve_C",(void (**)(void))&f);CHKERRQ(ierr);
554   if (f) {
555     ierr = (*f)(pc,presolve);CHKERRQ(ierr);
556   }
557   PetscFunctionReturn(0);
558 }
559 
560 #undef __FUNCT__
561 #define __FUNCT__ "PCShellSetPostSolve"
562 /*@C
563    PCShellSetPostSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
564       applied. This usually does something like scale the linear system in some application
565       specific way.
566 
567    Collective on PC
568 
569    Input Parameters:
570 +  pc - the preconditioner context
571 -  postsolve - the application-provided presolve routine
572 
573    Calling sequence of postsolve:
574 .vb
575    PetscErrorCode postsolve(void *ptr,KSP ksp,Vec b,Vec x)
576 .ve
577 
578 +  ptr - the application context
579 .  xin - input vector
580 -  xout - output vector
581 
582    Level: developer
583 
584 .keywords: PC, shell, set, apply, user-provided
585 
586 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPreSolve(), PCShellSetContext()
587 @*/
588 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPostSolve(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec))
589 {
590   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));
591 
592   PetscFunctionBegin;
593   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
594   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPostSolve_C",(void (**)(void))&f);CHKERRQ(ierr);
595   if (f) {
596     ierr = (*f)(pc,postsolve);CHKERRQ(ierr);
597   }
598   PetscFunctionReturn(0);
599 }
600 
601 #undef __FUNCT__
602 #define __FUNCT__ "PCShellSetName"
603 /*@C
604    PCShellSetName - Sets an optional name to associate with a shell
605    preconditioner.
606 
607    Not Collective
608 
609    Input Parameters:
610 +  pc - the preconditioner context
611 -  name - character string describing shell preconditioner
612 
613    Level: developer
614 
615 .keywords: PC, shell, set, name, user-provided
616 
617 .seealso: PCShellGetName()
618 @*/
619 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetName(PC pc,const char name[])
620 {
621   PetscErrorCode ierr,(*f)(PC,const char []);
622 
623   PetscFunctionBegin;
624   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
625   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)(void))&f);CHKERRQ(ierr);
626   if (f) {
627     ierr = (*f)(pc,name);CHKERRQ(ierr);
628   }
629   PetscFunctionReturn(0);
630 }
631 
632 #undef __FUNCT__
633 #define __FUNCT__ "PCShellGetName"
634 /*@C
635    PCShellGetName - Gets an optional name that the user has set for a shell
636    preconditioner.
637 
638    Not Collective
639 
640    Input Parameter:
641 .  pc - the preconditioner context
642 
643    Output Parameter:
644 .  name - character string describing shell preconditioner (you should not free this)
645 
646    Level: developer
647 
648 .keywords: PC, shell, get, name, user-provided
649 
650 .seealso: PCShellSetName()
651 @*/
652 PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetName(PC pc,char *name[])
653 {
654   PetscErrorCode ierr,(*f)(PC,char *[]);
655 
656   PetscFunctionBegin;
657   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
658   PetscValidPointer(name,2);
659   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)(void))&f);CHKERRQ(ierr);
660   if (f) {
661     ierr = (*f)(pc,name);CHKERRQ(ierr);
662   } else {
663     SETERRQ(PETSC_ERR_ARG_WRONG,"Not shell preconditioner, cannot get name");
664   }
665   PetscFunctionReturn(0);
666 }
667 
668 #undef __FUNCT__
669 #define __FUNCT__ "PCShellSetApplyRichardson"
670 /*@C
671    PCShellSetApplyRichardson - Sets routine to use as preconditioner
672    in Richardson iteration.
673 
674    Collective on PC
675 
676    Input Parameters:
677 +  pc - the preconditioner context
678 -  apply - the application-provided preconditioning routine
679 
680    Calling sequence of apply:
681 .vb
682    PetscErrorCode apply (void *ptr,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits)
683 .ve
684 
685 +  ptr - the application context
686 .  b - right-hand-side
687 .  x - current iterate
688 .  r - work space
689 .  rtol - relative tolerance of residual norm to stop at
690 .  abstol - absolute tolerance of residual norm to stop at
691 .  dtol - if residual norm increases by this factor than return
692 -  maxits - number of iterations to run
693 
694    Level: developer
695 
696 .keywords: PC, shell, set, apply, Richardson, user-provided
697 
698 .seealso: PCShellSetApply(), PCShellSetContext()
699 @*/
700 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyRichardson(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt))
701 {
702   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt));
703 
704   PetscFunctionBegin;
705   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
706   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)(void))&f);CHKERRQ(ierr);
707   if (f) {
708     ierr = (*f)(pc,apply);CHKERRQ(ierr);
709   }
710   PetscFunctionReturn(0);
711 }
712 
713 /*MC
714    PCSHELL - Creates a new preconditioner class for use with your
715               own private data storage format.
716 
717    Level: advanced
718 
719    Concepts: providing your own preconditioner
720 
721   Usage:
722 $             PetscErrorCode (*mult)(void*,Vec,Vec);
723 $             PetscErrorCode (*setup)(void*);
724 $             PCCreate(comm,&pc);
725 $             PCSetType(pc,PCSHELL);
726 $             PCShellSetApply(pc,mult);
727 $             PCShellSetContext(pc,ctx)
728 $             PCShellSetSetUp(pc,setup);       (optional)
729 
730 .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
731            MATSHELL, PCShellSetSetUp(), PCShellSetApply(), PCShellSetView(),
732            PCShellSetApplyTranspose(), PCShellSetName(), PCShellSetApplyRichardson(),
733            PCShellGetName(), PCShellSetContext(), PCShellGetContext()
734 M*/
735 
736 EXTERN_C_BEGIN
737 #undef __FUNCT__
738 #define __FUNCT__ "PCCreate_Shell"
739 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_Shell(PC pc)
740 {
741   PetscErrorCode ierr;
742   PC_Shell       *shell;
743 
744   PetscFunctionBegin;
745   pc->ops->destroy    = PCDestroy_Shell;
746   ierr                = PetscNew(PC_Shell,&shell);CHKERRQ(ierr);
747   ierr = PetscLogObjectMemory(pc,sizeof(PC_Shell));CHKERRQ(ierr);
748   pc->data         = (void*)shell;
749   pc->name         = 0;
750 
751   pc->ops->apply           = PCApply_Shell;
752   pc->ops->view            = PCView_Shell;
753   pc->ops->applytranspose  = PCApplyTranspose_Shell;
754   pc->ops->applyrichardson = 0;
755   pc->ops->setup           = PCSetUp_Shell;
756   pc->ops->presolve        = 0;
757   pc->ops->postsolve       = 0;
758   pc->ops->view            = PCView_Shell;
759 
760   shell->apply          = 0;
761   shell->applytranspose = 0;
762   shell->name           = 0;
763   shell->applyrich      = 0;
764   shell->presolve       = 0;
765   shell->postsolve      = 0;
766   shell->ctx            = 0;
767   shell->setup          = 0;
768   shell->view           = 0;
769 
770   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell",
771                     PCShellSetSetUp_Shell);CHKERRQ(ierr);
772   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell",
773                     PCShellSetApply_Shell);CHKERRQ(ierr);
774   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPreSolve_C","PCShellSetPreSolve_Shell",
775                     PCShellSetPreSolve_Shell);CHKERRQ(ierr);
776   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPostSolve_C","PCShellSetPostSolve_Shell",
777                     PCShellSetPostSolve_Shell);CHKERRQ(ierr);
778   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell",
779                     PCShellSetView_Shell);CHKERRQ(ierr);
780   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C","PCShellSetApplyTranspose_Shell",
781                     PCShellSetApplyTranspose_Shell);CHKERRQ(ierr);
782   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell",
783                     PCShellSetName_Shell);CHKERRQ(ierr);
784   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell",
785                     PCShellGetName_Shell);CHKERRQ(ierr);
786   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C","PCShellSetApplyRichardson_Shell",
787                     PCShellSetApplyRichardson_Shell);CHKERRQ(ierr);
788   PetscFunctionReturn(0);
789 }
790 EXTERN_C_END
791 
792 
793 
794 
795 
796 
797