xref: /petsc/src/snes/impls/shell/snesshell.c (revision f6dfbefd03961ab3be6f06be75c96cbf27a49667)
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
9074cc835SBarry Smith    SNESShellSetSolve - Sets routine to apply as solver
10074cc835SBarry Smith 
11*f6dfbefdSBarry Smith    Logically Collective on snes
12074cc835SBarry Smith 
13074cc835SBarry Smith    Input Parameters:
14*f6dfbefdSBarry Smith +  snes - the `SNES` nonlinear solver context
15074cc835SBarry Smith -  apply - the application-provided solver routine
16074cc835SBarry Smith 
17074cc835SBarry Smith    Calling sequence of solve:
18074cc835SBarry Smith .vb
19074cc835SBarry Smith    PetscErrorCode apply (SNES snes,Vec xout)
20074cc835SBarry Smith .ve
21074cc835SBarry Smith 
22*f6dfbefdSBarry Smith +  snes - the preconditioner, get the application context with `SNESShellGetContext()` provided with `SNESShelletContext()`
23074cc835SBarry Smith -  xout - solution vector
24074cc835SBarry Smith 
25074cc835SBarry Smith    Level: advanced
26074cc835SBarry Smith 
27db781477SPatrick Sanan .seealso: `SNESSHELL`, `SNESShellSetContext()`, `SNESShellGetContext()`
28074cc835SBarry Smith @*/
299371c9d4SSatish Balay PetscErrorCode SNESShellSetSolve(SNES snes, PetscErrorCode (*solve)(SNES, Vec)) {
30074cc835SBarry Smith   PetscFunctionBegin;
31074cc835SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
32cac4c232SBarry Smith   PetscTryMethod(snes, "SNESShellSetSolve_C", (SNES, PetscErrorCode(*)(SNES, Vec)), (snes, solve));
33074cc835SBarry Smith   PetscFunctionReturn(0);
34074cc835SBarry Smith }
35074cc835SBarry Smith 
369371c9d4SSatish Balay PetscErrorCode SNESReset_Shell(SNES snes) {
37074cc835SBarry Smith   PetscFunctionBegin;
38074cc835SBarry Smith   PetscFunctionReturn(0);
39074cc835SBarry Smith }
40074cc835SBarry Smith 
419371c9d4SSatish Balay PetscErrorCode SNESDestroy_Shell(SNES snes) {
42074cc835SBarry Smith   PetscFunctionBegin;
439566063dSJacob Faibussowitsch   PetscCall(SNESReset_Shell(snes));
449566063dSJacob Faibussowitsch   PetscCall(PetscFree(snes->data));
45074cc835SBarry Smith   PetscFunctionReturn(0);
46074cc835SBarry Smith }
47074cc835SBarry Smith 
489371c9d4SSatish Balay PetscErrorCode SNESSetUp_Shell(SNES snes) {
49074cc835SBarry Smith   PetscFunctionBegin;
50074cc835SBarry Smith   PetscFunctionReturn(0);
51074cc835SBarry Smith }
52074cc835SBarry Smith 
539371c9d4SSatish Balay PetscErrorCode SNESSetFromOptions_Shell(SNES snes, PetscOptionItems *PetscOptionsObject) {
54074cc835SBarry Smith   PetscFunctionBegin;
55d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "SNES Shell options");
56074cc835SBarry Smith   PetscFunctionReturn(0);
57074cc835SBarry Smith }
58074cc835SBarry Smith 
599371c9d4SSatish Balay PetscErrorCode SNESView_Shell(SNES snes, PetscViewer viewer) {
60074cc835SBarry Smith   PetscFunctionBegin;
61074cc835SBarry Smith   PetscFunctionReturn(0);
62074cc835SBarry Smith }
63074cc835SBarry Smith 
6490b77ac2SPeter Brune /*@
65*f6dfbefdSBarry Smith     SNESShellGetContext - Returns the user-provided context associated with a `SNESSHELL`
66074cc835SBarry Smith 
67074cc835SBarry Smith     Not Collective
68074cc835SBarry Smith 
69074cc835SBarry Smith     Input Parameter:
70*f6dfbefdSBarry Smith .   snes - should have been created with `SNESSetType`(snes,`SNESSHELL`);
71074cc835SBarry Smith 
72074cc835SBarry Smith     Output Parameter:
73074cc835SBarry Smith .   ctx - the user provided context
74074cc835SBarry Smith 
75074cc835SBarry Smith     Level: advanced
76074cc835SBarry Smith 
77*f6dfbefdSBarry Smith .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellSetContext()`
78074cc835SBarry Smith @*/
799371c9d4SSatish Balay PetscErrorCode SNESShellGetContext(SNES snes, void *ctx) {
80074cc835SBarry Smith   PetscBool flg;
81074cc835SBarry Smith 
82074cc835SBarry Smith   PetscFunctionBegin;
83074cc835SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
84074cc835SBarry Smith   PetscValidPointer(ctx, 2);
859566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
863ec1f749SStefano Zampini   if (!flg) *(void **)ctx = NULL;
873ec1f749SStefano Zampini   else *(void **)ctx = ((SNES_Shell *)(snes->data))->ctx;
88074cc835SBarry Smith   PetscFunctionReturn(0);
89074cc835SBarry Smith }
90074cc835SBarry Smith 
91074cc835SBarry Smith /*@
92*f6dfbefdSBarry Smith     SNESShellSetContext - sets the context for a `SNESSHELL`
93074cc835SBarry Smith 
94*f6dfbefdSBarry Smith    Logically Collective on snes
95074cc835SBarry Smith 
96074cc835SBarry Smith     Input Parameters:
97*f6dfbefdSBarry Smith +   snes - the `SNESSHELL`
98074cc835SBarry Smith -   ctx - the context
99074cc835SBarry Smith 
100074cc835SBarry Smith    Level: advanced
101074cc835SBarry Smith 
102*f6dfbefdSBarry Smith    Fortran Note:
103*f6dfbefdSBarry Smith    The context can only be an integer or a `PetscObject` it cannot be a Fortran array or derived type.
104074cc835SBarry Smith 
105*f6dfbefdSBarry Smith .seealso: `SNESSHELL`, `SNESCreateShell()`, `SNESShellGetContext()`
106074cc835SBarry Smith @*/
1079371c9d4SSatish Balay PetscErrorCode SNESShellSetContext(SNES snes, void *ctx) {
108074cc835SBarry Smith   SNES_Shell *shell = (SNES_Shell *)snes->data;
109074cc835SBarry Smith   PetscBool   flg;
110074cc835SBarry Smith 
111074cc835SBarry Smith   PetscFunctionBegin;
112074cc835SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1139566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESSHELL, &flg));
1141aa26658SKarl Rupp   if (flg) shell->ctx = ctx;
115074cc835SBarry Smith   PetscFunctionReturn(0);
116074cc835SBarry Smith }
117074cc835SBarry Smith 
1189371c9d4SSatish Balay PetscErrorCode SNESSolve_Shell(SNES snes) {
119074cc835SBarry Smith   SNES_Shell *shell = (SNES_Shell *)snes->data;
120074cc835SBarry Smith 
121074cc835SBarry Smith   PetscFunctionBegin;
12228b400f6SJacob Faibussowitsch   PetscCheck(shell->solve, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONGSTATE, "Must call SNESShellSetSolve() first");
1231e633543SBarry Smith   snes->reason = SNES_CONVERGED_ITS;
1249566063dSJacob Faibussowitsch   PetscCall((*shell->solve)(snes, snes->vec_sol));
125074cc835SBarry Smith   PetscFunctionReturn(0);
126074cc835SBarry Smith }
127074cc835SBarry Smith 
1289371c9d4SSatish Balay PetscErrorCode SNESShellSetSolve_Shell(SNES snes, PetscErrorCode (*solve)(SNES, Vec)) {
129074cc835SBarry Smith   SNES_Shell *shell = (SNES_Shell *)snes->data;
130074cc835SBarry Smith 
131074cc835SBarry Smith   PetscFunctionBegin;
132074cc835SBarry Smith   shell->solve = solve;
133074cc835SBarry Smith   PetscFunctionReturn(0);
134074cc835SBarry Smith }
135074cc835SBarry Smith 
136074cc835SBarry Smith /*MC
137074cc835SBarry Smith   SNESSHELL - a user provided nonlinear solver
138074cc835SBarry Smith 
139074cc835SBarry Smith    Level: advanced
140074cc835SBarry Smith 
141*f6dfbefdSBarry Smith .seealso: `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESType`, `SNESShellGetContext()`, `SNESShellSetContext()`, `SNESShellSetSolve()`
142074cc835SBarry Smith M*/
143074cc835SBarry Smith 
1449371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode SNESCreate_Shell(SNES snes) {
145074cc835SBarry Smith   SNES_Shell *shell;
146074cc835SBarry Smith 
147074cc835SBarry Smith   PetscFunctionBegin;
148074cc835SBarry Smith   snes->ops->destroy        = SNESDestroy_Shell;
149074cc835SBarry Smith   snes->ops->setup          = SNESSetUp_Shell;
150074cc835SBarry Smith   snes->ops->setfromoptions = SNESSetFromOptions_Shell;
151074cc835SBarry Smith   snes->ops->view           = SNESView_Shell;
152074cc835SBarry Smith   snes->ops->solve          = SNESSolve_Shell;
153074cc835SBarry Smith   snes->ops->reset          = SNESReset_Shell;
154074cc835SBarry Smith 
155074cc835SBarry Smith   snes->usesksp = PETSC_FALSE;
156efd4aadfSBarry Smith   snes->usesnpc = PETSC_FALSE;
157074cc835SBarry Smith 
1584fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
1594fc747eaSLawrence Mitchell 
1609566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(snes, &shell));
161074cc835SBarry Smith   snes->data = (void *)shell;
1629566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)snes, "SNESShellSetSolve_C", SNESShellSetSolve_Shell));
163074cc835SBarry Smith   PetscFunctionReturn(0);
164074cc835SBarry Smith }
165