xref: /petsc/src/ksp/pc/impls/shell/shellpc.c (revision 4dfa11a44d5adf2389f1d3acbc8f3c1116dc6c3a)
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
29f1580f4eSBarry Smith     PCShellGetContext - Returns the user-provided context associated with a shell `PC`
30be29d3c6SBarry Smith 
31be29d3c6SBarry Smith     Not Collective
32be29d3c6SBarry Smith 
33be29d3c6SBarry Smith     Input Parameter:
34f1580f4eSBarry Smith .   pc - of type `PCSHELL` 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 
41f1580f4eSBarry Smith     Note:
42be29d3c6SBarry Smith     This routine is intended for use within various shell routines
43be29d3c6SBarry Smith 
44f1580f4eSBarry Smith    Fortran Note:
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 
48f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellSetContext()`
49be29d3c6SBarry Smith @*/
509371c9d4SSatish 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 /*@
63f1580f4eSBarry Smith     PCShellSetContext - sets the context for a shell `PC`
64be29d3c6SBarry Smith 
65f1580f4eSBarry Smith    Logically Collective on pc
66be29d3c6SBarry Smith 
67be29d3c6SBarry Smith     Input Parameters:
68f1580f4eSBarry Smith +   pc - the `PC` of type `PCSHELL`
69be29d3c6SBarry Smith -   ctx - the context
70be29d3c6SBarry Smith 
71be29d3c6SBarry Smith    Level: advanced
72be29d3c6SBarry Smith 
73f1580f4eSBarry Smith    Fortran Note:
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 @*/
799371c9d4SSatish 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 
909371c9d4SSatish 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 
999371c9d4SSatish 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 
1139371c9d4SSatish 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 
1279371c9d4SSatish 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 
1369371c9d4SSatish 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 
1459371c9d4SSatish 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 
1599371c9d4SSatish 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 
1659371c9d4SSatish 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 
1749371c9d4SSatish 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 
1839371c9d4SSatish 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 
1979371c9d4SSatish 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 
2119371c9d4SSatish 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 
2369371c9d4SSatish 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 
2549371c9d4SSatish Balay static PetscErrorCode PCShellSetDestroy_Shell(PC pc, PetscErrorCode (*destroy)(PC)) {
255c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
25618be62a5SSatish Balay 
25718be62a5SSatish Balay   PetscFunctionBegin;
25818be62a5SSatish Balay   shell->destroy = destroy;
25918be62a5SSatish Balay   PetscFunctionReturn(0);
26018be62a5SSatish Balay }
26118be62a5SSatish Balay 
2629371c9d4SSatish Balay static PetscErrorCode PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(PC)) {
263feb237baSPierre Jolivet   PC_Shell *shell = (PC_Shell *)pc->data;
2644b9ad928SBarry Smith 
2654b9ad928SBarry Smith   PetscFunctionBegin;
2664b9ad928SBarry Smith   shell->setup = setup;
267d01c8aa3SLisandro Dalcin   if (setup) pc->ops->setup = PCSetUp_Shell;
2680a545947SLisandro Dalcin   else pc->ops->setup = NULL;
2694b9ad928SBarry Smith   PetscFunctionReturn(0);
2704b9ad928SBarry Smith }
2714b9ad928SBarry Smith 
2729371c9d4SSatish Balay static PetscErrorCode PCShellSetApply_Shell(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec)) {
273c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
2744b9ad928SBarry Smith 
2754b9ad928SBarry Smith   PetscFunctionBegin;
2764b9ad928SBarry Smith   shell->apply = apply;
2774b9ad928SBarry Smith   PetscFunctionReturn(0);
2784b9ad928SBarry Smith }
2794b9ad928SBarry Smith 
2809371c9d4SSatish Balay static PetscErrorCode PCShellSetMatApply_Shell(PC pc, PetscErrorCode (*matapply)(PC, Mat, Mat)) {
2817b6e2003SPierre Jolivet   PC_Shell *shell = (PC_Shell *)pc->data;
2827b6e2003SPierre Jolivet 
2837b6e2003SPierre Jolivet   PetscFunctionBegin;
2847b6e2003SPierre Jolivet   shell->matapply = matapply;
2850e0fe96bSStefano Zampini   if (matapply) pc->ops->matapply = PCMatApply_Shell;
2860e0fe96bSStefano Zampini   else pc->ops->matapply = NULL;
2877b6e2003SPierre Jolivet   PetscFunctionReturn(0);
2887b6e2003SPierre Jolivet }
2897b6e2003SPierre Jolivet 
2909371c9d4SSatish Balay static PetscErrorCode PCShellSetApplySymmetricLeft_Shell(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec)) {
2911b581b66SBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
2921b581b66SBarry Smith 
2931b581b66SBarry Smith   PetscFunctionBegin;
2941b581b66SBarry Smith   shell->applysymmetricleft = apply;
2951b581b66SBarry Smith   PetscFunctionReturn(0);
2961b581b66SBarry Smith }
2971b581b66SBarry Smith 
2989371c9d4SSatish Balay static PetscErrorCode PCShellSetApplySymmetricRight_Shell(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec)) {
2991b581b66SBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3001b581b66SBarry Smith 
3011b581b66SBarry Smith   PetscFunctionBegin;
3021b581b66SBarry Smith   shell->applysymmetricright = apply;
3031b581b66SBarry Smith   PetscFunctionReturn(0);
3041b581b66SBarry Smith }
3051b581b66SBarry Smith 
3069371c9d4SSatish Balay static PetscErrorCode PCShellSetApplyBA_Shell(PC pc, PetscErrorCode (*applyBA)(PC, PCSide, Vec, Vec, Vec)) {
307c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3082bb17772SBarry Smith 
3092bb17772SBarry Smith   PetscFunctionBegin;
310d01c8aa3SLisandro Dalcin   shell->applyBA = applyBA;
311d01c8aa3SLisandro Dalcin   if (applyBA) pc->ops->applyBA = PCApplyBA_Shell;
3120a545947SLisandro Dalcin   else pc->ops->applyBA = NULL;
3132bb17772SBarry Smith   PetscFunctionReturn(0);
3142bb17772SBarry Smith }
3152bb17772SBarry Smith 
3169371c9d4SSatish Balay static PetscErrorCode PCShellSetPreSolve_Shell(PC pc, PetscErrorCode (*presolve)(PC, KSP, Vec, Vec)) {
317c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3187cdd61b2SBarry Smith 
3197cdd61b2SBarry Smith   PetscFunctionBegin;
3207cdd61b2SBarry Smith   shell->presolve = presolve;
321a06fd7f2SStefano Zampini   if (presolve) {
322a06fd7f2SStefano Zampini     pc->ops->presolve = PCPreSolve_Shell;
3239566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPreSolveChangeRHS_C", PCPreSolveChangeRHS_Shell));
324a06fd7f2SStefano Zampini   } else {
3250a545947SLisandro Dalcin     pc->ops->presolve = NULL;
3269566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCPreSolveChangeRHS_C", NULL));
327a06fd7f2SStefano Zampini   }
3287cdd61b2SBarry Smith   PetscFunctionReturn(0);
3297cdd61b2SBarry Smith }
3307cdd61b2SBarry Smith 
3319371c9d4SSatish Balay static PetscErrorCode PCShellSetPostSolve_Shell(PC pc, PetscErrorCode (*postsolve)(PC, KSP, Vec, Vec)) {
332c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3337cdd61b2SBarry Smith 
3347cdd61b2SBarry Smith   PetscFunctionBegin;
3357cdd61b2SBarry Smith   shell->postsolve = postsolve;
336d01c8aa3SLisandro Dalcin   if (postsolve) pc->ops->postsolve = PCPostSolve_Shell;
3370a545947SLisandro Dalcin   else pc->ops->postsolve = NULL;
3387cdd61b2SBarry Smith   PetscFunctionReturn(0);
3397cdd61b2SBarry Smith }
3407cdd61b2SBarry Smith 
3419371c9d4SSatish Balay static PetscErrorCode PCShellSetView_Shell(PC pc, PetscErrorCode (*view)(PC, PetscViewer)) {
342c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3434b9ad928SBarry Smith 
3444b9ad928SBarry Smith   PetscFunctionBegin;
3454b9ad928SBarry Smith   shell->view = view;
3464b9ad928SBarry Smith   PetscFunctionReturn(0);
3474b9ad928SBarry Smith }
3484b9ad928SBarry Smith 
3499371c9d4SSatish Balay static PetscErrorCode PCShellSetApplyTranspose_Shell(PC pc, PetscErrorCode (*applytranspose)(PC, Vec, Vec)) {
350c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3514b9ad928SBarry Smith 
3524b9ad928SBarry Smith   PetscFunctionBegin;
3534b9ad928SBarry Smith   shell->applytranspose = applytranspose;
354d01c8aa3SLisandro Dalcin   if (applytranspose) pc->ops->applytranspose = PCApplyTranspose_Shell;
3550a545947SLisandro Dalcin   else pc->ops->applytranspose = NULL;
356d01c8aa3SLisandro Dalcin   PetscFunctionReturn(0);
357d01c8aa3SLisandro Dalcin }
358d01c8aa3SLisandro Dalcin 
3599371c9d4SSatish Balay static PetscErrorCode PCShellSetApplyRichardson_Shell(PC pc, PetscErrorCode (*applyrich)(PC, Vec, Vec, Vec, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *)) {
360c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
361d01c8aa3SLisandro Dalcin 
362d01c8aa3SLisandro Dalcin   PetscFunctionBegin;
363d01c8aa3SLisandro Dalcin   shell->applyrich = applyrich;
364d01c8aa3SLisandro Dalcin   if (applyrich) pc->ops->applyrichardson = PCApplyRichardson_Shell;
3650a545947SLisandro Dalcin   else pc->ops->applyrichardson = NULL;
3664b9ad928SBarry Smith   PetscFunctionReturn(0);
3674b9ad928SBarry Smith }
3684b9ad928SBarry Smith 
3699371c9d4SSatish Balay static PetscErrorCode PCShellSetName_Shell(PC pc, const char name[]) {
370c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3714b9ad928SBarry Smith 
3724b9ad928SBarry Smith   PetscFunctionBegin;
3739566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell->name));
3749566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &shell->name));
3754b9ad928SBarry Smith   PetscFunctionReturn(0);
3764b9ad928SBarry Smith }
3774b9ad928SBarry Smith 
3789371c9d4SSatish Balay static PetscErrorCode PCShellGetName_Shell(PC pc, const char *name[]) {
379c5ae4b9aSBarry Smith   PC_Shell *shell = (PC_Shell *)pc->data;
3804b9ad928SBarry Smith 
3814b9ad928SBarry Smith   PetscFunctionBegin;
3824b9ad928SBarry Smith   *name = shell->name;
3834b9ad928SBarry Smith   PetscFunctionReturn(0);
3844b9ad928SBarry Smith }
3854b9ad928SBarry Smith 
38618be62a5SSatish Balay /*@C
38718be62a5SSatish Balay    PCShellSetDestroy - Sets routine to use to destroy the user-provided
38818be62a5SSatish Balay    application context.
38918be62a5SSatish Balay 
390f1580f4eSBarry Smith    Logically Collective on pc
39118be62a5SSatish Balay 
39218be62a5SSatish Balay    Input Parameters:
39318be62a5SSatish Balay +  pc - the preconditioner context
394a2b725a8SWilliam Gropp -  destroy - the application-provided destroy routine
39518be62a5SSatish Balay 
39618be62a5SSatish Balay    Calling sequence of destroy:
39718be62a5SSatish Balay .vb
3986891c3e4SJed Brown    PetscErrorCode destroy (PC)
39918be62a5SSatish Balay .ve
40018be62a5SSatish Balay 
40118be62a5SSatish Balay .  ptr - the application context
40218be62a5SSatish Balay 
403f1580f4eSBarry Smith    Note:
40495452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
4054aa34b0aSBarry Smith 
406f1580f4eSBarry Smith    Level: intermediate
40718be62a5SSatish Balay 
408f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellSetApply()`, `PCShellSetContext()`
40918be62a5SSatish Balay @*/
4109371c9d4SSatish Balay PetscErrorCode PCShellSetDestroy(PC pc, PetscErrorCode (*destroy)(PC)) {
41118be62a5SSatish Balay   PetscFunctionBegin;
4120700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
413cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetDestroy_C", (PC, PetscErrorCode(*)(PC)), (pc, destroy));
41418be62a5SSatish Balay   PetscFunctionReturn(0);
41518be62a5SSatish Balay }
41618be62a5SSatish Balay 
4174b9ad928SBarry Smith /*@C
4184b9ad928SBarry Smith    PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
4194b9ad928SBarry Smith    matrix operator is changed.
4204b9ad928SBarry Smith 
421f1580f4eSBarry Smith    Logically Collective on pc
4224b9ad928SBarry Smith 
4234b9ad928SBarry Smith    Input Parameters:
4244b9ad928SBarry Smith +  pc - the preconditioner context
425a2b725a8SWilliam Gropp -  setup - the application-provided setup routine
4264b9ad928SBarry Smith 
4274b9ad928SBarry Smith    Calling sequence of setup:
4284b9ad928SBarry Smith .vb
4296891c3e4SJed Brown    PetscErrorCode setup (PC pc)
4304b9ad928SBarry Smith .ve
4314b9ad928SBarry Smith 
4326891c3e4SJed Brown .  pc - the preconditioner, get the application context with PCShellGetContext()
4334b9ad928SBarry Smith 
434f1580f4eSBarry Smith    Note:
43595452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
4364aa34b0aSBarry Smith 
437f1580f4eSBarry Smith    Level: intermediate
4384b9ad928SBarry Smith 
439f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetApply()`, `PCShellSetContext()`
4404b9ad928SBarry Smith @*/
4419371c9d4SSatish Balay PetscErrorCode PCShellSetSetUp(PC pc, PetscErrorCode (*setup)(PC)) {
4424b9ad928SBarry Smith   PetscFunctionBegin;
4430700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
444cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetSetUp_C", (PC, PetscErrorCode(*)(PC)), (pc, setup));
4454b9ad928SBarry Smith   PetscFunctionReturn(0);
4464b9ad928SBarry Smith }
4474b9ad928SBarry Smith 
4484b9ad928SBarry Smith /*@C
4494b9ad928SBarry Smith    PCShellSetView - Sets routine to use as viewer of shell preconditioner
4504b9ad928SBarry Smith 
451f1580f4eSBarry Smith    Logically Collective on pc
4524b9ad928SBarry Smith 
4534b9ad928SBarry Smith    Input Parameters:
4544b9ad928SBarry Smith +  pc - the preconditioner context
4554b9ad928SBarry Smith -  view - the application-provided view routine
4564b9ad928SBarry Smith 
45753a7a830SPatrick Sanan    Calling sequence of view:
4584b9ad928SBarry Smith .vb
4596891c3e4SJed Brown    PetscErrorCode view(PC pc,PetscViewer v)
4604b9ad928SBarry Smith .ve
4614b9ad928SBarry Smith 
4626891c3e4SJed Brown +  pc - the preconditioner, get the application context with PCShellGetContext()
4634b9ad928SBarry Smith -  v   - viewer
4644b9ad928SBarry Smith 
465f1580f4eSBarry Smith    Note:
46695452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
4674aa34b0aSBarry Smith 
468f1580f4eSBarry Smith    Level: advanced
4694b9ad928SBarry Smith 
470f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`
4714b9ad928SBarry Smith @*/
4729371c9d4SSatish Balay PetscErrorCode PCShellSetView(PC pc, PetscErrorCode (*view)(PC, PetscViewer)) {
4734b9ad928SBarry Smith   PetscFunctionBegin;
4740700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
475cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetView_C", (PC, PetscErrorCode(*)(PC, PetscViewer)), (pc, view));
4764b9ad928SBarry Smith   PetscFunctionReturn(0);
4774b9ad928SBarry Smith }
4784b9ad928SBarry Smith 
4794b9ad928SBarry Smith /*@C
4804b9ad928SBarry Smith    PCShellSetApply - Sets routine to use as preconditioner.
4814b9ad928SBarry Smith 
482f1580f4eSBarry Smith    Logically Collective on pc
4834b9ad928SBarry Smith 
4844b9ad928SBarry Smith    Input Parameters:
4854b9ad928SBarry Smith +  pc - the preconditioner context
486be29d3c6SBarry Smith -  apply - the application-provided preconditioning routine
4874b9ad928SBarry Smith 
4884b9ad928SBarry Smith    Calling sequence of apply:
4894b9ad928SBarry Smith .vb
4906891c3e4SJed Brown    PetscErrorCode apply (PC pc,Vec xin,Vec xout)
4914b9ad928SBarry Smith .ve
4924b9ad928SBarry Smith 
4936891c3e4SJed Brown +  pc - the preconditioner, get the application context with PCShellGetContext()
4944b9ad928SBarry Smith .  xin - input vector
4954b9ad928SBarry Smith -  xout - output vector
4964b9ad928SBarry Smith 
497f1580f4eSBarry Smith    Note:
49895452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
4994aa34b0aSBarry Smith 
500f1580f4eSBarry Smith    Level: intermediate
5014b9ad928SBarry Smith 
502f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`, `PCShellSetApplyBA()`, `PCShellSetApplySymmetricRight()`, `PCShellSetApplySymmetricLeft()`
5034b9ad928SBarry Smith @*/
5049371c9d4SSatish Balay PetscErrorCode PCShellSetApply(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec)) {
5054b9ad928SBarry Smith   PetscFunctionBegin;
5060700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
507cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetApply_C", (PC, PetscErrorCode(*)(PC, Vec, Vec)), (pc, apply));
5084b9ad928SBarry Smith   PetscFunctionReturn(0);
5094b9ad928SBarry Smith }
5104b9ad928SBarry Smith 
5111b581b66SBarry Smith /*@C
5126437efc7SEric Chamberland    PCShellSetMatApply - Sets routine to use as preconditioner on a block of vectors.
5137b6e2003SPierre Jolivet 
514f1580f4eSBarry Smith    Logically Collective on pc
5157b6e2003SPierre Jolivet 
5167b6e2003SPierre Jolivet    Input Parameters:
5177b6e2003SPierre Jolivet +  pc - the preconditioner context
5187b6e2003SPierre Jolivet -  apply - the application-provided preconditioning routine
5197b6e2003SPierre Jolivet 
5207b6e2003SPierre Jolivet    Calling sequence of apply:
5217b6e2003SPierre Jolivet .vb
5227b6e2003SPierre Jolivet    PetscErrorCode apply (PC pc,Mat Xin,Mat Xout)
5237b6e2003SPierre Jolivet .ve
5247b6e2003SPierre Jolivet 
5257b6e2003SPierre Jolivet +  pc - the preconditioner, get the application context with PCShellGetContext()
5267b6e2003SPierre Jolivet .  Xin - input block of vectors
5277b6e2003SPierre Jolivet -  Xout - output block of vectors
5287b6e2003SPierre Jolivet 
529f1580f4eSBarry Smith    Note:
530f1580f4eSBarry Smith    The function MUST return an error code of 0 on success and nonzero on failure.
5317b6e2003SPierre Jolivet 
532f1580f4eSBarry Smith    Level: advanced
5337b6e2003SPierre Jolivet 
534f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellSetApply()`
5357b6e2003SPierre Jolivet @*/
5369371c9d4SSatish Balay PetscErrorCode PCShellSetMatApply(PC pc, PetscErrorCode (*matapply)(PC, Mat, Mat)) {
5377b6e2003SPierre Jolivet   PetscFunctionBegin;
5387b6e2003SPierre Jolivet   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
539cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetMatApply_C", (PC, PetscErrorCode(*)(PC, Mat, Mat)), (pc, matapply));
5407b6e2003SPierre Jolivet   PetscFunctionReturn(0);
5417b6e2003SPierre Jolivet }
5427b6e2003SPierre Jolivet 
5437b6e2003SPierre Jolivet /*@C
544f1580f4eSBarry Smith    PCShellSetApplySymmetricLeft - Sets routine to use as left preconditioner (when the `PC_SYMMETRIC` is used).
5451b581b66SBarry Smith 
546f1580f4eSBarry Smith    Logically Collective on pc
5471b581b66SBarry Smith 
5481b581b66SBarry Smith    Input Parameters:
5491b581b66SBarry Smith +  pc - the preconditioner context
5501b581b66SBarry Smith -  apply - the application-provided left preconditioning routine
5511b581b66SBarry Smith 
5521b581b66SBarry Smith    Calling sequence of apply:
5531b581b66SBarry Smith .vb
5541b581b66SBarry Smith    PetscErrorCode apply (PC pc,Vec xin,Vec xout)
5551b581b66SBarry Smith .ve
5561b581b66SBarry Smith 
557f1580f4eSBarry Smith +  pc - the preconditioner, get the application context with `PCShellGetContext()`
5581b581b66SBarry Smith .  xin - input vector
5591b581b66SBarry Smith -  xout - output vector
5601b581b66SBarry Smith 
561f1580f4eSBarry Smith    Note:
562f1580f4eSBarry Smith   The function MUST return an error code of 0 on success and nonzero on failure.
5631b581b66SBarry Smith 
564f1580f4eSBarry Smith    Level: advanced
5651b581b66SBarry Smith 
566f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellSetApply()`, `PCShellSetApplySymmetricLeft()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`
5671b581b66SBarry Smith @*/
5689371c9d4SSatish Balay PetscErrorCode PCShellSetApplySymmetricLeft(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec)) {
5691b581b66SBarry Smith   PetscFunctionBegin;
5701b581b66SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
571cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetApplySymmetricLeft_C", (PC, PetscErrorCode(*)(PC, Vec, Vec)), (pc, apply));
5721b581b66SBarry Smith   PetscFunctionReturn(0);
5731b581b66SBarry Smith }
5741b581b66SBarry Smith 
5751b581b66SBarry Smith /*@C
576f1580f4eSBarry Smith    PCShellSetApplySymmetricRight - Sets routine to use as right preconditioner (when the `PC_SYMMETRIC` is used).
5771b581b66SBarry Smith 
578f1580f4eSBarry Smith    Logically Collective on pc
5791b581b66SBarry Smith 
5801b581b66SBarry Smith    Input Parameters:
5811b581b66SBarry Smith +  pc - the preconditioner context
5821b581b66SBarry Smith -  apply - the application-provided right preconditioning routine
5831b581b66SBarry Smith 
5841b581b66SBarry Smith    Calling sequence of apply:
5851b581b66SBarry Smith .vb
5861b581b66SBarry Smith    PetscErrorCode apply (PC pc,Vec xin,Vec xout)
5871b581b66SBarry Smith .ve
5881b581b66SBarry Smith 
5891b581b66SBarry Smith +  pc - the preconditioner, get the application context with PCShellGetContext()
5901b581b66SBarry Smith .  xin - input vector
5911b581b66SBarry Smith -  xout - output vector
5921b581b66SBarry Smith 
593f1580f4eSBarry Smith    Note:
594f1580f4eSBarry Smith    The function MUST return an error code of 0 on success and nonzero on failure.
5951b581b66SBarry Smith 
596f1580f4eSBarry Smith    Level: advanced
5971b581b66SBarry Smith 
598f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellSetApply()`, `PCShellSetApplySymmetricLeft()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`
5991b581b66SBarry Smith @*/
6009371c9d4SSatish Balay PetscErrorCode PCShellSetApplySymmetricRight(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec)) {
6011b581b66SBarry Smith   PetscFunctionBegin;
6021b581b66SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
603cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetApplySymmetricRight_C", (PC, PetscErrorCode(*)(PC, Vec, Vec)), (pc, apply));
6041b581b66SBarry Smith   PetscFunctionReturn(0);
6051b581b66SBarry Smith }
6061b581b66SBarry Smith 
6072bb17772SBarry Smith /*@C
6082bb17772SBarry Smith    PCShellSetApplyBA - Sets routine to use as preconditioner times operator.
6092bb17772SBarry Smith 
610f1580f4eSBarry Smith    Logically Collective on pc
6112bb17772SBarry Smith 
6122bb17772SBarry Smith    Input Parameters:
6132bb17772SBarry Smith +  pc - the preconditioner context
6142bb17772SBarry Smith -  applyBA - the application-provided BA routine
6152bb17772SBarry Smith 
61653a7a830SPatrick Sanan    Calling sequence of applyBA:
6172bb17772SBarry Smith .vb
6186891c3e4SJed Brown    PetscErrorCode applyBA (PC pc,Vec xin,Vec xout)
6192bb17772SBarry Smith .ve
6202bb17772SBarry Smith 
6216891c3e4SJed Brown +  pc - the preconditioner, get the application context with PCShellGetContext()
6222bb17772SBarry Smith .  xin - input vector
6232bb17772SBarry Smith -  xout - output vector
6242bb17772SBarry Smith 
625f1580f4eSBarry Smith    Note:
626f1580f4eSBarry Smith    The function MUST return an error code of 0 on success and nonzero on failure.
6274aa34b0aSBarry Smith 
628f1580f4eSBarry Smith    Level: intermediate
6292bb17772SBarry Smith 
630f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetContext()`, `PCShellSetApply()`
6312bb17772SBarry Smith @*/
6329371c9d4SSatish Balay PetscErrorCode PCShellSetApplyBA(PC pc, PetscErrorCode (*applyBA)(PC, PCSide, Vec, Vec, Vec)) {
6332bb17772SBarry Smith   PetscFunctionBegin;
6340700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
635cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetApplyBA_C", (PC, PetscErrorCode(*)(PC, PCSide, Vec, Vec, Vec)), (pc, applyBA));
6362bb17772SBarry Smith   PetscFunctionReturn(0);
6372bb17772SBarry Smith }
6382bb17772SBarry Smith 
6394b9ad928SBarry Smith /*@C
6404b9ad928SBarry Smith    PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
6414b9ad928SBarry Smith 
642f1580f4eSBarry Smith    Logically Collective on pc
6434b9ad928SBarry Smith 
6444b9ad928SBarry Smith    Input Parameters:
6454b9ad928SBarry Smith +  pc - the preconditioner context
6464b9ad928SBarry Smith -  apply - the application-provided preconditioning transpose routine
6474b9ad928SBarry Smith 
6484b9ad928SBarry Smith    Calling sequence of apply:
6494b9ad928SBarry Smith .vb
6506891c3e4SJed Brown    PetscErrorCode applytranspose (PC pc,Vec xin,Vec xout)
6514b9ad928SBarry Smith .ve
6524b9ad928SBarry Smith 
6536891c3e4SJed Brown +  pc - the preconditioner, get the application context with PCShellGetContext()
6544b9ad928SBarry Smith .  xin - input vector
6554b9ad928SBarry Smith -  xout - output vector
6564b9ad928SBarry Smith 
657f1580f4eSBarry Smith    Note:
65895452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
6594aa34b0aSBarry Smith 
660f1580f4eSBarry Smith    Level: intermediate
6614b9ad928SBarry Smith 
662f1580f4eSBarry Smith    Note:
663f1580f4eSBarry Smith    Uses the same context variable as `PCShellSetApply()`.
6644b9ad928SBarry Smith 
665f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApply()`, `PCSetContext()`, `PCShellSetApplyBA()`
6664b9ad928SBarry Smith @*/
6679371c9d4SSatish Balay PetscErrorCode PCShellSetApplyTranspose(PC pc, PetscErrorCode (*applytranspose)(PC, Vec, Vec)) {
6684b9ad928SBarry Smith   PetscFunctionBegin;
6690700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
670cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetApplyTranspose_C", (PC, PetscErrorCode(*)(PC, Vec, Vec)), (pc, applytranspose));
6714b9ad928SBarry Smith   PetscFunctionReturn(0);
6724b9ad928SBarry Smith }
6734b9ad928SBarry Smith 
6747cdd61b2SBarry Smith /*@C
675f1580f4eSBarry Smith    PCShellSetPreSolve - Sets routine to apply to the operators/vectors before a `KSPSolve()` is
6767cdd61b2SBarry Smith       applied. This usually does something like scale the linear system in some application
6777cdd61b2SBarry Smith       specific way.
6787cdd61b2SBarry Smith 
679f1580f4eSBarry Smith    Logically Collective on pc
6807cdd61b2SBarry Smith 
6817cdd61b2SBarry Smith    Input Parameters:
6827cdd61b2SBarry Smith +  pc - the preconditioner context
6837cdd61b2SBarry Smith -  presolve - the application-provided presolve routine
6847cdd61b2SBarry Smith 
6857cdd61b2SBarry Smith    Calling sequence of presolve:
6867cdd61b2SBarry Smith .vb
6876891c3e4SJed Brown    PetscErrorCode presolve (PC,KSP ksp,Vec b,Vec x)
6887cdd61b2SBarry Smith .ve
6897cdd61b2SBarry Smith 
6906891c3e4SJed Brown +  pc - the preconditioner, get the application context with PCShellGetContext()
6917cdd61b2SBarry Smith .  xin - input vector
6927cdd61b2SBarry Smith -  xout - output vector
6937cdd61b2SBarry Smith 
694f1580f4eSBarry Smith    Note:
695f1580f4eSBarry Smith    The function MUST return an error code of 0 on success and nonzero on failure.
6964aa34b0aSBarry Smith 
697f1580f4eSBarry Smith    Level: advanced
6987cdd61b2SBarry Smith 
699f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetPostSolve()`, `PCShellSetContext()`
7007cdd61b2SBarry Smith @*/
7019371c9d4SSatish Balay PetscErrorCode PCShellSetPreSolve(PC pc, PetscErrorCode (*presolve)(PC, KSP, Vec, Vec)) {
7027cdd61b2SBarry Smith   PetscFunctionBegin;
7030700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
704cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetPreSolve_C", (PC, PetscErrorCode(*)(PC, KSP, Vec, Vec)), (pc, presolve));
7057cdd61b2SBarry Smith   PetscFunctionReturn(0);
7067cdd61b2SBarry Smith }
7077cdd61b2SBarry Smith 
7087cdd61b2SBarry Smith /*@C
709f1580f4eSBarry Smith    PCShellSetPostSolve - Sets routine to apply to the operators/vectors before a `KSPSolve()` is
7107cdd61b2SBarry Smith       applied. This usually does something like scale the linear system in some application
7117cdd61b2SBarry Smith       specific way.
7127cdd61b2SBarry Smith 
713f1580f4eSBarry Smith    Logically Collective on pc
7147cdd61b2SBarry Smith 
7157cdd61b2SBarry Smith    Input Parameters:
7167cdd61b2SBarry Smith +  pc - the preconditioner context
7177cdd61b2SBarry Smith -  postsolve - the application-provided presolve routine
7187cdd61b2SBarry Smith 
7197cdd61b2SBarry Smith    Calling sequence of postsolve:
7207cdd61b2SBarry Smith .vb
7216891c3e4SJed Brown    PetscErrorCode postsolve(PC,KSP ksp,Vec b,Vec x)
7227cdd61b2SBarry Smith .ve
7237cdd61b2SBarry Smith 
724f1580f4eSBarry Smith +  pc - the preconditioner, get the application context with `PCShellGetContext()`
7257cdd61b2SBarry Smith .  xin - input vector
7267cdd61b2SBarry Smith -  xout - output vector
7277cdd61b2SBarry Smith 
728f1580f4eSBarry Smith    Note:
72995452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
7304aa34b0aSBarry Smith 
731f1580f4eSBarry Smith    Level: advanced
7327cdd61b2SBarry Smith 
733f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellSetApplyRichardson()`, `PCShellSetSetUp()`, `PCShellSetApplyTranspose()`, `PCShellSetPreSolve()`, `PCShellSetContext()`
7347cdd61b2SBarry Smith @*/
7359371c9d4SSatish Balay PetscErrorCode PCShellSetPostSolve(PC pc, PetscErrorCode (*postsolve)(PC, KSP, Vec, Vec)) {
7367cdd61b2SBarry Smith   PetscFunctionBegin;
7370700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
738cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetPostSolve_C", (PC, PetscErrorCode(*)(PC, KSP, Vec, Vec)), (pc, postsolve));
7397cdd61b2SBarry Smith   PetscFunctionReturn(0);
7407cdd61b2SBarry Smith }
7417cdd61b2SBarry Smith 
7424b9ad928SBarry Smith /*@C
743f1580f4eSBarry Smith    PCShellSetName - Sets an optional name to associate with a `PCSHELL`
7444b9ad928SBarry Smith    preconditioner.
7454b9ad928SBarry Smith 
7464b9ad928SBarry Smith    Not Collective
7474b9ad928SBarry Smith 
7484b9ad928SBarry Smith    Input Parameters:
7494b9ad928SBarry Smith +  pc - the preconditioner context
7504b9ad928SBarry Smith -  name - character string describing shell preconditioner
7514b9ad928SBarry Smith 
752f1580f4eSBarry Smith    Level: intermediate
7534b9ad928SBarry Smith 
754f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellGetName()`
7554b9ad928SBarry Smith @*/
7569371c9d4SSatish Balay PetscErrorCode PCShellSetName(PC pc, const char name[]) {
7574b9ad928SBarry Smith   PetscFunctionBegin;
7580700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
759cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetName_C", (PC, const char[]), (pc, name));
7604b9ad928SBarry Smith   PetscFunctionReturn(0);
7614b9ad928SBarry Smith }
7624b9ad928SBarry Smith 
7634b9ad928SBarry Smith /*@C
764f1580f4eSBarry Smith    PCShellGetName - Gets an optional name that the user has set for a `PCSHELL`
7654b9ad928SBarry Smith    preconditioner.
7664b9ad928SBarry Smith 
7674b9ad928SBarry Smith    Not Collective
7684b9ad928SBarry Smith 
7694b9ad928SBarry Smith    Input Parameter:
7704b9ad928SBarry Smith .  pc - the preconditioner context
7714b9ad928SBarry Smith 
7724b9ad928SBarry Smith    Output Parameter:
7734b9ad928SBarry Smith .  name - character string describing shell preconditioner (you should not free this)
7744b9ad928SBarry Smith 
775f1580f4eSBarry Smith    Level: intermediate
7764b9ad928SBarry Smith 
777f1580f4eSBarry Smith .seealso: `PCSHELL`, `PCShellSetName()`
7784b9ad928SBarry Smith @*/
7799371c9d4SSatish Balay PetscErrorCode PCShellGetName(PC pc, const char *name[]) {
7804b9ad928SBarry Smith   PetscFunctionBegin;
7810700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
7824482741eSBarry Smith   PetscValidPointer(name, 2);
783cac4c232SBarry Smith   PetscUseMethod(pc, "PCShellGetName_C", (PC, const char *[]), (pc, name));
7844b9ad928SBarry Smith   PetscFunctionReturn(0);
7854b9ad928SBarry Smith }
7864b9ad928SBarry Smith 
7874b9ad928SBarry Smith /*@C
7884b9ad928SBarry Smith    PCShellSetApplyRichardson - Sets routine to use as preconditioner
7894b9ad928SBarry Smith    in Richardson iteration.
7904b9ad928SBarry Smith 
791f1580f4eSBarry Smith    Logically Collective on pc
7924b9ad928SBarry Smith 
7934b9ad928SBarry Smith    Input Parameters:
7944b9ad928SBarry Smith +  pc - the preconditioner context
795be29d3c6SBarry Smith -  apply - the application-provided preconditioning routine
7964b9ad928SBarry Smith 
7974b9ad928SBarry Smith    Calling sequence of apply:
7984b9ad928SBarry Smith .vb
7996891c3e4SJed Brown    PetscErrorCode apply (PC pc,Vec b,Vec x,Vec r,PetscReal rtol,PetscReal abstol,PetscReal dtol,PetscInt maxits)
8004b9ad928SBarry Smith .ve
8014b9ad928SBarry Smith 
8026891c3e4SJed Brown +  pc - the preconditioner, get the application context with PCShellGetContext()
8034b9ad928SBarry Smith .  b - right-hand-side
8044b9ad928SBarry Smith .  x - current iterate
8054b9ad928SBarry Smith .  r - work space
8064b9ad928SBarry Smith .  rtol - relative tolerance of residual norm to stop at
80770441072SBarry Smith .  abstol - absolute tolerance of residual norm to stop at
8084b9ad928SBarry Smith .  dtol - if residual norm increases by this factor than return
8094b9ad928SBarry Smith -  maxits - number of iterations to run
8104b9ad928SBarry Smith 
811f1580f4eSBarry Smith    Note:
81295452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
8134aa34b0aSBarry Smith 
814f1580f4eSBarry Smith    Level: advanced
8154b9ad928SBarry Smith 
816db781477SPatrick Sanan .seealso: `PCShellSetApply()`, `PCShellSetContext()`
8174b9ad928SBarry Smith @*/
8189371c9d4SSatish Balay PetscErrorCode PCShellSetApplyRichardson(PC pc, PetscErrorCode (*apply)(PC, Vec, Vec, Vec, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *)) {
8194b9ad928SBarry Smith   PetscFunctionBegin;
8200700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
821cac4c232SBarry Smith   PetscTryMethod(pc, "PCShellSetApplyRichardson_C", (PC, PetscErrorCode(*)(PC, Vec, Vec, Vec, PetscReal, PetscReal, PetscReal, PetscInt, PetscBool, PetscInt *, PCRichardsonConvergedReason *)), (pc, apply));
8224b9ad928SBarry Smith   PetscFunctionReturn(0);
8234b9ad928SBarry Smith }
8244b9ad928SBarry Smith 
8254b9ad928SBarry Smith /*MC
826f1580f4eSBarry Smith    PCSHELL - Creates a new preconditioner class for use with a users
827f1580f4eSBarry Smith               own private data storage format and preconditioner application code
8284b9ad928SBarry Smith 
8294b9ad928SBarry Smith    Level: advanced
830e0bb08deSStefano Zampini 
8314b9ad928SBarry Smith   Usage:
832f1580f4eSBarry Smith .vb
833f1580f4eSBarry Smith        extern PetscErrorCode apply(PC,Vec,Vec);
834f1580f4eSBarry Smith        extern PetscErrorCode applyba(PC,PCSide,Vec,Vec,Vec);
835f1580f4eSBarry Smith        extern PetscErrorCode applytranspose(PC,Vec,Vec);
836f1580f4eSBarry Smith        extern PetscErrorCode setup(PC);
837f1580f4eSBarry Smith        extern PetscErrorCode destroy(PC);
838f1580f4eSBarry Smith 
839f1580f4eSBarry Smith        PCCreate(comm,&pc);
840f1580f4eSBarry Smith        PCSetType(pc,PCSHELL);
841f1580f4eSBarry Smith        PCShellSetContext(pc,ctx)
842f1580f4eSBarry Smith        PCShellSetApply(pc,apply);
843f1580f4eSBarry Smith        PCShellSetApplyBA(pc,applyba);               (optional)
844f1580f4eSBarry Smith        PCShellSetApplyTranspose(pc,applytranspose); (optional)
845f1580f4eSBarry Smith        PCShellSetSetUp(pc,setup);                   (optional)
846f1580f4eSBarry Smith        PCShellSetDestroy(pc,destroy);               (optional)
847f1580f4eSBarry Smith .ve
8484b9ad928SBarry Smith 
849db781477SPatrick Sanan .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`,
850f1580f4eSBarry Smith           `MATSHELL`, `PCShellSetSetUp()`, `PCShellSetApply()`, `PCShellSetView()`, `PCShellSetDestroy()`, `PCShellSetPostSolve()`,
851f1580f4eSBarry Smith           `PCShellSetApplyTranspose()`, `PCShellSetName()`, `PCShellSetApplyRichardson()`, `PCShellSetPreSolve()`, `PCShellSetView()`,
852f1580f4eSBarry Smith           `PCShellGetName()`, `PCShellSetContext()`, `PCShellGetContext()`, `PCShellSetApplyBA()`, `MATSHELL`, `PCShellSetMatApply()`,
8534b9ad928SBarry Smith M*/
8544b9ad928SBarry Smith 
8559371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PCCreate_Shell(PC pc) {
8564b9ad928SBarry Smith   PC_Shell *shell;
8574b9ad928SBarry Smith 
8584b9ad928SBarry Smith   PetscFunctionBegin;
859*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&shell));
8604b9ad928SBarry Smith   pc->data = (void *)shell;
8614b9ad928SBarry Smith 
862d01c8aa3SLisandro Dalcin   pc->ops->destroy             = PCDestroy_Shell;
8634b9ad928SBarry Smith   pc->ops->view                = PCView_Shell;
864d01c8aa3SLisandro Dalcin   pc->ops->apply               = PCApply_Shell;
8651b581b66SBarry Smith   pc->ops->applysymmetricleft  = PCApplySymmetricLeft_Shell;
8661b581b66SBarry Smith   pc->ops->applysymmetricright = PCApplySymmetricRight_Shell;
8670e0fe96bSStefano Zampini   pc->ops->matapply            = NULL;
8680a545947SLisandro Dalcin   pc->ops->applytranspose      = NULL;
8690a545947SLisandro Dalcin   pc->ops->applyrichardson     = NULL;
8700a545947SLisandro Dalcin   pc->ops->setup               = NULL;
8710a545947SLisandro Dalcin   pc->ops->presolve            = NULL;
8720a545947SLisandro Dalcin   pc->ops->postsolve           = NULL;
8734b9ad928SBarry Smith 
8740a545947SLisandro Dalcin   shell->apply               = NULL;
8750a545947SLisandro Dalcin   shell->applytranspose      = NULL;
8760a545947SLisandro Dalcin   shell->name                = NULL;
8770a545947SLisandro Dalcin   shell->applyrich           = NULL;
8780a545947SLisandro Dalcin   shell->presolve            = NULL;
8790a545947SLisandro Dalcin   shell->postsolve           = NULL;
8800a545947SLisandro Dalcin   shell->ctx                 = NULL;
8810a545947SLisandro Dalcin   shell->setup               = NULL;
8820a545947SLisandro Dalcin   shell->view                = NULL;
8830a545947SLisandro Dalcin   shell->destroy             = NULL;
8840a545947SLisandro Dalcin   shell->applysymmetricleft  = NULL;
8850a545947SLisandro Dalcin   shell->applysymmetricright = NULL;
8864b9ad928SBarry Smith 
8879566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetDestroy_C", PCShellSetDestroy_Shell));
8889566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetSetUp_C", PCShellSetSetUp_Shell));
8899566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApply_C", PCShellSetApply_Shell));
8909566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetMatApply_C", PCShellSetMatApply_Shell));
8919566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricLeft_C", PCShellSetApplySymmetricLeft_Shell));
8929566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplySymmetricRight_C", PCShellSetApplySymmetricRight_Shell));
8939566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyBA_C", PCShellSetApplyBA_Shell));
8949566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPreSolve_C", PCShellSetPreSolve_Shell));
8959566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetPostSolve_C", PCShellSetPostSolve_Shell));
8969566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetView_C", PCShellSetView_Shell));
8979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyTranspose_C", PCShellSetApplyTranspose_Shell));
8989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetName_C", PCShellSetName_Shell));
8999566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellGetName_C", PCShellGetName_Shell));
9009566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCShellSetApplyRichardson_C", PCShellSetApplyRichardson_Shell));
9014b9ad928SBarry Smith   PetscFunctionReturn(0);
9024b9ad928SBarry Smith }
903