1af0996ceSBarry Smith #include <petsc/private/linesearchimpl.h> 2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> 3bf7f4e0aSPeter Brune 49371c9d4SSatish Balay static PetscErrorCode SNESLineSearchApply_Basic(SNESLineSearch linesearch) { 5bf7f4e0aSPeter Brune PetscBool changed_y, changed_w; 66a388c36SPeter Brune Vec X, F, Y, W; 76a388c36SPeter Brune SNES snes; 86a388c36SPeter Brune PetscReal gnorm, xnorm, ynorm, lambda; 96a388c36SPeter Brune PetscBool domainerror; 10bf7f4e0aSPeter Brune 11bf7f4e0aSPeter Brune PetscFunctionBegin; 129566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetVecs(linesearch, &X, &F, &Y, &W, NULL)); 139566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetNorms(linesearch, &xnorm, &gnorm, &ynorm)); 149566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetLambda(linesearch, &lambda)); 159566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetSNES(linesearch, &snes)); 169566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetReason(linesearch, SNES_LINESEARCH_SUCCEEDED)); 17bf7f4e0aSPeter Brune 18bf7f4e0aSPeter Brune /* precheck */ 199566063dSJacob Faibussowitsch PetscCall(SNESLineSearchPreCheck(linesearch, X, Y, &changed_y)); 20bf7f4e0aSPeter Brune 21bf7f4e0aSPeter Brune /* update */ 229566063dSJacob Faibussowitsch PetscCall(VecWAXPY(W, -lambda, Y, X)); 231baa6e33SBarry Smith if (linesearch->ops->viproject) PetscCall((*linesearch->ops->viproject)(snes, W)); 24bf7f4e0aSPeter Brune 25bf7f4e0aSPeter Brune /* postcheck */ 269566063dSJacob Faibussowitsch PetscCall(SNESLineSearchPostCheck(linesearch, X, Y, W, &changed_y, &changed_w)); 27bf7f4e0aSPeter Brune if (changed_y) { 289566063dSJacob Faibussowitsch PetscCall(VecWAXPY(W, -lambda, Y, X)); 291baa6e33SBarry Smith if (linesearch->ops->viproject) PetscCall((*linesearch->ops->viproject)(snes, W)); 30bf7f4e0aSPeter Brune } 315fc09b23SPeter Brune if (linesearch->norms || snes->iter < snes->max_its - 1) { 329566063dSJacob Faibussowitsch PetscCall((*linesearch->ops->snesfunc)(snes, W, F)); 339566063dSJacob Faibussowitsch PetscCall(SNESGetFunctionDomainError(snes, &domainerror)); 346a388c36SPeter Brune if (domainerror) { 359566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetReason(linesearch, SNES_LINESEARCH_FAILED_DOMAIN)); 36bf7f4e0aSPeter Brune PetscFunctionReturn(0); 37bf7f4e0aSPeter Brune } 385fc09b23SPeter Brune } 396a388c36SPeter Brune 405fc09b23SPeter Brune if (linesearch->norms) { 419566063dSJacob Faibussowitsch if (!linesearch->ops->vinorm) PetscCall(VecNormBegin(F, NORM_2, &linesearch->fnorm)); 429566063dSJacob Faibussowitsch PetscCall(VecNormBegin(Y, NORM_2, &linesearch->ynorm)); 439566063dSJacob Faibussowitsch PetscCall(VecNormBegin(W, NORM_2, &linesearch->xnorm)); 449566063dSJacob Faibussowitsch if (!linesearch->ops->vinorm) PetscCall(VecNormEnd(F, NORM_2, &linesearch->fnorm)); 459566063dSJacob Faibussowitsch PetscCall(VecNormEnd(Y, NORM_2, &linesearch->ynorm)); 469566063dSJacob Faibussowitsch PetscCall(VecNormEnd(W, NORM_2, &linesearch->xnorm)); 475fc09b23SPeter Brune 489bd66eb0SPeter Brune if (linesearch->ops->vinorm) { 499bd66eb0SPeter Brune linesearch->fnorm = gnorm; 50f5af7f23SKarl Rupp 519566063dSJacob Faibussowitsch PetscCall((*linesearch->ops->vinorm)(snes, F, W, &linesearch->fnorm)); 529bd66eb0SPeter Brune } else { 539566063dSJacob Faibussowitsch PetscCall(VecNorm(F, NORM_2, &linesearch->fnorm)); 549bd66eb0SPeter Brune } 555fc09b23SPeter Brune } 566a388c36SPeter Brune 57bf7f4e0aSPeter Brune /* copy the solution over */ 589566063dSJacob Faibussowitsch PetscCall(VecCopy(W, X)); 59bf7f4e0aSPeter Brune PetscFunctionReturn(0); 60bf7f4e0aSPeter Brune } 61bf7f4e0aSPeter Brune 62954494b2SJed Brown /*MC 631a4f838cSPeter Brune SNESLINESEARCHBASIC - This line search implementation is not a line 64cd7522eaSPeter Brune search at all; it simply uses the full step. Thus, this routine is intended 65*f6dfbefdSBarry Smith for methods with well-scaled updates; i.e. Newton's method (`SNESNEWTONLS`), on 66*f6dfbefdSBarry Smith well-behaved problems. Also named as `SNESLINESEARCHNONE` 67cd7522eaSPeter Brune 68cd7522eaSPeter Brune Options Database Keys: 697c720adbSBarry Smith + -snes_linesearch_damping <damping> - search vector is scaled by this amount, default is 1.0 701fe24845SBarry Smith - -snes_linesearch_norms <flag> - whether to compute norms or not, default is true (SNESLineSearchSetComputeNorms()) 71cd7522eaSPeter Brune 72*f6dfbefdSBarry Smith Note: 73*f6dfbefdSBarry Smith For methods with ill-scaled updates (`SNESNRICHARDSON`, `SNESNCG`), a small 74cd7522eaSPeter Brune damping parameter may yield satisfactory but slow convergence despite 75*f6dfbefdSBarry Smith the lack of the line search. 76954494b2SJed Brown 77954494b2SJed Brown Level: advanced 78954494b2SJed Brown 79*f6dfbefdSBarry Smith .seealso: `SNES`, `SNESLineSearch`, `SNESLineSearchType`, `SNESLineSearchCreate()`, `SNESLineSearchSetType()`, `SNESLineSearchSetDamping()`, `SNESLineSearchSetComputeNorms()` 80954494b2SJed Brown M*/ 819371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode SNESLineSearchCreate_Basic(SNESLineSearch linesearch) { 82bf7f4e0aSPeter Brune PetscFunctionBegin; 83f1c6b773SPeter Brune linesearch->ops->apply = SNESLineSearchApply_Basic; 840298fd71SBarry Smith linesearch->ops->destroy = NULL; 850298fd71SBarry Smith linesearch->ops->setfromoptions = NULL; 860298fd71SBarry Smith linesearch->ops->reset = NULL; 870298fd71SBarry Smith linesearch->ops->view = NULL; 880298fd71SBarry Smith linesearch->ops->setup = NULL; 89bf7f4e0aSPeter Brune PetscFunctionReturn(0); 90bf7f4e0aSPeter Brune } 91