xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision f6dfbefd03961ab3be6f06be75c96cbf27a49667)
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
10*f6dfbefdSBarry Smith    SNESLineSearchShellSetUserFunc - Sets the user function for the `SNESLINESEARCHSHELL` implementation.
11f40b411bSPeter Brune 
12f40b411bSPeter Brune    Not Collective
13f40b411bSPeter Brune 
14cd7522eaSPeter Brune    Input Parameters:
15*f6dfbefdSBarry 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));
36cd7522eaSPeter Brune $     PetscFunctionReturn(0);
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 
47*f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellGetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`
48f40b411bSPeter Brune @*/
499371c9d4SSatish Balay PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx) {
506a388c36SPeter Brune   PetscBool             flg;
51f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
520adebc6cSBarry Smith 
536a388c36SPeter Brune   PetscFunctionBegin;
54f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
559566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
566a388c36SPeter Brune   if (flg) {
576a388c36SPeter Brune     shell->ctx  = ctx;
589e764e56SPeter Brune     shell->func = func;
596a388c36SPeter Brune   }
606a388c36SPeter Brune   PetscFunctionReturn(0);
616a388c36SPeter Brune }
626a388c36SPeter Brune 
63f40b411bSPeter Brune /*@C
64*f6dfbefdSBarry Smith    SNESLineSearchShellGetUserFunc - Gets the user function and context for the  `SNESLINESEARCHSHELL`
65f40b411bSPeter Brune 
66f40b411bSPeter Brune    Not Collective
67f40b411bSPeter Brune 
684a2f8832SBarry Smith    Input Parameter:
694a2f8832SBarry Smith .   linesearch - the line search object
704a2f8832SBarry Smith 
714a2f8832SBarry Smith    Output Parameters:
724a2f8832SBarry Smith +    func  - the user function; can be NULL if you do not want it
734a2f8832SBarry Smith -    ctx   - the user function context; can be NULL if you do not want it
744a2f8832SBarry Smith 
75f40b411bSPeter Brune    Level: advanced
76f40b411bSPeter Brune 
77*f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellSetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`
78f40b411bSPeter Brune @*/
799371c9d4SSatish Balay PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx) {
806a388c36SPeter Brune   PetscBool             flg;
81f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
820adebc6cSBarry Smith 
836a388c36SPeter Brune   PetscFunctionBegin;
84f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
856a388c36SPeter Brune   if (func) PetscValidPointer(func, 2);
866a388c36SPeter Brune   if (ctx) PetscValidPointer(ctx, 3);
879566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
886a388c36SPeter Brune   if (flg) {
894a2f8832SBarry Smith     if (func) *func = shell->func;
904a2f8832SBarry Smith     if (ctx) *ctx = shell->ctx;
916a388c36SPeter Brune   }
926a388c36SPeter Brune   PetscFunctionReturn(0);
936a388c36SPeter Brune }
946a388c36SPeter Brune 
959371c9d4SSatish Balay static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch) {
96f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
976a388c36SPeter Brune 
986a388c36SPeter Brune   PetscFunctionBegin;
996a388c36SPeter Brune   /* apply the user function */
1006a388c36SPeter Brune   if (shell->func) {
1019566063dSJacob Faibussowitsch     PetscCall((*shell->func)(linesearch, shell->ctx));
102ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
1036a388c36SPeter Brune   PetscFunctionReturn(0);
1046a388c36SPeter Brune }
1056a388c36SPeter Brune 
1069371c9d4SSatish Balay static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch) {
107f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
1086a388c36SPeter Brune 
1096a388c36SPeter Brune   PetscFunctionBegin;
1109566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell));
1116a388c36SPeter Brune   PetscFunctionReturn(0);
1126a388c36SPeter Brune }
1136a388c36SPeter Brune 
114954494b2SJed Brown /*MC
1151a4f838cSPeter Brune    SNESLINESEARCHSHELL - Provides context for a user-provided line search routine.
116954494b2SJed Brown 
117f1c6b773SPeter Brune The user routine has one argument, the SNESLineSearch context.  The user uses the interface to
118954494b2SJed Brown extract line search parameters and set them accordingly when the computation is finished.
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
121cd7522eaSPeter Brune template in the documentation for SNESLineSearchShellSetUserFunc().
122954494b2SJed Brown 
123954494b2SJed Brown Level: advanced
124954494b2SJed Brown 
125*f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`
126954494b2SJed Brown M*/
1279371c9d4SSatish 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