1 #include <petsc/private/linesearchimpl.h>
2 #include <petsc/private/snesimpl.h>
3
4 typedef struct {
5 SNESLineSearchShellApplyFn *func;
6 void *ctx;
7 } SNESLineSearch_Shell;
8
9 // PetscClangLinter pragma disable: -fdoc-param-list-func-parameter-documentation
10 /*@C
11 SNESLineSearchShellSetApply - Sets the apply function for the `SNESLINESEARCHSHELL` implementation.
12
13 Not Collective
14
15 Input Parameters:
16 + linesearch - `SNESLineSearch` context
17 . func - function implementing the linesearch shell, see `SNESLineSearchShellApplyFn` for calling sequence
18 - ctx - context for func
19
20 Usage\:
21 .vb
22 PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx)
23 {
24 Vec X,Y,F,W,G;
25 SNES snes;
26
27 PetscFunctionBegin;
28 PetscCall(SNESLineSearchGetSNES(linesearch,&snes));
29 PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED));
30 PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G));
31 // determine lambda using W and G as work vecs..
32 PetscCall(VecAXPY(X,-lambda,Y));
33 PetscCall(SNESComputeFunction(snes,X,F));
34 PetscCall(SNESLineSearchComputeNorms(linesearch));
35 PetscFunctionReturn(PETSC_SUCCESS);
36 }
37
38 PetscCall(SNESGetLineSearch(snes, &linesearch));
39 PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
40 PetscCall(SNESLineSearchShellSetApply(linesearch, shellfunc, NULL));
41 .ve
42
43 Level: advanced
44
45 .seealso: [](ch_snes), `SNESLineSearchShellGetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`,
46 `SNESLineSearchShellApplyFn`
47 @*/
SNESLineSearchShellSetApply(SNESLineSearch linesearch,SNESLineSearchShellApplyFn * func,PetscCtx ctx)48 PetscErrorCode SNESLineSearchShellSetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn *func, PetscCtx ctx)
49 {
50 PetscBool flg;
51 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
52
53 PetscFunctionBegin;
54 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
55 PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
56 if (flg) {
57 shell->ctx = ctx;
58 shell->func = func;
59 }
60 PetscFunctionReturn(PETSC_SUCCESS);
61 }
62
63 /*@C
64 SNESLineSearchShellGetApply - Gets the apply function and context for the `SNESLINESEARCHSHELL`
65
66 Not Collective
67
68 Input Parameter:
69 . linesearch - the line search object
70
71 Output Parameters:
72 + func - the user function; can be `NULL` if it is not needed, see `SNESLineSearchShellApplyFn` for calling sequence
73 - ctx - the user function context; can be `NULL` if it is not needed
74
75 Level: advanced
76
77 .seealso: [](ch_snes), `SNESLineSearchShellSetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`,
78 `SNESLineSearchShellApplyFn`
79 @*/
SNESLineSearchShellGetApply(SNESLineSearch linesearch,SNESLineSearchShellApplyFn ** func,PetscCtxRt ctx)80 PetscErrorCode SNESLineSearchShellGetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn **func, PetscCtxRt ctx)
81 {
82 PetscBool flg;
83 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
84
85 PetscFunctionBegin;
86 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
87 if (func) PetscAssertPointer(func, 2);
88 if (ctx) PetscAssertPointer(ctx, 3);
89 PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
90 if (flg) {
91 if (func) *func = shell->func;
92 if (ctx) *(void **)ctx = shell->ctx;
93 }
94 PetscFunctionReturn(PETSC_SUCCESS);
95 }
96
SNESLineSearchApply_Shell(SNESLineSearch linesearch)97 static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch)
98 {
99 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
100
101 PetscFunctionBegin;
102 /* apply the user function */
103 PetscCheck(shell->func, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetApply()");
104 PetscCall((*shell->func)(linesearch, shell->ctx));
105 PetscFunctionReturn(PETSC_SUCCESS);
106 }
107
SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)108 static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
109 {
110 SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
111
112 PetscFunctionBegin;
113 PetscCall(PetscFree(shell));
114 PetscFunctionReturn(PETSC_SUCCESS);
115 }
116
117 /*MC
118 SNESLINESEARCHSHELL - Provides an API for a user-provided line search routine.
119
120 Any of the other line searches may serve as a guide to how this is to be done. There is also a basic
121 template in the documentation for `SNESLineSearchShellSetApply()`.
122
123 Level: advanced
124
125 .seealso: [](ch_snes), `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`, `SNESLineSearchShellSetApply()`,
126 `SNESLineSearchShellApplyFn`
127 M*/
128
SNESLineSearchCreate_Shell(SNESLineSearch linesearch)129 PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
130 {
131 SNESLineSearch_Shell *shell;
132
133 PetscFunctionBegin;
134 linesearch->ops->apply = SNESLineSearchApply_Shell;
135 linesearch->ops->destroy = SNESLineSearchDestroy_Shell;
136 linesearch->ops->setfromoptions = NULL;
137 linesearch->ops->reset = NULL;
138 linesearch->ops->view = NULL;
139 linesearch->ops->setup = NULL;
140
141 PetscCall(PetscNew(&shell));
142
143 linesearch->data = (void *)shell;
144 PetscFunctionReturn(PETSC_SUCCESS);
145 }
146