Actual source code: linesearchbasic.c

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

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

 12:   SNESLineSearchGetVecs(linesearch, &X, &F, &Y, &W, NULL);
 13:   SNESLineSearchGetNorms(linesearch, &xnorm, &gnorm, &ynorm);
 14:   SNESLineSearchGetLambda(linesearch, &lambda);
 15:   SNESLineSearchGetSNES(linesearch, &snes);
 16:   SNESLineSearchSetReason(linesearch, SNES_LINESEARCH_SUCCEEDED);

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

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

 25:   /* postcheck */
 26:   SNESLineSearchPostCheck(linesearch, X, Y, W, &changed_y, &changed_w);
 27:   if (changed_y) {
 28:     VecWAXPY(W, -lambda, Y, X);
 29:     if (linesearch->ops->viproject) (*linesearch->ops->viproject)(snes, W);
 30:   }
 31:   if (linesearch->norms || snes->iter < snes->max_its - 1) {
 32:     (*linesearch->ops->snesfunc)(snes, W, F);
 33:     SNESGetFunctionDomainError(snes, &domainerror);
 34:     if (domainerror) {
 35:       SNESLineSearchSetReason(linesearch, SNES_LINESEARCH_FAILED_DOMAIN);
 36:       return 0;
 37:     }
 38:   }

 40:   if (linesearch->norms) {
 41:     if (!linesearch->ops->vinorm) VecNormBegin(F, NORM_2, &linesearch->fnorm);
 42:     VecNormBegin(Y, NORM_2, &linesearch->ynorm);
 43:     VecNormBegin(W, NORM_2, &linesearch->xnorm);
 44:     if (!linesearch->ops->vinorm) VecNormEnd(F, NORM_2, &linesearch->fnorm);
 45:     VecNormEnd(Y, NORM_2, &linesearch->ynorm);
 46:     VecNormEnd(W, NORM_2, &linesearch->xnorm);

 48:     if (linesearch->ops->vinorm) {
 49:       linesearch->fnorm = gnorm;

 51:       (*linesearch->ops->vinorm)(snes, F, W, &linesearch->fnorm);
 52:     } else {
 53:       VecNorm(F, NORM_2, &linesearch->fnorm);
 54:     }
 55:   }

 57:   /* copy the solution over */
 58:   VecCopy(W, X);
 59:   return 0;
 60: }

 62: /*MC
 63:    SNESLINESEARCHBASIC - This line search implementation is not a line
 64:    search at all; it simply uses the full step.  Thus, this routine is intended
 65:    for methods with well-scaled updates; i.e. Newton's method (`SNESNEWTONLS`), on
 66:    well-behaved problems. Also named as `SNESLINESEARCHNONE`

 68:    Options Database Keys:
 69: +   -snes_linesearch_damping <damping> - search vector is scaled by this amount, default is 1.0
 70: -   -snes_linesearch_norms <flag> - whether to compute norms or not, default is true (SNESLineSearchSetComputeNorms())

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

 77:    Level: advanced

 79: .seealso: `SNES`, `SNESLineSearch`, `SNESLineSearchType`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`, `SNESLineSearchSetDamping()`, `SNESLineSearchSetComputeNorms()`
 80: M*/
 81: PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Basic(SNESLineSearch linesearch)
 82: {
 83:   linesearch->ops->apply          = SNESLineSearchApply_Basic;
 84:   linesearch->ops->destroy        = NULL;
 85:   linesearch->ops->setfromoptions = NULL;
 86:   linesearch->ops->reset          = NULL;
 87:   linesearch->ops->view           = NULL;
 88:   linesearch->ops->setup          = NULL;
 89:   return 0;
 90: }