xref: /petsc/src/snes/linesearch/impls/basic/linesearchbasic.c (revision c4762a1b19cd2af06abeed90e8f9d34fb975dd94)
1 #include <petsc/private/linesearchimpl.h>
2 #include <petsc/private/snesimpl.h>
3 
4 static PetscErrorCode  SNESLineSearchApply_Basic(SNESLineSearch linesearch)
5 {
6   PetscBool      changed_y, changed_w;
7   PetscErrorCode ierr;
8   Vec            X, F, Y, W;
9   SNES           snes;
10   PetscReal      gnorm, xnorm, ynorm, lambda;
11   PetscBool      domainerror;
12 
13   PetscFunctionBegin;
14   ierr = SNESLineSearchGetVecs(linesearch, &X, &F, &Y, &W, NULL);CHKERRQ(ierr);
15   ierr = SNESLineSearchGetNorms(linesearch, &xnorm, &gnorm, &ynorm);CHKERRQ(ierr);
16   ierr = SNESLineSearchGetLambda(linesearch, &lambda);CHKERRQ(ierr);
17   ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr);
18   ierr = SNESLineSearchSetReason(linesearch, SNES_LINESEARCH_SUCCEEDED);CHKERRQ(ierr);
19 
20   /* precheck */
21   ierr = SNESLineSearchPreCheck(linesearch,X,Y,&changed_y);CHKERRQ(ierr);
22 
23   /* update */
24   ierr = VecWAXPY(W,-lambda,Y,X);CHKERRQ(ierr);
25   if (linesearch->ops->viproject) {
26     ierr = (*linesearch->ops->viproject)(snes, W);CHKERRQ(ierr);
27   }
28 
29   /* postcheck */
30   ierr = SNESLineSearchPostCheck(linesearch,X,Y,W,&changed_y,&changed_w);CHKERRQ(ierr);
31   if (changed_y) {
32     ierr = VecWAXPY(W,-lambda,Y,X);CHKERRQ(ierr);
33     if (linesearch->ops->viproject) {
34       ierr = (*linesearch->ops->viproject)(snes, W);CHKERRQ(ierr);
35     }
36   }
37   if (linesearch->norms || snes->iter < snes->max_its-1) {
38     ierr = (*linesearch->ops->snesfunc)(snes,W,F);CHKERRQ(ierr);
39     ierr = SNESGetFunctionDomainError(snes, &domainerror);CHKERRQ(ierr);
40     if (domainerror) {
41       ierr = SNESLineSearchSetReason(linesearch, SNES_LINESEARCH_FAILED_DOMAIN);CHKERRQ(ierr);
42       PetscFunctionReturn(0);
43     }
44   }
45 
46   if (linesearch->norms) {
47     if (!linesearch->ops->vinorm) {ierr = VecNormBegin(F, NORM_2, &linesearch->fnorm);CHKERRQ(ierr);}
48     ierr = VecNormBegin(Y, NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
49     ierr = VecNormBegin(W, NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
50     if (!linesearch->ops->vinorm) {ierr = VecNormEnd(F, NORM_2, &linesearch->fnorm);CHKERRQ(ierr);}
51     ierr = VecNormEnd(Y, NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
52     ierr = VecNormEnd(W, NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
53 
54     if (linesearch->ops->vinorm) {
55       linesearch->fnorm = gnorm;
56 
57       ierr = (*linesearch->ops->vinorm)(snes, F, W, &linesearch->fnorm);CHKERRQ(ierr);
58     } else {
59       ierr = VecNorm(F,NORM_2,&linesearch->fnorm);CHKERRQ(ierr);
60     }
61   }
62 
63   /* copy the solution over */
64   ierr = VecCopy(W, X);CHKERRQ(ierr);
65   PetscFunctionReturn(0);
66 }
67 
68 /*MC
69    SNESLINESEARCHBASIC - This line search implementation is not a line
70    search at all; it simply uses the full step.  Thus, this routine is intended
71    for methods with well-scaled updates; i.e. Newton's method (SNESNEWTONLS), on
72    well-behaved problems.
73 
74    Options Database Keys:
75 +   -snes_linesearch_damping <damping> - search vector is scaled by this amount, default is 1.0
76 -   -snes_linesearch_norms <flag> - whether to compute norms or not, default is true (SNESLineSearchSetComputeNorms())
77 
78    Notes:
79    For methods with ill-scaled updates (SNESNRICHARDSON, SNESNCG), a small
80    damping parameter may yield satisfactory but slow convergence despite
81    the simplicity of the line search.
82 
83    Level: advanced
84 
85 .seealso: SNESLineSearchCreate(), SNESLineSearchSetType(), SNESLineSearchSetDamping(), SNESLineSearchSetComputeNorms()
86 M*/
87 PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Basic(SNESLineSearch linesearch)
88 {
89   PetscFunctionBegin;
90   linesearch->ops->apply          = SNESLineSearchApply_Basic;
91   linesearch->ops->destroy        = NULL;
92   linesearch->ops->setfromoptions = NULL;
93   linesearch->ops->reset          = NULL;
94   linesearch->ops->view           = NULL;
95   linesearch->ops->setup          = NULL;
96   PetscFunctionReturn(0);
97 }
98