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