xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 5f80ce2ab25dff0f4601e710601cbbcecf323266)
1 #include <petsc/private/linesearchimpl.h>
2 #include <petsc/private/snesimpl.h>
3 
4 typedef struct {
5   SNESLineSearchUserFunc func;
6   void                   *ctx;
7 } SNESLineSearch_Shell;
8 
9 /*@C
10    SNESLineSearchShellSetUserFunc - Sets the user function for the SNESLineSearch Shell implementation.
11 
12    Not Collective
13 
14    Input Parameters:
15 +  linesearch - SNESLineSearch context
16 .  func - function implementing the linesearch shell.
17 -  ctx - context for func
18 
19    Calling sequence of func:
20 +  linesearch - the linesearch instance
21 -  ctx - the above mentioned context
22 
23    Usage:
24 
25 $  PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx)
26 $  {
27 $     Vec  X,Y,F,W,G;
28 $     SNES snes;
29 $     PetscFunctionBegin;
30 $     CHKERRQ(SNESLineSearchGetSNES(linesearch,&snes));
31 $     CHKERRQ(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED));
32 $     CHKERRQ(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G));
33 $     .. determine lambda using W and G as work vecs..
34 $     CHKERRQ(VecAXPY(X,-lambda,Y));
35 $     CHKERRQ(SNESComputeFunction(snes,X,F));
36 $     CHKERRQ(SNESLineSearchComputeNorms(linesearch));
37 $     PetscFunctionReturn(0);
38 $  }
39 $
40 $  ...
41 $
42 $  CHKERRQ(SNESGetLineSearch(snes, &linesearch));
43 $  CHKERRQ(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
44 $  CHKERRQ(SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL));
45 
46    Level: advanced
47 
48    .seealso: SNESLineSearchShellGetUserFunc(), SNESLINESEARCHSHELL
49 @*/
50 PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx)
51 {
52   PetscBool            flg;
53   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
54 
55   PetscFunctionBegin;
56   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
57   CHKERRQ(PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg));
58   if (flg) {
59     shell->ctx  = ctx;
60     shell->func = func;
61   }
62   PetscFunctionReturn(0);
63 }
64 
65 /*@C
66    SNESLineSearchShellGetUserFunc - Gets the user function and context for the shell implementation.
67 
68    Not Collective
69 
70    Input Parameter:
71 .     linesearch - the line search object
72 
73    Output Parameters:
74 +    func  - the user function; can be NULL if you do not want it
75 -    ctx   - the user function context; can be NULL if you do not want it
76 
77    Level: advanced
78 
79    .seealso: SNESLineSearchShellSetUserFunc()
80 @*/
81 PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx)
82 {
83   PetscBool            flg;
84   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
85 
86   PetscFunctionBegin;
87   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
88   if (func) PetscValidPointer(func,2);
89   if (ctx)  PetscValidPointer(ctx,3);
90   CHKERRQ(PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg));
91   if (flg) {
92     if (func) *func = shell->func;
93     if (ctx) *ctx  = shell->ctx;
94   }
95   PetscFunctionReturn(0);
96 }
97 
98 static PetscErrorCode  SNESLineSearchApply_Shell(SNESLineSearch linesearch)
99 {
100   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
101 
102   PetscFunctionBegin;
103   /* apply the user function */
104   if (shell->func) {
105     CHKERRQ((*shell->func)(linesearch, shell->ctx));
106   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
107   PetscFunctionReturn(0);
108 }
109 
110 static PetscErrorCode  SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
111 {
112   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
113 
114   PetscFunctionBegin;
115   CHKERRQ(PetscFree(shell));
116   PetscFunctionReturn(0);
117 }
118 
119 /*MC
120    SNESLINESEARCHSHELL - Provides context for a user-provided line search routine.
121 
122 The user routine has one argument, the SNESLineSearch context.  The user uses the interface to
123 extract line search parameters and set them accordingly when the computation is finished.
124 
125 Any of the other line searches may serve as a guide to how this is to be done.  There is also a basic
126 template in the documentation for SNESLineSearchShellSetUserFunc().
127 
128 Level: advanced
129 
130 M*/
131 PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
132 {
133 
134   SNESLineSearch_Shell *shell;
135 
136   PetscFunctionBegin;
137   linesearch->ops->apply          = SNESLineSearchApply_Shell;
138   linesearch->ops->destroy        = SNESLineSearchDestroy_Shell;
139   linesearch->ops->setfromoptions = NULL;
140   linesearch->ops->reset          = NULL;
141   linesearch->ops->view           = NULL;
142   linesearch->ops->setup          = NULL;
143 
144   CHKERRQ(PetscNewLog(linesearch,&shell));
145 
146   linesearch->data = (void*) shell;
147   PetscFunctionReturn(0);
148 }
149