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