xref: /petsc/src/snes/impls/shell/snesshell.c (revision ceaaa4989964adb3f5eb130cb04b8f49c83e49c9)
1af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I   "petscsnes.h"   I*/
2074cc835SBarry Smith 
39371c9d4SSatish Balay typedef struct {
49371c9d4SSatish Balay   PetscErrorCode (*solve)(SNES, Vec);
59371c9d4SSatish Balay   void *ctx;
69371c9d4SSatish Balay } SNES_Shell;
7074cc835SBarry Smith 
8074cc835SBarry Smith /*@C
9*ceaaa498SBarry Smith   SNESShellSetSolve - Sets routine to apply as solver to a `SNESSHELL` `SNES` object
10074cc835SBarry Smith 
11c3339decSBarry Smith   Logically Collective
12074cc835SBarry Smith 
13074cc835SBarry Smith   Input Parameters:
14f6dfbefdSBarry Smith + snes  - the `SNES` nonlinear solver context
15*ceaaa498SBarry Smith - solve - the application-provided solver routine
16074cc835SBarry Smith 
1720f4b53cSBarry Smith   Calling sequence of `apply`:
18f6dfbefdSBarry Smith + snes - the preconditioner, get the application context with `SNESShellGetContext()` provided with `SNESShelletContext()`
19*ceaaa498SBarry Smith - xout - solution vector
20074cc835SBarry Smith 
21074cc835SBarry Smith   Level: advanced
22074cc835SBarry Smith 
23db781477SPatrick Sanan .seealso: `SNESSHELL`, `SNESShellSetContext()`, `SNESShellGetContext()`
24074cc835SBarry Smith @*/
25*ceaaa498SBarry Smith PetscErrorCode SNESShellSetSolve(SNES snes, PetscErrorCode (*solve)(SNES snes, Vec xout))
26d71ae5a4SJacob Faibussowitsch {
27074cc835SBarry Smith   PetscFunctionBegin;
28074cc835SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
29cac4c232SBarry Smith   PetscTryMethod(snes, "SNESShellSetSolve_C", (SNES, PetscErrorCode(*)(SNES, Vec)), (snes, solve));
303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31074cc835SBarry Smith }
32074cc835SBarry Smith 
33d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESReset_Shell(SNES snes)
34d71ae5a4SJacob Faibussowitsch {
35074cc835SBarry Smith   PetscFunctionBegin;
363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
37074cc835SBarry Smith }
38074cc835SBarry Smith 
39d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESDestroy_Shell(SNES snes)
40d71ae5a4SJacob Faibussowitsch {
41074cc835SBarry Smith   PetscFunctionBegin;
429566063dSJacob Faibussowitsch   PetscCall(SNESReset_Shell(snes));
439566063dSJacob Faibussowitsch   PetscCall(PetscFree(snes->data));
443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45074cc835SBarry Smith }
46074cc835SBarry Smith 
47d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUp_Shell(SNES snes)
48d71ae5a4SJacob Faibussowitsch {
49074cc835SBarry Smith   PetscFunctionBegin;
503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
51074cc835SBarry Smith }
52074cc835SBarry Smith 
53d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFromOptions_Shell(SNES snes, PetscOptionItems *PetscOptionsObject)
54d71ae5a4SJacob Faibussowitsch {
55074cc835SBarry Smith   PetscFunctionBegin;
56d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "SNES Shell options");
573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
58074cc835SBarry Smith }
59074cc835SBarry Smith 
60d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer)
61d71ae5a4SJacob Faibussowitsch {
62074cc835SBarry Smith   PetscFunctionBegin;
633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
64074cc835SBarry Smith }
65074cc835SBarry Smith 
6690b77ac2SPeter Brune /*@
67f6dfbefdSBarry Smith   SNESShellGetContext - Returns the user-provided context associated with a `SNESSHELL`
68074cc835SBarry Smith 
69074cc835SBarry Smith   Not Collective
70074cc835SBarry Smith 
71074cc835SBarry Smith   Input Parameter:
72f6dfbefdSBarry Smith . snes - should have been created with `SNESSetType`(snes,`SNESSHELL`);
73074cc835SBarry Smith 
74074cc835SBarry Smith   Output Parameter:
75074cc835SBarry Smith . ctx - the user provided context
76074cc835SBarry Smith 
77074cc835SBarry Smith   Level: advanced
78074cc835SBarry Smith 
79f6dfbefdSBarry Smith .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellSetContext()`
80074cc835SBarry Smith @*/
81d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESShellGetContext(SNES snes, void *ctx)
82d71ae5a4SJacob Faibussowitsch {
83074cc835SBarry Smith   PetscBool flg;
84074cc835SBarry Smith 
85074cc835SBarry Smith   PetscFunctionBegin;
86074cc835SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
874f572ea9SToby Isaac   PetscAssertPointer(ctx, 2);
889566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
893ec1f749SStefano Zampini   if (!flg) *(void **)ctx = NULL;
903ec1f749SStefano Zampini   else *(void **)ctx = ((SNES_Shell *)(snes->data))->ctx;
913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
92074cc835SBarry Smith }
93074cc835SBarry Smith 
94074cc835SBarry Smith /*@
95f6dfbefdSBarry Smith   SNESShellSetContext - sets the context for a `SNESSHELL`
96074cc835SBarry Smith 
97c3339decSBarry Smith   Logically Collective
98074cc835SBarry Smith 
99074cc835SBarry Smith   Input Parameters:
100f6dfbefdSBarry Smith + snes - the `SNESSHELL`
101074cc835SBarry Smith - ctx  - the context
102074cc835SBarry Smith 
103074cc835SBarry Smith   Level: advanced
104074cc835SBarry Smith 
105e4094ef1SJacob Faibussowitsch   Fortran Notes:
106f6dfbefdSBarry Smith   The context can only be an integer or a `PetscObject` it cannot be a Fortran array or derived type.
107074cc835SBarry Smith 
108f6dfbefdSBarry Smith .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellGetContext()`
109074cc835SBarry Smith @*/
110d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESShellSetContext(SNES snes, void *ctx)
111d71ae5a4SJacob Faibussowitsch {
112074cc835SBarry Smith   SNES_Shell *shell = (SNES_Shell *)snes->data;
113074cc835SBarry Smith   PetscBool   flg;
114074cc835SBarry Smith 
115074cc835SBarry Smith   PetscFunctionBegin;
116074cc835SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1179566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
1181aa26658SKarl Rupp   if (flg) shell->ctx = ctx;
1193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
120074cc835SBarry Smith }
121074cc835SBarry Smith 
122d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSolve_Shell(SNES snes)
123d71ae5a4SJacob Faibussowitsch {
124074cc835SBarry Smith   SNES_Shell *shell = (SNES_Shell *)snes->data;
125074cc835SBarry Smith 
126074cc835SBarry Smith   PetscFunctionBegin;
12728b400f6SJacob Faibussowitsch   PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first");
1281e633543SBarry Smith   snes->reason = SNES_CONVERGED_ITS;
1299566063dSJacob Faibussowitsch   PetscCall((*shell->solve)(snes, snes->vec_sol));
1303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
131074cc835SBarry Smith }
132074cc835SBarry Smith 
133d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec))
134d71ae5a4SJacob Faibussowitsch {
135074cc835SBarry Smith   SNES_Shell *shell = (SNES_Shell *)snes->data;
136074cc835SBarry Smith 
137074cc835SBarry Smith   PetscFunctionBegin;
138074cc835SBarry Smith   shell->solve = solve;
1393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
140074cc835SBarry Smith }
141074cc835SBarry Smith 
142074cc835SBarry Smith /*MC
143074cc835SBarry Smith   SNESSHELL - a user provided nonlinear solver
144074cc835SBarry Smith 
145074cc835SBarry Smith    Level: advanced
146074cc835SBarry Smith 
147f6dfbefdSBarry Smith .seealso: `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType`, `SNESShellGetContext()`, `SNESShellSetContext()`, `SNESShellSetSolve()`
148074cc835SBarry Smith M*/
149074cc835SBarry Smith 
150d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes)
151d71ae5a4SJacob Faibussowitsch {
152074cc835SBarry Smith   SNES_Shell *shell;
153074cc835SBarry Smith 
154074cc835SBarry Smith   PetscFunctionBegin;
155074cc835SBarry Smith   snes->ops->destroy        = SNESDestroy_Shell;
156074cc835SBarry Smith   snes->ops->setup          = SNESSetUp_Shell;
157074cc835SBarry Smith   snes->ops->setfromoptions = SNESSetFromOptions_Shell;
158074cc835SBarry Smith   snes->ops->view           = SNESView_Shell;
159074cc835SBarry Smith   snes->ops->solve          = SNESSolve_Shell;
160074cc835SBarry Smith   snes->ops->reset          = SNESReset_Shell;
161074cc835SBarry Smith 
162074cc835SBarry Smith   snes->usesksp = PETSC_FALSE;
163efd4aadfSBarry Smith   snes->usesnpc = PETSC_FALSE;
164074cc835SBarry Smith 
1654fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
1664fc747eaSLawrence Mitchell 
1674dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&shell));
168074cc835SBarry Smith   snes->data = (void *)shell;
1699566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell));
1703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
171074cc835SBarry Smith }
172