xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 5a4671aecb2b1c6017089db16b143293c51b8cb0)
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 $     Vec  X, Y, F, W, G;
30 $     SNES snes;
31 $     PetscFunctionBegin;
32 $     ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr);
33 $     ierr = SNESLineSearchSetSuccess(linesearch, PETSC_TRUE);CHKERRQ(ierr);
34 $     ierr = SNESLineSearchGetVecs(linesearch, X, Y, F, W, G);CHKERRQ(ierr);
35 $     .. determine lambda using W and G as work vecs..
36 $     ierr = VecAXPY(X, -lambda, Y);CHKERRQ(ierr);
37 $     ierr = SNESComputeFunction(snes, X, F);CHKERRQ(ierr);
38 $     ierr = SNESLineSearchComputeNorms(linesearch);CHKERRQ(ierr);
39 $     PetscFunctionReturn(0);
40 $  }
41 $
42 $  ...
43 $
44 $  ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
45 $  ierr = SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL);CHKERRQ(ierr);
46 $  ierr = SNESLineSearchShellSetUserFunc(linesearch, shellfunc, PETSC_NULL);CHKERRQ(ierr);
47 
48    Level: advanced
49 
50    .keywords: SNESLineSearch, Shell, user, function, set
51 
52    .seealso: SNESLineSearchShellGetUserFunc(), SNESLINESEARCHSHELL
53 @*/
54 PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx) {
55 
56   PetscErrorCode   ierr;
57   PetscBool        flg;
58   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
59   PetscFunctionBegin;
60   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
61   ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr);
62   if (flg) {
63     shell->ctx = ctx;
64     shell->func = func;
65   }
66   PetscFunctionReturn(0);
67 }
68 
69 
70 #undef __FUNCT__
71 #define __FUNCT__ "SNESLineSearchShellGetUserFunc"
72 /*@C
73    SNESLineSearchShellGetUserFunc - Gets the user function and context for the shell implementation.
74 
75    Not Collective
76 
77    Level: advanced
78 
79    .keywords: SNESLineSearch, get, Shell, user, function
80 
81    .seealso: SNESLineSearchShellSetUserFunc()
82 @*/
83 PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx) {
84 
85   PetscErrorCode   ierr;
86   PetscBool        flg;
87   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
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     *ctx  = shell->ctx;
95     *func = shell->func;
96   }
97   PetscFunctionReturn(0);
98 }
99 
100 
101 #undef __FUNCT__
102 #define __FUNCT__ "SNESLineSearchApply_Shell"
103 static PetscErrorCode  SNESLineSearchApply_Shell(SNESLineSearch linesearch)
104 {
105   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
106   PetscErrorCode   ierr;
107 
108   PetscFunctionBegin;
109 
110   /* apply the user function */
111   if (shell->func) {
112     ierr = (*shell->func)(linesearch, shell->ctx);CHKERRQ(ierr);
113   } else {
114     SETERRQ(((PetscObject)linesearch)->comm, PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
115   }
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 
154   linesearch->ops->apply          = SNESLineSearchApply_Shell;
155   linesearch->ops->destroy        = SNESLineSearchDestroy_Shell;
156   linesearch->ops->setfromoptions = PETSC_NULL;
157   linesearch->ops->reset          = PETSC_NULL;
158   linesearch->ops->view           = PETSC_NULL;
159   linesearch->ops->setup          = PETSC_NULL;
160 
161   ierr = PetscNewLog(linesearch, SNESLineSearch_Shell, &shell);CHKERRQ(ierr);
162   linesearch->data = (void*) shell;
163   PetscFunctionReturn(0);
164 }
165