xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision ceaaa4989964adb3f5eb130cb04b8f49c83e49c9)
1af0996ceSBarry Smith #include <petsc/private/linesearchimpl.h>
2af0996ceSBarry Smith #include <petsc/private/snesimpl.h>
36a388c36SPeter Brune 
46a388c36SPeter Brune typedef struct {
5f1c6b773SPeter Brune   SNESLineSearchUserFunc func;
66a388c36SPeter Brune   void                  *ctx;
7f1c6b773SPeter Brune } SNESLineSearch_Shell;
86a388c36SPeter Brune 
9*ceaaa498SBarry Smith // PetscClangLinter pragma disable: -fdoc-param-list-func-parameter-documentation
10f40b411bSPeter Brune /*@C
11f6dfbefdSBarry Smith   SNESLineSearchShellSetUserFunc - Sets the user function for the `SNESLINESEARCHSHELL` implementation.
12f40b411bSPeter Brune 
13f40b411bSPeter Brune   Not Collective
14f40b411bSPeter Brune 
15cd7522eaSPeter Brune   Input Parameters:
16f6dfbefdSBarry Smith + linesearch - `SNESLineSearch` context
17cd7522eaSPeter Brune . func       - function implementing the linesearch shell.
18cd7522eaSPeter Brune - ctx        - context for func
19cd7522eaSPeter Brune 
2020f4b53cSBarry Smith   Calling sequence of `func`:
21*ceaaa498SBarry Smith $  PetscErrorCode func(SNESLinesearch ls, void *ctx)
22*ceaaa498SBarry Smith + ls  - the linesearch instance
23cd7522eaSPeter Brune - ctx - the above mentioned context
24cd7522eaSPeter Brune 
25*ceaaa498SBarry Smith   Usage\:
2620f4b53cSBarry Smith .vb
2720f4b53cSBarry Smith   PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx)
2820f4b53cSBarry Smith   {
2920f4b53cSBarry Smith      Vec  X,Y,F,W,G;
3020f4b53cSBarry Smith      SNES snes;
3120f4b53cSBarry Smith      PetscFunctionBegin;
3220f4b53cSBarry Smith      PetscCall(SNESLineSearchGetSNES(linesearch,&snes));
3320f4b53cSBarry Smith      PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED));
3420f4b53cSBarry Smith      PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G));
35*ceaaa498SBarry Smith      // determine lambda using W and G as work vecs..
3620f4b53cSBarry Smith      PetscCall(VecAXPY(X,-lambda,Y));
3720f4b53cSBarry Smith      PetscCall(SNESComputeFunction(snes,X,F));
3820f4b53cSBarry Smith      PetscCall(SNESLineSearchComputeNorms(linesearch));
3920f4b53cSBarry Smith      PetscFunctionReturn(PETSC_SUCCESS);
4020f4b53cSBarry Smith   }
4120f4b53cSBarry Smith 
4220f4b53cSBarry Smith   PetscCall(SNESGetLineSearch(snes, &linesearch));
4320f4b53cSBarry Smith   PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
4420f4b53cSBarry Smith   PetscCall(SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL));
4520f4b53cSBarry Smith .ve
46cd7522eaSPeter Brune 
47f40b411bSPeter Brune   Level: advanced
48f40b411bSPeter Brune 
49f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellGetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`
50f40b411bSPeter Brune @*/
51d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx)
52d71ae5a4SJacob Faibussowitsch {
536a388c36SPeter Brune   PetscBool             flg;
54f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
550adebc6cSBarry Smith 
566a388c36SPeter Brune   PetscFunctionBegin;
57f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
589566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
596a388c36SPeter Brune   if (flg) {
606a388c36SPeter Brune     shell->ctx  = ctx;
619e764e56SPeter Brune     shell->func = func;
626a388c36SPeter Brune   }
633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
646a388c36SPeter Brune }
656a388c36SPeter Brune 
66f40b411bSPeter Brune /*@C
67f6dfbefdSBarry Smith   SNESLineSearchShellGetUserFunc - Gets the user function and context for the  `SNESLINESEARCHSHELL`
68f40b411bSPeter Brune 
69f40b411bSPeter Brune   Not Collective
70f40b411bSPeter Brune 
714a2f8832SBarry Smith   Input Parameter:
724a2f8832SBarry Smith . linesearch - the line search object
734a2f8832SBarry Smith 
744a2f8832SBarry Smith   Output Parameters:
754a2f8832SBarry Smith + func - the user function; can be NULL if you do not want it
764a2f8832SBarry Smith - ctx  - the user function context; can be NULL if you do not want it
774a2f8832SBarry Smith 
78f40b411bSPeter Brune   Level: advanced
79f40b411bSPeter Brune 
80f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellSetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`
81f40b411bSPeter Brune @*/
82d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx)
83d71ae5a4SJacob Faibussowitsch {
846a388c36SPeter Brune   PetscBool             flg;
85f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
860adebc6cSBarry Smith 
876a388c36SPeter Brune   PetscFunctionBegin;
88f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
894f572ea9SToby Isaac   if (func) PetscAssertPointer(func, 2);
904f572ea9SToby Isaac   if (ctx) PetscAssertPointer(ctx, 3);
919566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
926a388c36SPeter Brune   if (flg) {
934a2f8832SBarry Smith     if (func) *func = shell->func;
944a2f8832SBarry Smith     if (ctx) *ctx = shell->ctx;
956a388c36SPeter Brune   }
963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
976a388c36SPeter Brune }
986a388c36SPeter Brune 
99d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch)
100d71ae5a4SJacob Faibussowitsch {
101f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
1026a388c36SPeter Brune 
1036a388c36SPeter Brune   PetscFunctionBegin;
1046a388c36SPeter Brune   /* apply the user function */
1056a388c36SPeter Brune   if (shell->func) {
1069566063dSJacob Faibussowitsch     PetscCall((*shell->func)(linesearch, shell->ctx));
107ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
1083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1096a388c36SPeter Brune }
1106a388c36SPeter Brune 
111d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
112d71ae5a4SJacob Faibussowitsch {
113f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
1146a388c36SPeter Brune 
1156a388c36SPeter Brune   PetscFunctionBegin;
1169566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell));
1173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1186a388c36SPeter Brune }
1196a388c36SPeter Brune 
120954494b2SJed Brown /*MC
1211a4f838cSPeter Brune    SNESLINESEARCHSHELL - Provides context for a user-provided line search routine.
122954494b2SJed Brown 
123f1c6b773SPeter Brune The user routine has one argument, the SNESLineSearch context.  The user uses the interface to
124954494b2SJed Brown extract line search parameters and set them accordingly when the computation is finished.
125954494b2SJed Brown 
126cd7522eaSPeter Brune Any of the other line searches may serve as a guide to how this is to be done.  There is also a basic
127cd7522eaSPeter Brune template in the documentation for SNESLineSearchShellSetUserFunc().
128954494b2SJed Brown 
129954494b2SJed Brown Level: advanced
130954494b2SJed Brown 
131f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`
132954494b2SJed Brown M*/
133d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
134d71ae5a4SJacob Faibussowitsch {
135f1c6b773SPeter Brune   SNESLineSearch_Shell *shell;
1366a388c36SPeter Brune 
1376a388c36SPeter Brune   PetscFunctionBegin;
138f1c6b773SPeter Brune   linesearch->ops->apply          = SNESLineSearchApply_Shell;
139f1c6b773SPeter Brune   linesearch->ops->destroy        = SNESLineSearchDestroy_Shell;
1400298fd71SBarry Smith   linesearch->ops->setfromoptions = NULL;
1410298fd71SBarry Smith   linesearch->ops->reset          = NULL;
1420298fd71SBarry Smith   linesearch->ops->view           = NULL;
1430298fd71SBarry Smith   linesearch->ops->setup          = NULL;
1446a388c36SPeter Brune 
1454dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&shell));
146f5af7f23SKarl Rupp 
1476a388c36SPeter Brune   linesearch->data = (void *)shell;
1483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1496a388c36SPeter Brune }
150