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 .keywords: SNES, SNESLineSearch, damping 86 87 .seealso: SNESLineSearchCreate(), SNESLineSearchSetType(), SNESLineSearchSetDamping(), SNESLineSearchSetComputeNorms() 88 M*/ 89 PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Basic(SNESLineSearch linesearch) 90 { 91 PetscFunctionBegin; 92 linesearch->ops->apply = SNESLineSearchApply_Basic; 93 linesearch->ops->destroy = NULL; 94 linesearch->ops->setfromoptions = NULL; 95 linesearch->ops->reset = NULL; 96 linesearch->ops->view = NULL; 97 linesearch->ops->setup = NULL; 98 PetscFunctionReturn(0); 99 } 100