xref: /petsc/src/snes/impls/shell/snesshell.c (revision b2951d5e8985bc9dd47a017ca09361ac8fb89749)
1 #include <private/snesimpl.h>             /*I   "petscsnes.h"   I*/
2 
3 typedef struct {PetscErrorCode (*solve)(SNES,Vec);void *ctx;} SNES_Shell;
4 
5 #undef __FUNCT__
6 #define __FUNCT__ "SNESShellSetSolve"
7 /*@C
8    SNESShellSetSolve - Sets routine to apply as solver
9 
10    Logically Collective on SNES
11 
12    Input Parameters:
13 +  snes - the nonlinear solver context
14 -  apply - the application-provided solver routine
15 
16    Calling sequence of solve:
17 .vb
18    PetscErrorCode apply (SNES snes,Vec xout)
19 .ve
20 
21 +  snes - the preconditioner, get the application context with SNESShellGetContext()
22 -  xout - solution vector
23 
24    Notes: the function MUST return an error code of 0 on success and nonzero on failure.
25 
26    Level: advanced
27 
28 .keywords: SNES, shell, set, apply, user-provided
29 
30 .seealso: SNESSHELL, SNESShellSetContext(), SNESShellGetContext()
31 @*/
32 PetscErrorCode  SNESShellSetSolve(SNES snes,PetscErrorCode (*solve)(SNES,Vec))
33 {
34   PetscErrorCode ierr;
35 
36   PetscFunctionBegin;
37   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
38   ierr = PetscTryMethod(snes,"SNESShellSetSolve_C",(SNES,PetscErrorCode (*)(SNES,Vec)),(snes,solve));CHKERRQ(ierr);
39   PetscFunctionReturn(0);
40 }
41 
42 #undef __FUNCT__
43 #define __FUNCT__ "SNESReset_Shell"
44 PetscErrorCode SNESReset_Shell(SNES snes)
45 {
46   SNES_Shell     *shell = (SNES_Shell*) snes->data;
47 
48   PetscFunctionBegin;
49   PetscFunctionReturn(0);
50 }
51 
52 #undef __FUNCT__
53 #define __FUNCT__ "SNESDestroy_Shell"
54 PetscErrorCode SNESDestroy_Shell(SNES snes)
55 {
56   PetscErrorCode ierr;
57 
58   PetscFunctionBegin;
59   ierr = SNESReset_Shell(snes);CHKERRQ(ierr);
60   ierr = PetscFree(snes->data);
61   PetscFunctionReturn(0);
62 }
63 
64 #undef __FUNCT__
65 #define __FUNCT__ "SNESSetUp_Shell"
66 PetscErrorCode SNESSetUp_Shell(SNES snes)
67 {
68   SNES_Shell    *shell = (SNES_Shell *) snes->data;
69 
70   PetscFunctionBegin;
71   PetscFunctionReturn(0);
72 }
73 
74 #undef __FUNCT__
75 #define __FUNCT__ "SNESSetFromOptions_Shell"
76 PetscErrorCode SNESSetFromOptions_Shell(SNES snes)
77 {
78   SNES_Shell     *shell = (SNES_Shell *) snes->data;
79   PetscErrorCode ierr;
80 
81   PetscFunctionBegin;
82   ierr = PetscOptionsHead("SNES Shell options");CHKERRQ(ierr);
83   PetscFunctionReturn(0);
84 }
85 
86 #undef __FUNCT__
87 #define __FUNCT__ "SNESView_Shell"
88 PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer)
89 {
90   SNES_Shell     *shell = (SNES_Shell *) snes->data;
91 
92   PetscFunctionBegin;
93   PetscFunctionReturn(0);
94 }
95 
96 #undef __FUNCT__
97 #define __FUNCT__ "SNESShellGetContext"
98 /*@C
99     SNESShellGetContext - Returns the user-provided context associated with a shell SNES
100 
101     Not Collective
102 
103     Input Parameter:
104 .   snes - should have been created with SNESSetType(snes,SNESSHELL);
105 
106     Output Parameter:
107 .   ctx - the user provided context
108 
109     Level: advanced
110 
111     Notes:
112     This routine is intended for use within various shell routines
113 
114 .keywords: SNES, shell, get, context
115 
116 .seealso: SNESCreateShell(), SNESShellSetContext()
117 @*/
118 PetscErrorCode  SNESShellGetContext(SNES snes,void **ctx)
119 {
120   PetscErrorCode ierr;
121   PetscBool      flg;
122 
123   PetscFunctionBegin;
124   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
125   PetscValidPointer(ctx,2);
126   ierr = PetscTypeCompare((PetscObject)snes,SNESSHELL,&flg);CHKERRQ(ierr);
127   if (!flg) *ctx = 0;
128   else      *ctx = ((SNES_Shell*)(snes->data))->ctx;
129   PetscFunctionReturn(0);
130 }
131 
132 #undef __FUNCT__
133 #define __FUNCT__ "SNESShellSetContext"
134 /*@
135     SNESShellSetContext - sets the context for a shell SNES
136 
137    Logically Collective on SNES
138 
139     Input Parameters:
140 +   snes - the shell SNES
141 -   ctx - the context
142 
143    Level: advanced
144 
145    Fortran Notes: The context can only be an integer or a PetscObject
146       unfortunately it cannot be a Fortran array or derived type.
147 
148 
149 .seealso: SNESCreateShell(), SNESShellGetContext()
150 @*/
151 PetscErrorCode  SNESShellSetContext(SNES snes,void *ctx)
152 {
153   SNES_Shell     *shell = (SNES_Shell*)snes->data;
154   PetscErrorCode ierr;
155   PetscBool      flg;
156 
157   PetscFunctionBegin;
158   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
159   ierr = PetscTypeCompare((PetscObject)snes,SNESSHELL,&flg);CHKERRQ(ierr);
160   if (flg) {
161     shell->ctx = ctx;
162   }
163   PetscFunctionReturn(0);
164 }
165 
166 #undef __FUNCT__
167 #define __FUNCT__ "SNESSolve_Shell"
168 PetscErrorCode SNESSolve_Shell(SNES snes)
169 {
170   SNES_Shell     *shell = (SNES_Shell *) snes->data;
171   PetscErrorCode ierr;
172 
173   PetscFunctionBegin;
174   if (!shell->solve) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESShellSetSolve() first");
175   ierr = (*shell->solve)(snes,snes->vec_sol);CHKERRQ(ierr);
176   PetscFunctionReturn(0);
177 }
178 
179 EXTERN_C_BEGIN
180 #undef __FUNCT__
181 #define __FUNCT__ "SNESShellSetSolve_Shell"
182 PetscErrorCode  SNESShellSetSolve_Shell(SNES snes,PetscErrorCode (*solve)(SNES,Vec))
183 {
184   SNES_Shell *shell = (SNES_Shell*)snes->data;
185 
186   PetscFunctionBegin;
187   shell->solve = solve;
188   PetscFunctionReturn(0);
189 }
190 EXTERN_C_END
191 
192 /*MC
193   SNESSHELL - a user provided nonlinear solver
194 
195    Level: advanced
196 
197 .seealso: SNESCreate(), SNES, SNESSetType(), SNESType (for list of available types)
198 M*/
199 
200 EXTERN_C_BEGIN
201 #undef __FUNCT__
202 #define __FUNCT__ "SNESCreate_Shell"
203 PetscErrorCode SNESCreate_Shell(SNES snes)
204 {
205   SNES_Shell     *shell;
206   PetscErrorCode ierr;
207 
208   PetscFunctionBegin;
209   snes->ops->destroy        = SNESDestroy_Shell;
210   snes->ops->setup          = SNESSetUp_Shell;
211   snes->ops->setfromoptions = SNESSetFromOptions_Shell;
212   snes->ops->view           = SNESView_Shell;
213   snes->ops->solve          = SNESSolve_Shell;
214   snes->ops->reset          = SNESReset_Shell;
215 
216   snes->usesksp             = PETSC_FALSE;
217 
218   ierr = PetscNewLog(snes, SNES_Shell, &shell);CHKERRQ(ierr);
219   snes->data = (void*) shell;
220   ierr = PetscObjectComposeFunctionDynamic((PetscObject)snes,"SNESShellSetSolve_C","SNESShellSetSolve_Shell",SNESShellSetSolve_Shell);CHKERRQ(ierr);
221   PetscFunctionReturn(0);
222 }
223 EXTERN_C_END
224