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