xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
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;
309566063dSJacob Faibussowitsch $     PetscCall(SNESLineSearchGetSNES(linesearch,&snes));
319566063dSJacob Faibussowitsch $     PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED));
329566063dSJacob Faibussowitsch $     PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G));
3378bcb3b5SPeter Brune $     .. determine lambda using W and G as work vecs..
349566063dSJacob Faibussowitsch $     PetscCall(VecAXPY(X,-lambda,Y));
359566063dSJacob Faibussowitsch $     PetscCall(SNESComputeFunction(snes,X,F));
369566063dSJacob Faibussowitsch $     PetscCall(SNESLineSearchComputeNorms(linesearch));
37cd7522eaSPeter Brune $     PetscFunctionReturn(0);
38cd7522eaSPeter Brune $  }
39cd7522eaSPeter Brune $
40cd7522eaSPeter Brune $  ...
41cd7522eaSPeter Brune $
429566063dSJacob Faibussowitsch $  PetscCall(SNESGetLineSearch(snes, &linesearch));
439566063dSJacob Faibussowitsch $  PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
449566063dSJacob Faibussowitsch $  PetscCall(SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL));
45cd7522eaSPeter Brune 
46f40b411bSPeter Brune    Level: advanced
47f40b411bSPeter Brune 
48db781477SPatrick Sanan    .seealso: `SNESLineSearchShellGetUserFunc()`, `SNESLINESEARCHSHELL`
49f40b411bSPeter Brune @*/
50*9371c9d4SSatish Balay PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx) {
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   }
616a388c36SPeter Brune   PetscFunctionReturn(0);
626a388c36SPeter Brune }
636a388c36SPeter Brune 
64f40b411bSPeter Brune /*@C
65f1c6b773SPeter Brune    SNESLineSearchShellGetUserFunc - Gets the user function and context for the shell implementation.
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 
78db781477SPatrick Sanan    .seealso: `SNESLineSearchShellSetUserFunc()`
79f40b411bSPeter Brune @*/
80*9371c9d4SSatish Balay PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx) {
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);
866a388c36SPeter Brune   if (func) PetscValidPointer(func, 2);
876a388c36SPeter Brune   if (ctx) PetscValidPointer(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   }
936a388c36SPeter Brune   PetscFunctionReturn(0);
946a388c36SPeter Brune }
956a388c36SPeter Brune 
96*9371c9d4SSatish Balay static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch) {
97f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
986a388c36SPeter Brune 
996a388c36SPeter Brune   PetscFunctionBegin;
1006a388c36SPeter Brune   /* apply the user function */
1016a388c36SPeter Brune   if (shell->func) {
1029566063dSJacob Faibussowitsch     PetscCall((*shell->func)(linesearch, shell->ctx));
103ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
1046a388c36SPeter Brune   PetscFunctionReturn(0);
1056a388c36SPeter Brune }
1066a388c36SPeter Brune 
107*9371c9d4SSatish Balay static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch) {
108f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
1096a388c36SPeter Brune 
1106a388c36SPeter Brune   PetscFunctionBegin;
1119566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell));
1126a388c36SPeter Brune   PetscFunctionReturn(0);
1136a388c36SPeter Brune }
1146a388c36SPeter Brune 
115954494b2SJed Brown /*MC
1161a4f838cSPeter Brune    SNESLINESEARCHSHELL - Provides context for a user-provided line search routine.
117954494b2SJed Brown 
118f1c6b773SPeter Brune The user routine has one argument, the SNESLineSearch context.  The user uses the interface to
119954494b2SJed Brown extract line search parameters and set them accordingly when the computation is finished.
120954494b2SJed Brown 
121cd7522eaSPeter Brune Any of the other line searches may serve as a guide to how this is to be done.  There is also a basic
122cd7522eaSPeter Brune template in the documentation for SNESLineSearchShellSetUserFunc().
123954494b2SJed Brown 
124954494b2SJed Brown Level: advanced
125954494b2SJed Brown 
126954494b2SJed Brown M*/
127*9371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch) {
128f1c6b773SPeter Brune   SNESLineSearch_Shell *shell;
1296a388c36SPeter Brune 
1306a388c36SPeter Brune   PetscFunctionBegin;
131f1c6b773SPeter Brune   linesearch->ops->apply          = SNESLineSearchApply_Shell;
132f1c6b773SPeter Brune   linesearch->ops->destroy        = SNESLineSearchDestroy_Shell;
1330298fd71SBarry Smith   linesearch->ops->setfromoptions = NULL;
1340298fd71SBarry Smith   linesearch->ops->reset          = NULL;
1350298fd71SBarry Smith   linesearch->ops->view           = NULL;
1360298fd71SBarry Smith   linesearch->ops->setup          = NULL;
1376a388c36SPeter Brune 
1389566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(linesearch, &shell));
139f5af7f23SKarl Rupp 
1406a388c36SPeter Brune   linesearch->data = (void *)shell;
1416a388c36SPeter Brune   PetscFunctionReturn(0);
1426a388c36SPeter Brune }
143