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