xref: /petsc/src/ksp/pc/impls/shell/shellpc.c (revision f1580f4e3ce5d5b2393648fd039d0d41b440385d)
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
29*f1580f4eSBarry Smith     PCShellGetContext - Returns the user-provided context associated with a shell `PC`
30be29d3c6SBarry Smith 
31be29d3c6SBarry Smith     Not Collective
32be29d3c6SBarry Smith 
33be29d3c6SBarry Smith     Input Parameter:
34*f1580f4eSBarry 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 
41*f1580f4eSBarry Smith     Note:
42be29d3c6SBarry Smith     This routine is intended for use within various shell routines
43be29d3c6SBarry Smith 
44*f1580f4eSBarry 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 
48*f1580f4eSBarry 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 /*@
63*f1580f4eSBarry Smith     PCShellSetContext - sets the context for a shell `PC`
64be29d3c6SBarry Smith 
65*f1580f4eSBarry Smith    Logically Collective on pc
66be29d3c6SBarry Smith 
67be29d3c6SBarry Smith     Input Parameters:
68*f1580f4eSBarry Smith +   pc - the `PC` of type `PCSHELL`
69be29d3c6SBarry Smith -   ctx - the context
70be29d3c6SBarry Smith 
71be29d3c6SBarry Smith    Level: advanced
72be29d3c6SBarry Smith 
73*f1580f4eSBarry 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 
390*f1580f4eSBarry 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 
403*f1580f4eSBarry Smith    Note:
40495452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
4054aa34b0aSBarry Smith 
406*f1580f4eSBarry Smith    Level: intermediate
40718be62a5SSatish Balay 
408*f1580f4eSBarry 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 
421*f1580f4eSBarry 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 
434*f1580f4eSBarry Smith    Note:
43595452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
4364aa34b0aSBarry Smith 
437*f1580f4eSBarry Smith    Level: intermediate
4384b9ad928SBarry Smith 
439*f1580f4eSBarry 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 
451*f1580f4eSBarry 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 
465*f1580f4eSBarry Smith    Note:
46695452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
4674aa34b0aSBarry Smith 
468*f1580f4eSBarry Smith    Level: advanced
4694b9ad928SBarry Smith 
470*f1580f4eSBarry 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 
482*f1580f4eSBarry 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 
497*f1580f4eSBarry Smith    Note:
49895452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
4994aa34b0aSBarry Smith 
500*f1580f4eSBarry Smith    Level: intermediate
5014b9ad928SBarry Smith 
502*f1580f4eSBarry 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 
514*f1580f4eSBarry 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 
529*f1580f4eSBarry Smith    Note:
530*f1580f4eSBarry Smith    The function MUST return an error code of 0 on success and nonzero on failure.
5317b6e2003SPierre Jolivet 
532*f1580f4eSBarry Smith    Level: advanced
5337b6e2003SPierre Jolivet 
534*f1580f4eSBarry 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
544*f1580f4eSBarry Smith    PCShellSetApplySymmetricLeft - Sets routine to use as left preconditioner (when the `PC_SYMMETRIC` is used).
5451b581b66SBarry Smith 
546*f1580f4eSBarry 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 
557*f1580f4eSBarry Smith +  pc - the preconditioner, get the application context with `PCShellGetContext()`
5581b581b66SBarry Smith .  xin - input vector
5591b581b66SBarry Smith -  xout - output vector
5601b581b66SBarry Smith 
561*f1580f4eSBarry Smith    Note:
562*f1580f4eSBarry Smith   The function MUST return an error code of 0 on success and nonzero on failure.
5631b581b66SBarry Smith 
564*f1580f4eSBarry Smith    Level: advanced
5651b581b66SBarry Smith 
566*f1580f4eSBarry 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
576*f1580f4eSBarry Smith    PCShellSetApplySymmetricRight - Sets routine to use as right preconditioner (when the `PC_SYMMETRIC` is used).
5771b581b66SBarry Smith 
578*f1580f4eSBarry 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 
593*f1580f4eSBarry Smith    Note:
594*f1580f4eSBarry Smith    The function MUST return an error code of 0 on success and nonzero on failure.
5951b581b66SBarry Smith 
596*f1580f4eSBarry Smith    Level: advanced
5971b581b66SBarry Smith 
598*f1580f4eSBarry 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 
610*f1580f4eSBarry 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 
625*f1580f4eSBarry Smith    Note:
626*f1580f4eSBarry Smith    The function MUST return an error code of 0 on success and nonzero on failure.
6274aa34b0aSBarry Smith 
628*f1580f4eSBarry Smith    Level: intermediate
6292bb17772SBarry Smith 
630*f1580f4eSBarry 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 
642*f1580f4eSBarry 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 
657*f1580f4eSBarry Smith    Note:
65895452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
6594aa34b0aSBarry Smith 
660*f1580f4eSBarry Smith    Level: intermediate
6614b9ad928SBarry Smith 
662*f1580f4eSBarry Smith    Note:
663*f1580f4eSBarry Smith    Uses the same context variable as `PCShellSetApply()`.
6644b9ad928SBarry Smith 
665*f1580f4eSBarry 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
675*f1580f4eSBarry 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 
679*f1580f4eSBarry 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 
694*f1580f4eSBarry Smith    Note:
695*f1580f4eSBarry Smith    The function MUST return an error code of 0 on success and nonzero on failure.
6964aa34b0aSBarry Smith 
697*f1580f4eSBarry Smith    Level: advanced
6987cdd61b2SBarry Smith 
699*f1580f4eSBarry 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
709*f1580f4eSBarry 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 
713*f1580f4eSBarry 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 
724*f1580f4eSBarry Smith +  pc - the preconditioner, get the application context with `PCShellGetContext()`
7257cdd61b2SBarry Smith .  xin - input vector
7267cdd61b2SBarry Smith -  xout - output vector
7277cdd61b2SBarry Smith 
728*f1580f4eSBarry Smith    Note:
72995452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
7304aa34b0aSBarry Smith 
731*f1580f4eSBarry Smith    Level: advanced
7327cdd61b2SBarry Smith 
733*f1580f4eSBarry 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
743*f1580f4eSBarry 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 
752*f1580f4eSBarry Smith    Level: intermediate
7534b9ad928SBarry Smith 
754*f1580f4eSBarry 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
764*f1580f4eSBarry 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 
775*f1580f4eSBarry Smith    Level: intermediate
7764b9ad928SBarry Smith 
777*f1580f4eSBarry 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 
791*f1580f4eSBarry 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 
811*f1580f4eSBarry Smith    Note:
81295452b02SPatrick Sanan     the function MUST return an error code of 0 on success and nonzero on failure.
8134aa34b0aSBarry Smith 
814*f1580f4eSBarry 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
826*f1580f4eSBarry Smith    PCSHELL - Creates a new preconditioner class for use with a users
827*f1580f4eSBarry Smith               own private data storage format and preconditioner application code
8284b9ad928SBarry Smith 
8294b9ad928SBarry Smith    Level: advanced
830e0bb08deSStefano Zampini 
8314b9ad928SBarry Smith   Usage:
832*f1580f4eSBarry Smith .vb
833*f1580f4eSBarry Smith        extern PetscErrorCode apply(PC,Vec,Vec);
834*f1580f4eSBarry Smith        extern PetscErrorCode applyba(PC,PCSide,Vec,Vec,Vec);
835*f1580f4eSBarry Smith        extern PetscErrorCode applytranspose(PC,Vec,Vec);
836*f1580f4eSBarry Smith        extern PetscErrorCode setup(PC);
837*f1580f4eSBarry Smith        extern PetscErrorCode destroy(PC);
838*f1580f4eSBarry Smith 
839*f1580f4eSBarry Smith        PCCreate(comm,&pc);
840*f1580f4eSBarry Smith        PCSetType(pc,PCSHELL);
841*f1580f4eSBarry Smith        PCShellSetContext(pc,ctx)
842*f1580f4eSBarry Smith        PCShellSetApply(pc,apply);
843*f1580f4eSBarry Smith        PCShellSetApplyBA(pc,applyba);               (optional)
844*f1580f4eSBarry Smith        PCShellSetApplyTranspose(pc,applytranspose); (optional)
845*f1580f4eSBarry Smith        PCShellSetSetUp(pc,setup);                   (optional)
846*f1580f4eSBarry Smith        PCShellSetDestroy(pc,destroy);               (optional)
847*f1580f4eSBarry Smith .ve
8484b9ad928SBarry Smith 
849db781477SPatrick Sanan .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`,
850*f1580f4eSBarry Smith           `MATSHELL`, `PCShellSetSetUp()`, `PCShellSetApply()`, `PCShellSetView()`, `PCShellSetDestroy()`, `PCShellSetPostSolve()`,
851*f1580f4eSBarry Smith           `PCShellSetApplyTranspose()`, `PCShellSetName()`, `PCShellSetApplyRichardson()`, `PCShellSetPreSolve()`, `PCShellSetView()`,
852*f1580f4eSBarry 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;
8599566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(pc, &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