xref: /petsc/src/snes/impls/shell/snesshell.c (revision 3e1910f1ab6113d8365e15c6b8c907ccce7ce4ea)
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) shell->ctx = ctx;
154   PetscFunctionReturn(0);
155 }
156 
157 #undef __FUNCT__
158 #define __FUNCT__ "SNESSolve_Shell"
159 PetscErrorCode SNESSolve_Shell(SNES snes)
160 {
161   SNES_Shell     *shell = (SNES_Shell*) snes->data;
162   PetscErrorCode ierr;
163 
164   PetscFunctionBegin;
165   if (!shell->solve) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE,"Must call SNESShellSetSolve() first");
166   snes->reason = SNES_CONVERGED_ITS;
167   ierr         = (*shell->solve)(snes,snes->vec_sol);CHKERRQ(ierr);
168   PetscFunctionReturn(0);
169 }
170 
171 #undef __FUNCT__
172 #define __FUNCT__ "SNESShellSetSolve_Shell"
173 PetscErrorCode  SNESShellSetSolve_Shell(SNES snes,PetscErrorCode (*solve)(SNES,Vec))
174 {
175   SNES_Shell *shell = (SNES_Shell*)snes->data;
176 
177   PetscFunctionBegin;
178   shell->solve = solve;
179   PetscFunctionReturn(0);
180 }
181 
182 /*MC
183   SNESSHELL - a user provided nonlinear solver
184 
185    Level: advanced
186 
187 .seealso: SNESCreate(), SNES, SNESSetType(), SNESType (for list of available types)
188 M*/
189 
190 #undef __FUNCT__
191 #define __FUNCT__ "SNESCreate_Shell"
192 PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes)
193 {
194   SNES_Shell     *shell;
195   PetscErrorCode ierr;
196 
197   PetscFunctionBegin;
198   snes->ops->destroy        = SNESDestroy_Shell;
199   snes->ops->setup          = SNESSetUp_Shell;
200   snes->ops->setfromoptions = SNESSetFromOptions_Shell;
201   snes->ops->view           = SNESView_Shell;
202   snes->ops->solve          = SNESSolve_Shell;
203   snes->ops->reset          = SNESReset_Shell;
204 
205   snes->usesksp = PETSC_FALSE;
206   snes->usespc  = PETSC_FALSE;
207 
208   ierr       = PetscNewLog(snes, SNES_Shell, &shell);CHKERRQ(ierr);
209   snes->data = (void*) shell;
210   ierr       = PetscObjectComposeFunction((PetscObject)snes,"SNESShellSetSolve_C",SNESShellSetSolve_Shell);CHKERRQ(ierr);
211   PetscFunctionReturn(0);
212 }
213