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