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