Actual source code: linesearchshell.c
1: #include <petsc/private/linesearchimpl.h>
2: #include <petsc/private/snesimpl.h>
4: typedef struct {
5: SNESLineSearchUserFunc func;
6: void *ctx;
7: } SNESLineSearch_Shell;
9: /*@C
10: SNESLineSearchShellSetUserFunc - Sets the user function for the `SNESLINESEARCHSHELL` implementation.
12: Not Collective
14: Input Parameters:
15: + linesearch - `SNESLineSearch` context
16: . func - function implementing the linesearch shell.
17: - ctx - context for func
19: Calling sequence of `func`:
20: $ PetscErrorCode func(SNESLinesearch, void *ctx)
21: + linesearch - the linesearch instance
22: - ctx - the above mentioned context
24: Usage:
25: .vb
26: PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx)
27: {
28: Vec X,Y,F,W,G;
29: SNES snes;
30: PetscFunctionBegin;
31: PetscCall(SNESLineSearchGetSNES(linesearch,&snes));
32: PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED));
33: PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G));
34: .. determine lambda using W and G as work vecs..
35: PetscCall(VecAXPY(X,-lambda,Y));
36: PetscCall(SNESComputeFunction(snes,X,F));
37: PetscCall(SNESLineSearchComputeNorms(linesearch));
38: PetscFunctionReturn(PETSC_SUCCESS);
39: }
41: ...
43: PetscCall(SNESGetLineSearch(snes, &linesearch));
44: PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
45: PetscCall(SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL));
46: .ve
48: Level: advanced
50: .seealso: `SNESLineSearchShellGetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`
51: @*/
52: PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx)
53: {
54: PetscBool flg;
55: SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
57: PetscFunctionBegin;
59: PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
60: if (flg) {
61: shell->ctx = ctx;
62: shell->func = func;
63: }
64: PetscFunctionReturn(PETSC_SUCCESS);
65: }
67: /*@C
68: SNESLineSearchShellGetUserFunc - Gets the user function and context for the `SNESLINESEARCHSHELL`
70: Not Collective
72: Input Parameter:
73: . linesearch - the line search object
75: Output Parameters:
76: + func - the user function; can be NULL if you do not want it
77: - ctx - the user function context; can be NULL if you do not want it
79: Level: advanced
81: .seealso: `SNESLineSearchShellSetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`
82: @*/
83: PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx)
84: {
85: PetscBool flg;
86: SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
88: PetscFunctionBegin;
92: PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
93: if (flg) {
94: if (func) *func = shell->func;
95: if (ctx) *ctx = shell->ctx;
96: }
97: PetscFunctionReturn(PETSC_SUCCESS);
98: }
100: static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch)
101: {
102: SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
104: PetscFunctionBegin;
105: /* apply the user function */
106: if (shell->func) {
107: PetscCall((*shell->func)(linesearch, shell->ctx));
108: } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
109: PetscFunctionReturn(PETSC_SUCCESS);
110: }
112: static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
113: {
114: SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
116: PetscFunctionBegin;
117: PetscCall(PetscFree(shell));
118: PetscFunctionReturn(PETSC_SUCCESS);
119: }
121: /*MC
122: SNESLINESEARCHSHELL - Provides context for a user-provided line search routine.
124: The user routine has one argument, the SNESLineSearch context. The user uses the interface to
125: extract line search parameters and set them accordingly when the computation is finished.
127: Any of the other line searches may serve as a guide to how this is to be done. There is also a basic
128: template in the documentation for SNESLineSearchShellSetUserFunc().
130: Level: advanced
132: .seealso: `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`
133: M*/
134: PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
135: {
136: SNESLineSearch_Shell *shell;
138: PetscFunctionBegin;
139: linesearch->ops->apply = SNESLineSearchApply_Shell;
140: linesearch->ops->destroy = SNESLineSearchDestroy_Shell;
141: linesearch->ops->setfromoptions = NULL;
142: linesearch->ops->reset = NULL;
143: linesearch->ops->view = NULL;
144: linesearch->ops->setup = NULL;
146: PetscCall(PetscNew(&shell));
148: linesearch->data = (void *)shell;
149: PetscFunctionReturn(PETSC_SUCCESS);
150: }