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