xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 4e8208cbcbc709572b8abe32f33c78b69c819375)
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;
264d86920dSPierre 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 @*/
SNESLineSearchShellSetApply(SNESLineSearch linesearch,SNESLineSearchShellApplyFn * func,PetscCtx ctx)48*2a8381b2SBarry Smith PetscErrorCode SNESLineSearchShellSetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn *func, PetscCtx 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 @*/
SNESLineSearchShellGetApply(SNESLineSearch linesearch,SNESLineSearchShellApplyFn ** func,PetscCtxRt ctx)80*2a8381b2SBarry Smith PetscErrorCode SNESLineSearchShellGetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn **func, PetscCtxRt 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;
92*2a8381b2SBarry Smith     if (ctx) *(void **)ctx = shell->ctx;
936a388c36SPeter Brune   }
943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
956a388c36SPeter Brune }
966a388c36SPeter Brune 
SNESLineSearchApply_Shell(SNESLineSearch linesearch)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 */
103966bd95aSPierre Jolivet   PetscCheck(shell->func, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetApply()");
1049566063dSJacob Faibussowitsch   PetscCall((*shell->func)(linesearch, shell->ctx));
1053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1066a388c36SPeter Brune }
1076a388c36SPeter Brune 
SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)108d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
109d71ae5a4SJacob Faibussowitsch {
110f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
1116a388c36SPeter Brune 
1126a388c36SPeter Brune   PetscFunctionBegin;
1139566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell));
1143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1156a388c36SPeter Brune }
1166a388c36SPeter Brune 
117954494b2SJed Brown /*MC
1189bcc50f1SBarry Smith   SNESLINESEARCHSHELL - Provides an API for a user-provided line search routine.
119954494b2SJed Brown 
120cd7522eaSPeter Brune   Any of the other line searches may serve as a guide to how this is to be done.  There is also a basic
1219bcc50f1SBarry Smith   template in the documentation for `SNESLineSearchShellSetApply()`.
122954494b2SJed Brown 
123954494b2SJed Brown   Level: advanced
124954494b2SJed Brown 
1259bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`, `SNESLineSearchShellSetApply()`,
1268434afd1SBarry Smith           `SNESLineSearchShellApplyFn`
127954494b2SJed Brown M*/
128420bcc1bSBarry Smith 
SNESLineSearchCreate_Shell(SNESLineSearch linesearch)129d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
130d71ae5a4SJacob Faibussowitsch {
131f1c6b773SPeter Brune   SNESLineSearch_Shell *shell;
1326a388c36SPeter Brune 
1336a388c36SPeter Brune   PetscFunctionBegin;
134f1c6b773SPeter Brune   linesearch->ops->apply          = SNESLineSearchApply_Shell;
135f1c6b773SPeter Brune   linesearch->ops->destroy        = SNESLineSearchDestroy_Shell;
1360298fd71SBarry Smith   linesearch->ops->setfromoptions = NULL;
1370298fd71SBarry Smith   linesearch->ops->reset          = NULL;
1380298fd71SBarry Smith   linesearch->ops->view           = NULL;
1390298fd71SBarry Smith   linesearch->ops->setup          = NULL;
1406a388c36SPeter Brune 
1414dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&shell));
142f5af7f23SKarl Rupp 
1436a388c36SPeter Brune   linesearch->data = (void *)shell;
1443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1456a388c36SPeter Brune }
146