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