xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 0adebc6ce4218bb5a986f93c65179d861410e0be)
1b45d2f2cSJed Brown #include <petsc-private/linesearchimpl.h>
2b45d2f2cSJed Brown #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 
28cd7522eaSPeter Brune $  PetscErrorCode shellfunc(SNESLineSearch linesearch, void * ctx) {
2978bcb3b5SPeter Brune $     Vec  X, Y, F, W, G;
3078bcb3b5SPeter Brune $     SNES snes;
31cd7522eaSPeter Brune $     PetscFunctionBegin;
3278bcb3b5SPeter Brune $     ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr);
33cd7522eaSPeter Brune $     ierr = SNESLineSearchSetSuccess(linesearch, PETSC_TRUE);CHKERRQ(ierr);
3478bcb3b5SPeter Brune $     ierr = SNESLineSearchGetVecs(linesearch, X, Y, F, W, G);CHKERRQ(ierr);
3578bcb3b5SPeter Brune $     .. determine lambda using W and G as work vecs..
3678bcb3b5SPeter Brune $     ierr = VecAXPY(X, -lambda, Y);CHKERRQ(ierr);
3778bcb3b5SPeter Brune $     ierr = SNESComputeFunction(snes, X, F);CHKERRQ(ierr);
38cd7522eaSPeter Brune $     ierr = SNESLineSearchComputeNorms(linesearch);CHKERRQ(ierr);
39cd7522eaSPeter Brune $     PetscFunctionReturn(0);
40cd7522eaSPeter Brune $  }
41cd7522eaSPeter Brune $
42cd7522eaSPeter Brune $  ...
43cd7522eaSPeter Brune $
44cd7522eaSPeter Brune $  ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
451a4f838cSPeter Brune $  ierr = SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL);CHKERRQ(ierr);
46cd7522eaSPeter Brune $  ierr = SNESLineSearchShellSetUserFunc(linesearch, shellfunc, PETSC_NULL);CHKERRQ(ierr);
47cd7522eaSPeter Brune 
48f40b411bSPeter Brune    Level: advanced
49f40b411bSPeter Brune 
5078bcb3b5SPeter Brune    .keywords: SNESLineSearch, Shell, user, function, set
51f40b411bSPeter Brune 
521a4f838cSPeter Brune    .seealso: SNESLineSearchShellGetUserFunc(), SNESLINESEARCHSHELL
53f40b411bSPeter Brune @*/
54*0adebc6cSBarry Smith PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx)
55*0adebc6cSBarry Smith {
566a388c36SPeter Brune   PetscErrorCode       ierr;
576a388c36SPeter Brune   PetscBool            flg;
58f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
59*0adebc6cSBarry Smith 
606a388c36SPeter Brune   PetscFunctionBegin;
61f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
62251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr);
636a388c36SPeter Brune   if (flg) {
646a388c36SPeter Brune     shell->ctx = ctx;
659e764e56SPeter Brune     shell->func = func;
666a388c36SPeter Brune   }
676a388c36SPeter Brune   PetscFunctionReturn(0);
686a388c36SPeter Brune }
696a388c36SPeter Brune 
706a388c36SPeter Brune 
716a388c36SPeter Brune #undef __FUNCT__
72f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchShellGetUserFunc"
73f40b411bSPeter Brune /*@C
74f1c6b773SPeter Brune    SNESLineSearchShellGetUserFunc - Gets the user function and context for the shell implementation.
75f40b411bSPeter Brune 
76f40b411bSPeter Brune    Not Collective
77f40b411bSPeter Brune 
78f40b411bSPeter Brune    Level: advanced
79f40b411bSPeter Brune 
8078bcb3b5SPeter Brune    .keywords: SNESLineSearch, get, Shell, user, function
81f40b411bSPeter Brune 
82f1c6b773SPeter Brune    .seealso: SNESLineSearchShellSetUserFunc()
83f40b411bSPeter Brune @*/
84*0adebc6cSBarry Smith PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx)
85*0adebc6cSBarry Smith {
866a388c36SPeter Brune   PetscErrorCode       ierr;
876a388c36SPeter Brune   PetscBool            flg;
88f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
89*0adebc6cSBarry Smith 
906a388c36SPeter Brune   PetscFunctionBegin;
91f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
926a388c36SPeter Brune   if (func) PetscValidPointer(func,2);
936a388c36SPeter Brune   if (ctx)  PetscValidPointer(ctx,3);
94251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr);
956a388c36SPeter Brune   if (flg) {
966a388c36SPeter Brune     *ctx  = shell->ctx;
976a388c36SPeter Brune     *func = shell->func;
986a388c36SPeter Brune   }
996a388c36SPeter Brune   PetscFunctionReturn(0);
1006a388c36SPeter Brune }
1016a388c36SPeter Brune 
1026a388c36SPeter Brune 
1036a388c36SPeter Brune #undef __FUNCT__
104f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchApply_Shell"
105f1c6b773SPeter Brune static PetscErrorCode  SNESLineSearchApply_Shell(SNESLineSearch linesearch)
1066a388c36SPeter Brune {
107f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
1086a388c36SPeter Brune   PetscErrorCode       ierr;
1096a388c36SPeter Brune 
1106a388c36SPeter Brune   PetscFunctionBegin;
1116a388c36SPeter Brune 
1126a388c36SPeter Brune   /* apply the user function */
1136a388c36SPeter Brune   if (shell->func) {
1146a388c36SPeter Brune     ierr = (*shell->func)(linesearch, shell->ctx);CHKERRQ(ierr);
115*0adebc6cSBarry Smith   } else SETERRQ(((PetscObject)linesearch)->comm, PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
1166a388c36SPeter Brune   PetscFunctionReturn(0);
1176a388c36SPeter Brune }
1186a388c36SPeter Brune 
1196a388c36SPeter Brune #undef __FUNCT__
120f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchDestroy_Shell"
121f1c6b773SPeter Brune static PetscErrorCode  SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
1226a388c36SPeter Brune {
123f1c6b773SPeter Brune   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
1246a388c36SPeter Brune   PetscErrorCode       ierr;
1256a388c36SPeter Brune 
1266a388c36SPeter Brune   PetscFunctionBegin;
1276a388c36SPeter Brune   ierr = PetscFree(shell);CHKERRQ(ierr);
1286a388c36SPeter Brune   PetscFunctionReturn(0);
1296a388c36SPeter Brune }
1306a388c36SPeter Brune 
1316a388c36SPeter Brune #undef __FUNCT__
132f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchCreate_Shell"
133954494b2SJed Brown /*MC
134954494b2SJed Brown 
1351a4f838cSPeter Brune SNESLINESEARCHSHELL - Provides context for a user-provided line search routine.
136954494b2SJed Brown 
137f1c6b773SPeter Brune The user routine has one argument, the SNESLineSearch context.  The user uses the interface to
138954494b2SJed Brown extract line search parameters and set them accordingly when the computation is finished.
139954494b2SJed Brown 
140cd7522eaSPeter Brune Any of the other line searches may serve as a guide to how this is to be done.  There is also a basic
141cd7522eaSPeter Brune template in the documentation for SNESLineSearchShellSetUserFunc().
142954494b2SJed Brown 
143954494b2SJed Brown Level: advanced
144954494b2SJed Brown 
145954494b2SJed Brown M*/
146f1c6b773SPeter Brune PETSC_EXTERN_C PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
1476a388c36SPeter Brune {
1486a388c36SPeter Brune 
149f1c6b773SPeter Brune   SNESLineSearch_Shell *shell;
1506a388c36SPeter Brune   PetscErrorCode       ierr;
1516a388c36SPeter Brune 
1526a388c36SPeter Brune   PetscFunctionBegin;
153f1c6b773SPeter Brune   linesearch->ops->apply          = SNESLineSearchApply_Shell;
154f1c6b773SPeter Brune   linesearch->ops->destroy        = SNESLineSearchDestroy_Shell;
1556a388c36SPeter Brune   linesearch->ops->setfromoptions = PETSC_NULL;
1566a388c36SPeter Brune   linesearch->ops->reset          = PETSC_NULL;
1576a388c36SPeter Brune   linesearch->ops->view           = PETSC_NULL;
1586a388c36SPeter Brune   linesearch->ops->setup          = PETSC_NULL;
1596a388c36SPeter Brune 
160f1c6b773SPeter Brune   ierr = PetscNewLog(linesearch, SNESLineSearch_Shell, &shell);CHKERRQ(ierr);
1616a388c36SPeter Brune   linesearch->data = (void*) shell;
1626a388c36SPeter Brune   PetscFunctionReturn(0);
1636a388c36SPeter Brune }
164