1af0996ceSBarry Smith #include <petsc/private/linesearchimpl.h> 2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> 3bf7f4e0aSPeter Brune 4f1c6b773SPeter Brune static PetscErrorCode SNESLineSearchApply_Basic(SNESLineSearch linesearch) 5bf7f4e0aSPeter Brune { 6bf7f4e0aSPeter Brune PetscBool changed_y, changed_w; 7bf7f4e0aSPeter Brune PetscErrorCode ierr; 86a388c36SPeter Brune Vec X, F, Y, W; 96a388c36SPeter Brune SNES snes; 106a388c36SPeter Brune PetscReal gnorm, xnorm, ynorm, lambda; 116a388c36SPeter Brune PetscBool domainerror; 12bf7f4e0aSPeter Brune 13bf7f4e0aSPeter Brune PetscFunctionBegin; 140298fd71SBarry Smith ierr = SNESLineSearchGetVecs(linesearch, &X, &F, &Y, &W, NULL);CHKERRQ(ierr); 15f1c6b773SPeter Brune ierr = SNESLineSearchGetNorms(linesearch, &xnorm, &gnorm, &ynorm);CHKERRQ(ierr); 16f1c6b773SPeter Brune ierr = SNESLineSearchGetLambda(linesearch, &lambda);CHKERRQ(ierr); 17f1c6b773SPeter Brune ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr); 18422a814eSBarry Smith ierr = SNESLineSearchSetReason(linesearch, SNES_LINESEARCH_SUCCEEDED);CHKERRQ(ierr); 19bf7f4e0aSPeter Brune 20bf7f4e0aSPeter Brune /* precheck */ 217b1df9c1SPeter Brune ierr = SNESLineSearchPreCheck(linesearch,X,Y,&changed_y);CHKERRQ(ierr); 22bf7f4e0aSPeter Brune 23bf7f4e0aSPeter Brune /* update */ 246a388c36SPeter Brune ierr = VecWAXPY(W,-lambda,Y,X);CHKERRQ(ierr); 259bd66eb0SPeter Brune if (linesearch->ops->viproject) { 269bd66eb0SPeter Brune ierr = (*linesearch->ops->viproject)(snes, W);CHKERRQ(ierr); 279bd66eb0SPeter Brune } 28bf7f4e0aSPeter Brune 29bf7f4e0aSPeter Brune /* postcheck */ 307b1df9c1SPeter Brune ierr = SNESLineSearchPostCheck(linesearch,X,Y,W,&changed_y,&changed_w);CHKERRQ(ierr); 31bf7f4e0aSPeter Brune if (changed_y) { 326a388c36SPeter Brune ierr = VecWAXPY(W,-lambda,Y,X);CHKERRQ(ierr); 339bd66eb0SPeter Brune if (linesearch->ops->viproject) { 349bd66eb0SPeter Brune ierr = (*linesearch->ops->viproject)(snes, W);CHKERRQ(ierr); 359bd66eb0SPeter Brune } 36bf7f4e0aSPeter Brune } 375fc09b23SPeter Brune if (linesearch->norms || snes->iter < snes->max_its-1) { 38fb8e56e0SPeter Brune ierr = (*linesearch->ops->snesfunc)(snes,W,F);CHKERRQ(ierr); 396a388c36SPeter Brune ierr = SNESGetFunctionDomainError(snes, &domainerror);CHKERRQ(ierr); 406a388c36SPeter Brune if (domainerror) { 41e9b602ebSSatish Balay ierr = SNESLineSearchSetReason(linesearch, SNES_LINESEARCH_FAILED_DOMAIN);CHKERRQ(ierr); 42bf7f4e0aSPeter Brune PetscFunctionReturn(0); 43bf7f4e0aSPeter Brune } 445fc09b23SPeter Brune } 456a388c36SPeter Brune 465fc09b23SPeter Brune if (linesearch->norms) { 47937e61d6SBarry Smith if (!linesearch->ops->vinorm) {ierr = VecNormBegin(F, NORM_2, &linesearch->fnorm);CHKERRQ(ierr);} 485fc09b23SPeter Brune ierr = VecNormBegin(Y, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 495fc09b23SPeter Brune ierr = VecNormBegin(W, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 50937e61d6SBarry Smith if (!linesearch->ops->vinorm) {ierr = VecNormEnd(F, NORM_2, &linesearch->fnorm);CHKERRQ(ierr);} 515fc09b23SPeter Brune ierr = VecNormEnd(Y, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 525fc09b23SPeter Brune ierr = VecNormEnd(W, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 535fc09b23SPeter Brune 549bd66eb0SPeter Brune if (linesearch->ops->vinorm) { 559bd66eb0SPeter Brune linesearch->fnorm = gnorm; 56f5af7f23SKarl Rupp 579bd66eb0SPeter Brune ierr = (*linesearch->ops->vinorm)(snes, F, W, &linesearch->fnorm);CHKERRQ(ierr); 589bd66eb0SPeter Brune } else { 599bd66eb0SPeter Brune ierr = VecNorm(F,NORM_2,&linesearch->fnorm);CHKERRQ(ierr); 609bd66eb0SPeter Brune } 615fc09b23SPeter Brune } 626a388c36SPeter Brune 63bf7f4e0aSPeter Brune /* copy the solution over */ 64bf7f4e0aSPeter Brune ierr = VecCopy(W, X);CHKERRQ(ierr); 65bf7f4e0aSPeter Brune PetscFunctionReturn(0); 66bf7f4e0aSPeter Brune } 67bf7f4e0aSPeter Brune 68954494b2SJed Brown /*MC 691a4f838cSPeter Brune SNESLINESEARCHBASIC - This line search implementation is not a line 70cd7522eaSPeter Brune search at all; it simply uses the full step. Thus, this routine is intended 7104d7464bSBarry Smith for methods with well-scaled updates; i.e. Newton's method (SNESNEWTONLS), on 72cd7522eaSPeter Brune well-behaved problems. 73cd7522eaSPeter Brune 74cd7522eaSPeter Brune Options Database Keys: 757c720adbSBarry Smith + -snes_linesearch_damping <damping> - search vector is scaled by this amount, default is 1.0 76*1fe24845SBarry Smith - -snes_linesearch_norms <flag> - whether to compute norms or not, default is true (SNESLineSearchSetComputeNorms()) 77cd7522eaSPeter Brune 78cd7522eaSPeter Brune Notes: 79cd7522eaSPeter Brune For methods with ill-scaled updates (SNESNRICHARDSON, SNESNCG), a small 80cd7522eaSPeter Brune damping parameter may yield satisfactory but slow convergence despite 81cd7522eaSPeter Brune the simplicity of the line search. 82954494b2SJed Brown 83954494b2SJed Brown Level: advanced 84954494b2SJed Brown 85f1c6b773SPeter Brune .keywords: SNES, SNESLineSearch, damping 86954494b2SJed Brown 87*1fe24845SBarry Smith .seealso: SNESLineSearchCreate(), SNESLineSearchSetType(), SNESLineSearchSetDamping(), SNESLineSearchSetComputeNorms() 88954494b2SJed Brown M*/ 898cc058d9SJed Brown PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Basic(SNESLineSearch linesearch) 90bf7f4e0aSPeter Brune { 91bf7f4e0aSPeter Brune PetscFunctionBegin; 92f1c6b773SPeter Brune linesearch->ops->apply = SNESLineSearchApply_Basic; 930298fd71SBarry Smith linesearch->ops->destroy = NULL; 940298fd71SBarry Smith linesearch->ops->setfromoptions = NULL; 950298fd71SBarry Smith linesearch->ops->reset = NULL; 960298fd71SBarry Smith linesearch->ops->view = NULL; 970298fd71SBarry Smith linesearch->ops->setup = NULL; 98bf7f4e0aSPeter Brune PetscFunctionReturn(0); 99bf7f4e0aSPeter Brune } 100