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