xref: /petsc/src/ksp/pc/impls/shell/shellpc.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
14d0a8057SBarry Smith 
24b9ad928SBarry Smith /*
34b9ad928SBarry Smith    This provides a simple shell for Fortran (and C programmers) to
44b9ad928SBarry Smith   create their own preconditioner without writing much interface code.
54b9ad928SBarry Smith */
64b9ad928SBarry Smith 
7af0996ceSBarry Smith #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/
84b9ad928SBarry Smith 
94b9ad928SBarry Smith typedef struct {
10be29d3c6SBarry Smith   void *ctx; /* user provided contexts for preconditioner */
112fa5cd67SKarl Rupp 
126891c3e4SJed Brown   PetscErrorCode (*destroy)(PC);
136891c3e4SJed Brown   PetscErrorCode (*setup)(PC);
146891c3e4SJed Brown   PetscErrorCode (*apply)(PC, Vec, Vec);
157b6e2003SPierre Jolivet   PetscErrorCode (*matapply)(PC, Mat, Mat);
161b581b66SBarry Smith   PetscErrorCode (*applysymmetricleft)(PC, Vec, Vec);
171b581b66SBarry Smith   PetscErrorCode (*applysymmetricright)(PC, Vec, Vec);
186891c3e4SJed Brown   PetscErrorCode (*applyBA)(PC, PCSide, Vec, Vec, Vec);
196891c3e4SJed Brown   PetscErrorCode (*presolve)(PC, KSP, Vec, Vec);
206891c3e4SJed Brown   PetscErrorCode (*postsolve)(PC, KSP, Vec, Vec);
216891c3e4SJed Brown   PetscErrorCode (*view)(PC, PetscViewer);
226891c3e4SJed Brown   PetscErrorCode (*applytranspose)(PC, Vec, Vec);
23ace3abfcSBarry Smith   PetscErrorCode (*applyrich)(PC, Vec, Vec, Vec, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *);
242fa5cd67SKarl Rupp 
254b9ad928SBarry Smith   char *name;
264b9ad928SBarry Smith } PC_Shell;
274b9ad928SBarry Smith 
28b29801fcSSatish Balay /*@C
29be29d3c6SBarry Smith     PCShellGetContext - Returns the user-provided context associated with a shell PC
30be29d3c6SBarry Smith 
31be29d3c6SBarry Smith     Not Collective
32be29d3c6SBarry Smith 
33be29d3c6SBarry Smith     Input Parameter:
34c5ae4b9aSBarry Smith .   pc - should have been created with PCSetType(pc,shell)
35be29d3c6SBarry Smith 
36be29d3c6SBarry Smith     Output Parameter:
37be29d3c6SBarry Smith .   ctx - the user provided context
38be29d3c6SBarry Smith 
39be29d3c6SBarry Smith     Level: advanced
40be29d3c6SBarry Smith 
41be29d3c6SBarry Smith     Notes:
42be29d3c6SBarry Smith     This routine is intended for use within various shell routines
43be29d3c6SBarry Smith 
4495452b02SPatrick Sanan    Fortran Notes:
4595452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
46daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
47daf670e6SBarry Smith 
48db781477SPatrick Sanan .seealso: `PCShellSetContext()`
49be29d3c6SBarry Smith @*/
50*9371c9d4SSatish Balay PetscErrorCode PCShellGetContext(PC pc, void *ctx) {
51ace3abfcSBarry Smith   PetscBool flg;
52be29d3c6SBarry Smith 
53be29d3c6SBarry Smith   PetscFunctionBegin;
540700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
55be29d3c6SBarry Smith   PetscValidPointer(ctx, 2);
569566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCSHELL, &flg));
573ec1f749SStefano Zampini   if (!flg) *(void **)ctx = NULL;
583ec1f749SStefano Zampini   else *(void **)ctx = ((PC_Shell *)(pc->data))->ctx;
59be29d3c6SBarry Smith   PetscFunctionReturn(0);
60be29d3c6SBarry Smith }
61be29d3c6SBarry Smith 
629dd1005fSJed Brown /*@
63be29d3c6SBarry Smith     PCShellSetContext - sets the context for a shell PC
64be29d3c6SBarry Smith 
653f9fe445SBarry Smith    Logically Collective on PC
66be29d3c6SBarry Smith 
67be29d3c6SBarry Smith     Input Parameters:
68be29d3c6SBarry Smith +   pc - the shell PC
69be29d3c6SBarry Smith -   ctx - the context
70be29d3c6SBarry Smith 
71be29d3c6SBarry Smith    Level: advanced
72be29d3c6SBarry Smith 
7395452b02SPatrick Sanan    Fortran Notes:
7495452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
75daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
76daf670e6SBarry Smith 
77db781477SPatrick Sanan .seealso: `PCShellGetContext()`, `PCSHELL`
78be29d3c6SBarry Smith @*/
79*9371c9d4SSatish Balay PetscErrorCode PCShellSetContext(PC pc, void *ctx) {
80c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
81ace3abfcSBarry Smith   PetscBool flg;
82be29d3c6SBarry Smith 
83be29d3c6SBarry Smith   PetscFunctionBegin;
840700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
859566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCSHELL, &flg));
862fa5cd67SKarl Rupp   if (flg) shell->ctx = ctx;
87be29d3c6SBarry Smith   PetscFunctionReturn(0);
88be29d3c6SBarry Smith }
89be29d3c6SBarry Smith 
90*9371c9d4SSatish Balay static PetscErrorCode PCSetUp_Shell(PC pc) {
91c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
924b9ad928SBarry Smith 
934b9ad928SBarry Smith   PetscFunctionBegin;
9428b400f6SJacob Faibussowitsch   PetscCheck(shell->setup, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No setup() routine provided to Shell PC");
9525e27a38SBarry Smith   PetscCallBack("PCSHELL callback setup", (*shell->setup)(pc));
964b9ad928SBarry Smith   PetscFunctionReturn(0);
974b9ad928SBarry Smith }
984b9ad928SBarry Smith 
99*9371c9d4SSatish Balay static PetscErrorCode PCApply_Shell(PC pc, Vec x, Vec y) {
100c5ae4b9aSBarry Smith   PC_Shell        *shell = (PC_Shell *)pc->data;
101e3f487b0SBarry Smith   PetscObjectState instate, outstate;
1024b9ad928SBarry Smith 
1034b9ad928SBarry Smith   PetscFunctionBegin;
10428b400f6SJacob Faibussowitsch   PetscCheck(shell->apply, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No apply() routine provided to Shell PC");
1059566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)y, &instate));
10625e27a38SBarry Smith   PetscCallBack("PCSHELL callback apply", (*shell->apply)(pc, x, y));
1079566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)y, &outstate));
1081e66621cSBarry Smith   /* increase the state of the output vector if the user did not update its state themself as should have been done */
1091e66621cSBarry Smith   if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)y));
1104b9ad928SBarry Smith   PetscFunctionReturn(0);
1114b9ad928SBarry Smith }
1124b9ad928SBarry Smith 
113*9371c9d4SSatish Balay static PetscErrorCode PCMatApply_Shell(PC pc, Mat X, Mat Y) {
1147b6e2003SPierre Jolivet   PC_Shell        *shell = (PC_Shell *)pc->data;
1157b6e2003SPierre Jolivet   PetscObjectState instate, outstate;
1167b6e2003SPierre Jolivet 
1177b6e2003SPierre Jolivet   PetscFunctionBegin;
11828b400f6SJacob Faibussowitsch   PetscCheck(shell->matapply, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No apply() routine provided to Shell PC");
1199566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)Y, &instate));
12025e27a38SBarry Smith   PetscCallBack("PCSHELL callback apply", (*shell->matapply)(pc, X, Y));
1219566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)Y, &outstate));
1221e66621cSBarry Smith   /* increase the state of the output vector if the user did not update its state themself as should have been done */
1231e66621cSBarry Smith   if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)Y));
1247b6e2003SPierre Jolivet   PetscFunctionReturn(0);
1257b6e2003SPierre Jolivet }
1267b6e2003SPierre Jolivet 
127*9371c9d4SSatish Balay static PetscErrorCode PCApplySymmetricLeft_Shell(PC pc, Vec x, Vec y) {
1281b581b66SBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
1291b581b66SBarry Smith 
1301b581b66SBarry Smith   PetscFunctionBegin;
13128b400f6SJacob Faibussowitsch   PetscCheck(shell->applysymmetricleft, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No apply() routine provided to Shell PC");
13225e27a38SBarry Smith   PetscCallBack("PCSHELL callback apply symmetric left", (*shell->applysymmetricleft)(pc, x, y));
1331b581b66SBarry Smith   PetscFunctionReturn(0);
1341b581b66SBarry Smith }
1351b581b66SBarry Smith 
136*9371c9d4SSatish Balay static PetscErrorCode PCApplySymmetricRight_Shell(PC pc, Vec x, Vec y) {
1371b581b66SBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
1381b581b66SBarry Smith 
1391b581b66SBarry Smith   PetscFunctionBegin;
14028b400f6SJacob Faibussowitsch   PetscCheck(shell->applysymmetricright, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No apply() routine provided to Shell PC");
14125e27a38SBarry Smith   PetscCallBack("PCSHELL callback apply symmetric right", (*shell->applysymmetricright)(pc, x, y));
1421b581b66SBarry Smith   PetscFunctionReturn(0);
1431b581b66SBarry Smith }
1441b581b66SBarry Smith 
145*9371c9d4SSatish Balay static PetscErrorCode PCApplyBA_Shell(PC pc, PCSide side, Vec x, Vec y, Vec w) {
146c5ae4b9aSBarry Smith   PC_Shell        *shell = (PC_Shell *)pc->data;
147e3f487b0SBarry Smith   PetscObjectState instate, outstate;
1482bb17772SBarry Smith 
1492bb17772SBarry Smith   PetscFunctionBegin;
15028b400f6SJacob Faibussowitsch   PetscCheck(shell->applyBA, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No applyBA() routine provided to Shell PC");
1519566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)w, &instate));
15225e27a38SBarry Smith   PetscCallBack("PCSHELL callback applyBA", (*shell->applyBA)(pc, side, x, y, w));
1539566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)w, &outstate));
1541e66621cSBarry Smith   /* increase the state of the output vector if the user did not update its state themself as should have been done */
1551e66621cSBarry Smith   if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)w));
1562bb17772SBarry Smith   PetscFunctionReturn(0);
1572bb17772SBarry Smith }
1582bb17772SBarry Smith 
159*9371c9d4SSatish Balay static PetscErrorCode PCPreSolveChangeRHS_Shell(PC pc, PetscBool *change) {
160a06fd7f2SStefano Zampini   PetscFunctionBegin;
161a06fd7f2SStefano Zampini   *change = PETSC_TRUE;
162a06fd7f2SStefano Zampini   PetscFunctionReturn(0);
163a06fd7f2SStefano Zampini }
164a06fd7f2SStefano Zampini 
165*9371c9d4SSatish Balay static PetscErrorCode PCPreSolve_Shell(PC pc, KSP ksp, Vec b, Vec x) {
166c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
1677cdd61b2SBarry Smith 
1687cdd61b2SBarry Smith   PetscFunctionBegin;
16928b400f6SJacob Faibussowitsch   PetscCheck(shell->presolve, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No presolve() routine provided to Shell PC");
17025e27a38SBarry Smith   PetscCallBack("PCSHELL callback presolve", (*shell->presolve)(pc, ksp, b, x));
1717cdd61b2SBarry Smith   PetscFunctionReturn(0);
1727cdd61b2SBarry Smith }
1737cdd61b2SBarry Smith 
174*9371c9d4SSatish Balay static PetscErrorCode PCPostSolve_Shell(PC pc, KSP ksp, Vec b, Vec x) {
175c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
1767cdd61b2SBarry Smith 
1777cdd61b2SBarry Smith   PetscFunctionBegin;
17828b400f6SJacob Faibussowitsch   PetscCheck(shell->postsolve, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No postsolve() routine provided to Shell PC");
17925e27a38SBarry Smith   PetscCallBack("PCSHELL callback postsolve()", (*shell->postsolve)(pc, ksp, b, x));
1807cdd61b2SBarry Smith   PetscFunctionReturn(0);
1817cdd61b2SBarry Smith }
1827cdd61b2SBarry Smith 
183*9371c9d4SSatish Balay static PetscErrorCode PCApplyTranspose_Shell(PC pc, Vec x, Vec y) {
184c5ae4b9aSBarry Smith   PC_Shell        *shell = (PC_Shell *)pc->data;
185e3f487b0SBarry Smith   PetscObjectState instate, outstate;
1864b9ad928SBarry Smith 
1874b9ad928SBarry Smith   PetscFunctionBegin;
18828b400f6SJacob Faibussowitsch   PetscCheck(shell->applytranspose, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No applytranspose() routine provided to Shell PC");
1899566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)y, &instate));
19025e27a38SBarry Smith   PetscCallBack("PCSHELL callback applytranspose", (*shell->applytranspose)(pc, x, y));
1919566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)y, &outstate));
1921e66621cSBarry Smith   /* increase the state of the output vector if the user did not update its state themself as should have been done */
1931e66621cSBarry Smith   if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)y));
1944b9ad928SBarry Smith   PetscFunctionReturn(0);
1954b9ad928SBarry Smith }
1964b9ad928SBarry Smith 
197*9371c9d4SSatish Balay 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) {
198c5ae4b9aSBarry Smith   PC_Shell        *shell = (PC_Shell *)pc->data;
199e3f487b0SBarry Smith   PetscObjectState instate, outstate;
2004b9ad928SBarry Smith 
2014b9ad928SBarry Smith   PetscFunctionBegin;
20228b400f6SJacob Faibussowitsch   PetscCheck(shell->applyrich, PetscObjectComm((PetscObject)pc), PETSC_ERR_USER, "No applyrichardson() routine provided to Shell PC");
2039566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)y, &instate));
20425e27a38SBarry Smith   PetscCallBack("PCSHELL callback applyrichardson", (*shell->applyrich)(pc, x, y, w, rtol, abstol, dtol, it, guesszero, outits, reason));
2059566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)y, &outstate));
206e3f487b0SBarry Smith   /* increase the state of the output vector since the user did not update its state themself as should have been done */
2071e66621cSBarry Smith   if (instate == outstate) PetscCall(PetscObjectStateIncrease((PetscObject)y));
2084b9ad928SBarry Smith   PetscFunctionReturn(0);
2094b9ad928SBarry Smith }
2104b9ad928SBarry Smith 
211*9371c9d4SSatish Balay static PetscErrorCode PCDestroy_Shell(PC pc) {
2124b9ad928SBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
2134b9ad928SBarry Smith 
2144b9ad928SBarry Smith   PetscFunctionBegin;
2159566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell->name));
21625e27a38SBarry Smith   if (shell->destroy) PetscCallBack("PCSHELL callback destroy", (*shell->destroy)(pc));
2179566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetDestroy_C", NULL));
2189566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetSetUp_C", NULL));
2199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApply_C", NULL));
2209566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetMatApply_C", NULL));
2219566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricLeft_C", NULL));
2229566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricRight_C", NULL));
2239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyBA_C", NULL));
2249566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPreSolve_C", NULL));
2259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPostSolve_C", NULL));
2269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetView_C", NULL));
2279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyTranspose_C", NULL));
2289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetName_C", NULL));
2299566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellGetName_C", NULL));
2309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyRichardson_C", NULL));
2319566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPreSolveChangeRHS_C", NULL));
2329566063dSJacob Faibussowitsch   PetscCall(PetscFree(pc->data));
2334b9ad928SBarry Smith   PetscFunctionReturn(0);
2344b9ad928SBarry Smith }
2354b9ad928SBarry Smith 
236*9371c9d4SSatish Balay static PetscErrorCode PCView_Shell(PC pc, PetscViewer viewer) {
2374b9ad928SBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
238ace3abfcSBarry Smith   PetscBool iascii;
2394b9ad928SBarry Smith 
2404b9ad928SBarry Smith   PetscFunctionBegin;
2419566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
24232077d6dSBarry Smith   if (iascii) {
2431e66621cSBarry Smith     if (shell->name) PetscCall(PetscViewerASCIIPrintf(viewer, "  %s\n", shell->name));
2441e66621cSBarry Smith     else PetscCall(PetscViewerASCIIPrintf(viewer, "  no name\n"));
2454b9ad928SBarry Smith   }
2464b9ad928SBarry Smith   if (shell->view) {
2479566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
2489566063dSJacob Faibussowitsch     PetscCall((*shell->view)(pc, viewer));
2499566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
2504b9ad928SBarry Smith   }
2514b9ad928SBarry Smith   PetscFunctionReturn(0);
2524b9ad928SBarry Smith }
2534b9ad928SBarry Smith 
2544b9ad928SBarry Smith /* ------------------------------------------------------------------------------*/
255*9371c9d4SSatish Balay static PetscErrorCode PCShellSetDestroy_Shell(PC pc, PetscErrorCode (*destroy)(PC)) {
256c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
25718be62a5SSatish Balay 
25818be62a5SSatish Balay   PetscFunctionBegin;
25918be62a5SSatish Balay   shell->destroy = destroy;
26018be62a5SSatish Balay   PetscFunctionReturn(0);
26118be62a5SSatish Balay }
26218be62a5SSatish Balay 
263*9371c9d4SSatish Balay static PetscErrorCode PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(PC)) {
264feb237baSPierre Jolivet   PC_Shell *shell = (PC_Shell *)pc->data;
2654b9ad928SBarry Smith 
2664b9ad928SBarry Smith   PetscFunctionBegin;
2674b9ad928SBarry Smith   shell->setup = setup;
268d01c8aa3SLisandro Dalcin   if (setup) pc->ops->setup = PCSetUp_Shell;
2690a545947SLisandro Dalcin   else pc->ops->setup = NULL;
2704b9ad928SBarry Smith   PetscFunctionReturn(0);
2714b9ad928SBarry Smith }
2724b9ad928SBarry Smith 
273*9371c9d4SSatish Balay static PetscErrorCode PCShellSetApply_Shell(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec)) {
274c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
2754b9ad928SBarry Smith 
2764b9ad928SBarry Smith   PetscFunctionBegin;
2774b9ad928SBarry Smith   shell->apply = apply;
2784b9ad928SBarry Smith   PetscFunctionReturn(0);
2794b9ad928SBarry Smith }
2804b9ad928SBarry Smith 
281*9371c9d4SSatish Balay static PetscErrorCode PCShellSetMatApply_Shell(PC pc, PetscErrorCode (*matapply)(PC, Mat, Mat)) {
2827b6e2003SPierre Jolivet   PC_Shell *shell = (PC_Shell *)pc->data;
2837b6e2003SPierre Jolivet 
2847b6e2003SPierre Jolivet   PetscFunctionBegin;
2857b6e2003SPierre Jolivet   shell->matapply = matapply;
2860e0fe96bSStefano Zampini   if (matapply) pc->ops->matapply = PCMatApply_Shell;
2870e0fe96bSStefano Zampini   else pc->ops->matapply = NULL;
2887b6e2003SPierre Jolivet   PetscFunctionReturn(0);
2897b6e2003SPierre Jolivet }
2907b6e2003SPierre Jolivet 
291*9371c9d4SSatish Balay static PetscErrorCode PCShellSetApplySymmetricLeft_Shell(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec)) {
2921b581b66SBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
2931b581b66SBarry Smith 
2941b581b66SBarry Smith   PetscFunctionBegin;
2951b581b66SBarry Smith   shell->applysymmetricleft = apply;
2961b581b66SBarry Smith   PetscFunctionReturn(0);
2971b581b66SBarry Smith }
2981b581b66SBarry Smith 
299*9371c9d4SSatish Balay static PetscErrorCode PCShellSetApplySymmetricRight_Shell(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec)) {
3001b581b66SBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3011b581b66SBarry Smith 
3021b581b66SBarry Smith   PetscFunctionBegin;
3031b581b66SBarry Smith   shell->applysymmetricright = apply;
3041b581b66SBarry Smith   PetscFunctionReturn(0);
3051b581b66SBarry Smith }
3061b581b66SBarry Smith 
307*9371c9d4SSatish Balay static PetscErrorCode PCShellSetApplyBA_Shell(PC pc, PetscErrorCode (*applyBA)(PC, PCSide, Vec, Vec, Vec)) {
308c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3092bb17772SBarry Smith 
3102bb17772SBarry Smith   PetscFunctionBegin;
311d01c8aa3SLisandro Dalcin   shell->applyBA = applyBA;
312d01c8aa3SLisandro Dalcin   if (applyBA) pc->ops->applyBA = PCApplyBA_Shell;
3130a545947SLisandro Dalcin   else pc->ops->applyBA = NULL;
3142bb17772SBarry Smith   PetscFunctionReturn(0);
3152bb17772SBarry Smith }
3162bb17772SBarry Smith 
317*9371c9d4SSatish Balay static PetscErrorCode PCShellSetPreSolve_Shell(PC pc, PetscErrorCode (*presolve)(PC, KSP, Vec, Vec)) {
318c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3197cdd61b2SBarry Smith 
3207cdd61b2SBarry Smith   PetscFunctionBegin;
3217cdd61b2SBarry Smith   shell->presolve = presolve;
322a06fd7f2SStefano Zampini   if (presolve) {
323a06fd7f2SStefano Zampini     pc->ops->presolve = PCPreSolve_Shell;
3249566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPreSolveChangeRHS_C", PCPreSolveChangeRHS_Shell));
325a06fd7f2SStefano Zampini   } else {
3260a545947SLisandro Dalcin     pc->ops->presolve = NULL;
3279566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPreSolveChangeRHS_C", NULL));
328a06fd7f2SStefano Zampini   }
3297cdd61b2SBarry Smith   PetscFunctionReturn(0);
3307cdd61b2SBarry Smith }
3317cdd61b2SBarry Smith 
332*9371c9d4SSatish Balay static PetscErrorCode PCShellSetPostSolve_Shell(PC pc, PetscErrorCode (*postsolve)(PC, KSP, Vec, Vec)) {
333c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3347cdd61b2SBarry Smith 
3357cdd61b2SBarry Smith   PetscFunctionBegin;
3367cdd61b2SBarry Smith   shell->postsolve = postsolve;
337d01c8aa3SLisandro Dalcin   if (postsolve) pc->ops->postsolve = PCPostSolve_Shell;
3380a545947SLisandro Dalcin   else pc->ops->postsolve = NULL;
3397cdd61b2SBarry Smith   PetscFunctionReturn(0);
3407cdd61b2SBarry Smith }
3417cdd61b2SBarry Smith 
342*9371c9d4SSatish Balay static PetscErrorCode PCShellSetView_Shell(PC pc, PetscErrorCode (*view)(PC, PetscViewer)) {
343c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3444b9ad928SBarry Smith 
3454b9ad928SBarry Smith   PetscFunctionBegin;
3464b9ad928SBarry Smith   shell->view = view;
3474b9ad928SBarry Smith   PetscFunctionReturn(0);
3484b9ad928SBarry Smith }
3494b9ad928SBarry Smith 
350*9371c9d4SSatish Balay static PetscErrorCode PCShellSetApplyTranspose_Shell(PC pc, PetscErrorCode (*applytranspose)(PC, Vec, Vec)) {
351c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3524b9ad928SBarry Smith 
3534b9ad928SBarry Smith   PetscFunctionBegin;
3544b9ad928SBarry Smith   shell->applytranspose = applytranspose;
355d01c8aa3SLisandro Dalcin   if (applytranspose) pc->ops->applytranspose = PCApplyTranspose_Shell;
3560a545947SLisandro Dalcin   else pc->ops->applytranspose = NULL;
357d01c8aa3SLisandro Dalcin   PetscFunctionReturn(0);
358d01c8aa3SLisandro Dalcin }
359d01c8aa3SLisandro Dalcin 
360*9371c9d4SSatish Balay static PetscErrorCode PCShellSetApplyRichardson_Shell(PC pc, PetscErrorCode (*applyrich)(PC, Vec, Vec, Vec, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *)) {
361c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
362d01c8aa3SLisandro Dalcin 
363d01c8aa3SLisandro Dalcin   PetscFunctionBegin;
364d01c8aa3SLisandro Dalcin   shell->applyrich = applyrich;
365d01c8aa3SLisandro Dalcin   if (applyrich) pc->ops->applyrichardson = PCApplyRichardson_Shell;
3660a545947SLisandro Dalcin   else pc->ops->applyrichardson = NULL;
3674b9ad928SBarry Smith   PetscFunctionReturn(0);
3684b9ad928SBarry Smith }
3694b9ad928SBarry Smith 
370*9371c9d4SSatish Balay static PetscErrorCode PCShellSetName_Shell(PC pc, const char name[]) {
371c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3724b9ad928SBarry Smith 
3734b9ad928SBarry Smith   PetscFunctionBegin;
3749566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell->name));
3759566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &shell->name));
3764b9ad928SBarry Smith   PetscFunctionReturn(0);
3774b9ad928SBarry Smith }
3784b9ad928SBarry Smith 
379*9371c9d4SSatish Balay static PetscErrorCode PCShellGetName_Shell(PC pc, const char *name[]) {
380c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3814b9ad928SBarry Smith 
3824b9ad928SBarry Smith   PetscFunctionBegin;
3834b9ad928SBarry Smith   *name = shell->name;
3844b9ad928SBarry Smith   PetscFunctionReturn(0);
3854b9ad928SBarry Smith }
3864b9ad928SBarry Smith 
3874b9ad928SBarry Smith /* -------------------------------------------------------------------------------*/
3884b9ad928SBarry Smith 
38918be62a5SSatish Balay /*@C
39018be62a5SSatish Balay    PCShellSetDestroy - Sets routine to use to destroy the user-provided
39118be62a5SSatish Balay    application context.
39218be62a5SSatish Balay 
3933f9fe445SBarry Smith    Logically Collective on PC
39418be62a5SSatish Balay 
39518be62a5SSatish Balay    Input Parameters:
39618be62a5SSatish Balay +  pc - the preconditioner context
397a2b725a8SWilliam Gropp -  destroy - the application-provided destroy routine
39818be62a5SSatish Balay 
39918be62a5SSatish Balay    Calling sequence of destroy:
40018be62a5SSatish Balay .vb
4016891c3e4SJed Brown    PetscErrorCode destroy (PC)
40218be62a5SSatish Balay .ve
40318be62a5SSatish Balay 
40418be62a5SSatish Balay .  ptr - the application context
40518be62a5SSatish Balay 
40695452b02SPatrick Sanan    Notes:
40795452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
4084aa34b0aSBarry Smith 
40918be62a5SSatish Balay    Level: developer
41018be62a5SSatish Balay 
411db781477SPatrick Sanan .seealso: `PCShellSetApply()`, `PCShellSetContext()`
41218be62a5SSatish Balay @*/
413*9371c9d4SSatish Balay PetscErrorCode PCShellSetDestroy(PC pc, PetscErrorCode (*destroy)(PC)) {
41418be62a5SSatish Balay   PetscFunctionBegin;
4150700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
416cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetDestroy_C", (PC, PetscErrorCode(*)(PC)), (pc, destroy));
41718be62a5SSatish Balay   PetscFunctionReturn(0);
41818be62a5SSatish Balay }
41918be62a5SSatish Balay 
4204b9ad928SBarry Smith /*@C
4214b9ad928SBarry Smith    PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
4224b9ad928SBarry Smith    matrix operator is changed.
4234b9ad928SBarry Smith 
4243f9fe445SBarry Smith    Logically Collective on PC
4254b9ad928SBarry Smith 
4264b9ad928SBarry Smith    Input Parameters:
4274b9ad928SBarry Smith +  pc - the preconditioner context
428a2b725a8SWilliam Gropp -  setup - the application-provided setup routine
4294b9ad928SBarry Smith 
4304b9ad928SBarry Smith    Calling sequence of setup:
4314b9ad928SBarry Smith .vb
4326891c3e4SJed Brown    PetscErrorCode setup (PC pc)
4334b9ad928SBarry Smith .ve
4344b9ad928SBarry Smith 
4356891c3e4SJed Brown .  pc - the preconditioner, get the application context with PCShellGetContext()
4364b9ad928SBarry Smith 
43795452b02SPatrick Sanan    Notes:
43895452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
4394aa34b0aSBarry Smith 
4404b9ad928SBarry Smith    Level: developer
4414b9ad928SBarry Smith 
442db781477SPatrick Sanan .seealso: `PCShellSetApplyRichardson()`, `PCShellSetApply()`, `PCShellSetContext()`
4434b9ad928SBarry Smith @*/
444*9371c9d4SSatish Balay PetscErrorCode PCShellSetSetUp(PC pc, PetscErrorCode (*setup)(PC)) {
4454b9ad928SBarry Smith   PetscFunctionBegin;
4460700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
447cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetSetUp_C", (PC, PetscErrorCode(*)(PC)), (pc, setup));
4484b9ad928SBarry Smith   PetscFunctionReturn(0);
4494b9ad928SBarry Smith }
4504b9ad928SBarry Smith 
4514b9ad928SBarry Smith /*@C
4524b9ad928SBarry Smith    PCShellSetView - Sets routine to use as viewer of shell preconditioner
4534b9ad928SBarry Smith 
4543f9fe445SBarry Smith    Logically Collective on PC
4554b9ad928SBarry Smith 
4564b9ad928SBarry Smith    Input Parameters:
4574b9ad928SBarry Smith +  pc - the preconditioner context
4584b9ad928SBarry Smith -  view - the application-provided view routine
4594b9ad928SBarry Smith 
46053a7a830SPatrick Sanan    Calling sequence of view:
4614b9ad928SBarry Smith .vb
4626891c3e4SJed Brown    PetscErrorCode view(PC pc,PetscViewer v)
4634b9ad928SBarry Smith .ve
4644b9ad928SBarry Smith 
4656891c3e4SJed Brown +  pc - the preconditioner, get the application context with PCShellGetContext()
4664b9ad928SBarry Smith -  v   - viewer
4674b9ad928SBarry Smith 
46895452b02SPatrick Sanan    Notes:
46995452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
4704aa34b0aSBarry Smith 
4714b9ad928SBarry Smith    Level: developer
4724b9ad928SBarry Smith 
473db781477SPatrick Sanan .seealso: `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`
4744b9ad928SBarry Smith @*/
475*9371c9d4SSatish Balay PetscErrorCode PCShellSetView(PC pc, PetscErrorCode (*view)(PC, PetscViewer)) {
4764b9ad928SBarry Smith   PetscFunctionBegin;
4770700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
478cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetView_C", (PC, PetscErrorCode(*)(PC, PetscViewer)), (pc, view));
4794b9ad928SBarry Smith   PetscFunctionReturn(0);
4804b9ad928SBarry Smith }
4814b9ad928SBarry Smith 
4824b9ad928SBarry Smith /*@C
4834b9ad928SBarry Smith    PCShellSetApply - Sets routine to use as preconditioner.
4844b9ad928SBarry Smith 
4853f9fe445SBarry Smith    Logically Collective on PC
4864b9ad928SBarry Smith 
4874b9ad928SBarry Smith    Input Parameters:
4884b9ad928SBarry Smith +  pc - the preconditioner context
489be29d3c6SBarry Smith -  apply - the application-provided preconditioning routine
4904b9ad928SBarry Smith 
4914b9ad928SBarry Smith    Calling sequence of apply:
4924b9ad928SBarry Smith .vb
4936891c3e4SJed Brown    PetscErrorCode apply (PC pc,Vec xin,Vec xout)
4944b9ad928SBarry Smith .ve
4954b9ad928SBarry Smith 
4966891c3e4SJed Brown +  pc - the preconditioner, get the application context with PCShellGetContext()
4974b9ad928SBarry Smith .  xin - input vector
4984b9ad928SBarry Smith -  xout - output vector
4994b9ad928SBarry Smith 
50095452b02SPatrick Sanan    Notes:
50195452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
5024aa34b0aSBarry Smith 
5034b9ad928SBarry Smith    Level: developer
5044b9ad928SBarry Smith 
505c2e3fba1SPatrick Sanan .seealso: `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`, `PCShellSetApplyBA()`, `PCShellSetApplySymmetricRight()`, `PCShellSetApplySymmetricLeft()`
5064b9ad928SBarry Smith @*/
507*9371c9d4SSatish Balay PetscErrorCode PCShellSetApply(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec)) {
5084b9ad928SBarry Smith   PetscFunctionBegin;
5090700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
510cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetApply_C", (PC, PetscErrorCode(*)(PC, Vec, Vec)), (pc, apply));
5114b9ad928SBarry Smith   PetscFunctionReturn(0);
5124b9ad928SBarry Smith }
5134b9ad928SBarry Smith 
5141b581b66SBarry Smith /*@C
5156437efc7SEric Chamberland    PCShellSetMatApply - Sets routine to use as preconditioner on a block of vectors.
5167b6e2003SPierre Jolivet 
5177b6e2003SPierre Jolivet    Logically Collective on PC
5187b6e2003SPierre Jolivet 
5197b6e2003SPierre Jolivet    Input Parameters:
5207b6e2003SPierre Jolivet +  pc - the preconditioner context
5217b6e2003SPierre Jolivet -  apply - the application-provided preconditioning routine
5227b6e2003SPierre Jolivet 
5237b6e2003SPierre Jolivet    Calling sequence of apply:
5247b6e2003SPierre Jolivet .vb
5257b6e2003SPierre Jolivet    PetscErrorCode apply (PC pc,Mat Xin,Mat Xout)
5267b6e2003SPierre Jolivet .ve
5277b6e2003SPierre Jolivet 
5287b6e2003SPierre Jolivet +  pc - the preconditioner, get the application context with PCShellGetContext()
5297b6e2003SPierre Jolivet .  Xin - input block of vectors
5307b6e2003SPierre Jolivet -  Xout - output block of vectors
5317b6e2003SPierre Jolivet 
5327b6e2003SPierre Jolivet    Notes:
5337b6e2003SPierre Jolivet     the function MUST return an error code of 0 on success and nonzero on failure.
5347b6e2003SPierre Jolivet 
5357b6e2003SPierre Jolivet    Level: developer
5367b6e2003SPierre Jolivet 
537db781477SPatrick Sanan .seealso: `PCShellSetApply()`
5387b6e2003SPierre Jolivet @*/
539*9371c9d4SSatish Balay PetscErrorCode PCShellSetMatApply(PC pc, PetscErrorCode (*matapply)(PC, Mat, Mat)) {
5407b6e2003SPierre Jolivet   PetscFunctionBegin;
5417b6e2003SPierre Jolivet   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
542cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetMatApply_C", (PC, PetscErrorCode(*)(PC, Mat, Mat)), (pc, matapply));
5437b6e2003SPierre Jolivet   PetscFunctionReturn(0);
5447b6e2003SPierre Jolivet }
5457b6e2003SPierre Jolivet 
5467b6e2003SPierre Jolivet /*@C
5471b581b66SBarry Smith    PCShellSetApplySymmetricLeft - Sets routine to use as left preconditioner (when the PC_SYMMETRIC is used).
5481b581b66SBarry Smith 
5491b581b66SBarry Smith    Logically Collective on PC
5501b581b66SBarry Smith 
5511b581b66SBarry Smith    Input Parameters:
5521b581b66SBarry Smith +  pc - the preconditioner context
5531b581b66SBarry Smith -  apply - the application-provided left preconditioning routine
5541b581b66SBarry Smith 
5551b581b66SBarry Smith    Calling sequence of apply:
5561b581b66SBarry Smith .vb
5571b581b66SBarry Smith    PetscErrorCode apply (PC pc,Vec xin,Vec xout)
5581b581b66SBarry Smith .ve
5591b581b66SBarry Smith 
5601b581b66SBarry Smith +  pc - the preconditioner, get the application context with PCShellGetContext()
5611b581b66SBarry Smith .  xin - input vector
5621b581b66SBarry Smith -  xout - output vector
5631b581b66SBarry Smith 
56495452b02SPatrick Sanan    Notes:
56595452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
5661b581b66SBarry Smith 
5671b581b66SBarry Smith    Level: developer
5681b581b66SBarry Smith 
569db781477SPatrick Sanan .seealso: `PCShellSetApply()`, `PCShellSetApplySymmetricLeft()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`
5701b581b66SBarry Smith @*/
571*9371c9d4SSatish Balay PetscErrorCode PCShellSetApplySymmetricLeft(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec)) {
5721b581b66SBarry Smith   PetscFunctionBegin;
5731b581b66SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
574cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetApplySymmetricLeft_C", (PC, PetscErrorCode(*)(PC, Vec, Vec)), (pc, apply));
5751b581b66SBarry Smith   PetscFunctionReturn(0);
5761b581b66SBarry Smith }
5771b581b66SBarry Smith 
5781b581b66SBarry Smith /*@C
579a4c07401SPatrick Sanan    PCShellSetApplySymmetricRight - Sets routine to use as right preconditioner (when the PC_SYMMETRIC is used).
5801b581b66SBarry Smith 
5811b581b66SBarry Smith    Logically Collective on PC
5821b581b66SBarry Smith 
5831b581b66SBarry Smith    Input Parameters:
5841b581b66SBarry Smith +  pc - the preconditioner context
5851b581b66SBarry Smith -  apply - the application-provided right preconditioning routine
5861b581b66SBarry Smith 
5871b581b66SBarry Smith    Calling sequence of apply:
5881b581b66SBarry Smith .vb
5891b581b66SBarry Smith    PetscErrorCode apply (PC pc,Vec xin,Vec xout)
5901b581b66SBarry Smith .ve
5911b581b66SBarry Smith 
5921b581b66SBarry Smith +  pc - the preconditioner, get the application context with PCShellGetContext()
5931b581b66SBarry Smith .  xin - input vector
5941b581b66SBarry Smith -  xout - output vector
5951b581b66SBarry Smith 
59695452b02SPatrick Sanan    Notes:
59795452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
5981b581b66SBarry Smith 
5991b581b66SBarry Smith    Level: developer
6001b581b66SBarry Smith 
601db781477SPatrick Sanan .seealso: `PCShellSetApply()`, `PCShellSetApplySymmetricLeft()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`
6021b581b66SBarry Smith @*/
603*9371c9d4SSatish Balay PetscErrorCode PCShellSetApplySymmetricRight(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec)) {
6041b581b66SBarry Smith   PetscFunctionBegin;
6051b581b66SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
606cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetApplySymmetricRight_C", (PC, PetscErrorCode(*)(PC, Vec, Vec)), (pc, apply));
6071b581b66SBarry Smith   PetscFunctionReturn(0);
6081b581b66SBarry Smith }
6091b581b66SBarry Smith 
6102bb17772SBarry Smith /*@C
6112bb17772SBarry Smith    PCShellSetApplyBA - Sets routine to use as preconditioner times operator.
6122bb17772SBarry Smith 
6133f9fe445SBarry Smith    Logically Collective on PC
6142bb17772SBarry Smith 
6152bb17772SBarry Smith    Input Parameters:
6162bb17772SBarry Smith +  pc - the preconditioner context
6172bb17772SBarry Smith -  applyBA - the application-provided BA routine
6182bb17772SBarry Smith 
61953a7a830SPatrick Sanan    Calling sequence of applyBA:
6202bb17772SBarry Smith .vb
6216891c3e4SJed Brown    PetscErrorCode applyBA (PC pc,Vec xin,Vec xout)
6222bb17772SBarry Smith .ve
6232bb17772SBarry Smith 
6246891c3e4SJed Brown +  pc - the preconditioner, get the application context with PCShellGetContext()
6252bb17772SBarry Smith .  xin - input vector
6262bb17772SBarry Smith -  xout - output vector
6272bb17772SBarry Smith 
62895452b02SPatrick Sanan    Notes:
62995452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
6304aa34b0aSBarry Smith 
6312bb17772SBarry Smith    Level: developer
6322bb17772SBarry Smith 
633db781477SPatrick Sanan .seealso: `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`, `PCShellSetApply()`
6342bb17772SBarry Smith @*/
635*9371c9d4SSatish Balay PetscErrorCode PCShellSetApplyBA(PC pc, PetscErrorCode (*applyBA)(PC, PCSide, Vec, Vec, Vec)) {
6362bb17772SBarry Smith   PetscFunctionBegin;
6370700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
638cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetApplyBA_C", (PC, PetscErrorCode(*)(PC, PCSide, Vec, Vec, Vec)), (pc, applyBA));
6392bb17772SBarry Smith   PetscFunctionReturn(0);
6402bb17772SBarry Smith }
6412bb17772SBarry Smith 
6424b9ad928SBarry Smith /*@C
6434b9ad928SBarry Smith    PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
6444b9ad928SBarry Smith 
6453f9fe445SBarry Smith    Logically Collective on PC
6464b9ad928SBarry Smith 
6474b9ad928SBarry Smith    Input Parameters:
6484b9ad928SBarry Smith +  pc - the preconditioner context
6494b9ad928SBarry Smith -  apply - the application-provided preconditioning transpose routine
6504b9ad928SBarry Smith 
6514b9ad928SBarry Smith    Calling sequence of apply:
6524b9ad928SBarry Smith .vb
6536891c3e4SJed Brown    PetscErrorCode applytranspose (PC pc,Vec xin,Vec xout)
6544b9ad928SBarry Smith .ve
6554b9ad928SBarry Smith 
6566891c3e4SJed Brown +  pc - the preconditioner, get the application context with PCShellGetContext()
6574b9ad928SBarry Smith .  xin - input vector
6584b9ad928SBarry Smith -  xout - output vector
6594b9ad928SBarry Smith 
66095452b02SPatrick Sanan    Notes:
66195452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
6624aa34b0aSBarry Smith 
6634b9ad928SBarry Smith    Level: developer
6644b9ad928SBarry Smith 
6654b9ad928SBarry Smith    Notes:
6664b9ad928SBarry Smith    Uses the same context variable as PCShellSetApply().
6674b9ad928SBarry Smith 
668db781477SPatrick Sanan .seealso: `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApply()`, `PCSetContext()`, `PCShellSetApplyBA()`
6694b9ad928SBarry Smith @*/
670*9371c9d4SSatish Balay PetscErrorCode PCShellSetApplyTranspose(PC pc, PetscErrorCode (*applytranspose)(PC, Vec, Vec)) {
6714b9ad928SBarry Smith   PetscFunctionBegin;
6720700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
673cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetApplyTranspose_C", (PC, PetscErrorCode(*)(PC, Vec, Vec)), (pc, applytranspose));
6744b9ad928SBarry Smith   PetscFunctionReturn(0);
6754b9ad928SBarry Smith }
6764b9ad928SBarry Smith 
6777cdd61b2SBarry Smith /*@C
6787cdd61b2SBarry Smith    PCShellSetPreSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
6797cdd61b2SBarry Smith       applied. This usually does something like scale the linear system in some application
6807cdd61b2SBarry Smith       specific way.
6817cdd61b2SBarry Smith 
6823f9fe445SBarry Smith    Logically Collective on PC
6837cdd61b2SBarry Smith 
6847cdd61b2SBarry Smith    Input Parameters:
6857cdd61b2SBarry Smith +  pc - the preconditioner context
6867cdd61b2SBarry Smith -  presolve - the application-provided presolve routine
6877cdd61b2SBarry Smith 
6887cdd61b2SBarry Smith    Calling sequence of presolve:
6897cdd61b2SBarry Smith .vb
6906891c3e4SJed Brown    PetscErrorCode presolve (PC,KSP ksp,Vec b,Vec x)
6917cdd61b2SBarry Smith .ve
6927cdd61b2SBarry Smith 
6936891c3e4SJed Brown +  pc - the preconditioner, get the application context with PCShellGetContext()
6947cdd61b2SBarry Smith .  xin - input vector
6957cdd61b2SBarry Smith -  xout - output vector
6967cdd61b2SBarry Smith 
69795452b02SPatrick Sanan    Notes:
69895452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
6994aa34b0aSBarry Smith 
7007cdd61b2SBarry Smith    Level: developer
7017cdd61b2SBarry Smith 
702db781477SPatrick Sanan .seealso: `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetPostSolve()`, `PCShellSetContext()`
7037cdd61b2SBarry Smith @*/
704*9371c9d4SSatish Balay PetscErrorCode PCShellSetPreSolve(PC pc, PetscErrorCode (*presolve)(PC, KSP, Vec, Vec)) {
7057cdd61b2SBarry Smith   PetscFunctionBegin;
7060700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
707cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetPreSolve_C", (PC, PetscErrorCode(*)(PC, KSP, Vec, Vec)), (pc, presolve));
7087cdd61b2SBarry Smith   PetscFunctionReturn(0);
7097cdd61b2SBarry Smith }
7107cdd61b2SBarry Smith 
7117cdd61b2SBarry Smith /*@C
7127cdd61b2SBarry Smith    PCShellSetPostSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
7137cdd61b2SBarry Smith       applied. This usually does something like scale the linear system in some application
7147cdd61b2SBarry Smith       specific way.
7157cdd61b2SBarry Smith 
7163f9fe445SBarry Smith    Logically Collective on PC
7177cdd61b2SBarry Smith 
7187cdd61b2SBarry Smith    Input Parameters:
7197cdd61b2SBarry Smith +  pc - the preconditioner context
7207cdd61b2SBarry Smith -  postsolve - the application-provided presolve routine
7217cdd61b2SBarry Smith 
7227cdd61b2SBarry Smith    Calling sequence of postsolve:
7237cdd61b2SBarry Smith .vb
7246891c3e4SJed Brown    PetscErrorCode postsolve(PC,KSP ksp,Vec b,Vec x)
7257cdd61b2SBarry Smith .ve
7267cdd61b2SBarry Smith 
7276891c3e4SJed Brown +  pc - the preconditioner, get the application context with PCShellGetContext()
7287cdd61b2SBarry Smith .  xin - input vector
7297cdd61b2SBarry Smith -  xout - output vector
7307cdd61b2SBarry Smith 
73195452b02SPatrick Sanan    Notes:
73295452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
7334aa34b0aSBarry Smith 
7347cdd61b2SBarry Smith    Level: developer
7357cdd61b2SBarry Smith 
736db781477SPatrick Sanan .seealso: `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetPreSolve()`, `PCShellSetContext()`
7377cdd61b2SBarry Smith @*/
738*9371c9d4SSatish Balay PetscErrorCode PCShellSetPostSolve(PC pc, PetscErrorCode (*postsolve)(PC, KSP, Vec, Vec)) {
7397cdd61b2SBarry Smith   PetscFunctionBegin;
7400700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
741cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetPostSolve_C", (PC, PetscErrorCode(*)(PC, KSP, Vec, Vec)), (pc, postsolve));
7427cdd61b2SBarry Smith   PetscFunctionReturn(0);
7437cdd61b2SBarry Smith }
7447cdd61b2SBarry Smith 
7454b9ad928SBarry Smith /*@C
7464b9ad928SBarry Smith    PCShellSetName - Sets an optional name to associate with a shell
7474b9ad928SBarry Smith    preconditioner.
7484b9ad928SBarry Smith 
7494b9ad928SBarry Smith    Not Collective
7504b9ad928SBarry Smith 
7514b9ad928SBarry Smith    Input Parameters:
7524b9ad928SBarry Smith +  pc - the preconditioner context
7534b9ad928SBarry Smith -  name - character string describing shell preconditioner
7544b9ad928SBarry Smith 
7554b9ad928SBarry Smith    Level: developer
7564b9ad928SBarry Smith 
757db781477SPatrick Sanan .seealso: `PCShellGetName()`
7584b9ad928SBarry Smith @*/
759*9371c9d4SSatish Balay PetscErrorCode PCShellSetName(PC pc, const char name[]) {
7604b9ad928SBarry Smith   PetscFunctionBegin;
7610700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
762cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetName_C", (PC, const char[]), (pc, name));
7634b9ad928SBarry Smith   PetscFunctionReturn(0);
7644b9ad928SBarry Smith }
7654b9ad928SBarry Smith 
7664b9ad928SBarry Smith /*@C
7674b9ad928SBarry Smith    PCShellGetName - Gets an optional name that the user has set for a shell
7684b9ad928SBarry Smith    preconditioner.
7694b9ad928SBarry Smith 
7704b9ad928SBarry Smith    Not Collective
7714b9ad928SBarry Smith 
7724b9ad928SBarry Smith    Input Parameter:
7734b9ad928SBarry Smith .  pc - the preconditioner context
7744b9ad928SBarry Smith 
7754b9ad928SBarry Smith    Output Parameter:
7764b9ad928SBarry Smith .  name - character string describing shell preconditioner (you should not free this)
7774b9ad928SBarry Smith 
7784b9ad928SBarry Smith    Level: developer
7794b9ad928SBarry Smith 
780db781477SPatrick Sanan .seealso: `PCShellSetName()`
7814b9ad928SBarry Smith @*/
782*9371c9d4SSatish Balay PetscErrorCode PCShellGetName(PC pc, const char *name[]) {
7834b9ad928SBarry Smith   PetscFunctionBegin;
7840700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
7854482741eSBarry Smith   PetscValidPointer(name, 2);
786cac4c232SBarry Smith   PetscUseMethod(pc, "PCShellGetName_C", (PC, const char *[]), (pc, name));
7874b9ad928SBarry Smith   PetscFunctionReturn(0);
7884b9ad928SBarry Smith }
7894b9ad928SBarry Smith 
7904b9ad928SBarry Smith /*@C
7914b9ad928SBarry Smith    PCShellSetApplyRichardson - Sets routine to use as preconditioner
7924b9ad928SBarry Smith    in Richardson iteration.
7934b9ad928SBarry Smith 
7943f9fe445SBarry Smith    Logically Collective on PC
7954b9ad928SBarry Smith 
7964b9ad928SBarry Smith    Input Parameters:
7974b9ad928SBarry Smith +  pc - the preconditioner context
798be29d3c6SBarry Smith -  apply - the application-provided preconditioning routine
7994b9ad928SBarry Smith 
8004b9ad928SBarry Smith    Calling sequence of apply:
8014b9ad928SBarry Smith .vb
8026891c3e4SJed Brown    PetscErrorCode apply (PC pc,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits)
8034b9ad928SBarry Smith .ve
8044b9ad928SBarry Smith 
8056891c3e4SJed Brown +  pc - the preconditioner, get the application context with PCShellGetContext()
8064b9ad928SBarry Smith .  b - right-hand-side
8074b9ad928SBarry Smith .  x - current iterate
8084b9ad928SBarry Smith .  r - work space
8094b9ad928SBarry Smith .  rtol - relative tolerance of residual norm to stop at
81070441072SBarry Smith .  abstol - absolute tolerance of residual norm to stop at
8114b9ad928SBarry Smith .  dtol - if residual norm increases by this factor than return
8124b9ad928SBarry Smith -  maxits - number of iterations to run
8134b9ad928SBarry Smith 
81495452b02SPatrick Sanan    Notes:
81595452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
8164aa34b0aSBarry Smith 
8174b9ad928SBarry Smith    Level: developer
8184b9ad928SBarry Smith 
819db781477SPatrick Sanan .seealso: `PCShellSetApply()`, `PCShellSetContext()`
8204b9ad928SBarry Smith @*/
821*9371c9d4SSatish Balay PetscErrorCode PCShellSetApplyRichardson(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec, Vec, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *)) {
8224b9ad928SBarry Smith   PetscFunctionBegin;
8230700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
824cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetApplyRichardson_C", (PC, PetscErrorCode(*)(PC, Vec, Vec, Vec, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *)), (pc, apply));
8254b9ad928SBarry Smith   PetscFunctionReturn(0);
8264b9ad928SBarry Smith }
8274b9ad928SBarry Smith 
8284b9ad928SBarry Smith /*MC
8294b9ad928SBarry Smith    PCSHELL - Creates a new preconditioner class for use with your
8304b9ad928SBarry Smith               own private data storage format.
8314b9ad928SBarry Smith 
8324b9ad928SBarry Smith    Level: advanced
833e0bb08deSStefano Zampini 
8344b9ad928SBarry Smith   Usage:
8356891c3e4SJed Brown $             extern PetscErrorCode apply(PC,Vec,Vec);
8366891c3e4SJed Brown $             extern PetscErrorCode applyba(PC,PCSide,Vec,Vec,Vec);
8376891c3e4SJed Brown $             extern PetscErrorCode applytranspose(PC,Vec,Vec);
8386891c3e4SJed Brown $             extern PetscErrorCode setup(PC);
8396891c3e4SJed Brown $             extern PetscErrorCode destroy(PC);
8406891c3e4SJed Brown $
8414b9ad928SBarry Smith $             PCCreate(comm,&pc);
8424b9ad928SBarry Smith $             PCSetType(pc,PCSHELL);
843be29d3c6SBarry Smith $             PCShellSetContext(pc,ctx)
8446891c3e4SJed Brown $             PCShellSetApply(pc,apply);
8456891c3e4SJed Brown $             PCShellSetApplyBA(pc,applyba);               (optional)
8466891c3e4SJed Brown $             PCShellSetApplyTranspose(pc,applytranspose); (optional)
8474b9ad928SBarry Smith $             PCShellSetSetUp(pc,setup);                   (optional)
848d01c8aa3SLisandro Dalcin $             PCShellSetDestroy(pc,destroy);               (optional)
8494b9ad928SBarry Smith 
850db781477SPatrick Sanan .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`,
851db781477SPatrick Sanan           `MATSHELL`, `PCShellSetSetUp()`, `PCShellSetApply()`, `PCShellSetView()`,
852db781477SPatrick Sanan           `PCShellSetApplyTranspose()`, `PCShellSetName()`, `PCShellSetApplyRichardson()`,
853db781477SPatrick Sanan           `PCShellGetName()`, `PCShellSetContext()`, `PCShellGetContext()`, `PCShellSetApplyBA()`
8544b9ad928SBarry Smith M*/
8554b9ad928SBarry Smith 
856*9371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PCCreate_Shell(PC pc) {
8574b9ad928SBarry Smith   PC_Shell *shell;
8584b9ad928SBarry Smith 
8594b9ad928SBarry Smith   PetscFunctionBegin;
8609566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(pc, &shell));
8614b9ad928SBarry Smith   pc->data = (void *)shell;
8624b9ad928SBarry Smith 
863d01c8aa3SLisandro Dalcin   pc->ops->destroy             = PCDestroy_Shell;
8644b9ad928SBarry Smith   pc->ops->view                = PCView_Shell;
865d01c8aa3SLisandro Dalcin   pc->ops->apply               = PCApply_Shell;
8661b581b66SBarry Smith   pc->ops->applysymmetricleft  = PCApplySymmetricLeft_Shell;
8671b581b66SBarry Smith   pc->ops->applysymmetricright = PCApplySymmetricRight_Shell;
8680e0fe96bSStefano Zampini   pc->ops->matapply            = NULL;
8690a545947SLisandro Dalcin   pc->ops->applytranspose      = NULL;
8700a545947SLisandro Dalcin   pc->ops->applyrichardson     = NULL;
8710a545947SLisandro Dalcin   pc->ops->setup               = NULL;
8720a545947SLisandro Dalcin   pc->ops->presolve            = NULL;
8730a545947SLisandro Dalcin   pc->ops->postsolve           = NULL;
8744b9ad928SBarry Smith 
8750a545947SLisandro Dalcin   shell->apply               = NULL;
8760a545947SLisandro Dalcin   shell->applytranspose      = NULL;
8770a545947SLisandro Dalcin   shell->name                = NULL;
8780a545947SLisandro Dalcin   shell->applyrich           = NULL;
8790a545947SLisandro Dalcin   shell->presolve            = NULL;
8800a545947SLisandro Dalcin   shell->postsolve           = NULL;
8810a545947SLisandro Dalcin   shell->ctx                 = NULL;
8820a545947SLisandro Dalcin   shell->setup               = NULL;
8830a545947SLisandro Dalcin   shell->view                = NULL;
8840a545947SLisandro Dalcin   shell->destroy             = NULL;
8850a545947SLisandro Dalcin   shell->applysymmetricleft  = NULL;
8860a545947SLisandro Dalcin   shell->applysymmetricright = NULL;
8874b9ad928SBarry Smith 
8889566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetDestroy_C", PCShellSetDestroy_Shell));
8899566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetSetUp_C", PCShellSetSetUp_Shell));
8909566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApply_C", PCShellSetApply_Shell));
8919566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetMatApply_C", PCShellSetMatApply_Shell));
8929566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricLeft_C", PCShellSetApplySymmetricLeft_Shell));
8939566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricRight_C", PCShellSetApplySymmetricRight_Shell));
8949566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyBA_C", PCShellSetApplyBA_Shell));
8959566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPreSolve_C", PCShellSetPreSolve_Shell));
8969566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPostSolve_C", PCShellSetPostSolve_Shell));
8979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetView_C", PCShellSetView_Shell));
8989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyTranspose_C", PCShellSetApplyTranspose_Shell));
8999566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetName_C", PCShellSetName_Shell));
9009566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellGetName_C", PCShellGetName_Shell));
9019566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyRichardson_C", PCShellSetApplyRichardson_Shell));
9024b9ad928SBarry Smith   PetscFunctionReturn(0);
9034b9ad928SBarry Smith }
904