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: // PetscClangLinter pragma disable: -fdoc-param-list-func-parameter-documentation
10: /*@C
11: SNESLineSearchShellSetUserFunc - Sets the user function for the `SNESLINESEARCHSHELL` implementation.
13: Not Collective
15: Input Parameters:
16: + linesearch - `SNESLineSearch` context
17: . func - function implementing the linesearch shell.
18: - ctx - context for func
20: Calling sequence of `func`:
21: $ PetscErrorCode func(SNESLinesearch ls, void *ctx)
22: + ls - the linesearch instance
23: - ctx - the above mentioned context
25: Usage\:
26: .vb
27: PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx)
28: {
29: Vec X,Y,F,W,G;
30: SNES snes;
31: PetscFunctionBegin;
32: PetscCall(SNESLineSearchGetSNES(linesearch,&snes));
33: PetscCall(SNESLineSearchSetReason(linesearch,SNES_LINESEARCH_SUCCEEDED));
34: PetscCall(SNESLineSearchGetVecs(linesearch,&X,&F,&Y,&W,&G));
35: // determine lambda using W and G as work vecs..
36: PetscCall(VecAXPY(X,-lambda,Y));
37: PetscCall(SNESComputeFunction(snes,X,F));
38: PetscCall(SNESLineSearchComputeNorms(linesearch));
39: PetscFunctionReturn(PETSC_SUCCESS);
40: }
42: PetscCall(SNESGetLineSearch(snes, &linesearch));
43: PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
44: PetscCall(SNESLineSearchShellSetUserFunc(linesearch, shellfunc, NULL));
45: .ve
47: Level: advanced
49: .seealso: [](ch_snes), `SNESLineSearchShellGetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`
50: @*/
51: PetscErrorCode SNESLineSearchShellSetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc func, void *ctx)
52: {
53: PetscBool flg;
54: SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
56: PetscFunctionBegin;
58: PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
59: if (flg) {
60: shell->ctx = ctx;
61: shell->func = func;
62: }
63: PetscFunctionReturn(PETSC_SUCCESS);
64: }
66: /*@C
67: SNESLineSearchShellGetUserFunc - Gets the user function and context for the `SNESLINESEARCHSHELL`
69: Not Collective
71: Input Parameter:
72: . linesearch - the line search object
74: Output Parameters:
75: + func - the user function; can be `NULL` if it is not needed
76: - ctx - the user function context; can be `NULL` if it is not needed
78: Level: advanced
80: .seealso: [](ch_snes), `SNESLineSearchShellSetUserFunc()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`
81: @*/
82: PetscErrorCode SNESLineSearchShellGetUserFunc(SNESLineSearch linesearch, SNESLineSearchUserFunc *func, void **ctx)
83: {
84: PetscBool flg;
85: SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
87: PetscFunctionBegin;
89: if (func) PetscAssertPointer(func, 2);
90: if (ctx) PetscAssertPointer(ctx, 3);
91: PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
92: if (flg) {
93: if (func) *func = shell->func;
94: if (ctx) *ctx = shell->ctx;
95: }
96: PetscFunctionReturn(PETSC_SUCCESS);
97: }
99: static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch)
100: {
101: SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
103: PetscFunctionBegin;
104: /* apply the user function */
105: if (shell->func) {
106: PetscCall((*shell->func)(linesearch, shell->ctx));
107: } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetUserFunc");
108: PetscFunctionReturn(PETSC_SUCCESS);
109: }
111: static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
112: {
113: SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
115: PetscFunctionBegin;
116: PetscCall(PetscFree(shell));
117: PetscFunctionReturn(PETSC_SUCCESS);
118: }
120: /*MC
121: SNESLINESEARCHSHELL - Provides context for a user-provided line search routine.
123: The user routine has one argument, the `SNESLineSearch` context. The user uses the interface to
124: extract line search parameters and set them accordingly when the computation is finished.
126: Any of the other line searches may serve as a guide to how this is to be done. There is also a basic
127: template in the documentation for `SNESLineSearchShellSetUserFunc()`.
129: Level: advanced
131: .seealso: [](ch_snes), `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`
132: 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: }