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