Actual source code: linesearchshell.c
1: #include <petsc/private/linesearchimpl.h>
2: #include <petsc/private/snesimpl.h>
4: typedef struct {
5: SNESLineSearchShellApplyFn *func;
6: void *ctx;
7: } SNESLineSearch_Shell;
9: // PetscClangLinter pragma disable: -fdoc-param-list-func-parameter-documentation
10: /*@C
11: SNESLineSearchShellSetApply - Sets the apply function for the `SNESLINESEARCHSHELL` implementation.
13: Not Collective
15: Input Parameters:
16: + linesearch - `SNESLineSearch` context
17: . func - function implementing the linesearch shell, see `SNESLineSearchShellApplyFn` for calling sequence
18: - ctx - context for func
20: Usage\:
21: .vb
22: PetscErrorCode shellfunc(SNESLineSearch linesearch,void * ctx)
23: {
24: Vec X,Y,F,W,G;
25: SNES snes;
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: }
38: PetscCall(SNESGetLineSearch(snes, &linesearch));
39: PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHSHELL));
40: PetscCall(SNESLineSearchShellSetApply(linesearch, shellfunc, NULL));
41: .ve
43: Level: advanced
45: .seealso: [](ch_snes), `SNESLineSearchShellGetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`,
46: `SNESLineSearchShellApplyFn`
47: @*/
48: PetscErrorCode SNESLineSearchShellSetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn *func, void *ctx)
49: {
50: PetscBool flg;
51: SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
53: PetscFunctionBegin;
55: PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, SNESLINESEARCHSHELL, &flg));
56: if (flg) {
57: shell->ctx = ctx;
58: shell->func = func;
59: }
60: PetscFunctionReturn(PETSC_SUCCESS);
61: }
63: /*@C
64: SNESLineSearchShellGetApply - Gets the apply function and context for the `SNESLINESEARCHSHELL`
66: Not Collective
68: Input Parameter:
69: . linesearch - the line search object
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
75: Level: advanced
77: .seealso: [](ch_snes), `SNESLineSearchShellSetApply()`, `SNESLINESEARCHSHELL`, `SNESLineSearchType`, `SNESLineSearch`,
78: `SNESLineSearchShellApplyFn`
79: @*/
80: PetscErrorCode SNESLineSearchShellGetApply(SNESLineSearch linesearch, SNESLineSearchShellApplyFn **func, void **ctx)
81: {
82: PetscBool flg;
83: SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
85: PetscFunctionBegin;
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) *ctx = shell->ctx;
93: }
94: PetscFunctionReturn(PETSC_SUCCESS);
95: }
97: static PetscErrorCode SNESLineSearchApply_Shell(SNESLineSearch linesearch)
98: {
99: SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
101: PetscFunctionBegin;
102: /* apply the user function */
103: if (shell->func) {
104: PetscCall((*shell->func)(linesearch, shell->ctx));
105: } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "SNESLineSearchShell needs to have a shell function set with SNESLineSearchShellSetApply()");
106: PetscFunctionReturn(PETSC_SUCCESS);
107: }
109: static PetscErrorCode SNESLineSearchDestroy_Shell(SNESLineSearch linesearch)
110: {
111: SNESLineSearch_Shell *shell = (SNESLineSearch_Shell *)linesearch->data;
113: PetscFunctionBegin;
114: PetscCall(PetscFree(shell));
115: PetscFunctionReturn(PETSC_SUCCESS);
116: }
118: /*MC
119: SNESLINESEARCHSHELL - Provides an API for a user-provided line search routine.
121: Any of the other line searches may serve as a guide to how this is to be done. There is also a basic
122: template in the documentation for `SNESLineSearchShellSetApply()`.
124: Level: advanced
126: .seealso: [](ch_snes), `SNESLineSearch`, `SNES`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`, `SNESLineSearchShellSetApply()`,
127: `SNESLineSearchShellApplyFn`
128: M*/
130: PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Shell(SNESLineSearch linesearch)
131: {
132: SNESLineSearch_Shell *shell;
134: PetscFunctionBegin;
135: linesearch->ops->apply = SNESLineSearchApply_Shell;
136: linesearch->ops->destroy = SNESLineSearchDestroy_Shell;
137: linesearch->ops->setfromoptions = NULL;
138: linesearch->ops->reset = NULL;
139: linesearch->ops->view = NULL;
140: linesearch->ops->setup = NULL;
142: PetscCall(PetscNew(&shell));
144: linesearch->data = (void *)shell;
145: PetscFunctionReturn(PETSC_SUCCESS);
146: }