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