xref: /petsc/src/snes/impls/shell/snesshell.c (revision 66c9fbdd036b1e887ebf0d2bef6dbdcafd086d45)
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
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 {
31   PetscFunctionBegin;
32   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
33   PetscTryMethod(snes, "SNESShellSetSolve_C", (SNES, PetscErrorCode(*)(SNES, Vec)), (snes, solve));
34   PetscFunctionReturn(0);
35 }
36 
37 PetscErrorCode SNESReset_Shell(SNES snes)
38 {
39   PetscFunctionBegin;
40   PetscFunctionReturn(0);
41 }
42 
43 PetscErrorCode SNESDestroy_Shell(SNES snes)
44 {
45   PetscFunctionBegin;
46   PetscCall(SNESReset_Shell(snes));
47   PetscCall(PetscFree(snes->data));
48   PetscFunctionReturn(0);
49 }
50 
51 PetscErrorCode SNESSetUp_Shell(SNES snes)
52 {
53   PetscFunctionBegin;
54   PetscFunctionReturn(0);
55 }
56 
57 PetscErrorCode SNESSetFromOptions_Shell(SNES snes, PetscOptionItems *PetscOptionsObject)
58 {
59   PetscFunctionBegin;
60   PetscOptionsHeadBegin(PetscOptionsObject, "SNES Shell options");
61   PetscFunctionReturn(0);
62 }
63 
64 PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer)
65 {
66   PetscFunctionBegin;
67   PetscFunctionReturn(0);
68 }
69 
70 /*@
71     SNESShellGetContext - Returns the user-provided context associated with a `SNESSHELL`
72 
73     Not Collective
74 
75     Input Parameter:
76 .   snes - should have been created with `SNESSetType`(snes,`SNESSHELL`);
77 
78     Output Parameter:
79 .   ctx - the user provided context
80 
81     Level: advanced
82 
83 .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellSetContext()`
84 @*/
85 PetscErrorCode SNESShellGetContext(SNES snes, void *ctx)
86 {
87   PetscBool flg;
88 
89   PetscFunctionBegin;
90   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
91   PetscValidPointer(ctx, 2);
92   PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
93   if (!flg) *(void **)ctx = NULL;
94   else *(void **)ctx = ((SNES_Shell *)(snes->data))->ctx;
95   PetscFunctionReturn(0);
96 }
97 
98 /*@
99     SNESShellSetContext - sets the context for a `SNESSHELL`
100 
101    Logically Collective
102 
103     Input Parameters:
104 +   snes - the `SNESSHELL`
105 -   ctx - the context
106 
107    Level: advanced
108 
109    Fortran Note:
110    The context can only be an integer or a `PetscObject` it cannot be a Fortran array or derived type.
111 
112 .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellGetContext()`
113 @*/
114 PetscErrorCode SNESShellSetContext(SNES snes, void *ctx)
115 {
116   SNES_Shell *shell = (SNES_Shell *)snes->data;
117   PetscBool   flg;
118 
119   PetscFunctionBegin;
120   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
121   PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
122   if (flg) shell->ctx = ctx;
123   PetscFunctionReturn(0);
124 }
125 
126 PetscErrorCode SNESSolve_Shell(SNES snes)
127 {
128   SNES_Shell *shell = (SNES_Shell *)snes->data;
129 
130   PetscFunctionBegin;
131   PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first");
132   snes->reason = SNES_CONVERGED_ITS;
133   PetscCall((*shell->solve)(snes, snes->vec_sol));
134   PetscFunctionReturn(0);
135 }
136 
137 PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec))
138 {
139   SNES_Shell *shell = (SNES_Shell *)snes->data;
140 
141   PetscFunctionBegin;
142   shell->solve = solve;
143   PetscFunctionReturn(0);
144 }
145 
146 /*MC
147   SNESSHELL - a user provided nonlinear solver
148 
149    Level: advanced
150 
151 .seealso: `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType`, `SNESShellGetContext()`, `SNESShellSetContext()`, `SNESShellSetSolve()`
152 M*/
153 
154 PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes)
155 {
156   SNES_Shell *shell;
157 
158   PetscFunctionBegin;
159   snes->ops->destroy        = SNESDestroy_Shell;
160   snes->ops->setup          = SNESSetUp_Shell;
161   snes->ops->setfromoptions = SNESSetFromOptions_Shell;
162   snes->ops->view           = SNESView_Shell;
163   snes->ops->solve          = SNESSolve_Shell;
164   snes->ops->reset          = SNESReset_Shell;
165 
166   snes->usesksp = PETSC_FALSE;
167   snes->usesnpc = PETSC_FALSE;
168 
169   snes->alwayscomputesfinalresidual = PETSC_FALSE;
170 
171   PetscCall(PetscNew(&shell));
172   snes->data = (void *)shell;
173   PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell));
174   PetscFunctionReturn(0);
175 }
176