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