xref: /petsc/src/snes/impls/shell/snesshell.c (revision 4e8208cbcbc709572b8abe32f33c78b69c819375)
1af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I   "petscsnes.h"   I*/
2074cc835SBarry Smith 
39371c9d4SSatish Balay typedef struct {
49371c9d4SSatish Balay   PetscErrorCode (*solve)(SNES, Vec);
5*2a8381b2SBarry Smith   PetscCtx ctx;
69371c9d4SSatish Balay } SNES_Shell;
7074cc835SBarry Smith 
8074cc835SBarry Smith /*@C
9ceaaa498SBarry 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
15ceaaa498SBarry Smith - solve - the application-provided solver routine
16074cc835SBarry Smith 
1720f4b53cSBarry Smith   Calling sequence of `apply`:
1854c05997SPierre Jolivet + snes - the preconditioner, get the application context with `SNESShellGetContext()` provided with `SNESShellSetContext()`
19ceaaa498SBarry Smith - xout - solution vector
20074cc835SBarry Smith 
21074cc835SBarry Smith   Level: advanced
22074cc835SBarry Smith 
23420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSHELL`, `SNESShellSetContext()`, `SNESShellGetContext()`
24074cc835SBarry Smith @*/
SNESShellSetSolve(SNES snes,PetscErrorCode (* solve)(SNES snes,Vec xout))25ceaaa498SBarry 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 
SNESDestroy_Shell(SNES snes)3366976f2fSJacob Faibussowitsch static PetscErrorCode SNESDestroy_Shell(SNES snes)
34d71ae5a4SJacob Faibussowitsch {
35074cc835SBarry Smith   PetscFunctionBegin;
369566063dSJacob Faibussowitsch   PetscCall(PetscFree(snes->data));
373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38074cc835SBarry Smith }
39074cc835SBarry Smith 
4090b77ac2SPeter Brune /*@
41f6dfbefdSBarry Smith   SNESShellGetContext - Returns the user-provided context associated with a `SNESSHELL`
42074cc835SBarry Smith 
43074cc835SBarry Smith   Not Collective
44074cc835SBarry Smith 
45074cc835SBarry Smith   Input Parameter:
46f6dfbefdSBarry Smith . snes - should have been created with `SNESSetType`(snes,`SNESSHELL`);
47074cc835SBarry Smith 
48074cc835SBarry Smith   Output Parameter:
49074cc835SBarry Smith . ctx - the user provided context
50074cc835SBarry Smith 
51074cc835SBarry Smith   Level: advanced
52074cc835SBarry Smith 
53*2a8381b2SBarry Smith   Fortran Notes:
54*2a8381b2SBarry Smith   This only works when the context is a Fortran derived type or a `PetscObject`. Declare `ctx` with
55*2a8381b2SBarry Smith .vb
56*2a8381b2SBarry Smith   type(tUsertype), pointer :: ctx
57*2a8381b2SBarry Smith .ve
58*2a8381b2SBarry Smith 
59420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSHELL`, `SNESCreateShell()`, `SNESShellSetContext()`
60074cc835SBarry Smith @*/
SNESShellGetContext(SNES snes,PetscCtxRt ctx)61*2a8381b2SBarry Smith PetscErrorCode SNESShellGetContext(SNES snes, PetscCtxRt ctx)
62d71ae5a4SJacob Faibussowitsch {
63074cc835SBarry Smith   PetscBool flg;
64074cc835SBarry Smith 
65074cc835SBarry Smith   PetscFunctionBegin;
66074cc835SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
674f572ea9SToby Isaac   PetscAssertPointer(ctx, 2);
689566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
693ec1f749SStefano Zampini   if (!flg) *(void **)ctx = NULL;
70f4f49eeaSPierre Jolivet   else *(void **)ctx = ((SNES_Shell *)snes->data)->ctx;
713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
72074cc835SBarry Smith }
73074cc835SBarry Smith 
74074cc835SBarry Smith /*@
75f6dfbefdSBarry Smith   SNESShellSetContext - sets the context for a `SNESSHELL`
76074cc835SBarry Smith 
77c3339decSBarry Smith   Logically Collective
78074cc835SBarry Smith 
79074cc835SBarry Smith   Input Parameters:
80f6dfbefdSBarry Smith + snes - the `SNESSHELL`
81074cc835SBarry Smith - ctx  - the context
82074cc835SBarry Smith 
83074cc835SBarry Smith   Level: advanced
84074cc835SBarry Smith 
85420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSHELL`, `SNESCreateShell()`, `SNESShellGetContext()`
86074cc835SBarry Smith @*/
SNESShellSetContext(SNES snes,PetscCtx ctx)87*2a8381b2SBarry Smith PetscErrorCode SNESShellSetContext(SNES snes, PetscCtx ctx)
88d71ae5a4SJacob Faibussowitsch {
89074cc835SBarry Smith   SNES_Shell *shell = (SNES_Shell *)snes->data;
90074cc835SBarry Smith   PetscBool   flg;
91074cc835SBarry Smith 
92074cc835SBarry Smith   PetscFunctionBegin;
93074cc835SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
949566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
951aa26658SKarl Rupp   if (flg) shell->ctx = ctx;
963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
97074cc835SBarry Smith }
98074cc835SBarry Smith 
SNESSolve_Shell(SNES snes)9966976f2fSJacob Faibussowitsch static PetscErrorCode SNESSolve_Shell(SNES snes)
100d71ae5a4SJacob Faibussowitsch {
101074cc835SBarry Smith   SNES_Shell *shell = (SNES_Shell *)snes->data;
102074cc835SBarry Smith 
103074cc835SBarry Smith   PetscFunctionBegin;
10428b400f6SJacob Faibussowitsch   PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first");
1051e633543SBarry Smith   snes->reason = SNES_CONVERGED_ITS;
1069566063dSJacob Faibussowitsch   PetscCall((*shell->solve)(snes, snes->vec_sol));
1073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
108074cc835SBarry Smith }
109074cc835SBarry Smith 
SNESShellSetSolve_Shell(SNES snes,PetscErrorCode (* solve)(SNES,Vec))11066976f2fSJacob Faibussowitsch static PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec))
111d71ae5a4SJacob Faibussowitsch {
112074cc835SBarry Smith   SNES_Shell *shell = (SNES_Shell *)snes->data;
113074cc835SBarry Smith 
114074cc835SBarry Smith   PetscFunctionBegin;
115074cc835SBarry Smith   shell->solve = solve;
1163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
117074cc835SBarry Smith }
118074cc835SBarry Smith 
119074cc835SBarry Smith /*MC
120074cc835SBarry Smith   SNESSHELL - a user provided nonlinear solver
121074cc835SBarry Smith 
122074cc835SBarry Smith    Level: advanced
123074cc835SBarry Smith 
124420bcc1bSBarry Smith .seealso: [](ch_snes), `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType`, `SNESShellGetContext()`, `SNESShellSetContext()`, `SNESShellSetSolve()`
125074cc835SBarry Smith M*/
126074cc835SBarry Smith 
SNESCreate_Shell(SNES snes)127d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes)
128d71ae5a4SJacob Faibussowitsch {
129074cc835SBarry Smith   SNES_Shell *shell;
130074cc835SBarry Smith 
131074cc835SBarry Smith   PetscFunctionBegin;
132074cc835SBarry Smith   snes->ops->destroy = SNESDestroy_Shell;
133074cc835SBarry Smith   snes->ops->solve   = SNESSolve_Shell;
134074cc835SBarry Smith 
135074cc835SBarry Smith   snes->usesksp = PETSC_FALSE;
136efd4aadfSBarry Smith   snes->usesnpc = PETSC_FALSE;
137074cc835SBarry Smith 
1384fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
1394fc747eaSLawrence Mitchell 
14077e5a1f9SBarry Smith   PetscCall(SNESParametersInitialize(snes));
14177e5a1f9SBarry Smith 
1424dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&shell));
143074cc835SBarry Smith   snes->data = (void *)shell;
1449566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell));
1453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
146074cc835SBarry Smith }
147