xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 9bcc50f161f00fed78b30f628c8384653fee89b4)
1af0996ceSBarry Smith #include <petsc/private/linesearchimpl.h>
2af0996ceSBarry Smith #include <petsc/private/snesimpl.h>
36a388c36SPeter Brune 
46a388c36SPeter Brune typedef struct {
5*9bcc50f1SBarry Smith   SNESLineSearchShellApply_Fn *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
11*9bcc50f1SBarry 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
17*9bcc50f1SBarry Smith . func       - function implementing the linesearch shell, see `SNESLineSearchShellApply_Fn` 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;
2620f4b53cSBarry Smith      PetscFunctionBegin;
2720f4b53cSBarry Smith      PetscCall(SNESLineSearchGetSNES(linesearch,&snes));
2820f4b53cSBarry Smith      PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED));
2920f4b53cSBarry Smith      PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G));
30ceaaa498SBarry Smith      // determine lambda using W and G as work vecs..
3120f4b53cSBarry Smith      PetscCall(VecAXPY(X,-lambda,Y));
3220f4b53cSBarry Smith      PetscCall(SNESComputeFunction(snes,X,F));
3320f4b53cSBarry Smith      PetscCall(SNESLineSearchComputeNorms(linesearch));
3420f4b53cSBarry Smith      PetscFunctionReturn(PETSC_SUCCESS);
3520f4b53cSBarry Smith   }
3620f4b53cSBarry Smith 
3720f4b53cSBarry Smith   PetscCall(SNESGetLineSearch(snes, &linesearch));
3820f4b53cSBarry Smith   PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
39*9bcc50f1SBarry Smith   PetscCall(SNESLineSearchShellSetApply(linesearch, shellfunc, NULL));
4020f4b53cSBarry Smith .ve
41cd7522eaSPeter Brune 
42f40b411bSPeter Brune   Level: advanced
43f40b411bSPeter Brune 
44*9bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearchShellGetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`,
45*9bcc50f1SBarry Smith           `SNESLineSearchShellApply_Fn`
46f40b411bSPeter Brune @*/
47*9bcc50f1SBarry Smith PetscErrorCode SNESLineSearchShellSetApply(SNESLineSearch linesearch, SNESLineSearchShellApply_Fn *func, void *ctx)
48d71ae5a4SJacob Faibussowitsch {
496a388c36SPeter Brune   PetscBool             flg;
50f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
510adebc6cSBarry Smith 
526a388c36SPeter Brune   PetscFunctionBegin;
53f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
549566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
556a388c36SPeter Brune   if (flg) {
566a388c36SPeter Brune     shell->ctx  = ctx;
579e764e56SPeter Brune     shell->func = func;
586a388c36SPeter Brune   }
593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
606a388c36SPeter Brune }
616a388c36SPeter Brune 
62f40b411bSPeter Brune /*@C
63*9bcc50f1SBarry Smith   SNESLineSearchShellGetApply - Gets the apply function and context for the `SNESLINESEARCHSHELL`
64f40b411bSPeter Brune 
65f40b411bSPeter Brune   Not Collective
66f40b411bSPeter Brune 
674a2f8832SBarry Smith   Input Parameter:
684a2f8832SBarry Smith . linesearch - the line search object
694a2f8832SBarry Smith 
704a2f8832SBarry Smith   Output Parameters:
71*9bcc50f1SBarry Smith + func - the user function; can be `NULL` if it is not needed, see `SNESLineSearchShellApply_Fn` for calling sequence
72420bcc1bSBarry Smith - ctx  - the user function context; can be `NULL` if it is not needed
734a2f8832SBarry Smith 
74f40b411bSPeter Brune   Level: advanced
75f40b411bSPeter Brune 
76*9bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearchShellSetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`,
77*9bcc50f1SBarry Smith           `SNESLineSearchShellApply_Fn`
78f40b411bSPeter Brune @*/
79*9bcc50f1SBarry Smith PetscErrorCode SNESLineSearchShellGetApply(SNESLineSearch linesearch, SNESLineSearchShellApply_Fn **func, void **ctx)
80d71ae5a4SJacob Faibussowitsch {
816a388c36SPeter Brune   PetscBool             flg;
82f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
830adebc6cSBarry Smith 
846a388c36SPeter Brune   PetscFunctionBegin;
85f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
864f572ea9SToby Isaac   if (func) PetscAssertPointer(func, 2);
874f572ea9SToby Isaac   if (ctx) PetscAssertPointer(ctx, 3);
889566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
896a388c36SPeter Brune   if (flg) {
904a2f8832SBarry Smith     if (func) *func = shell->func;
914a2f8832SBarry Smith     if (ctx) *ctx = shell->ctx;
926a388c36SPeter Brune   }
933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
946a388c36SPeter Brune }
956a388c36SPeter Brune 
96d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch)
97d71ae5a4SJacob Faibussowitsch {
98f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
996a388c36SPeter Brune 
1006a388c36SPeter Brune   PetscFunctionBegin;
1016a388c36SPeter Brune   /* apply the user function */
1026a388c36SPeter Brune   if (shell->func) {
1039566063dSJacob Faibussowitsch     PetscCall((*shell->func)(linesearch, shell->ctx));
104*9bcc50f1SBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetApply()");
1053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1066a388c36SPeter Brune }
1076a388c36SPeter Brune 
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
118*9bcc50f1SBarry 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
121*9bcc50f1SBarry Smith   template in the documentation for `SNESLineSearchShellSetApply()`.
122954494b2SJed Brown 
123954494b2SJed Brown   Level: advanced
124954494b2SJed Brown 
125*9bcc50f1SBarry Smith .seealso: [](ch_snes), `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`, `SNESLineSearchShellSetApply()`,
126*9bcc50f1SBarry Smith           `SNESLineSearchShellApply_Fn`
127954494b2SJed Brown M*/
128420bcc1bSBarry Smith 
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