xref: /petsc/src/snes/impls/shell/snesshell.c (revision 750b007cd8d816cecd9de99077bb0a703b4cf61a)
1 #include <petsc/private/snesimpl.h> /*I   "petscsnes.h"   I*/
2 
3 typedef struct {
4   PetscErrorCode (*solve)(SNES, Vec);
5   void *ctx;
6 } SNES_Shell;
7 
8 /*@C
9    SNESShellSetSolve - Sets routine to apply as solver
10 
11    Logically Collective on snes
12 
13    Input Parameters:
14 +  snes - the `SNES` nonlinear solver context
15 -  apply - the application-provided solver routine
16 
17    Calling sequence of solve:
18 .vb
19    PetscErrorCode apply (SNES snes,Vec xout)
20 .ve
21 
22 +  snes - the preconditioner, get the application context with `SNESShellGetContext()` provided with `SNESShelletContext()`
23 -  xout - solution vector
24 
25    Level: advanced
26 
27 .seealso: `SNESSHELL`, `SNESShellSetContext()`, `SNESShellGetContext()`
28 @*/
29 PetscErrorCode SNESShellSetSolve(SNES snes, PetscErrorCode (*solve)(SNES, Vec)) {
30   PetscFunctionBegin;
31   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
32   PetscTryMethod(snes, "SNESShellSetSolve_C", (SNES, PetscErrorCode(*)(SNES, Vec)), (snes, solve));
33   PetscFunctionReturn(0);
34 }
35 
36 PetscErrorCode SNESReset_Shell(SNES snes) {
37   PetscFunctionBegin;
38   PetscFunctionReturn(0);
39 }
40 
41 PetscErrorCode SNESDestroy_Shell(SNES snes) {
42   PetscFunctionBegin;
43   PetscCall(SNESReset_Shell(snes));
44   PetscCall(PetscFree(snes->data));
45   PetscFunctionReturn(0);
46 }
47 
48 PetscErrorCode SNESSetUp_Shell(SNES snes) {
49   PetscFunctionBegin;
50   PetscFunctionReturn(0);
51 }
52 
53 PetscErrorCode SNESSetFromOptions_Shell(SNES snes, PetscOptionItems *PetscOptionsObject) {
54   PetscFunctionBegin;
55   PetscOptionsHeadBegin(PetscOptionsObject, "SNES Shell options");
56   PetscFunctionReturn(0);
57 }
58 
59 PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer) {
60   PetscFunctionBegin;
61   PetscFunctionReturn(0);
62 }
63 
64 /*@
65     SNESShellGetContext - Returns the user-provided context associated with a `SNESSHELL`
66 
67     Not Collective
68 
69     Input Parameter:
70 .   snes - should have been created with `SNESSetType`(snes,`SNESSHELL`);
71 
72     Output Parameter:
73 .   ctx - the user provided context
74 
75     Level: advanced
76 
77 .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellSetContext()`
78 @*/
79 PetscErrorCode SNESShellGetContext(SNES snes, void *ctx) {
80   PetscBool flg;
81 
82   PetscFunctionBegin;
83   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
84   PetscValidPointer(ctx, 2);
85   PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
86   if (!flg) *(void **)ctx = NULL;
87   else *(void **)ctx = ((SNES_Shell *)(snes->data))->ctx;
88   PetscFunctionReturn(0);
89 }
90 
91 /*@
92     SNESShellSetContext - sets the context for a `SNESSHELL`
93 
94    Logically Collective on snes
95 
96     Input Parameters:
97 +   snes - the `SNESSHELL`
98 -   ctx - the context
99 
100    Level: advanced
101 
102    Fortran Note:
103    The context can only be an integer or a `PetscObject` it cannot be a Fortran array or derived type.
104 
105 .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellGetContext()`
106 @*/
107 PetscErrorCode SNESShellSetContext(SNES snes, void *ctx) {
108   SNES_Shell *shell = (SNES_Shell *)snes->data;
109   PetscBool   flg;
110 
111   PetscFunctionBegin;
112   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
113   PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
114   if (flg) shell->ctx = ctx;
115   PetscFunctionReturn(0);
116 }
117 
118 PetscErrorCode SNESSolve_Shell(SNES snes) {
119   SNES_Shell *shell = (SNES_Shell *)snes->data;
120 
121   PetscFunctionBegin;
122   PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first");
123   snes->reason = SNES_CONVERGED_ITS;
124   PetscCall((*shell->solve)(snes, snes->vec_sol));
125   PetscFunctionReturn(0);
126 }
127 
128 PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec)) {
129   SNES_Shell *shell = (SNES_Shell *)snes->data;
130 
131   PetscFunctionBegin;
132   shell->solve = solve;
133   PetscFunctionReturn(0);
134 }
135 
136 /*MC
137   SNESSHELL - a user provided nonlinear solver
138 
139    Level: advanced
140 
141 .seealso: `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType`, `SNESShellGetContext()`, `SNESShellSetContext()`, `SNESShellSetSolve()`
142 M*/
143 
144 PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes) {
145   SNES_Shell *shell;
146 
147   PetscFunctionBegin;
148   snes->ops->destroy        = SNESDestroy_Shell;
149   snes->ops->setup          = SNESSetUp_Shell;
150   snes->ops->setfromoptions = SNESSetFromOptions_Shell;
151   snes->ops->view           = SNESView_Shell;
152   snes->ops->solve          = SNESSolve_Shell;
153   snes->ops->reset          = SNESReset_Shell;
154 
155   snes->usesksp = PETSC_FALSE;
156   snes->usesnpc = PETSC_FALSE;
157 
158   snes->alwayscomputesfinalresidual = PETSC_FALSE;
159 
160   PetscCall(PetscNew(&shell));
161   snes->data = (void *)shell;
162   PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell));
163   PetscFunctionReturn(0);
164 }
165