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