xref: /petsc/src/snes/linesearch/impls/shell/linesearchshell.c (revision f5f7c1b961d39659762614d2cf317c920ddf3bd2)
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 
60   PetscFunctionBegin;
61   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
62   ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr);
63   if (flg) {
64     shell->ctx = ctx;
65     shell->func = func;
66   }
67   PetscFunctionReturn(0);
68 }
69 
70 
71 #undef __FUNCT__
72 #define __FUNCT__ "SNESLineSearchShellGetUserFunc"
73 /*@C
74    SNESLineSearchShellGetUserFunc - Gets the user function and context for the shell implementation.
75 
76    Not Collective
77 
78    Level: advanced
79 
80    .keywords: SNESLineSearch, get, Shell, user, function
81 
82    .seealso: SNESLineSearchShellSetUserFunc()
83 @*/
84 PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx)
85 {
86   PetscErrorCode       ierr;
87   PetscBool            flg;
88   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
89 
90   PetscFunctionBegin;
91   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
92   if (func) PetscValidPointer(func,2);
93   if (ctx)  PetscValidPointer(ctx,3);
94   ierr = PetscObjectTypeCompare((PetscObject)linesearch,SNESLINESEARCHSHELL,&flg);CHKERRQ(ierr);
95   if (flg) {
96     *ctx  = shell->ctx;
97     *func = shell->func;
98   }
99   PetscFunctionReturn(0);
100 }
101 
102 
103 #undef __FUNCT__
104 #define __FUNCT__ "SNESLineSearchApply_Shell"
105 static PetscErrorCode  SNESLineSearchApply_Shell(SNESLineSearch linesearch)
106 {
107   SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
108   PetscErrorCode       ierr;
109 
110   PetscFunctionBegin;
111 
112   /* apply the user function */
113   if (shell->func) {
114     ierr = (*shell->func)(linesearch, shell->ctx);CHKERRQ(ierr);
115   } else SETERRQ(((PetscObject)linesearch)->comm, 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 = PETSC_NULL;
156   linesearch->ops->reset          = PETSC_NULL;
157   linesearch->ops->view           = PETSC_NULL;
158   linesearch->ops->setup          = PETSC_NULL;
159 
160   ierr = PetscNewLog(linesearch, SNESLineSearch_Shell, &shell);CHKERRQ(ierr);
161   linesearch->data = (void*) shell;
162   PetscFunctionReturn(0);
163 }
164