xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision 519f805a543c2a7f195bcba21173bb2cdfadb956)
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, PETSC_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 
113   /* apply the user function */
114   if (shell->func) {
115     ierr = (*shell->func)(linesearch, shell->ctx);CHKERRQ(ierr);
116   } else SETERRQ(((PetscObject)linesearch)->comm, PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
117   PetscFunctionReturn(0);
118 }
119 
120 #undef __FUNCT__
121 #define __FUNCT__ "SNESLineSearchDestroy_Shell"
122 static PetscErrorCode  SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
123 {
124   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
125   PetscErrorCode       ierr;
126 
127   PetscFunctionBegin;
128   ierr = PetscFree(shell);CHKERRQ(ierr);
129   PetscFunctionReturn(0);
130 }
131 
132 #undef __FUNCT__
133 #define __FUNCT__ "SNESLineSearchCreate_Shell"
134 /*MC
135 
136 SNESLINESEARCHSHELL - Provides context for a user-provided line search routine.
137 
138 The user routine has one argument, the SNESLineSearch context.  The user uses the interface to
139 extract line search parameters and set them accordingly when the computation is finished.
140 
141 Any of the other line searches may serve as a guide to how this is to be done.  There is also a basic
142 template in the documentation for SNESLineSearchShellSetUserFunc().
143 
144 Level: advanced
145 
146 M*/
147 PETSC_EXTERN_C PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
148 {
149 
150   SNESLineSearch_Shell *shell;
151   PetscErrorCode       ierr;
152 
153   PetscFunctionBegin;
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