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