xref: /petsc/src/ksp/pc/impls/shell/shellpc.c (revision 7d0a6c19129e7069c8a40e210b34ed62989173db) !
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 "private/pcimpl.h"        /*I "petscpc.h" I*/
8 #include "private/vecimpl.h"
9 
10 EXTERN_C_BEGIN
11 typedef struct {
12   void           *ctx;                     /* user provided contexts for preconditioner */
13   PetscErrorCode (*destroy)(PC);
14   PetscErrorCode (*setup)(PC);
15   PetscErrorCode (*apply)(PC,Vec,Vec);
16   PetscErrorCode (*applyBA)(PC,PCSide,Vec,Vec,Vec);
17   PetscErrorCode (*presolve)(PC,KSP,Vec,Vec);
18   PetscErrorCode (*postsolve)(PC,KSP,Vec,Vec);
19   PetscErrorCode (*view)(PC,PetscViewer);
20   PetscErrorCode (*applytranspose)(PC,Vec,Vec);
21   PetscErrorCode (*applyrich)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool ,PetscInt*,PCRichardsonConvergedReason*);
22   char           *name;
23 } PC_Shell;
24 EXTERN_C_END
25 
26 #undef __FUNCT__
27 #define __FUNCT__ "PCShellGetContext"
28 /*@C
29     PCShellGetContext - Returns the user-provided context associated with a shell PC
30 
31     Not Collective
32 
33     Input Parameter:
34 .   pc - should have been created with PCCreateShell()
35 
36     Output Parameter:
37 .   ctx - the user provided context
38 
39     Level: advanced
40 
41     Notes:
42     This routine is intended for use within various shell routines
43 
44 .keywords: PC, shell, get, context
45 
46 .seealso: PCCreateShell(), PCShellSetContext()
47 @*/
48 PetscErrorCode  PCShellGetContext(PC pc,void **ctx)
49 {
50   PetscErrorCode ierr;
51   PetscBool      flg;
52 
53   PetscFunctionBegin;
54   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
55   PetscValidPointer(ctx,2);
56   ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);CHKERRQ(ierr);
57   if (!flg) *ctx = 0;
58   else      *ctx = ((PC_Shell*)(pc->data))->ctx;
59   PetscFunctionReturn(0);
60 }
61 
62 #undef __FUNCT__
63 #define __FUNCT__ "PCShellSetContext"
64 /*@
65     PCShellSetContext - sets the context for a shell PC
66 
67    Logically Collective on PC
68 
69     Input Parameters:
70 +   pc - the shell PC
71 -   ctx - the context
72 
73    Level: advanced
74 
75    Fortran Notes: The context can only be an integer or a PetscObject
76       unfortunately it cannot be a Fortran array or derived type.
77 
78 
79 .seealso: PCCreateShell(), PCShellGetContext()
80 @*/
81 PetscErrorCode  PCShellSetContext(PC pc,void *ctx)
82 {
83   PC_Shell      *shell;
84   PetscErrorCode ierr;
85   PetscBool      flg;
86 
87   PetscFunctionBegin;
88   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
89   shell = (PC_Shell*)pc->data;
90   ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);CHKERRQ(ierr);
91   if (flg) {
92     shell->ctx = ctx;
93   }
94   PetscFunctionReturn(0);
95 }
96 
97 #undef __FUNCT__
98 #define __FUNCT__ "PCSetUp_Shell"
99 static PetscErrorCode PCSetUp_Shell(PC pc)
100 {
101   PC_Shell       *shell;
102   PetscErrorCode ierr;
103 
104   PetscFunctionBegin;
105   shell = (PC_Shell*)pc->data;
106   if (!shell->setup) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_USER,"No setup() routine provided to Shell PC");
107   PetscStackCall("PCSHELL user function setup()",ierr  = (*shell->setup)(pc);CHKERRQ(ierr));
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(((PetscObject)pc)->comm,PETSC_ERR_USER,"No apply() routine provided to Shell PC");
121   PetscStackCall("PCSHELL user function apply()",ierr = (*shell->apply)(pc,x,y);CHKERRQ(ierr));
122   PetscFunctionReturn(0);
123 }
124 
125 #undef __FUNCT__
126 #define __FUNCT__ "PCApplyBA_Shell"
127 static PetscErrorCode PCApplyBA_Shell(PC pc,PCSide side,Vec x,Vec y,Vec w)
128 {
129   PC_Shell       *shell;
130   PetscErrorCode ierr;
131 
132   PetscFunctionBegin;
133   shell = (PC_Shell*)pc->data;
134   if (!shell->applyBA) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_USER,"No applyBA() routine provided to Shell PC");
135   PetscStackCall("PCSHELL user function applyBA()",ierr  = (*shell->applyBA)(pc,side,x,y,w);CHKERRQ(ierr));
136   PetscFunctionReturn(0);
137 }
138 
139 #undef __FUNCT__
140 #define __FUNCT__ "PCPreSolve_Shell"
141 static PetscErrorCode PCPreSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
142 {
143   PC_Shell       *shell;
144   PetscErrorCode ierr;
145 
146   PetscFunctionBegin;
147   shell = (PC_Shell*)pc->data;
148   if (!shell->presolve) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_USER,"No presolve() routine provided to Shell PC");
149   PetscStackCall("PCSHELL user function presolve()",ierr  = (*shell->presolve)(pc,ksp,b,x);CHKERRQ(ierr));
150   PetscFunctionReturn(0);
151 }
152 
153 #undef __FUNCT__
154 #define __FUNCT__ "PCPostSolve_Shell"
155 static PetscErrorCode PCPostSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
156 {
157   PC_Shell       *shell;
158   PetscErrorCode ierr;
159 
160   PetscFunctionBegin;
161   shell = (PC_Shell*)pc->data;
162   if (!shell->postsolve) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_USER,"No postsolve() routine provided to Shell PC");
163   PetscStackCall("PCSHELL user function postsolve()",ierr  = (*shell->postsolve)(pc,ksp,b,x);CHKERRQ(ierr));
164   PetscFunctionReturn(0);
165 }
166 
167 #undef __FUNCT__
168 #define __FUNCT__ "PCApplyTranspose_Shell"
169 static PetscErrorCode PCApplyTranspose_Shell(PC pc,Vec x,Vec y)
170 {
171   PC_Shell       *shell;
172   PetscErrorCode ierr;
173 
174   PetscFunctionBegin;
175   shell = (PC_Shell*)pc->data;
176   if (!shell->applytranspose) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_USER,"No applytranspose() routine provided to Shell PC");
177   PetscStackCall("PCSHELL user function applytranspose()",ierr  = (*shell->applytranspose)(pc,x,y);CHKERRQ(ierr));
178   PetscFunctionReturn(0);
179 }
180 
181 #undef __FUNCT__
182 #define __FUNCT__ "PCApplyRichardson_Shell"
183 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)
184 {
185   PetscErrorCode ierr;
186   PC_Shell       *shell;
187 
188   PetscFunctionBegin;
189   shell = (PC_Shell*)pc->data;
190   if (!shell->applyrich) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_USER,"No applyrichardson() routine provided to Shell PC");
191   PetscStackCall("PCSHELL user function applyrichardson()",ierr  = (*shell->applyrich)(pc,x,y,w,rtol,abstol,dtol,it,guesszero,outits,reason);CHKERRQ(ierr));
192   PetscFunctionReturn(0);
193 }
194 
195 #undef __FUNCT__
196 #define __FUNCT__ "PCDestroy_Shell"
197 static PetscErrorCode PCDestroy_Shell(PC pc)
198 {
199   PC_Shell       *shell = (PC_Shell*)pc->data;
200   PetscErrorCode ierr;
201 
202   PetscFunctionBegin;
203   ierr = PetscFree(shell->name);CHKERRQ(ierr);
204   if (shell->destroy) {
205     PetscStackCall("PCSHELL user function destroy()",ierr  = (*shell->destroy)(pc);CHKERRQ(ierr));
206   }
207   ierr = PetscFree(pc->data);CHKERRQ(ierr);
208   PetscFunctionReturn(0);
209 }
210 
211 #undef __FUNCT__
212 #define __FUNCT__ "PCView_Shell"
213 static PetscErrorCode PCView_Shell(PC pc,PetscViewer viewer)
214 {
215   PC_Shell       *shell = (PC_Shell*)pc->data;
216   PetscErrorCode ierr;
217   PetscBool      iascii;
218 
219   PetscFunctionBegin;
220   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
221   if (iascii) {
222     if (shell->name) {ierr = PetscViewerASCIIPrintf(viewer,"  Shell: %s\n",shell->name);CHKERRQ(ierr);}
223     else             {ierr = PetscViewerASCIIPrintf(viewer,"  Shell: no name\n");CHKERRQ(ierr);}
224   }
225   if (shell->view) {
226     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
227     ierr  = (*shell->view)(pc,viewer);CHKERRQ(ierr);
228     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
229   }
230   PetscFunctionReturn(0);
231 }
232 
233 /* ------------------------------------------------------------------------------*/
234 EXTERN_C_BEGIN
235 #undef __FUNCT__
236 #define __FUNCT__ "PCShellSetDestroy_Shell"
237 PetscErrorCode  PCShellSetDestroy_Shell(PC pc, PetscErrorCode (*destroy)(PC))
238 {
239   PC_Shell *shell;
240 
241   PetscFunctionBegin;
242   shell          = (PC_Shell*)pc->data;
243   shell->destroy = destroy;
244   PetscFunctionReturn(0);
245 }
246 EXTERN_C_END
247 
248 EXTERN_C_BEGIN
249 #undef __FUNCT__
250 #define __FUNCT__ "PCShellSetSetUp_Shell"
251 PetscErrorCode  PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(PC))
252 {
253   PC_Shell *shell;
254 
255   PetscFunctionBegin;
256   shell        = (PC_Shell*)pc->data;
257   shell->setup = setup;
258   if (setup) pc->ops->setup = PCSetUp_Shell;
259   else       pc->ops->setup = 0;
260   PetscFunctionReturn(0);
261 }
262 EXTERN_C_END
263 
264 EXTERN_C_BEGIN
265 #undef __FUNCT__
266 #define __FUNCT__ "PCShellSetApply_Shell"
267 PetscErrorCode  PCShellSetApply_Shell(PC pc,PetscErrorCode (*apply)(PC,Vec,Vec))
268 {
269   PC_Shell *shell;
270 
271   PetscFunctionBegin;
272   shell        = (PC_Shell*)pc->data;
273   shell->apply = apply;
274   PetscFunctionReturn(0);
275 }
276 EXTERN_C_END
277 
278 EXTERN_C_BEGIN
279 #undef __FUNCT__
280 #define __FUNCT__ "PCShellSetApplyBA_Shell"
281 PetscErrorCode  PCShellSetApplyBA_Shell(PC pc,PetscErrorCode (*applyBA)(PC,PCSide,Vec,Vec,Vec))
282 {
283   PC_Shell *shell;
284 
285   PetscFunctionBegin;
286   shell          = (PC_Shell*)pc->data;
287   shell->applyBA = applyBA;
288   if (applyBA) pc->ops->applyBA  = PCApplyBA_Shell;
289   else         pc->ops->applyBA  = 0;
290   PetscFunctionReturn(0);
291 }
292 EXTERN_C_END
293 
294 EXTERN_C_BEGIN
295 #undef __FUNCT__
296 #define __FUNCT__ "PCShellSetPreSolve_Shell"
297 PetscErrorCode  PCShellSetPreSolve_Shell(PC pc,PetscErrorCode (*presolve)(PC,KSP,Vec,Vec))
298 {
299   PC_Shell *shell;
300 
301   PetscFunctionBegin;
302   shell           = (PC_Shell*)pc->data;
303   shell->presolve = presolve;
304   if (presolve) pc->ops->presolve = PCPreSolve_Shell;
305   else          pc->ops->presolve = 0;
306   PetscFunctionReturn(0);
307 }
308 EXTERN_C_END
309 
310 EXTERN_C_BEGIN
311 #undef __FUNCT__
312 #define __FUNCT__ "PCShellSetPostSolve_Shell"
313 PetscErrorCode  PCShellSetPostSolve_Shell(PC pc,PetscErrorCode (*postsolve)(PC,KSP,Vec,Vec))
314 {
315   PC_Shell *shell;
316 
317   PetscFunctionBegin;
318   shell            = (PC_Shell*)pc->data;
319   shell->postsolve = postsolve;
320   if (postsolve) pc->ops->postsolve = PCPostSolve_Shell;
321   else           pc->ops->postsolve = 0;
322   PetscFunctionReturn(0);
323 }
324 EXTERN_C_END
325 
326 EXTERN_C_BEGIN
327 #undef __FUNCT__
328 #define __FUNCT__ "PCShellSetView_Shell"
329 PetscErrorCode  PCShellSetView_Shell(PC pc,PetscErrorCode (*view)(PC,PetscViewer))
330 {
331   PC_Shell *shell;
332 
333   PetscFunctionBegin;
334   shell        = (PC_Shell*)pc->data;
335   shell->view = view;
336   PetscFunctionReturn(0);
337 }
338 EXTERN_C_END
339 
340 EXTERN_C_BEGIN
341 #undef __FUNCT__
342 #define __FUNCT__ "PCShellSetApplyTranspose_Shell"
343 PetscErrorCode  PCShellSetApplyTranspose_Shell(PC pc,PetscErrorCode (*applytranspose)(PC,Vec,Vec))
344 {
345   PC_Shell *shell;
346 
347   PetscFunctionBegin;
348   shell                 = (PC_Shell*)pc->data;
349   shell->applytranspose = applytranspose;
350   if (applytranspose) pc->ops->applytranspose = PCApplyTranspose_Shell;
351   else                pc->ops->applytranspose = 0;
352   PetscFunctionReturn(0);
353 }
354 EXTERN_C_END
355 
356 EXTERN_C_BEGIN
357 #undef __FUNCT__
358 #define __FUNCT__ "PCShellSetApplyRichardson_Shell"
359 PetscErrorCode  PCShellSetApplyRichardson_Shell(PC pc,PetscErrorCode (*applyrich)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt,PetscBool ,PetscInt*,PCRichardsonConvergedReason*))
360 {
361   PC_Shell *shell;
362 
363   PetscFunctionBegin;
364   shell            = (PC_Shell*)pc->data;
365   shell->applyrich = applyrich;
366   if (applyrich) pc->ops->applyrichardson  = PCApplyRichardson_Shell;
367   else           pc->ops->applyrichardson  = 0;
368   PetscFunctionReturn(0);
369 }
370 EXTERN_C_END
371 
372 EXTERN_C_BEGIN
373 #undef __FUNCT__
374 #define __FUNCT__ "PCShellSetName_Shell"
375 PetscErrorCode  PCShellSetName_Shell(PC pc,const char name[])
376 {
377   PC_Shell       *shell;
378   PetscErrorCode ierr;
379 
380   PetscFunctionBegin;
381   shell = (PC_Shell*)pc->data;
382   ierr = PetscFree(shell->name);CHKERRQ(ierr);
383   ierr = PetscStrallocpy(name,&shell->name);CHKERRQ(ierr);
384   PetscFunctionReturn(0);
385 }
386 EXTERN_C_END
387 
388 EXTERN_C_BEGIN
389 #undef __FUNCT__
390 #define __FUNCT__ "PCShellGetName_Shell"
391 PetscErrorCode  PCShellGetName_Shell(PC pc,char *name[])
392 {
393   PC_Shell *shell;
394 
395   PetscFunctionBegin;
396   shell  = (PC_Shell*)pc->data;
397   *name  = shell->name;
398   PetscFunctionReturn(0);
399 }
400 EXTERN_C_END
401 
402 /* -------------------------------------------------------------------------------*/
403 
404 #undef __FUNCT__
405 #define __FUNCT__ "PCShellSetDestroy"
406 /*@C
407    PCShellSetDestroy - Sets routine to use to destroy the user-provided
408    application context.
409 
410    Logically Collective on PC
411 
412    Input Parameters:
413 +  pc - the preconditioner context
414 .  destroy - the application-provided destroy routine
415 
416    Calling sequence of destroy:
417 .vb
418    PetscErrorCode destroy (PC)
419 .ve
420 
421 .  ptr - the application context
422 
423    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
424 
425    Level: developer
426 
427 .keywords: PC, shell, set, destroy, user-provided
428 
429 .seealso: PCShellSetApply(), PCShellSetContext()
430 @*/
431 PetscErrorCode  PCShellSetDestroy(PC pc,PetscErrorCode (*destroy)(PC))
432 {
433   PetscErrorCode ierr;
434 
435   PetscFunctionBegin;
436   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
437   ierr = PetscTryMethod(pc,"PCShellSetDestroy_C",(PC,PetscErrorCode (*)(PC)),(pc,destroy));CHKERRQ(ierr);
438   PetscFunctionReturn(0);
439 }
440 
441 
442 #undef __FUNCT__
443 #define __FUNCT__ "PCShellSetSetUp"
444 /*@C
445    PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
446    matrix operator is changed.
447 
448    Logically Collective on PC
449 
450    Input Parameters:
451 +  pc - the preconditioner context
452 .  setup - the application-provided setup routine
453 
454    Calling sequence of setup:
455 .vb
456    PetscErrorCode setup (PC pc)
457 .ve
458 
459 .  pc - the preconditioner, get the application context with PCShellGetContext()
460 
461    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
462 
463    Level: developer
464 
465 .keywords: PC, shell, set, setup, user-provided
466 
467 .seealso: PCShellSetApplyRichardson(), PCShellSetApply(), PCShellSetContext()
468 @*/
469 PetscErrorCode  PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(PC))
470 {
471   PetscErrorCode ierr;
472 
473   PetscFunctionBegin;
474   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
475   ierr = PetscTryMethod(pc,"PCShellSetSetUp_C",(PC,PetscErrorCode (*)(PC)),(pc,setup));CHKERRQ(ierr);
476   PetscFunctionReturn(0);
477 }
478 
479 
480 #undef __FUNCT__
481 #define __FUNCT__ "PCShellSetView"
482 /*@C
483    PCShellSetView - Sets routine to use as viewer of shell preconditioner
484 
485    Logically Collective on PC
486 
487    Input Parameters:
488 +  pc - the preconditioner context
489 -  view - the application-provided view routine
490 
491    Calling sequence of apply:
492 .vb
493    PetscErrorCode view(PC pc,PetscViewer v)
494 .ve
495 
496 +  pc - the preconditioner, get the application context with PCShellGetContext()
497 -  v   - viewer
498 
499    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
500 
501    Level: developer
502 
503 .keywords: PC, shell, set, apply, user-provided
504 
505 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
506 @*/
507 PetscErrorCode  PCShellSetView(PC pc,PetscErrorCode (*view)(PC,PetscViewer))
508 {
509   PetscErrorCode ierr;
510 
511   PetscFunctionBegin;
512   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
513   ierr = PetscTryMethod(pc,"PCShellSetView_C",(PC,PetscErrorCode (*)(PC,PetscViewer)),(pc,view));CHKERRQ(ierr);
514   PetscFunctionReturn(0);
515 }
516 
517 #undef __FUNCT__
518 #define __FUNCT__ "PCShellSetApply"
519 /*@C
520    PCShellSetApply - Sets routine to use as preconditioner.
521 
522    Logically Collective on PC
523 
524    Input Parameters:
525 +  pc - the preconditioner context
526 -  apply - the application-provided preconditioning routine
527 
528    Calling sequence of apply:
529 .vb
530    PetscErrorCode apply (PC pc,Vec xin,Vec xout)
531 .ve
532 
533 +  pc - the preconditioner, get the application context with PCShellGetContext()
534 .  xin - input vector
535 -  xout - output vector
536 
537    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
538 
539    Developer Notes: There should also be a PCShellSetApplySymmetricRight() and PCShellSetApplySymmetricLeft().
540 
541    Level: developer
542 
543 .keywords: PC, shell, set, apply, user-provided
544 
545 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApplyBA()
546 @*/
547 PetscErrorCode  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  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  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  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  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  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  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  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  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