Actual source code: linesearchnone.c

  1: #include <petsc/private/linesearchimpl.h>
  2: #include <petsc/private/snesimpl.h>

  4: static PetscErrorCode SNESLineSearchApply_None(SNESLineSearch linesearch)
  5: {
  6:   PetscBool changed_y, changed_w;
  7:   Vec       X, F, Y, W;
  8:   SNES      snes;
  9:   PetscReal gnorm, xnorm, ynorm, lambda, fnorm = 0.0;

 11:   PetscFunctionBegin;
 12:   PetscCall(SNESLineSearchGetVecs(linesearch, &X, &F, &Y, &W, NULL));
 13:   PetscCall(SNESLineSearchGetNorms(linesearch, &xnorm, &gnorm, &ynorm));
 14:   /* SNESLineSearchSetUp() sets linesearch->lambda to linesearch->damping */
 15:   PetscCall(SNESLineSearchGetLambda(linesearch, &lambda));
 16:   PetscCall(SNESLineSearchGetSNES(linesearch, &snes));
 17:   PetscCall(SNESLineSearchSetReason(linesearch, SNES_LINESEARCH_SUCCEEDED));

 19:   /* precheck */
 20:   PetscCall(SNESLineSearchPreCheck(linesearch, X, Y, &changed_y));

 22:   /* update */
 23:   PetscCall(VecWAXPY(W, -lambda, Y, X));
 24:   if (linesearch->ops->viproject) PetscCall((*linesearch->ops->viproject)(snes, W));

 26:   /* postcheck */
 27:   PetscCall(SNESLineSearchPostCheck(linesearch, X, Y, W, &changed_y, &changed_w));
 28:   if (changed_y) {
 29:     if (!changed_w) PetscCall(VecWAXPY(W, -lambda, Y, X));
 30:     if (linesearch->ops->viproject) PetscCall((*linesearch->ops->viproject)(snes, W));
 31:   }
 32:   if (linesearch->norms || snes->iter < snes->max_its - 1) {
 33:     PetscCall((*linesearch->ops->snesfunc)(snes, W, F));
 34:     PetscCall(VecNorm(F, NORM_2, &fnorm));
 35:     SNESLineSearchCheckFunctionDomainError(snes, linesearch, fnorm);
 36:   }
 37:   if (linesearch->norms) {
 38:     PetscCall(VecNormBegin(Y, NORM_2, &linesearch->ynorm));
 39:     PetscCall(VecNormBegin(W, NORM_2, &linesearch->xnorm));
 40:     PetscCall(VecNormEnd(Y, NORM_2, &linesearch->ynorm));
 41:     PetscCall(VecNormEnd(W, NORM_2, &linesearch->xnorm));

 43:     if (linesearch->ops->vinorm) {
 44:       linesearch->fnorm = gnorm;

 46:       PetscCall((*linesearch->ops->vinorm)(snes, F, W, &linesearch->fnorm));
 47:     } else linesearch->fnorm = fnorm;
 48:   }

 50:   /* copy the solution over */
 51:   PetscCall(VecCopy(W, X));
 52:   PetscFunctionReturn(PETSC_SUCCESS);
 53: }

 55: static PetscErrorCode SNESLineSearchView_None(SNESLineSearch linesearch, PetscViewer viewer)
 56: {
 57:   PetscBool isascii;

 59:   PetscFunctionBegin;
 60:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
 61:   if (isascii && linesearch->damping != 1.) PetscCall(PetscViewerASCIIPrintf(viewer, "  damping factor: %g\n", (double)linesearch->damping));
 62:   PetscFunctionReturn(PETSC_SUCCESS);
 63: }

 65: /*MC
 66:    SNESLINESEARCHNONE - This line search implementation is not a line
 67:    search at all; it simply uses the full step $x_{k+1} = x_k - \lambda Y_k$.
 68:    $\lambda=1$ by default, but it can be configured to be a constant damping factor using `-snes_linesearch_damping` or `SNESLineSearchSetDamping()`.
 69:    Thus, this routine is intended for methods with well-scaled updates; i.e. Newton's method (`SNESNEWTONLS`), on
 70:    well-behaved problems.

 72:    Options Database Keys:
 73: +  -snes_linesearch_damping damping    - step length is scaled by this factor, i.e. this is the $\lambda$ above
 74: -  -snes_linesearch_norms (true|false) - whether to compute norms or not (`SNESLineSearchSetComputeNorms()`)

 76:    Level: advanced

 78:    Note:
 79:    For methods with ill-scaled updates (`SNESNRICHARDSON`, `SNESNCG`), a small
 80:    damping parameter may yield satisfactory, but slow convergence, despite
 81:    the lack of the line search.

 83: .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchType`, `SNESGetLineSearch()`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`, `SNESLineSearchSetDamping()`, `SNESLineSearchSetComputeNorms()`
 84: M*/
 85: PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_None(SNESLineSearch linesearch)
 86: {
 87:   PetscFunctionBegin;
 88:   linesearch->ops->apply          = SNESLineSearchApply_None;
 89:   linesearch->ops->destroy        = NULL;
 90:   linesearch->ops->setfromoptions = NULL;
 91:   linesearch->ops->reset          = NULL;
 92:   linesearch->ops->view           = SNESLineSearchView_None;
 93:   linesearch->ops->setup          = NULL;
 94:   PetscFunctionReturn(PETSC_SUCCESS);
 95: }