xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 3ba1676111f5c958fe6c2729b46ca4d523958bb3)
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 
9f40b411bSPeter Brune /*@C
10f6dfbefdSBarry Smith    SNESLineSearchShellSetUserFunc - Sets the user function for the `SNESLINESEARCHSHELL` implementation.
11f40b411bSPeter Brune 
12f40b411bSPeter Brune    Not Collective
13f40b411bSPeter Brune 
14cd7522eaSPeter Brune    Input Parameters:
15f6dfbefdSBarry Smith +  linesearch - `SNESLineSearch` context
16cd7522eaSPeter Brune .  func - function implementing the linesearch shell.
17cd7522eaSPeter Brune -  ctx - context for func
18cd7522eaSPeter Brune 
19cd7522eaSPeter Brune    Calling sequence of func:
20cd7522eaSPeter Brune +  linesearch - the linesearch instance
21cd7522eaSPeter Brune -  ctx - the above mentioned context
22cd7522eaSPeter Brune 
23cd7522eaSPeter Brune    Usage:
24a6dfd86eSKarl Rupp $  PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx)
25a6dfd86eSKarl Rupp $  {
2678bcb3b5SPeter Brune $     Vec  X,Y,F,W,G;
2778bcb3b5SPeter Brune $     SNES snes;
28cd7522eaSPeter Brune $     PetscFunctionBegin;
299566063dSJacob Faibussowitsch $     PetscCall(SNESLineSearchGetSNES(linesearch,&snes));
309566063dSJacob Faibussowitsch $     PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED));
319566063dSJacob Faibussowitsch $     PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G));
3278bcb3b5SPeter Brune $     .. determine lambda using W and G as work vecs..
339566063dSJacob Faibussowitsch $     PetscCall(VecAXPY(X,-lambda,Y));
349566063dSJacob Faibussowitsch $     PetscCall(SNESComputeFunction(snes,X,F));
359566063dSJacob Faibussowitsch $     PetscCall(SNESLineSearchComputeNorms(linesearch));
36*3ba16761SJacob Faibussowitsch $     PetscFunctionReturn(PETSC_SUCCESS);
37cd7522eaSPeter Brune $  }
38cd7522eaSPeter Brune $
39cd7522eaSPeter Brune $  ...
40cd7522eaSPeter Brune $
419566063dSJacob Faibussowitsch $  PetscCall(SNESGetLineSearch(snes, &linesearch));
429566063dSJacob Faibussowitsch $  PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
439566063dSJacob Faibussowitsch $  PetscCall(SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL));
44cd7522eaSPeter Brune 
45f40b411bSPeter Brune    Level: advanced
46f40b411bSPeter Brune 
47f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellGetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`
48f40b411bSPeter Brune @*/
49d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx)
50d71ae5a4SJacob Faibussowitsch {
516a388c36SPeter Brune   PetscBool             flg;
52f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
530adebc6cSBarry Smith 
546a388c36SPeter Brune   PetscFunctionBegin;
55f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
569566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
576a388c36SPeter Brune   if (flg) {
586a388c36SPeter Brune     shell->ctx  = ctx;
599e764e56SPeter Brune     shell->func = func;
606a388c36SPeter Brune   }
61*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
626a388c36SPeter Brune }
636a388c36SPeter Brune 
64f40b411bSPeter Brune /*@C
65f6dfbefdSBarry Smith    SNESLineSearchShellGetUserFunc - Gets the user function and context for the  `SNESLINESEARCHSHELL`
66f40b411bSPeter Brune 
67f40b411bSPeter Brune    Not Collective
68f40b411bSPeter Brune 
694a2f8832SBarry Smith    Input Parameter:
704a2f8832SBarry Smith .   linesearch - the line search object
714a2f8832SBarry Smith 
724a2f8832SBarry Smith    Output Parameters:
734a2f8832SBarry Smith +    func  - the user function; can be NULL if you do not want it
744a2f8832SBarry Smith -    ctx   - the user function context; can be NULL if you do not want it
754a2f8832SBarry Smith 
76f40b411bSPeter Brune    Level: advanced
77f40b411bSPeter Brune 
78f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellSetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`
79f40b411bSPeter Brune @*/
80d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *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);
876a388c36SPeter Brune   if (func) PetscValidPointer(func, 2);
886a388c36SPeter Brune   if (ctx) PetscValidPointer(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   }
94*3ba16761SJacob 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));
105ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
106*3ba16761SJacob 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));
115*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1166a388c36SPeter Brune }
1176a388c36SPeter Brune 
118954494b2SJed Brown /*MC
1191a4f838cSPeter Brune    SNESLINESEARCHSHELL - Provides context for a user-provided line search routine.
120954494b2SJed Brown 
121f1c6b773SPeter Brune The user routine has one argument, the SNESLineSearch context.  The user uses the interface to
122954494b2SJed Brown extract line search parameters and set them accordingly when the computation is finished.
123954494b2SJed Brown 
124cd7522eaSPeter Brune Any of the other line searches may serve as a guide to how this is to be done.  There is also a basic
125cd7522eaSPeter Brune template in the documentation for SNESLineSearchShellSetUserFunc().
126954494b2SJed Brown 
127954494b2SJed Brown Level: advanced
128954494b2SJed Brown 
129f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`
130954494b2SJed Brown M*/
131d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
132d71ae5a4SJacob Faibussowitsch {
133f1c6b773SPeter Brune   SNESLineSearch_Shell *shell;
1346a388c36SPeter Brune 
1356a388c36SPeter Brune   PetscFunctionBegin;
136f1c6b773SPeter Brune   linesearch->ops->apply          = SNESLineSearchApply_Shell;
137f1c6b773SPeter Brune   linesearch->ops->destroy        = SNESLineSearchDestroy_Shell;
1380298fd71SBarry Smith   linesearch->ops->setfromoptions = NULL;
1390298fd71SBarry Smith   linesearch->ops->reset          = NULL;
1400298fd71SBarry Smith   linesearch->ops->view           = NULL;
1410298fd71SBarry Smith   linesearch->ops->setup          = NULL;
1426a388c36SPeter Brune 
1434dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&shell));
144f5af7f23SKarl Rupp 
1456a388c36SPeter Brune   linesearch->data = (void *)shell;
146*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1476a388c36SPeter Brune }
148