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: }