Date: 2025-03-29T05:58:40+00:00

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:   PetscFunctionBegin;
     13:   PetscCall(SNESLineSearchGetVecs(linesearch, &X, &F, &Y, &W, NULL));
     14:   PetscCall(SNESLineSearchGetNorms(linesearch, &xnorm, &gnorm, &ynorm));
     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(SNESGetFunctionDomainError(snes, &domainerror));
     35:     if (domainerror) {
     36:       PetscCall(SNESLineSearchSetReason(linesearch, SNES_LINESEARCH_FAILED_DOMAIN));
     37:       PetscFunctionReturn(PETSC_SUCCESS);
     38:     }
     39:   }
     40:   if (linesearch->norms) {
     41:     if (!linesearch->ops->vinorm) PetscCall(VecNormBegin(F, NORM_2, &linesearch->fnorm));
     42:     PetscCall(VecNormBegin(Y, NORM_2, &linesearch->ynorm));
     43:     PetscCall(VecNormBegin(W, NORM_2, &linesearch->xnorm));
     44:     if (!linesearch->ops->vinorm) PetscCall(VecNormEnd(F, NORM_2, &linesearch->fnorm));
     45:     PetscCall(VecNormEnd(Y, NORM_2, &linesearch->ynorm));
     46:     PetscCall(VecNormEnd(W, NORM_2, &linesearch->xnorm));

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

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

     57:   /* copy the solution over */
     58:   PetscCall(VecCopy(W, X));
     59:   PetscFunctionReturn(PETSC_SUCCESS);
     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 on entry to the line search, 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: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchType`, `SNESGetLineSearch()`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`, `SNESLineSearchSetDamping()`, `SNESLineSearchSetComputeNorms()`
     80: M*/
     81: PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Basic(SNESLineSearch linesearch)
     82: {
     83:   PetscFunctionBegin;
     84:   linesearch->ops->apply          = SNESLineSearchApply_Basic;
     85:   linesearch->ops->destroy        = NULL;
     86:   linesearch->ops->setfromoptions = NULL;
     87:   linesearch->ops->reset          = NULL;
     88:   linesearch->ops->view           = NULL;
     89:   linesearch->ops->setup          = NULL;
     90:   PetscFunctionReturn(PETSC_SUCCESS);
     91: }