xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 4d86920da9ee67c835173a5dfffa1b3a52fd24ca)
1af0996ceSBarry Smith #include <petsc/private/linesearchimpl.h>
2af0996ceSBarry Smith #include <petsc/private/snesimpl.h>
36a388c36SPeter Brune 
46a388c36SPeter Brune typedef struct {
58434afd1SBarry Smith   SNESLineSearchShellApplyFn *func;
66a388c36SPeter Brune   void                       *ctx;
7f1c6b773SPeter Brune } SNESLineSearch_Shell;
86a388c36SPeter Brune 
9ceaaa498SBarry Smith // PetscClangLinter pragma disable: -fdoc-param-list-func-parameter-documentation
10f40b411bSPeter Brune /*@C
119bcc50f1SBarry Smith   SNESLineSearchShellSetApply - Sets the apply function for the `SNESLINESEARCHSHELL` implementation.
12f40b411bSPeter Brune 
13f40b411bSPeter Brune   Not Collective
14f40b411bSPeter Brune 
15cd7522eaSPeter Brune   Input Parameters:
16f6dfbefdSBarry Smith + linesearch - `SNESLineSearch` context
178434afd1SBarry Smith . func       - function implementing the linesearch shell, see `SNESLineSearchShellApplyFn` for calling sequence
18cd7522eaSPeter Brune - ctx        - context for func
19cd7522eaSPeter Brune 
20ceaaa498SBarry Smith   Usage\:
2120f4b53cSBarry Smith .vb
2220f4b53cSBarry Smith   PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx)
2320f4b53cSBarry Smith   {
2420f4b53cSBarry Smith      Vec  X,Y,F,W,G;
2520f4b53cSBarry Smith      SNES snes;
26*4d86920dSPierre Jolivet 
2720f4b53cSBarry Smith      PetscFunctionBegin;
2820f4b53cSBarry Smith      PetscCall(SNESLineSearchGetSNES(linesearch,&snes));
2920f4b53cSBarry Smith      PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED));
3020f4b53cSBarry Smith      PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G));
31ceaaa498SBarry Smith      // determine lambda using W and G as work vecs..
3220f4b53cSBarry Smith      PetscCall(VecAXPY(X,-lambda,Y));
3320f4b53cSBarry Smith      PetscCall(SNESComputeFunction(snes,X,F));
3420f4b53cSBarry Smith      PetscCall(SNESLineSearchComputeNorms(linesearch));
3520f4b53cSBarry Smith      PetscFunctionReturn(PETSC_SUCCESS);
3620f4b53cSBarry Smith   }
3720f4b53cSBarry Smith 
3820f4b53cSBarry Smith   PetscCall(SNESGetLineSearch(snes, &linesearch));
3920f4b53cSBarry Smith   PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
409bcc50f1SBarry Smith   PetscCall(SNESLineSearchShellSetApply(linesearch, shellfunc, NULL));
4120f4b53cSBarry Smith .ve
42cd7522eaSPeter Brune 
43f40b411bSPeter Brune   Level: advanced
44f40b411bSPeter Brune 
459bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearchShellGetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`,
468434afd1SBarry Smith           `SNESLineSearchShellApplyFn`
47f40b411bSPeter Brune @*/
488434afd1SBarry Smith PetscErrorCode SNESLineSearchShellSetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn *func, void *ctx)
49d71ae5a4SJacob Faibussowitsch {
506a388c36SPeter Brune   PetscBool             flg;
51f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
520adebc6cSBarry Smith 
536a388c36SPeter Brune   PetscFunctionBegin;
54f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
559566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
566a388c36SPeter Brune   if (flg) {
576a388c36SPeter Brune     shell->ctx  = ctx;
589e764e56SPeter Brune     shell->func = func;
596a388c36SPeter Brune   }
603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
616a388c36SPeter Brune }
626a388c36SPeter Brune 
63f40b411bSPeter Brune /*@C
649bcc50f1SBarry Smith   SNESLineSearchShellGetApply - Gets the apply function and context for the `SNESLINESEARCHSHELL`
65f40b411bSPeter Brune 
66f40b411bSPeter Brune   Not Collective
67f40b411bSPeter Brune 
684a2f8832SBarry Smith   Input Parameter:
694a2f8832SBarry Smith . linesearch - the line search object
704a2f8832SBarry Smith 
714a2f8832SBarry Smith   Output Parameters:
728434afd1SBarry Smith + func - the user function; can be `NULL` if it is not needed, see `SNESLineSearchShellApplyFn` for calling sequence
73420bcc1bSBarry Smith - ctx  - the user function context; can be `NULL` if it is not needed
744a2f8832SBarry Smith 
75f40b411bSPeter Brune   Level: advanced
76f40b411bSPeter Brune 
779bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearchShellSetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`,
788434afd1SBarry Smith           `SNESLineSearchShellApplyFn`
79f40b411bSPeter Brune @*/
808434afd1SBarry Smith PetscErrorCode SNESLineSearchShellGetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn **func, void **ctx)
81d71ae5a4SJacob Faibussowitsch {
826a388c36SPeter Brune   PetscBool             flg;
83f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
840adebc6cSBarry Smith 
856a388c36SPeter Brune   PetscFunctionBegin;
86f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
874f572ea9SToby Isaac   if (func) PetscAssertPointer(func, 2);
884f572ea9SToby Isaac   if (ctx) PetscAssertPointer(ctx, 3);
899566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
906a388c36SPeter Brune   if (flg) {
914a2f8832SBarry Smith     if (func) *func = shell->func;
924a2f8832SBarry Smith     if (ctx) *ctx = shell->ctx;
936a388c36SPeter Brune   }
943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
956a388c36SPeter Brune }
966a388c36SPeter Brune 
97d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch)
98d71ae5a4SJacob Faibussowitsch {
99f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
1006a388c36SPeter Brune 
1016a388c36SPeter Brune   PetscFunctionBegin;
1026a388c36SPeter Brune   /* apply the user function */
1036a388c36SPeter Brune   if (shell->func) {
1049566063dSJacob Faibussowitsch     PetscCall((*shell->func)(linesearch, shell->ctx));
1059bcc50f1SBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetApply()");
1063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1076a388c36SPeter Brune }
1086a388c36SPeter Brune 
109d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
110d71ae5a4SJacob Faibussowitsch {
111f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
1126a388c36SPeter Brune 
1136a388c36SPeter Brune   PetscFunctionBegin;
1149566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell));
1153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1166a388c36SPeter Brune }
1176a388c36SPeter Brune 
118954494b2SJed Brown /*MC
1199bcc50f1SBarry Smith   SNESLINESEARCHSHELL - Provides an API for a user-provided line search routine.
120954494b2SJed Brown 
121cd7522eaSPeter Brune   Any of the other line searches may serve as a guide to how this is to be done.  There is also a basic
1229bcc50f1SBarry Smith   template in the documentation for `SNESLineSearchShellSetApply()`.
123954494b2SJed Brown 
124954494b2SJed Brown   Level: advanced
125954494b2SJed Brown 
1269bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`, `SNESLineSearchShellSetApply()`,
1278434afd1SBarry Smith           `SNESLineSearchShellApplyFn`
128954494b2SJed Brown M*/
129420bcc1bSBarry Smith 
130d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
131d71ae5a4SJacob Faibussowitsch {
132f1c6b773SPeter Brune   SNESLineSearch_Shell *shell;
1336a388c36SPeter Brune 
1346a388c36SPeter Brune   PetscFunctionBegin;
135f1c6b773SPeter Brune   linesearch->ops->apply          = SNESLineSearchApply_Shell;
136f1c6b773SPeter Brune   linesearch->ops->destroy        = SNESLineSearchDestroy_Shell;
1370298fd71SBarry Smith   linesearch->ops->setfromoptions = NULL;
1380298fd71SBarry Smith   linesearch->ops->reset          = NULL;
1390298fd71SBarry Smith   linesearch->ops->view           = NULL;
1400298fd71SBarry Smith   linesearch->ops->setup          = NULL;
1416a388c36SPeter Brune 
1424dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&shell));
143f5af7f23SKarl Rupp 
1446a388c36SPeter Brune   linesearch->data = (void *)shell;
1453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1466a388c36SPeter Brune }
147