xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 9566063d113dddea24716c546802770db7481bc0)
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
10f1c6b773SPeter Brune    SNESLineSearchShellSetUserFunc - Sets the user function for the SNESLineSearch Shell implementation.
11f40b411bSPeter Brune 
12f40b411bSPeter Brune    Not Collective
13f40b411bSPeter Brune 
14cd7522eaSPeter Brune    Input Parameters:
15cd7522eaSPeter Brune +  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:
24cd7522eaSPeter Brune 
25a6dfd86eSKarl Rupp $  PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx)
26a6dfd86eSKarl Rupp $  {
2778bcb3b5SPeter Brune $     Vec  X,Y,F,W,G;
2878bcb3b5SPeter Brune $     SNES snes;
29cd7522eaSPeter Brune $     PetscFunctionBegin;
30*9566063dSJacob Faibussowitsch $     PetscCall(SNESLineSearchGetSNES(linesearch,&snes));
31*9566063dSJacob Faibussowitsch $     PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED));
32*9566063dSJacob Faibussowitsch $     PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G));
3378bcb3b5SPeter Brune $     .. determine lambda using W and G as work vecs..
34*9566063dSJacob Faibussowitsch $     PetscCall(VecAXPY(X,-lambda,Y));
35*9566063dSJacob Faibussowitsch $     PetscCall(SNESComputeFunction(snes,X,F));
36*9566063dSJacob Faibussowitsch $     PetscCall(SNESLineSearchComputeNorms(linesearch));
37cd7522eaSPeter Brune $     PetscFunctionReturn(0);
38cd7522eaSPeter Brune $  }
39cd7522eaSPeter Brune $
40cd7522eaSPeter Brune $  ...
41cd7522eaSPeter Brune $
42*9566063dSJacob Faibussowitsch $  PetscCall(SNESGetLineSearch(snes, &linesearch));
43*9566063dSJacob Faibussowitsch $  PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
44*9566063dSJacob Faibussowitsch $  PetscCall(SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL));
45cd7522eaSPeter Brune 
46f40b411bSPeter Brune    Level: advanced
47f40b411bSPeter Brune 
481a4f838cSPeter Brune    .seealso: SNESLineSearchShellGetUserFunc(), SNESLINESEARCHSHELL
49f40b411bSPeter Brune @*/
500adebc6cSBarry Smith PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx)
510adebc6cSBarry Smith {
526a388c36SPeter Brune   PetscBool            flg;
53f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
540adebc6cSBarry Smith 
556a388c36SPeter Brune   PetscFunctionBegin;
56f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
57*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg));
586a388c36SPeter Brune   if (flg) {
596a388c36SPeter Brune     shell->ctx  = ctx;
609e764e56SPeter Brune     shell->func = func;
616a388c36SPeter Brune   }
626a388c36SPeter Brune   PetscFunctionReturn(0);
636a388c36SPeter Brune }
646a388c36SPeter Brune 
65f40b411bSPeter Brune /*@C
66f1c6b773SPeter Brune    SNESLineSearchShellGetUserFunc - Gets the user function and context for the shell implementation.
67f40b411bSPeter Brune 
68f40b411bSPeter Brune    Not Collective
69f40b411bSPeter Brune 
704a2f8832SBarry Smith    Input Parameter:
714a2f8832SBarry Smith .     linesearch - the line search object
724a2f8832SBarry Smith 
734a2f8832SBarry Smith    Output Parameters:
744a2f8832SBarry Smith +    func  - the user function; can be NULL if you do not want it
754a2f8832SBarry Smith -    ctx   - the user function context; can be NULL if you do not want it
764a2f8832SBarry Smith 
77f40b411bSPeter Brune    Level: advanced
78f40b411bSPeter Brune 
79f1c6b773SPeter Brune    .seealso: SNESLineSearchShellSetUserFunc()
80f40b411bSPeter Brune @*/
810adebc6cSBarry Smith PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx)
820adebc6cSBarry Smith {
836a388c36SPeter Brune   PetscBool            flg;
84f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
850adebc6cSBarry Smith 
866a388c36SPeter Brune   PetscFunctionBegin;
87f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
886a388c36SPeter Brune   if (func) PetscValidPointer(func,2);
896a388c36SPeter Brune   if (ctx)  PetscValidPointer(ctx,3);
90*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg));
916a388c36SPeter Brune   if (flg) {
924a2f8832SBarry Smith     if (func) *func = shell->func;
934a2f8832SBarry Smith     if (ctx) *ctx  = shell->ctx;
946a388c36SPeter Brune   }
956a388c36SPeter Brune   PetscFunctionReturn(0);
966a388c36SPeter Brune }
976a388c36SPeter Brune 
98f1c6b773SPeter Brune static PetscErrorCode  SNESLineSearchApply_Shell(SNESLineSearch linesearch)
996a388c36SPeter Brune {
100f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
1016a388c36SPeter Brune 
1026a388c36SPeter Brune   PetscFunctionBegin;
1036a388c36SPeter Brune   /* apply the user function */
1046a388c36SPeter Brune   if (shell->func) {
105*9566063dSJacob Faibussowitsch     PetscCall((*shell->func)(linesearch, shell->ctx));
106ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
1076a388c36SPeter Brune   PetscFunctionReturn(0);
1086a388c36SPeter Brune }
1096a388c36SPeter Brune 
110f1c6b773SPeter Brune static PetscErrorCode  SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
1116a388c36SPeter Brune {
112f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
1136a388c36SPeter Brune 
1146a388c36SPeter Brune   PetscFunctionBegin;
115*9566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell));
1166a388c36SPeter Brune   PetscFunctionReturn(0);
1176a388c36SPeter Brune }
1186a388c36SPeter Brune 
119954494b2SJed Brown /*MC
1201a4f838cSPeter Brune    SNESLINESEARCHSHELL - Provides context for a user-provided line search routine.
121954494b2SJed Brown 
122f1c6b773SPeter Brune The user routine has one argument, the SNESLineSearch context.  The user uses the interface to
123954494b2SJed Brown extract line search parameters and set them accordingly when the computation is finished.
124954494b2SJed Brown 
125cd7522eaSPeter Brune Any of the other line searches may serve as a guide to how this is to be done.  There is also a basic
126cd7522eaSPeter Brune template in the documentation for SNESLineSearchShellSetUserFunc().
127954494b2SJed Brown 
128954494b2SJed Brown Level: advanced
129954494b2SJed Brown 
130954494b2SJed Brown M*/
1318cc058d9SJed Brown PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
1326a388c36SPeter Brune {
1336a388c36SPeter Brune 
134f1c6b773SPeter Brune   SNESLineSearch_Shell *shell;
1356a388c36SPeter Brune 
1366a388c36SPeter Brune   PetscFunctionBegin;
137f1c6b773SPeter Brune   linesearch->ops->apply          = SNESLineSearchApply_Shell;
138f1c6b773SPeter Brune   linesearch->ops->destroy        = SNESLineSearchDestroy_Shell;
1390298fd71SBarry Smith   linesearch->ops->setfromoptions = NULL;
1400298fd71SBarry Smith   linesearch->ops->reset          = NULL;
1410298fd71SBarry Smith   linesearch->ops->view           = NULL;
1420298fd71SBarry Smith   linesearch->ops->setup          = NULL;
1436a388c36SPeter Brune 
144*9566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(linesearch,&shell));
145f5af7f23SKarl Rupp 
1466a388c36SPeter Brune   linesearch->data = (void*) shell;
1476a388c36SPeter Brune   PetscFunctionReturn(0);
1486a388c36SPeter Brune }
149