xref: /petsc/src/snes/impls/shell/snesshell.c (revision 1e633543be291cfcfe1cde705e1b44f9f92cb5cc)
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   snes->reason = SNES_CONVERGED_ITS;
176   ierr = (*shell->solve)(snes,snes->vec_sol);CHKERRQ(ierr);
177   PetscFunctionReturn(0);
178 }
179 
180 EXTERN_C_BEGIN
181 #undef __FUNCT__
182 #define __FUNCT__ "SNESShellSetSolve_Shell"
183 PetscErrorCode  SNESShellSetSolve_Shell(SNES snes,PetscErrorCode (*solve)(SNES,Vec))
184 {
185   SNES_Shell *shell = (SNES_Shell*)snes->data;
186 
187   PetscFunctionBegin;
188   shell->solve = solve;
189   PetscFunctionReturn(0);
190 }
191 EXTERN_C_END
192 
193 /*MC
194   SNESSHELL - a user provided nonlinear solver
195 
196    Level: advanced
197 
198 .seealso: SNESCreate(), SNES, SNESSetType(), SNESType (for list of available types)
199 M*/
200 
201 EXTERN_C_BEGIN
202 #undef __FUNCT__
203 #define __FUNCT__ "SNESCreate_Shell"
204 PetscErrorCode SNESCreate_Shell(SNES snes)
205 {
206   SNES_Shell     *shell;
207   PetscErrorCode ierr;
208 
209   PetscFunctionBegin;
210   snes->ops->destroy        = SNESDestroy_Shell;
211   snes->ops->setup          = SNESSetUp_Shell;
212   snes->ops->setfromoptions = SNESSetFromOptions_Shell;
213   snes->ops->view           = SNESView_Shell;
214   snes->ops->solve          = SNESSolve_Shell;
215   snes->ops->reset          = SNESReset_Shell;
216 
217   snes->usesksp             = PETSC_FALSE;
218 
219   ierr = PetscNewLog(snes, SNES_Shell, &shell);CHKERRQ(ierr);
220   snes->data = (void*) shell;
221   ierr = PetscObjectComposeFunctionDynamic((PetscObject)snes,"SNESShellSetSolve_C","SNESShellSetSolve_Shell",SNESShellSetSolve_Shell);CHKERRQ(ierr);
222   PetscFunctionReturn(0);
223 }
224 EXTERN_C_END
225