xref: /petsc/src/ksp/pc/impls/shell/shellpc.c (revision 6895c4454d0419b7d1cef7fe2938cafebbe2c313)
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    Level: developer
453 
454 .keywords: PC, shell, set, destroy, user-provided
455 
456 .seealso: PCShellSetApply(), PCShellSetContext()
457 @*/
458 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetDestroy(PC pc,PetscErrorCode (*destroy)(void*))
459 {
460   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*));
461 
462   PetscFunctionBegin;
463   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
464   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetDestroy_C",(void (**)(void))&f);CHKERRQ(ierr);
465   if (f) {
466     ierr = (*f)(pc,destroy);CHKERRQ(ierr);
467   }
468   PetscFunctionReturn(0);
469 }
470 
471 
472 #undef __FUNCT__
473 #define __FUNCT__ "PCShellSetSetUp"
474 /*@C
475    PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
476    matrix operator is changed.
477 
478    Collective on PC
479 
480    Input Parameters:
481 +  pc - the preconditioner context
482 .  setup - the application-provided setup routine
483 
484    Calling sequence of setup:
485 .vb
486    PetscErrorCode setup (void *ptr)
487 .ve
488 
489 .  ptr - the application context
490 
491    Level: developer
492 
493 .keywords: PC, shell, set, setup, user-provided
494 
495 .seealso: PCShellSetApplyRichardson(), PCShellSetApply(), PCShellSetContext()
496 @*/
497 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(void*))
498 {
499   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*));
500 
501   PetscFunctionBegin;
502   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
503   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)(void))&f);CHKERRQ(ierr);
504   if (f) {
505     ierr = (*f)(pc,setup);CHKERRQ(ierr);
506   }
507   PetscFunctionReturn(0);
508 }
509 
510 
511 #undef __FUNCT__
512 #define __FUNCT__ "PCShellSetView"
513 /*@C
514    PCShellSetView - Sets routine to use as viewer of shell preconditioner
515 
516    Collective on PC
517 
518    Input Parameters:
519 +  pc - the preconditioner context
520 -  view - the application-provided view routine
521 
522    Calling sequence of apply:
523 .vb
524    PetscErrorCode view(void *ptr,PetscViewer v)
525 .ve
526 
527 +  ptr - the application context
528 -  v   - viewer
529 
530    Level: developer
531 
532 .keywords: PC, shell, set, apply, user-provided
533 
534 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
535 @*/
536 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetView(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
537 {
538   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PetscViewer));
539 
540   PetscFunctionBegin;
541   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
542   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetView_C",(void (**)(void))&f);CHKERRQ(ierr);
543   if (f) {
544     ierr = (*f)(pc,view);CHKERRQ(ierr);
545   }
546   PetscFunctionReturn(0);
547 }
548 
549 #undef __FUNCT__
550 #define __FUNCT__ "PCShellSetApply"
551 /*@C
552    PCShellSetApply - Sets routine to use as preconditioner.
553 
554    Collective on PC
555 
556    Input Parameters:
557 +  pc - the preconditioner context
558 -  apply - the application-provided preconditioning routine
559 
560    Calling sequence of apply:
561 .vb
562    PetscErrorCode apply (void *ptr,Vec xin,Vec xout)
563 .ve
564 
565 +  ptr - the application context
566 .  xin - input vector
567 -  xout - output vector
568 
569    Level: developer
570 
571 .keywords: PC, shell, set, apply, user-provided
572 
573 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApplyBA()
574 @*/
575 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApply(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec))
576 {
577   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));
578 
579   PetscFunctionBegin;
580   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
581   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)(void))&f);CHKERRQ(ierr);
582   if (f) {
583     ierr = (*f)(pc,apply);CHKERRQ(ierr);
584   }
585   PetscFunctionReturn(0);
586 }
587 
588 #undef __FUNCT__
589 #define __FUNCT__ "PCShellSetApplyBA"
590 /*@C
591    PCShellSetApplyBA - Sets routine to use as preconditioner times operator.
592 
593    Collective on PC
594 
595    Input Parameters:
596 +  pc - the preconditioner context
597 -  applyBA - the application-provided BA routine
598 
599    Calling sequence of apply:
600 .vb
601    PetscErrorCode applyBA (void *ptr,Vec xin,Vec xout)
602 .ve
603 
604 +  ptr - the application context
605 .  xin - input vector
606 -  xout - output vector
607 
608    Level: developer
609 
610 .keywords: PC, shell, set, apply, user-provided
611 
612 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApply()
613 @*/
614 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyBA(PC pc,PetscErrorCode (*applyBA)(void*,PCSide,Vec,Vec,Vec))
615 {
616   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PCSide,Vec,Vec,Vec));
617 
618   PetscFunctionBegin;
619   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
620   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyBA_C",(void (**)(void))&f);CHKERRQ(ierr);
621   if (f) {
622     ierr = (*f)(pc,applyBA);CHKERRQ(ierr);
623   }
624   PetscFunctionReturn(0);
625 }
626 
627 #undef __FUNCT__
628 #define __FUNCT__ "PCShellSetApplyTranspose"
629 /*@C
630    PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
631 
632    Collective on PC
633 
634    Input Parameters:
635 +  pc - the preconditioner context
636 -  apply - the application-provided preconditioning transpose routine
637 
638    Calling sequence of apply:
639 .vb
640    PetscErrorCode applytranspose (void *ptr,Vec xin,Vec xout)
641 .ve
642 
643 +  ptr - the application context
644 .  xin - input vector
645 -  xout - output vector
646 
647    Level: developer
648 
649    Notes:
650    Uses the same context variable as PCShellSetApply().
651 
652 .keywords: PC, shell, set, apply, user-provided
653 
654 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply(), PCSetContext(), PCShellSetApplyBA()
655 @*/
656 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyTranspose(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
657 {
658   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));
659 
660   PetscFunctionBegin;
661   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
662   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
663   if (f) {
664     ierr = (*f)(pc,applytranspose);CHKERRQ(ierr);
665   }
666   PetscFunctionReturn(0);
667 }
668 
669 #undef __FUNCT__
670 #define __FUNCT__ "PCShellSetPreSolve"
671 /*@C
672    PCShellSetPreSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
673       applied. This usually does something like scale the linear system in some application
674       specific way.
675 
676    Collective on PC
677 
678    Input Parameters:
679 +  pc - the preconditioner context
680 -  presolve - the application-provided presolve routine
681 
682    Calling sequence of presolve:
683 .vb
684    PetscErrorCode presolve (void *ptr,KSP ksp,Vec b,Vec x)
685 .ve
686 
687 +  ptr - the application context
688 .  xin - input vector
689 -  xout - output vector
690 
691    Level: developer
692 
693 .keywords: PC, shell, set, apply, user-provided
694 
695 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPostSolve(), PCShellSetContext()
696 @*/
697 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPreSolve(PC pc,PetscErrorCode (*presolve)(void*,KSP,Vec,Vec))
698 {
699   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));
700 
701   PetscFunctionBegin;
702   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
703   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPreSolve_C",(void (**)(void))&f);CHKERRQ(ierr);
704   if (f) {
705     ierr = (*f)(pc,presolve);CHKERRQ(ierr);
706   }
707   PetscFunctionReturn(0);
708 }
709 
710 #undef __FUNCT__
711 #define __FUNCT__ "PCShellSetPostSolve"
712 /*@C
713    PCShellSetPostSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
714       applied. This usually does something like scale the linear system in some application
715       specific way.
716 
717    Collective on PC
718 
719    Input Parameters:
720 +  pc - the preconditioner context
721 -  postsolve - the application-provided presolve routine
722 
723    Calling sequence of postsolve:
724 .vb
725    PetscErrorCode postsolve(void *ptr,KSP ksp,Vec b,Vec x)
726 .ve
727 
728 +  ptr - the application context
729 .  xin - input vector
730 -  xout - output vector
731 
732    Level: developer
733 
734 .keywords: PC, shell, set, apply, user-provided
735 
736 .seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPreSolve(), PCShellSetContext()
737 @*/
738 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPostSolve(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec))
739 {
740   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));
741 
742   PetscFunctionBegin;
743   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
744   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPostSolve_C",(void (**)(void))&f);CHKERRQ(ierr);
745   if (f) {
746     ierr = (*f)(pc,postsolve);CHKERRQ(ierr);
747   }
748   PetscFunctionReturn(0);
749 }
750 
751 #undef __FUNCT__
752 #define __FUNCT__ "PCShellSetName"
753 /*@C
754    PCShellSetName - Sets an optional name to associate with a shell
755    preconditioner.
756 
757    Not Collective
758 
759    Input Parameters:
760 +  pc - the preconditioner context
761 -  name - character string describing shell preconditioner
762 
763    Level: developer
764 
765 .keywords: PC, shell, set, name, user-provided
766 
767 .seealso: PCShellGetName()
768 @*/
769 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetName(PC pc,const char name[])
770 {
771   PetscErrorCode ierr,(*f)(PC,const char []);
772 
773   PetscFunctionBegin;
774   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
775   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)(void))&f);CHKERRQ(ierr);
776   if (f) {
777     ierr = (*f)(pc,name);CHKERRQ(ierr);
778   }
779   PetscFunctionReturn(0);
780 }
781 
782 #undef __FUNCT__
783 #define __FUNCT__ "PCShellGetName"
784 /*@C
785    PCShellGetName - Gets an optional name that the user has set for a shell
786    preconditioner.
787 
788    Not Collective
789 
790    Input Parameter:
791 .  pc - the preconditioner context
792 
793    Output Parameter:
794 .  name - character string describing shell preconditioner (you should not free this)
795 
796    Level: developer
797 
798 .keywords: PC, shell, get, name, user-provided
799 
800 .seealso: PCShellSetName()
801 @*/
802 PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetName(PC pc,char *name[])
803 {
804   PetscErrorCode ierr,(*f)(PC,char *[]);
805 
806   PetscFunctionBegin;
807   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
808   PetscValidPointer(name,2);
809   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellGetName_C",(void (**)(void))&f);CHKERRQ(ierr);
810   if (f) {
811     ierr = (*f)(pc,name);CHKERRQ(ierr);
812   } else {
813     SETERRQ(PETSC_ERR_ARG_WRONG,"Not shell preconditioner, cannot get name");
814   }
815   PetscFunctionReturn(0);
816 }
817 
818 #undef __FUNCT__
819 #define __FUNCT__ "PCShellSetApplyRichardson"
820 /*@C
821    PCShellSetApplyRichardson - Sets routine to use as preconditioner
822    in Richardson iteration.
823 
824    Collective on PC
825 
826    Input Parameters:
827 +  pc - the preconditioner context
828 -  apply - the application-provided preconditioning routine
829 
830    Calling sequence of apply:
831 .vb
832    PetscErrorCode apply (void *ptr,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits)
833 .ve
834 
835 +  ptr - the application context
836 .  b - right-hand-side
837 .  x - current iterate
838 .  r - work space
839 .  rtol - relative tolerance of residual norm to stop at
840 .  abstol - absolute tolerance of residual norm to stop at
841 .  dtol - if residual norm increases by this factor than return
842 -  maxits - number of iterations to run
843 
844    Level: developer
845 
846 .keywords: PC, shell, set, apply, Richardson, user-provided
847 
848 .seealso: PCShellSetApply(), PCShellSetContext()
849 @*/
850 PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyRichardson(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt))
851 {
852   PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt));
853 
854   PetscFunctionBegin;
855   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
856   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyRichardson_C",(void (**)(void))&f);CHKERRQ(ierr);
857   if (f) {
858     ierr = (*f)(pc,apply);CHKERRQ(ierr);
859   }
860   PetscFunctionReturn(0);
861 }
862 
863 /*MC
864    PCSHELL - Creates a new preconditioner class for use with your
865               own private data storage format.
866 
867    Level: advanced
868 >
869    Concepts: providing your own preconditioner
870 
871   Usage:
872 $             PetscErrorCode (*mult)(void*,Vec,Vec);
873 $             PetscErrorCode (*setup)(void*);
874 $             PCCreate(comm,&pc);
875 $             PCSetType(pc,PCSHELL);
876 $             PCShellSetApply(pc,apply);
877 $             PCShellSetApplyBA(pc,apply); (optional)
878 $             PCShellSetApplyTranspose(pc,apply); (optional)
879 $             PCShellSetContext(pc,ctx)
880 $             PCShellSetSetUp(pc,setup); (optional)
881 $             PCShellSetDestroy(pc,destroy); (optional)
882 
883 .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
884            MATSHELL, PCShellSetSetUp(), PCShellSetApply(), PCShellSetView(),
885            PCShellSetApplyTranspose(), PCShellSetName(), PCShellSetApplyRichardson(),
886            PCShellGetName(), PCShellSetContext(), PCShellGetContext(), PCShellSetApplyBA()
887 M*/
888 
889 EXTERN_C_BEGIN
890 #undef __FUNCT__
891 #define __FUNCT__ "PCCreate_Shell"
892 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_Shell(PC pc)
893 {
894   PetscErrorCode ierr;
895   PC_Shell       *shell;
896 
897   PetscFunctionBegin;
898   ierr = PetscNewLog(pc,PC_Shell,&shell);CHKERRQ(ierr);
899   pc->data  = (void*)shell;
900 
901   pc->ops->destroy         = PCDestroy_Shell;
902   pc->ops->view            = PCView_Shell;
903   pc->ops->apply           = PCApply_Shell;
904   pc->ops->applytranspose  = 0;
905   pc->ops->applyrichardson = 0;
906   pc->ops->setup           = 0;
907   pc->ops->presolve        = 0;
908   pc->ops->postsolve       = 0;
909 
910   shell->apply          = 0;
911   shell->applytranspose = 0;
912   shell->name           = 0;
913   shell->applyrich      = 0;
914   shell->presolve       = 0;
915   shell->postsolve      = 0;
916   shell->ctx            = 0;
917   shell->setup          = 0;
918   shell->view           = 0;
919   shell->destroy        = 0;
920 
921   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetDestroy_C","PCShellSetDestroy_Shell",
922                     PCShellSetDestroy_Shell);CHKERRQ(ierr);
923   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetSetUp_C","PCShellSetSetUp_Shell",
924                     PCShellSetSetUp_Shell);CHKERRQ(ierr);
925   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApply_C","PCShellSetApply_Shell",
926                     PCShellSetApply_Shell);CHKERRQ(ierr);
927   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyBA_C","PCShellSetApplyBA_Shell",
928                     PCShellSetApplyBA_Shell);CHKERRQ(ierr);
929   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPreSolve_C","PCShellSetPreSolve_Shell",
930                     PCShellSetPreSolve_Shell);CHKERRQ(ierr);
931   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetPostSolve_C","PCShellSetPostSolve_Shell",
932                     PCShellSetPostSolve_Shell);CHKERRQ(ierr);
933   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetView_C","PCShellSetView_Shell",
934                     PCShellSetView_Shell);CHKERRQ(ierr);
935   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyTranspose_C","PCShellSetApplyTranspose_Shell",
936                     PCShellSetApplyTranspose_Shell);CHKERRQ(ierr);
937   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetName_C","PCShellSetName_Shell",
938                     PCShellSetName_Shell);CHKERRQ(ierr);
939   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellGetName_C","PCShellGetName_Shell",
940                     PCShellGetName_Shell);CHKERRQ(ierr);
941   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCShellSetApplyRichardson_C","PCShellSetApplyRichardson_Shell",
942                     PCShellSetApplyRichardson_Shell);CHKERRQ(ierr);
943   PetscFunctionReturn(0);
944 }
945 EXTERN_C_END
946 
947 
948 
949 
950 
951 
952