xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 9895aa37ac365bac650f6bd8bf977519f7222510)
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 = SNESLineSearchSetSuccess(linesearch, PETSC_TRUE);CHKERRQ(ierr);
35 $     ierr = SNESLineSearchGetVecs(linesearch, X, Y, F, 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 = SNESGetSNESLineSearch(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    Level: advanced
80 
81    .keywords: SNESLineSearch, get, Shell, user, function
82 
83    .seealso: SNESLineSearchShellSetUserFunc()
84 @*/
85 PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx)
86 {
87   PetscErrorCode       ierr;
88   PetscBool            flg;
89   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
90 
91   PetscFunctionBegin;
92   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
93   if (func) PetscValidPointer(func,2);
94   if (ctx)  PetscValidPointer(ctx,3);
95   ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr);
96   if (flg) {
97     *ctx  = shell->ctx;
98     *func = shell->func;
99   }
100   PetscFunctionReturn(0);
101 }
102 
103 
104 #undef __FUNCT__
105 #define __FUNCT__ "SNESLineSearchApply_Shell"
106 static PetscErrorCode  SNESLineSearchApply_Shell(SNESLineSearch linesearch)
107 {
108   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
109   PetscErrorCode       ierr;
110 
111   PetscFunctionBegin;
112   /* apply the user function */
113   if (shell->func) {
114     ierr = (*shell->func)(linesearch, shell->ctx);CHKERRQ(ierr);
115   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
116   PetscFunctionReturn(0);
117 }
118 
119 #undef __FUNCT__
120 #define __FUNCT__ "SNESLineSearchDestroy_Shell"
121 static PetscErrorCode  SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
122 {
123   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell*)linesearch->data;
124   PetscErrorCode       ierr;
125 
126   PetscFunctionBegin;
127   ierr = PetscFree(shell);CHKERRQ(ierr);
128   PetscFunctionReturn(0);
129 }
130 
131 #undef __FUNCT__
132 #define __FUNCT__ "SNESLineSearchCreate_Shell"
133 /*MC
134 
135 SNESLINESEARCHSHELL - Provides context for a user-provided line search routine.
136 
137 The user routine has one argument, the SNESLineSearch context.  The user uses the interface to
138 extract line search parameters and set them accordingly when the computation is finished.
139 
140 Any of the other line searches may serve as a guide to how this is to be done.  There is also a basic
141 template in the documentation for SNESLineSearchShellSetUserFunc().
142 
143 Level: advanced
144 
145 M*/
146 PETSC_EXTERN_C PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
147 {
148 
149   SNESLineSearch_Shell *shell;
150   PetscErrorCode       ierr;
151 
152   PetscFunctionBegin;
153   linesearch->ops->apply          = SNESLineSearchApply_Shell;
154   linesearch->ops->destroy        = SNESLineSearchDestroy_Shell;
155   linesearch->ops->setfromoptions = NULL;
156   linesearch->ops->reset          = NULL;
157   linesearch->ops->view           = NULL;
158   linesearch->ops->setup          = NULL;
159 
160   ierr = PetscNewLog(linesearch, SNESLineSearch_Shell, &shell);CHKERRQ(ierr);
161 
162   linesearch->data = (void*) shell;
163   PetscFunctionReturn(0);
164 }
165