xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 4a2f8832e687075714ce232dc09a9bd05f920d30)
1af0996ceSBarry Smith #include <petsc/private/linesearchimpl.h>
2af0996ceSBarry Smith #include <petsc/private/snesimpl.h>
36a388c36SPeter Brune 
4f40b411bSPeter Brune 
56a388c36SPeter Brune typedef struct {
6f1c6b773SPeter Brune   SNESLineSearchUserFunc func;
76a388c36SPeter Brune   void                   *ctx;
8f1c6b773SPeter Brune } SNESLineSearch_Shell;
96a388c36SPeter Brune 
106a388c36SPeter Brune #undef __FUNCT__
11f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchShellSetUserFunc"
12f40b411bSPeter Brune /*@C
13f1c6b773SPeter Brune    SNESLineSearchShellSetUserFunc - Sets the user function for the SNESLineSearch Shell implementation.
14f40b411bSPeter Brune 
15f40b411bSPeter Brune    Not Collective
16f40b411bSPeter Brune 
17cd7522eaSPeter Brune    Input Parameters:
18cd7522eaSPeter Brune +  linesearch - SNESLineSearch context
19cd7522eaSPeter Brune .  func - function implementing the linesearch shell.
20cd7522eaSPeter Brune -  ctx - context for func
21cd7522eaSPeter Brune 
22cd7522eaSPeter Brune    Calling sequence of func:
23cd7522eaSPeter Brune +  linesearch - the linesearch instance
24cd7522eaSPeter Brune -  ctx - the above mentioned context
25cd7522eaSPeter Brune 
26cd7522eaSPeter Brune    Usage:
27cd7522eaSPeter Brune 
28a6dfd86eSKarl Rupp $  PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx)
29a6dfd86eSKarl Rupp $  {
3078bcb3b5SPeter Brune $     Vec  X,Y,F,W,G;
3178bcb3b5SPeter Brune $     SNES snes;
32cd7522eaSPeter Brune $     PetscFunctionBegin;
3378bcb3b5SPeter Brune $     ierr = SNESLineSearchGetSNES(linesearch,&snes);CHKERRQ(ierr);
34422a814eSBarry Smith $     ierr = SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED);CHKERRQ(ierr);
358484119aSPeter Brune $     ierr = SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G);CHKERRQ(ierr);
3678bcb3b5SPeter Brune $     .. determine lambda using W and G as work vecs..
3778bcb3b5SPeter Brune $     ierr = VecAXPY(X,-lambda,Y);CHKERRQ(ierr);
3878bcb3b5SPeter Brune $     ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
39cd7522eaSPeter Brune $     ierr = SNESLineSearchComputeNorms(linesearch);CHKERRQ(ierr);
40cd7522eaSPeter Brune $     PetscFunctionReturn(0);
41cd7522eaSPeter Brune $  }
42cd7522eaSPeter Brune $
43cd7522eaSPeter Brune $  ...
44cd7522eaSPeter Brune $
457601faf0SJed Brown $  ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr);
461a4f838cSPeter Brune $  ierr = SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL);CHKERRQ(ierr);
470298fd71SBarry Smith $  ierr = SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL);CHKERRQ(ierr);
48cd7522eaSPeter Brune 
49f40b411bSPeter Brune    Level: advanced
50f40b411bSPeter Brune 
5178bcb3b5SPeter Brune    .keywords: SNESLineSearch, Shell, user, function, set
52f40b411bSPeter Brune 
531a4f838cSPeter Brune    .seealso: SNESLineSearchShellGetUserFunc(), SNESLINESEARCHSHELL
54f40b411bSPeter Brune @*/
550adebc6cSBarry Smith PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx)
560adebc6cSBarry Smith {
576a388c36SPeter Brune   PetscErrorCode       ierr;
586a388c36SPeter Brune   PetscBool            flg;
59f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
600adebc6cSBarry Smith 
616a388c36SPeter Brune   PetscFunctionBegin;
62f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
63251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr);
646a388c36SPeter Brune   if (flg) {
656a388c36SPeter Brune     shell->ctx  = ctx;
669e764e56SPeter Brune     shell->func = func;
676a388c36SPeter Brune   }
686a388c36SPeter Brune   PetscFunctionReturn(0);
696a388c36SPeter Brune }
706a388c36SPeter Brune 
716a388c36SPeter Brune 
726a388c36SPeter Brune #undef __FUNCT__
73f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchShellGetUserFunc"
74f40b411bSPeter Brune /*@C
75f1c6b773SPeter Brune    SNESLineSearchShellGetUserFunc - Gets the user function and context for the shell implementation.
76f40b411bSPeter Brune 
77f40b411bSPeter Brune    Not Collective
78f40b411bSPeter Brune 
79*4a2f8832SBarry Smith    Input Parameter:
80*4a2f8832SBarry Smith .     linesearch - the line search object
81*4a2f8832SBarry Smith 
82*4a2f8832SBarry Smith    Output Parameters:
83*4a2f8832SBarry Smith +    func  - the user function; can be NULL if you do not want it
84*4a2f8832SBarry Smith -    ctx   - the user function context; can be NULL if you do not want it
85*4a2f8832SBarry Smith 
86f40b411bSPeter Brune    Level: advanced
87f40b411bSPeter Brune 
8878bcb3b5SPeter Brune    .keywords: SNESLineSearch, get, Shell, user, function
89f40b411bSPeter Brune 
90f1c6b773SPeter Brune    .seealso: SNESLineSearchShellSetUserFunc()
91f40b411bSPeter Brune @*/
920adebc6cSBarry Smith PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx)
930adebc6cSBarry Smith {
946a388c36SPeter Brune   PetscErrorCode       ierr;
956a388c36SPeter Brune   PetscBool            flg;
96f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
970adebc6cSBarry Smith 
986a388c36SPeter Brune   PetscFunctionBegin;
99f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1006a388c36SPeter Brune   if (func) PetscValidPointer(func,2);
1016a388c36SPeter Brune   if (ctx)  PetscValidPointer(ctx,3);
102251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr);
1036a388c36SPeter Brune   if (flg) {
104*4a2f8832SBarry Smith     if (func) *func = shell->func;
105*4a2f8832SBarry Smith     if (ctx) *ctx  = shell->ctx;
1066a388c36SPeter Brune   }
1076a388c36SPeter Brune   PetscFunctionReturn(0);
1086a388c36SPeter Brune }
1096a388c36SPeter Brune 
1106a388c36SPeter Brune 
1116a388c36SPeter Brune #undef __FUNCT__
112f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchApply_Shell"
113f1c6b773SPeter Brune static PetscErrorCode  SNESLineSearchApply_Shell(SNESLineSearch linesearch)
1146a388c36SPeter Brune {
115f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
1166a388c36SPeter Brune   PetscErrorCode       ierr;
1176a388c36SPeter Brune 
1186a388c36SPeter Brune   PetscFunctionBegin;
1196a388c36SPeter Brune   /* apply the user function */
1206a388c36SPeter Brune   if (shell->func) {
1216a388c36SPeter Brune     ierr = (*shell->func)(linesearch, shell->ctx);CHKERRQ(ierr);
122ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
1236a388c36SPeter Brune   PetscFunctionReturn(0);
1246a388c36SPeter Brune }
1256a388c36SPeter Brune 
1266a388c36SPeter Brune #undef __FUNCT__
127f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchDestroy_Shell"
128f1c6b773SPeter Brune static PetscErrorCode  SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
1296a388c36SPeter Brune {
130f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
1316a388c36SPeter Brune   PetscErrorCode       ierr;
1326a388c36SPeter Brune 
1336a388c36SPeter Brune   PetscFunctionBegin;
1346a388c36SPeter Brune   ierr = PetscFree(shell);CHKERRQ(ierr);
1356a388c36SPeter Brune   PetscFunctionReturn(0);
1366a388c36SPeter Brune }
1376a388c36SPeter Brune 
1386a388c36SPeter Brune #undef __FUNCT__
139f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchCreate_Shell"
140954494b2SJed Brown /*MC
141954494b2SJed Brown 
1421a4f838cSPeter Brune SNESLINESEARCHSHELL - Provides context for a user-provided line search routine.
143954494b2SJed Brown 
144f1c6b773SPeter Brune The user routine has one argument, the SNESLineSearch context.  The user uses the interface to
145954494b2SJed Brown extract line search parameters and set them accordingly when the computation is finished.
146954494b2SJed Brown 
147cd7522eaSPeter Brune Any of the other line searches may serve as a guide to how this is to be done.  There is also a basic
148cd7522eaSPeter Brune template in the documentation for SNESLineSearchShellSetUserFunc().
149954494b2SJed Brown 
150954494b2SJed Brown Level: advanced
151954494b2SJed Brown 
152954494b2SJed Brown M*/
1538cc058d9SJed Brown PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
1546a388c36SPeter Brune {
1556a388c36SPeter Brune 
156f1c6b773SPeter Brune   SNESLineSearch_Shell *shell;
1576a388c36SPeter Brune   PetscErrorCode       ierr;
1586a388c36SPeter Brune 
1596a388c36SPeter Brune   PetscFunctionBegin;
160f1c6b773SPeter Brune   linesearch->ops->apply          = SNESLineSearchApply_Shell;
161f1c6b773SPeter Brune   linesearch->ops->destroy        = SNESLineSearchDestroy_Shell;
1620298fd71SBarry Smith   linesearch->ops->setfromoptions = NULL;
1630298fd71SBarry Smith   linesearch->ops->reset          = NULL;
1640298fd71SBarry Smith   linesearch->ops->view           = NULL;
1650298fd71SBarry Smith   linesearch->ops->setup          = NULL;
1666a388c36SPeter Brune 
167b00a9115SJed Brown   ierr = PetscNewLog(linesearch,&shell);CHKERRQ(ierr);
168f5af7f23SKarl Rupp 
1696a388c36SPeter Brune   linesearch->data = (void*) shell;
1706a388c36SPeter Brune   PetscFunctionReturn(0);
1716a388c36SPeter Brune }
172