xref: /petsc/src/snes/impls/shell/snesshell.c (revision 2da392cc7c10228af19ad9843ce5155178acb644)
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) *ctx = NULL;
104   else      *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 
124 .seealso: SNESCreateShell(), SNESShellGetContext()
125 @*/
126 PetscErrorCode  SNESShellSetContext(SNES snes,void *ctx)
127 {
128   SNES_Shell     *shell = (SNES_Shell*)snes->data;
129   PetscErrorCode ierr;
130   PetscBool      flg;
131 
132   PetscFunctionBegin;
133   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
134   ierr = PetscObjectTypeCompare((PetscObject)snes,SNESSHELL,&flg);CHKERRQ(ierr);
135   if (flg) shell->ctx = ctx;
136   PetscFunctionReturn(0);
137 }
138 
139 PetscErrorCode SNESSolve_Shell(SNES snes)
140 {
141   SNES_Shell     *shell = (SNES_Shell*) snes->data;
142   PetscErrorCode ierr;
143 
144   PetscFunctionBegin;
145   if (!shell->solve) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE,"Must call SNESShellSetSolve() first");
146   snes->reason = SNES_CONVERGED_ITS;
147   ierr         = (*shell->solve)(snes,snes->vec_sol);CHKERRQ(ierr);
148   PetscFunctionReturn(0);
149 }
150 
151 PetscErrorCode  SNESShellSetSolve_Shell(SNES snes,PetscErrorCode (*solve)(SNES,Vec))
152 {
153   SNES_Shell *shell = (SNES_Shell*)snes->data;
154 
155   PetscFunctionBegin;
156   shell->solve = solve;
157   PetscFunctionReturn(0);
158 }
159 
160 /*MC
161   SNESSHELL - a user provided nonlinear solver
162 
163    Level: advanced
164 
165 .seealso: SNESCreate(), SNES, SNESSetType(), SNESType (for list of available types)
166 M*/
167 
168 PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes)
169 {
170   SNES_Shell     *shell;
171   PetscErrorCode ierr;
172 
173   PetscFunctionBegin;
174   snes->ops->destroy        = SNESDestroy_Shell;
175   snes->ops->setup          = SNESSetUp_Shell;
176   snes->ops->setfromoptions = SNESSetFromOptions_Shell;
177   snes->ops->view           = SNESView_Shell;
178   snes->ops->solve          = SNESSolve_Shell;
179   snes->ops->reset          = SNESReset_Shell;
180 
181   snes->usesksp = PETSC_FALSE;
182   snes->usesnpc = PETSC_FALSE;
183 
184   snes->alwayscomputesfinalresidual = PETSC_FALSE;
185 
186   ierr       = PetscNewLog(snes,&shell);CHKERRQ(ierr);
187   snes->data = (void*) shell;
188   ierr       = PetscObjectComposeFunction((PetscObject)snes,"SNESShellSetSolve_C",SNESShellSetSolve_Shell);CHKERRQ(ierr);
189   PetscFunctionReturn(0);
190 }
191