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