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