xref: /petsc/src/snes/impls/shell/snesshell.c (revision daad07d386296cdcbb87925ef5f1432ee4a24ec4)
1 #include <petsc/private/snesimpl.h>             /*I   "petscsnes.h"   I*/
2 
3 typedef struct {PetscErrorCode (*solve)(SNES,Vec);void *ctx;} SNES_Shell;
4 
5 /*@C
6    SNESShellSetSolve - Sets routine to apply as solver
7 
8    Logically Collective on SNES
9 
10    Input Parameters:
11 +  snes - the nonlinear solver context
12 -  apply - the application-provided solver routine
13 
14    Calling sequence of solve:
15 .vb
16    PetscErrorCode apply (SNES snes,Vec xout)
17 .ve
18 
19 +  snes - the preconditioner, get the application context with SNESShellGetContext()
20 -  xout - solution vector
21 
22    Notes:
23     the function MUST return an error code of 0 on success and nonzero on failure.
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(PetscOptionItems *PetscOptionsObject,SNES snes)
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 shell SNES
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     Notes:
84     This routine is intended for use within various shell routines
85 
86 .seealso: `SNESCreateShell()`, `SNESShellSetContext()`
87 @*/
88 PetscErrorCode  SNESShellGetContext(SNES snes,void *ctx)
89 {
90   PetscBool      flg;
91 
92   PetscFunctionBegin;
93   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
94   PetscValidPointer(ctx,2);
95   PetscCall(PetscObjectTypeCompare((PetscObject)snes,SNESSHELL,&flg));
96   if (!flg) *(void**)ctx = NULL;
97   else      *(void**)ctx = ((SNES_Shell*)(snes->data))->ctx;
98   PetscFunctionReturn(0);
99 }
100 
101 /*@
102     SNESShellSetContext - sets the context for a shell SNES
103 
104    Logically Collective on SNES
105 
106     Input Parameters:
107 +   snes - the shell SNES
108 -   ctx - the context
109 
110    Level: advanced
111 
112    Fortran Notes:
113     The context can only be an integer or a PetscObject
114       unfortunately it cannot be a Fortran array or derived type.
115 
116 .seealso: `SNESCreateShell()`, `SNESShellGetContext()`
117 @*/
118 PetscErrorCode  SNESShellSetContext(SNES snes,void *ctx)
119 {
120   SNES_Shell     *shell = (SNES_Shell*)snes->data;
121   PetscBool      flg;
122 
123   PetscFunctionBegin;
124   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
125   PetscCall(PetscObjectTypeCompare((PetscObject)snes,SNESSHELL,&flg));
126   if (flg) shell->ctx = ctx;
127   PetscFunctionReturn(0);
128 }
129 
130 PetscErrorCode SNESSolve_Shell(SNES snes)
131 {
132   SNES_Shell     *shell = (SNES_Shell*) snes->data;
133 
134   PetscFunctionBegin;
135   PetscCheck(shell->solve,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE,"Must call SNESShellSetSolve() first");
136   snes->reason = SNES_CONVERGED_ITS;
137   PetscCall((*shell->solve)(snes,snes->vec_sol));
138   PetscFunctionReturn(0);
139 }
140 
141 PetscErrorCode  SNESShellSetSolve_Shell(SNES snes,PetscErrorCode (*solve)(SNES,Vec))
142 {
143   SNES_Shell *shell = (SNES_Shell*)snes->data;
144 
145   PetscFunctionBegin;
146   shell->solve = solve;
147   PetscFunctionReturn(0);
148 }
149 
150 /*MC
151   SNESSHELL - a user provided nonlinear solver
152 
153    Level: advanced
154 
155 .seealso: `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType`
156 M*/
157 
158 PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes)
159 {
160   SNES_Shell     *shell;
161 
162   PetscFunctionBegin;
163   snes->ops->destroy        = SNESDestroy_Shell;
164   snes->ops->setup          = SNESSetUp_Shell;
165   snes->ops->setfromoptions = SNESSetFromOptions_Shell;
166   snes->ops->view           = SNESView_Shell;
167   snes->ops->solve          = SNESSolve_Shell;
168   snes->ops->reset          = SNESReset_Shell;
169 
170   snes->usesksp = PETSC_FALSE;
171   snes->usesnpc = PETSC_FALSE;
172 
173   snes->alwayscomputesfinalresidual = PETSC_FALSE;
174 
175   PetscCall(PetscNewLog(snes,&shell));
176   snes->data = (void*) shell;
177   PetscCall(PetscObjectComposeFunction((PetscObject)snes,"SNESShellSetSolve_C",SNESShellSetSolve_Shell));
178   PetscFunctionReturn(0);
179 }
180