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