xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 20f4b53cbb5e9bd9ef12b76a8697d60d197cda17)
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 
19*20f4b53cSBarry Smith    Calling sequence of `func`:
20*20f4b53cSBarry Smith $  PetscErrorCode func(SNESLinesearch, void *ctx)
21cd7522eaSPeter Brune +  linesearch - the linesearch instance
22cd7522eaSPeter Brune -  ctx - the above mentioned context
23cd7522eaSPeter Brune 
24cd7522eaSPeter Brune    Usage:
25*20f4b53cSBarry Smith .vb
26*20f4b53cSBarry Smith   PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx)
27*20f4b53cSBarry Smith   {
28*20f4b53cSBarry Smith      Vec  X,Y,F,W,G;
29*20f4b53cSBarry Smith      SNES snes;
30*20f4b53cSBarry Smith      PetscFunctionBegin;
31*20f4b53cSBarry Smith      PetscCall(SNESLineSearchGetSNES(linesearch,&snes));
32*20f4b53cSBarry Smith      PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED));
33*20f4b53cSBarry Smith      PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G));
34*20f4b53cSBarry Smith      .. determine lambda using W and G as work vecs..
35*20f4b53cSBarry Smith      PetscCall(VecAXPY(X,-lambda,Y));
36*20f4b53cSBarry Smith      PetscCall(SNESComputeFunction(snes,X,F));
37*20f4b53cSBarry Smith      PetscCall(SNESLineSearchComputeNorms(linesearch));
38*20f4b53cSBarry Smith      PetscFunctionReturn(PETSC_SUCCESS);
39*20f4b53cSBarry Smith   }
40*20f4b53cSBarry Smith 
41*20f4b53cSBarry Smith   ...
42*20f4b53cSBarry Smith 
43*20f4b53cSBarry Smith   PetscCall(SNESGetLineSearch(snes, &linesearch));
44*20f4b53cSBarry Smith   PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
45*20f4b53cSBarry Smith   PetscCall(SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL));
46*20f4b53cSBarry Smith .ve
47cd7522eaSPeter Brune 
48f40b411bSPeter Brune    Level: advanced
49f40b411bSPeter Brune 
50f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellGetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`
51f40b411bSPeter Brune @*/
52d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx)
53d71ae5a4SJacob Faibussowitsch {
546a388c36SPeter Brune   PetscBool             flg;
55f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
560adebc6cSBarry Smith 
576a388c36SPeter Brune   PetscFunctionBegin;
58f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
599566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
606a388c36SPeter Brune   if (flg) {
616a388c36SPeter Brune     shell->ctx  = ctx;
629e764e56SPeter Brune     shell->func = func;
636a388c36SPeter Brune   }
643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
656a388c36SPeter Brune }
666a388c36SPeter Brune 
67f40b411bSPeter Brune /*@C
68f6dfbefdSBarry Smith    SNESLineSearchShellGetUserFunc - Gets the user function and context for the  `SNESLINESEARCHSHELL`
69f40b411bSPeter Brune 
70f40b411bSPeter Brune    Not Collective
71f40b411bSPeter Brune 
724a2f8832SBarry Smith    Input Parameter:
734a2f8832SBarry Smith .   linesearch - the line search object
744a2f8832SBarry Smith 
754a2f8832SBarry Smith    Output Parameters:
764a2f8832SBarry Smith +    func  - the user function; can be NULL if you do not want it
774a2f8832SBarry Smith -    ctx   - the user function context; can be NULL if you do not want it
784a2f8832SBarry Smith 
79f40b411bSPeter Brune    Level: advanced
80f40b411bSPeter Brune 
81f6dfbefdSBarry Smith .seealso: `SNESLineSearchShellSetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`
82f40b411bSPeter Brune @*/
83d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx)
84d71ae5a4SJacob Faibussowitsch {
856a388c36SPeter Brune   PetscBool             flg;
86f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
870adebc6cSBarry Smith 
886a388c36SPeter Brune   PetscFunctionBegin;
89f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
906a388c36SPeter Brune   if (func) PetscValidPointer(func, 2);
916a388c36SPeter Brune   if (ctx) PetscValidPointer(ctx, 3);
929566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
936a388c36SPeter Brune   if (flg) {
944a2f8832SBarry Smith     if (func) *func = shell->func;
954a2f8832SBarry Smith     if (ctx) *ctx = shell->ctx;
966a388c36SPeter Brune   }
973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
986a388c36SPeter Brune }
996a388c36SPeter Brune 
100d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch)
101d71ae5a4SJacob Faibussowitsch {
102f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
1036a388c36SPeter Brune 
1046a388c36SPeter Brune   PetscFunctionBegin;
1056a388c36SPeter Brune   /* apply the user function */
1066a388c36SPeter Brune   if (shell->func) {
1079566063dSJacob Faibussowitsch     PetscCall((*shell->func)(linesearch, shell->ctx));
108ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
1093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1106a388c36SPeter Brune }
1116a388c36SPeter Brune 
112d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
113d71ae5a4SJacob Faibussowitsch {
114f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
1156a388c36SPeter Brune 
1166a388c36SPeter Brune   PetscFunctionBegin;
1179566063dSJacob Faibussowitsch   PetscCall(PetscFree(shell));
1183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1196a388c36SPeter Brune }
1206a388c36SPeter Brune 
121954494b2SJed Brown /*MC
1221a4f838cSPeter Brune    SNESLINESEARCHSHELL - Provides context for a user-provided line search routine.
123954494b2SJed Brown 
124f1c6b773SPeter Brune The user routine has one argument, the SNESLineSearch context.  The user uses the interface to
125954494b2SJed Brown extract line search parameters and set them accordingly when the computation is finished.
126954494b2SJed Brown 
127cd7522eaSPeter Brune Any of the other line searches may serve as a guide to how this is to be done.  There is also a basic
128cd7522eaSPeter Brune template in the documentation for SNESLineSearchShellSetUserFunc().
129954494b2SJed Brown 
130954494b2SJed Brown Level: advanced
131954494b2SJed Brown 
132f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`
133954494b2SJed Brown M*/
134d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
135d71ae5a4SJacob Faibussowitsch {
136f1c6b773SPeter Brune   SNESLineSearch_Shell *shell;
1376a388c36SPeter Brune 
1386a388c36SPeter Brune   PetscFunctionBegin;
139f1c6b773SPeter Brune   linesearch->ops->apply          = SNESLineSearchApply_Shell;
140f1c6b773SPeter Brune   linesearch->ops->destroy        = SNESLineSearchDestroy_Shell;
1410298fd71SBarry Smith   linesearch->ops->setfromoptions = NULL;
1420298fd71SBarry Smith   linesearch->ops->reset          = NULL;
1430298fd71SBarry Smith   linesearch->ops->view           = NULL;
1440298fd71SBarry Smith   linesearch->ops->setup          = NULL;
1456a388c36SPeter Brune 
1464dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&shell));
147f5af7f23SKarl Rupp 
1486a388c36SPeter Brune   linesearch->data = (void *)shell;
1493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1506a388c36SPeter Brune }
151