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