xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 670f3ff9a12f3667ff7d4cebfc50ebc8579c9e33)
1 #include <private/linesearchimpl.h>
2 #include <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 $     Vec X, Y, F;
30 $     PetscFunctionBegin;
31 $     ierr = SNESLineSearchSetSuccess(linesearch, PETSC_TRUE);CHKERRQ(ierr);
32 $     ierr = SNESLineSearchGetVecs(linesearch, X, Y, F);CHKERRQ(ierr);
33 $     .. determine lambda ..
34 $     ierr = VecAXPY(X, -lambda, Y);CHKERRQ(ierr)
35 $     ierr = SNESLineSearchComputeNorms(linesearch);CHKERRQ(ierr);
36 $     PetscFunctionReturn(0);
37 $  }
38 $
39 $  ...
40 $
41 $  ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
42 $  ierr = SNESLineSearchSetType(linesearch, SNES_LINESEARCH_SHELL);CHKERRQ(ierr);
43 $  ierr = SNESLineSearchShellSetUserFunc(linesearch, shellfunc, PETSC_NULL);CHKERRQ(ierr);
44 
45    Level: advanced
46 
47    .keywords: SNESLineSearch, SNESLineSearchShell, Shell
48 
49    .seealso: SNESLineSearchShellGetUserFunc()
50 @*/
51 PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx) {
52 
53   PetscErrorCode   ierr;
54   PetscBool        flg;
55   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
56   PetscFunctionBegin;
57   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
58   ierr = PetscTypeCompare((PetscObject)linesearch,SNES_LINESEARCH_SHELL,&flg);CHKERRQ(ierr);
59   if (flg) {
60     shell->ctx = ctx;
61     shell->func = func;
62   }
63   PetscFunctionReturn(0);
64 }
65 
66 
67 #undef __FUNCT__
68 #define __FUNCT__ "SNESLineSearchShellGetUserFunc"
69 /*@C
70    SNESLineSearchShellGetUserFunc - Gets the user function and context for the shell implementation.
71 
72    Not Collective
73 
74    Level: advanced
75 
76    .keywords: SNESLineSearch, SNESLineSearchShell, Shell
77 
78    .seealso: SNESLineSearchShellSetUserFunc()
79 @*/
80 PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx) {
81 
82   PetscErrorCode   ierr;
83   PetscBool        flg;
84   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
85   PetscFunctionBegin;
86   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
87   if (func) PetscValidPointer(func,2);
88   if (ctx)  PetscValidPointer(ctx,3);
89   ierr = PetscTypeCompare((PetscObject)linesearch,SNES_LINESEARCH_SHELL,&flg);CHKERRQ(ierr);
90   if (flg) {
91     *ctx  = shell->ctx;
92     *func = shell->func;
93   }
94   PetscFunctionReturn(0);
95 }
96 
97 
98 #undef __FUNCT__
99 #define __FUNCT__ "SNESLineSearchApply_Shell"
100 static PetscErrorCode  SNESLineSearchApply_Shell(SNESLineSearch linesearch)
101 {
102   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
103   PetscErrorCode   ierr;
104 
105   PetscFunctionBegin;
106 
107   /* apply the user function */
108   if (shell->func) {
109     ierr = (*shell->func)(linesearch, shell->ctx);CHKERRQ(ierr);
110   } else {
111     SETERRQ(((PetscObject)linesearch)->comm, PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
112   }
113   PetscFunctionReturn(0);
114 }
115 
116 #undef __FUNCT__
117 #define __FUNCT__ "SNESLineSearchDestroy_Shell"
118 static PetscErrorCode  SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
119 {
120   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
121   PetscErrorCode   ierr;
122 
123   PetscFunctionBegin;
124   ierr = PetscFree(shell);CHKERRQ(ierr);
125   PetscFunctionReturn(0);
126 }
127 
128 #undef __FUNCT__
129 #define __FUNCT__ "SNESLineSearchCreate_Shell"
130 /*MC
131 
132 SNES_LINESEARCH_SHELL - Provides context for a user-provided line search routine.
133 
134 The user routine has one argument, the SNESLineSearch context.  The user uses the interface to
135 extract line search parameters and set them accordingly when the computation is finished.
136 
137 Any of the other line searches may serve as a guide to how this is to be done.  There is also a basic
138 template in the documentation for SNESLineSearchShellSetUserFunc().
139 
140 Level: advanced
141 
142 M*/
143 PETSC_EXTERN_C PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
144 {
145 
146   SNESLineSearch_Shell     *shell;
147   PetscErrorCode       ierr;
148 
149   PetscFunctionBegin;
150 
151   linesearch->ops->apply          = SNESLineSearchApply_Shell;
152   linesearch->ops->destroy        = SNESLineSearchDestroy_Shell;
153   linesearch->ops->setfromoptions = PETSC_NULL;
154   linesearch->ops->reset          = PETSC_NULL;
155   linesearch->ops->view           = PETSC_NULL;
156   linesearch->ops->setup          = PETSC_NULL;
157 
158   ierr = PetscNewLog(linesearch, SNESLineSearch_Shell, &shell);CHKERRQ(ierr);
159   linesearch->data = (void*) shell;
160   PetscFunctionReturn(0);
161 }
162