xref: /petsc/src/snes/impls/shell/snesshell.c (revision c30958fdb06df61c40a76215b00e4d9018fd89ec)
1 #include <petsc-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   PetscFunctionBegin;
47   PetscFunctionReturn(0);
48 }
49 
50 #undef __FUNCT__
51 #define __FUNCT__ "SNESDestroy_Shell"
52 PetscErrorCode SNESDestroy_Shell(SNES snes)
53 {
54   PetscErrorCode ierr;
55 
56   PetscFunctionBegin;
57   ierr = SNESReset_Shell(snes);CHKERRQ(ierr);
58   ierr = PetscFree(snes->data);CHKERRQ(ierr);
59   PetscFunctionReturn(0);
60 }
61 
62 #undef __FUNCT__
63 #define __FUNCT__ "SNESSetUp_Shell"
64 PetscErrorCode SNESSetUp_Shell(SNES snes)
65 {
66   PetscFunctionBegin;
67   PetscFunctionReturn(0);
68 }
69 
70 #undef __FUNCT__
71 #define __FUNCT__ "SNESSetFromOptions_Shell"
72 PetscErrorCode SNESSetFromOptions_Shell(SNES snes)
73 {
74   PetscErrorCode ierr;
75 
76   PetscFunctionBegin;
77   ierr = PetscOptionsHead("SNES Shell options");CHKERRQ(ierr);
78   PetscFunctionReturn(0);
79 }
80 
81 #undef __FUNCT__
82 #define __FUNCT__ "SNESView_Shell"
83 PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer)
84 {
85   PetscFunctionBegin;
86   PetscFunctionReturn(0);
87 }
88 
89 #undef __FUNCT__
90 #define __FUNCT__ "SNESShellGetContext"
91 /*@
92     SNESShellGetContext - Returns the user-provided context associated with a shell SNES
93 
94     Not Collective
95 
96     Input Parameter:
97 .   snes - should have been created with SNESSetType(snes,SNESSHELL);
98 
99     Output Parameter:
100 .   ctx - the user provided context
101 
102     Level: advanced
103 
104     Notes:
105     This routine is intended for use within various shell routines
106 
107 .keywords: SNES, shell, get, context
108 
109 .seealso: SNESCreateShell(), SNESShellSetContext()
110 @*/
111 PetscErrorCode  SNESShellGetContext(SNES snes,void **ctx)
112 {
113   PetscErrorCode ierr;
114   PetscBool      flg;
115 
116   PetscFunctionBegin;
117   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
118   PetscValidPointer(ctx,2);
119   ierr = PetscObjectTypeCompare((PetscObject)snes,SNESSHELL,&flg);CHKERRQ(ierr);
120   if (!flg) *ctx = 0;
121   else      *ctx = ((SNES_Shell*)(snes->data))->ctx;
122   PetscFunctionReturn(0);
123 }
124 
125 #undef __FUNCT__
126 #define __FUNCT__ "SNESShellSetContext"
127 /*@
128     SNESShellSetContext - sets the context for a shell SNES
129 
130    Logically Collective on SNES
131 
132     Input Parameters:
133 +   snes - the shell SNES
134 -   ctx - the context
135 
136    Level: advanced
137 
138    Fortran Notes: The context can only be an integer or a PetscObject
139       unfortunately it cannot be a Fortran array or derived type.
140 
141 
142 .seealso: SNESCreateShell(), SNESShellGetContext()
143 @*/
144 PetscErrorCode  SNESShellSetContext(SNES snes,void *ctx)
145 {
146   SNES_Shell     *shell = (SNES_Shell*)snes->data;
147   PetscErrorCode ierr;
148   PetscBool      flg;
149 
150   PetscFunctionBegin;
151   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
152   ierr = PetscObjectTypeCompare((PetscObject)snes,SNESSHELL,&flg);CHKERRQ(ierr);
153   if (flg) {
154     shell->ctx = ctx;
155   }
156   PetscFunctionReturn(0);
157 }
158 
159 #undef __FUNCT__
160 #define __FUNCT__ "SNESSolve_Shell"
161 PetscErrorCode SNESSolve_Shell(SNES snes)
162 {
163   SNES_Shell     *shell = (SNES_Shell *) snes->data;
164   PetscErrorCode ierr;
165 
166   PetscFunctionBegin;
167   if (!shell->solve) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESShellSetSolve() first");
168   snes->reason = SNES_CONVERGED_ITS;
169   ierr = (*shell->solve)(snes,snes->vec_sol);CHKERRQ(ierr);
170   PetscFunctionReturn(0);
171 }
172 
173 EXTERN_C_BEGIN
174 #undef __FUNCT__
175 #define __FUNCT__ "SNESShellSetSolve_Shell"
176 PetscErrorCode  SNESShellSetSolve_Shell(SNES snes,PetscErrorCode (*solve)(SNES,Vec))
177 {
178   SNES_Shell *shell = (SNES_Shell*)snes->data;
179 
180   PetscFunctionBegin;
181   shell->solve = solve;
182   PetscFunctionReturn(0);
183 }
184 EXTERN_C_END
185 
186 /*MC
187   SNESSHELL - a user provided nonlinear solver
188 
189    Level: advanced
190 
191 .seealso: SNESCreate(), SNES, SNESSetType(), SNESType (for list of available types)
192 M*/
193 
194 EXTERN_C_BEGIN
195 #undef __FUNCT__
196 #define __FUNCT__ "SNESCreate_Shell"
197 PetscErrorCode SNESCreate_Shell(SNES snes)
198 {
199   SNES_Shell     *shell;
200   PetscErrorCode ierr;
201 
202   PetscFunctionBegin;
203   snes->ops->destroy        = SNESDestroy_Shell;
204   snes->ops->setup          = SNESSetUp_Shell;
205   snes->ops->setfromoptions = SNESSetFromOptions_Shell;
206   snes->ops->view           = SNESView_Shell;
207   snes->ops->solve          = SNESSolve_Shell;
208   snes->ops->reset          = SNESReset_Shell;
209 
210   snes->usesksp             = PETSC_FALSE;
211   snes->usespc              = PETSC_FALSE;
212 
213   ierr = PetscNewLog(snes, SNES_Shell, &shell);CHKERRQ(ierr);
214   snes->data = (void*) shell;
215   ierr = PetscObjectComposeFunctionDynamic((PetscObject)snes,"SNESShellSetSolve_C","SNESShellSetSolve_Shell",SNESShellSetSolve_Shell);CHKERRQ(ierr);
216   PetscFunctionReturn(0);
217 }
218 EXTERN_C_END
219