1 #include <petsc/private/linesearchimpl.h> /*I "petscsnes.h" I*/ 2 3 PetscBool SNESLineSearchRegisterAllCalled = PETSC_FALSE; 4 PetscFunctionList SNESLineSearchList = NULL; 5 6 PetscClassId SNESLINESEARCH_CLASSID; 7 PetscLogEvent SNESLINESEARCH_Apply; 8 9 /*@ 10 SNESLineSearchMonitorCancel - Clears all the monitor functions for a SNESLineSearch object. 11 12 Logically Collective on SNESLineSearch 13 14 Input Parameters: 15 . ls - the SNESLineSearch context 16 17 Options Database Key: 18 . -snes_linesearch_monitor_cancel - cancels all monitors that have been hardwired 19 into a code by calls to SNESLineSearchMonitorSet(), but does not cancel those 20 set via the options database 21 22 Notes: 23 There is no way to clear one specific monitor from a SNESLineSearch object. 24 25 This does not clear the monitor set with SNESLineSearchSetDefaultMonitor() use SNESLineSearchSetDefaultMonitor(ls,NULL) to cancel 26 that one. 27 28 Level: intermediate 29 30 .seealso: `SNESGetLineSearch()`, `SNESLineSearchMonitorDefault()`, `SNESLineSearchMonitorSet()` 31 @*/ 32 PetscErrorCode SNESLineSearchMonitorCancel(SNESLineSearch ls) 33 { 34 PetscInt i; 35 36 PetscFunctionBegin; 37 PetscValidHeaderSpecific(ls,SNESLINESEARCH_CLASSID,1); 38 for (i=0; i<ls->numbermonitors; i++) { 39 if (ls->monitordestroy[i]) { 40 PetscCall((*ls->monitordestroy[i])(&ls->monitorcontext[i])); 41 } 42 } 43 ls->numbermonitors = 0; 44 PetscFunctionReturn(0); 45 } 46 47 /*@ 48 SNESLineSearchMonitor - runs the user provided monitor routines, if they exist 49 50 Collective on SNES 51 52 Input Parameters: 53 . ls - the linesearch object 54 55 Notes: 56 This routine is called by the SNES implementations. 57 It does not typically need to be called by the user. 58 59 Level: developer 60 61 .seealso: `SNESGetLineSearch()`, `SNESLineSearchMonitorSet()` 62 @*/ 63 PetscErrorCode SNESLineSearchMonitor(SNESLineSearch ls) 64 { 65 PetscInt i,n = ls->numbermonitors; 66 67 PetscFunctionBegin; 68 for (i=0; i<n; i++) { 69 PetscCall((*ls->monitorftns[i])(ls,ls->monitorcontext[i])); 70 } 71 PetscFunctionReturn(0); 72 } 73 74 /*@C 75 SNESLineSearchMonitorSet - Sets an ADDITIONAL function that is to be used at every 76 iteration of the nonlinear solver to display the iteration's 77 progress. 78 79 Logically Collective on SNESLineSearch 80 81 Input Parameters: 82 + ls - the SNESLineSearch context 83 . f - the monitor function 84 . mctx - [optional] user-defined context for private data for the 85 monitor routine (use NULL if no context is desired) 86 - monitordestroy - [optional] routine that frees monitor context 87 (may be NULL) 88 89 Notes: 90 Several different monitoring routines may be set by calling 91 SNESLineSearchMonitorSet() multiple times; all will be called in the 92 order in which they were set. 93 94 Fortran Notes: 95 Only a single monitor function can be set for each SNESLineSearch object 96 97 Level: intermediate 98 99 .seealso: `SNESGetLineSearch()`, `SNESLineSearchMonitorDefault()`, `SNESLineSearchMonitorCancel()` 100 @*/ 101 PetscErrorCode SNESLineSearchMonitorSet(SNESLineSearch ls,PetscErrorCode (*f)(SNESLineSearch,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 102 { 103 PetscInt i; 104 PetscBool identical; 105 106 PetscFunctionBegin; 107 PetscValidHeaderSpecific(ls,SNESLINESEARCH_CLASSID,1); 108 for (i=0; i<ls->numbermonitors;i++) { 109 PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))ls->monitorftns[i],ls->monitorcontext[i],ls->monitordestroy[i],&identical)); 110 if (identical) PetscFunctionReturn(0); 111 } 112 PetscCheck(ls->numbermonitors < MAXSNESLSMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 113 ls->monitorftns[ls->numbermonitors] = f; 114 ls->monitordestroy[ls->numbermonitors] = monitordestroy; 115 ls->monitorcontext[ls->numbermonitors++] = (void*)mctx; 116 PetscFunctionReturn(0); 117 } 118 119 /*@C 120 SNESLineSearchMonitorSolutionUpdate - Monitors each update a new function value the linesearch tries 121 122 Collective on SNESLineSearch 123 124 Input Parameters: 125 + ls - the SNES linesearch object 126 - vf - the context for the monitor, in this case it is an ASCII PetscViewer and format 127 128 Level: intermediate 129 130 .seealso: `SNESGetLineSearch()`, `SNESMonitorSet()`, `SNESMonitorSolution()` 131 @*/ 132 PetscErrorCode SNESLineSearchMonitorSolutionUpdate(SNESLineSearch ls,PetscViewerAndFormat *vf) 133 { 134 PetscViewer viewer = vf->viewer; 135 Vec Y,W,G; 136 137 PetscFunctionBegin; 138 PetscCall(SNESLineSearchGetVecs(ls,NULL,NULL,&Y,&W,&G)); 139 PetscCall(PetscViewerPushFormat(viewer,vf->format)); 140 PetscCall(PetscViewerASCIIPrintf(viewer,"LineSearch attempted update to solution \n")); 141 PetscCall(VecView(Y,viewer)); 142 PetscCall(PetscViewerASCIIPrintf(viewer,"LineSearch attempted new solution \n")); 143 PetscCall(VecView(W,viewer)); 144 PetscCall(PetscViewerASCIIPrintf(viewer,"LineSearch attempted updated function value\n")); 145 PetscCall(VecView(G,viewer)); 146 PetscCall(PetscViewerPopFormat(viewer)); 147 PetscFunctionReturn(0); 148 } 149 150 /*@ 151 SNESLineSearchCreate - Creates the line search context. 152 153 Logically Collective on Comm 154 155 Input Parameters: 156 . comm - MPI communicator for the line search (typically from the associated SNES context). 157 158 Output Parameters: 159 . outlinesearch - the new linesearch context 160 161 Level: developer 162 163 Notes: 164 The preferred calling sequence for users is to use SNESGetLineSearch() to acquire the SNESLineSearch instance 165 already associated with the SNES. This function is for developer use. 166 167 .seealso: `LineSearchDestroy()`, `SNESGetLineSearch()` 168 @*/ 169 170 PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch) 171 { 172 SNESLineSearch linesearch; 173 174 PetscFunctionBegin; 175 PetscValidPointer(outlinesearch,2); 176 PetscCall(SNESInitializePackage()); 177 *outlinesearch = NULL; 178 179 PetscCall(PetscHeaderCreate(linesearch,SNESLINESEARCH_CLASSID, "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView)); 180 181 linesearch->vec_sol_new = NULL; 182 linesearch->vec_func_new = NULL; 183 linesearch->vec_sol = NULL; 184 linesearch->vec_func = NULL; 185 linesearch->vec_update = NULL; 186 187 linesearch->lambda = 1.0; 188 linesearch->fnorm = 1.0; 189 linesearch->ynorm = 1.0; 190 linesearch->xnorm = 1.0; 191 linesearch->result = SNES_LINESEARCH_SUCCEEDED; 192 linesearch->norms = PETSC_TRUE; 193 linesearch->keeplambda = PETSC_FALSE; 194 linesearch->damping = 1.0; 195 linesearch->maxstep = 1e8; 196 linesearch->steptol = 1e-12; 197 linesearch->rtol = 1e-8; 198 linesearch->atol = 1e-15; 199 linesearch->ltol = 1e-8; 200 linesearch->precheckctx = NULL; 201 linesearch->postcheckctx = NULL; 202 linesearch->max_its = 1; 203 linesearch->setupcalled = PETSC_FALSE; 204 linesearch->monitor = NULL; 205 *outlinesearch = linesearch; 206 PetscFunctionReturn(0); 207 } 208 209 /*@ 210 SNESLineSearchSetUp - Prepares the line search for being applied by allocating 211 any required vectors. 212 213 Collective on SNESLineSearch 214 215 Input Parameters: 216 . linesearch - The LineSearch instance. 217 218 Notes: 219 For most cases, this needn't be called by users or outside of SNESLineSearchApply(). 220 The only current case where this is called outside of this is for the VI 221 solvers, which modify the solution and work vectors before the first call 222 of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be 223 allocated upfront. 224 225 Level: advanced 226 227 .seealso: `SNESGetLineSearch()`, `SNESLineSearchReset()` 228 @*/ 229 230 PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch) 231 { 232 PetscFunctionBegin; 233 if (!((PetscObject)linesearch)->type_name) { 234 PetscCall(SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC)); 235 } 236 if (!linesearch->setupcalled) { 237 if (!linesearch->vec_sol_new) { 238 PetscCall(VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new)); 239 } 240 if (!linesearch->vec_func_new) { 241 PetscCall(VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new)); 242 } 243 if (linesearch->ops->setup) PetscUseTypeMethod(linesearch,setup); 244 if (!linesearch->ops->snesfunc) PetscCall(SNESLineSearchSetFunction(linesearch,SNESComputeFunction)); 245 linesearch->lambda = linesearch->damping; 246 linesearch->setupcalled = PETSC_TRUE; 247 } 248 PetscFunctionReturn(0); 249 } 250 251 /*@ 252 SNESLineSearchReset - Undoes the SNESLineSearchSetUp() and deletes any Vecs or Mats allocated by the line search. 253 254 Collective on SNESLineSearch 255 256 Input Parameters: 257 . linesearch - The LineSearch instance. 258 259 Notes: 260 Usually only called by SNESReset() 261 262 Level: developer 263 264 .seealso: `SNESGetLineSearch()`, `SNESLineSearchSetUp()` 265 @*/ 266 267 PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch) 268 { 269 PetscFunctionBegin; 270 if (linesearch->ops->reset) PetscUseTypeMethod(linesearch,reset); 271 272 PetscCall(VecDestroy(&linesearch->vec_sol_new)); 273 PetscCall(VecDestroy(&linesearch->vec_func_new)); 274 275 PetscCall(VecDestroyVecs(linesearch->nwork, &linesearch->work)); 276 277 linesearch->nwork = 0; 278 linesearch->setupcalled = PETSC_FALSE; 279 PetscFunctionReturn(0); 280 } 281 282 /*@C 283 SNESLineSearchSetFunction - Sets the function evaluation used by the SNES line search 284 285 Input Parameters: 286 . linesearch - the SNESLineSearch context 287 + func - function evaluation routine 288 289 Level: developer 290 291 Notes: 292 This is used internally by PETSc and not called by users 293 294 .seealso: `SNESGetLineSearch()`, `SNESSetFunction()` 295 @*/ 296 PetscErrorCode SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec)) 297 { 298 PetscFunctionBegin; 299 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 300 linesearch->ops->snesfunc = func; 301 PetscFunctionReturn(0); 302 } 303 304 /*@C 305 SNESLineSearchSetPreCheck - Sets a user function that is called after the initial search direction has been computed but 306 before the line search routine has been applied. Allows the user to adjust the result of (usually a linear solve) that 307 determined the search direction. 308 309 Logically Collective on SNESLineSearch 310 311 Input Parameters: 312 + linesearch - the SNESLineSearch context 313 . func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for the calling sequence 314 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 315 316 Level: intermediate 317 318 Notes: 319 Use `SNESLineSearchSetPostCheck()` to change the step after the line search. 320 search is complete. 321 322 Use `SNESVISetVariableBounds()` and `SNESVISetComputeVariableBounds()` to cause `SNES` to automatically control the ranges of variables allowed. 323 324 .seealso: `SNESGetLineSearch()`, `SNESLineSearchPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchGetPreCheck()`, 325 `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESSetFunctionDomainError()`, `SNESSetJacobianDomainError() 326 327 @*/ 328 PetscErrorCode SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx) 329 { 330 PetscFunctionBegin; 331 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 332 if (func) linesearch->ops->precheck = func; 333 if (ctx) linesearch->precheckctx = ctx; 334 PetscFunctionReturn(0); 335 } 336 337 /*@C 338 SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine. 339 340 Input Parameter: 341 . linesearch - the SNESLineSearch context 342 343 Output Parameters: 344 + func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for calling sequence 345 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 346 347 Level: intermediate 348 349 .seealso: `SNESGetLineSearch()`, `SNESGetLineSearch()`, `SNESLineSearchPreCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 350 @*/ 351 PetscErrorCode SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx) 352 { 353 PetscFunctionBegin; 354 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 355 if (func) *func = linesearch->ops->precheck; 356 if (ctx) *ctx = linesearch->precheckctx; 357 PetscFunctionReturn(0); 358 } 359 360 /*@C 361 SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step 362 direction and length. Allows the user a chance to change or override the decision of the line search routine 363 364 Logically Collective on SNESLineSearch 365 366 Input Parameters: 367 + linesearch - the SNESLineSearch context 368 . func - [optional] function evaluation routine, see SNESLineSearchPostCheck() for the calling sequence 369 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 370 371 Level: intermediate 372 373 Notes: 374 Use `SNESLineSearchSetPreCheck()` to change the step before the line search. 375 search is complete. 376 377 Use `SNESVISetVariableBounds()` and `SNESVISetComputeVariableBounds()` to cause `SNES` to automatically control the ranges of variables allowed. 378 379 .seealso: `SNESGetLineSearch()`, `SNESLineSearchPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`, `SNESLineSearchGetPostCheck()`, 380 `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESSetFunctionDomainError()`, `SNESSetJacobianDomainError() 381 @*/ 382 PetscErrorCode SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx) 383 { 384 PetscFunctionBegin; 385 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 386 if (func) linesearch->ops->postcheck = func; 387 if (ctx) linesearch->postcheckctx = ctx; 388 PetscFunctionReturn(0); 389 } 390 391 /*@C 392 SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine. 393 394 Input Parameter: 395 . linesearch - the SNESLineSearch context 396 397 Output Parameters: 398 + func - [optional] function evaluation routine, see for the calling sequence SNESLineSearchPostCheck() 399 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 400 401 Level: intermediate 402 403 .seealso: `SNESGetLineSearch()`, `SNESLineSearchGetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchPostCheck()`, `SNESLineSearchSetPreCheck()` 404 @*/ 405 PetscErrorCode SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx) 406 { 407 PetscFunctionBegin; 408 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 409 if (func) *func = linesearch->ops->postcheck; 410 if (ctx) *ctx = linesearch->postcheckctx; 411 PetscFunctionReturn(0); 412 } 413 414 /*@ 415 SNESLineSearchPreCheck - Prepares the line search for being applied. 416 417 Logically Collective on SNESLineSearch 418 419 Input Parameters: 420 + linesearch - The linesearch instance. 421 . X - The current solution 422 - Y - The step direction 423 424 Output Parameters: 425 . changed - Indicator that the precheck routine has changed anything 426 427 Level: advanced 428 429 .seealso: `SNESGetLineSearch()`, `SNESLineSearchPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`, `SNESLineSearchSetPostCheck()`, 430 `SNESLineSearchGetPostCheck()`` 431 @*/ 432 PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed) 433 { 434 PetscFunctionBegin; 435 *changed = PETSC_FALSE; 436 if (linesearch->ops->precheck) { 437 PetscUseTypeMethod(linesearch,precheck , X, Y, changed, linesearch->precheckctx); 438 PetscValidLogicalCollectiveBool(linesearch,*changed,4); 439 } 440 PetscFunctionReturn(0); 441 } 442 443 /*@ 444 SNESLineSearchPostCheck - Hook to modify step direction or updated solution after a successful linesearch 445 446 Logically Collective on SNESLineSearch 447 448 Input Parameters: 449 + linesearch - The linesearch context 450 . X - The last solution 451 . Y - The step direction 452 - W - The updated solution, W = X + lambda*Y for some lambda 453 454 Output Parameters: 455 + changed_Y - Indicator if the direction Y has been changed. 456 - changed_W - Indicator if the new candidate solution W has been changed. 457 458 Level: developer 459 460 .seealso: `SNESGetLineSearch()`, `SNESLineSearchPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPrecheck()`, `SNESLineSearchGetPrecheck()` 461 @*/ 462 PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W) 463 { 464 PetscFunctionBegin; 465 *changed_Y = PETSC_FALSE; 466 *changed_W = PETSC_FALSE; 467 if (linesearch->ops->postcheck) { 468 PetscUseTypeMethod(linesearch,postcheck ,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx); 469 PetscValidLogicalCollectiveBool(linesearch,*changed_Y,5); 470 PetscValidLogicalCollectiveBool(linesearch,*changed_W,6); 471 } 472 PetscFunctionReturn(0); 473 } 474 475 /*@C 476 SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration 477 478 Logically Collective on SNESLineSearch 479 480 Input Parameters: 481 + linesearch - linesearch context 482 . X - base state for this step 483 - ctx - context for this function 484 485 Input/Output Parameter: 486 . Y - correction, possibly modified 487 488 Output Parameter: 489 . changed - flag indicating that Y was modified 490 491 Options Database Key: 492 + -snes_linesearch_precheck_picard - activate this routine 493 - -snes_linesearch_precheck_picard_angle - angle 494 495 Level: advanced 496 497 Notes: 498 This function should be passed to SNESLineSearchSetPreCheck() 499 500 The justification for this method involves the linear convergence of a Picard iteration 501 so the Picard linearization should be provided in place of the "Jacobian". This correction 502 is generally not useful when using a Newton linearization. 503 504 Reference: 505 Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology. 506 507 .seealso: `SNESGetLineSearch()`, `SNESLineSearchSetPreCheck()` 508 @*/ 509 PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx) 510 { 511 PetscReal angle = *(PetscReal*)linesearch->precheckctx; 512 Vec Ylast; 513 PetscScalar dot; 514 PetscInt iter; 515 PetscReal ynorm,ylastnorm,theta,angle_radians; 516 SNES snes; 517 518 PetscFunctionBegin; 519 PetscCall(SNESLineSearchGetSNES(linesearch, &snes)); 520 PetscCall(PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast)); 521 if (!Ylast) { 522 PetscCall(VecDuplicate(Y,&Ylast)); 523 PetscCall(PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast)); 524 PetscCall(PetscObjectDereference((PetscObject)Ylast)); 525 } 526 PetscCall(SNESGetIterationNumber(snes,&iter)); 527 if (iter < 2) { 528 PetscCall(VecCopy(Y,Ylast)); 529 *changed = PETSC_FALSE; 530 PetscFunctionReturn(0); 531 } 532 533 PetscCall(VecDot(Y,Ylast,&dot)); 534 PetscCall(VecNorm(Y,NORM_2,&ynorm)); 535 PetscCall(VecNorm(Ylast,NORM_2,&ylastnorm)); 536 /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */ 537 theta = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0)); 538 angle_radians = angle * PETSC_PI / 180.; 539 if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) { 540 /* Modify the step Y */ 541 PetscReal alpha,ydiffnorm; 542 PetscCall(VecAXPY(Ylast,-1.0,Y)); 543 PetscCall(VecNorm(Ylast,NORM_2,&ydiffnorm)); 544 alpha = (ydiffnorm > .001*ylastnorm) ? ylastnorm / ydiffnorm : 1000.0; 545 PetscCall(VecCopy(Y,Ylast)); 546 PetscCall(VecScale(Y,alpha)); 547 PetscCall(PetscInfo(snes,"Angle %14.12e degrees less than threshold %14.12e, corrected step by alpha=%14.12e\n",(double)(theta*180./PETSC_PI),(double)angle,(double)alpha)); 548 *changed = PETSC_TRUE; 549 } else { 550 PetscCall(PetscInfo(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle)); 551 PetscCall(VecCopy(Y,Ylast)); 552 *changed = PETSC_FALSE; 553 } 554 PetscFunctionReturn(0); 555 } 556 557 /*@ 558 SNESLineSearchApply - Computes the line-search update. 559 560 Collective on SNESLineSearch 561 562 Input Parameters: 563 + linesearch - The linesearch context 564 - Y - The search direction 565 566 Input/Output Parameters: 567 + X - The current solution, on output the new solution 568 . F - The current function, on output the new function 569 - fnorm - The current norm, on output the new function norm 570 571 Options Database Keys: 572 + -snes_linesearch_type - basic (or equivalently none), bt, l2, cp, nleqerr, shell 573 . -snes_linesearch_monitor [:filename] - Print progress of line searches 574 . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping) 575 . -snes_linesearch_norms - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms()) 576 . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess 577 - -snes_linesearch_max_it - The number of iterations for iterative line searches 578 579 Notes: 580 This is typically called from within a SNESSolve() implementation in order to 581 help with convergence of the nonlinear method. Various SNES types use line searches 582 in different ways, but the overarching theme is that a line search is used to determine 583 an optimal damping parameter of a step at each iteration of the method. Each 584 application of the line search may invoke SNESComputeFunction() several times, and 585 therefore may be fairly expensive. 586 587 Level: Intermediate 588 589 .seealso: `SNESGetLineSearch()`, `SNESLineSearchCreate()`, `SNESLineSearchPreCheck()`, `SNESLineSearchPostCheck()`, `SNESSolve()`, `SNESComputeFunction()`, `SNESLineSearchSetComputeNorms()`, 590 `SNESLineSearchType`, `SNESLineSearchSetType()` 591 @*/ 592 PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y) 593 { 594 PetscFunctionBegin; 595 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 596 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 597 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 598 PetscValidHeaderSpecific(Y,VEC_CLASSID,5); 599 600 linesearch->result = SNES_LINESEARCH_SUCCEEDED; 601 602 linesearch->vec_sol = X; 603 linesearch->vec_update = Y; 604 linesearch->vec_func = F; 605 606 PetscCall(SNESLineSearchSetUp(linesearch)); 607 608 if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */ 609 610 if (fnorm) linesearch->fnorm = *fnorm; 611 else { 612 PetscCall(VecNorm(F, NORM_2, &linesearch->fnorm)); 613 } 614 615 PetscCall(PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y)); 616 617 PetscUseTypeMethod(linesearch,apply); 618 619 PetscCall(PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y)); 620 621 if (fnorm) *fnorm = linesearch->fnorm; 622 PetscFunctionReturn(0); 623 } 624 625 /*@ 626 SNESLineSearchDestroy - Destroys the line search instance. 627 628 Collective on SNESLineSearch 629 630 Input Parameters: 631 . linesearch - The linesearch context 632 633 Level: developer 634 635 .seealso: `SNESGetLineSearch()`, `SNESLineSearchCreate()`, `SNESLineSearchReset()`, `SNESDestroy()` 636 @*/ 637 PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch) 638 { 639 PetscFunctionBegin; 640 if (!*linesearch) PetscFunctionReturn(0); 641 PetscValidHeaderSpecific((*linesearch),SNESLINESEARCH_CLASSID,1); 642 if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = NULL; PetscFunctionReturn(0);} 643 PetscCall(PetscObjectSAWsViewOff((PetscObject)*linesearch)); 644 PetscCall(SNESLineSearchReset(*linesearch)); 645 if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch); 646 PetscCall(PetscViewerDestroy(&(*linesearch)->monitor)); 647 PetscCall(SNESLineSearchMonitorCancel((*linesearch))); 648 PetscCall(PetscHeaderDestroy(linesearch)); 649 PetscFunctionReturn(0); 650 } 651 652 /*@ 653 SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search. 654 655 Input Parameters: 656 + linesearch - the linesearch object 657 - viewer - an ASCII PetscViewer or NULL to turn off monitor 658 659 Logically Collective on SNESLineSearch 660 661 Options Database: 662 . -snes_linesearch_monitor [:filename] - enables the monitor 663 664 Level: intermediate 665 666 Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with 667 SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the 668 line search that are not visible to the other monitors. 669 670 .seealso: `SNESGetLineSearch()`, `SNESLineSearchGetDefaultMonitor()`, `PetscViewer`, `SNESLineSearchSetMonitor()` 671 @*/ 672 PetscErrorCode SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer) 673 { 674 PetscFunctionBegin; 675 if (viewer) PetscCall(PetscObjectReference((PetscObject)viewer)); 676 PetscCall(PetscViewerDestroy(&linesearch->monitor)); 677 linesearch->monitor = viewer; 678 PetscFunctionReturn(0); 679 } 680 681 /*@ 682 SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor. 683 684 Input Parameter: 685 . linesearch - linesearch context 686 687 Output Parameter: 688 . monitor - monitor context 689 690 Logically Collective on SNES 691 692 Options Database Keys: 693 . -snes_linesearch_monitor - enables the monitor 694 695 Level: intermediate 696 697 .seealso: `SNESGetLineSearch()`, `SNESLineSearchSetDefaultMonitor()`, `PetscViewer` 698 @*/ 699 PetscErrorCode SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor) 700 { 701 PetscFunctionBegin; 702 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 703 *monitor = linesearch->monitor; 704 PetscFunctionReturn(0); 705 } 706 707 /*@C 708 SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 709 710 Collective on SNESLineSearch 711 712 Input Parameters: 713 + ls - LineSearch object you wish to monitor 714 . name - the monitor type one is seeking 715 . help - message indicating what monitoring is done 716 . manual - manual page for the monitor 717 . monitor - the monitor function 718 - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the SNESLineSearch or PetscViewer objects 719 720 Level: developer 721 722 .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 723 `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 724 `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, 725 `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 726 `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 727 `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 728 `PetscOptionsFList()`, `PetscOptionsEList()` 729 @*/ 730 PetscErrorCode SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*)) 731 { 732 PetscViewer viewer; 733 PetscViewerFormat format; 734 PetscBool flg; 735 736 PetscFunctionBegin; 737 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject) ls)->options,((PetscObject)ls)->prefix,name,&viewer,&format,&flg)); 738 if (flg) { 739 PetscViewerAndFormat *vf; 740 PetscCall(PetscViewerAndFormatCreate(viewer,format,&vf)); 741 PetscCall(PetscObjectDereference((PetscObject)viewer)); 742 if (monitorsetup) PetscCall((*monitorsetup)(ls,vf)); 743 PetscCall(SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy)); 744 } 745 PetscFunctionReturn(0); 746 } 747 748 /*@ 749 SNESLineSearchSetFromOptions - Sets options for the line search 750 751 Input Parameter: 752 . linesearch - linesearch context 753 754 Options Database Keys: 755 + -snes_linesearch_type <type> - basic (or equivalently none), bt, l2, cp, nleqerr, shell 756 . -snes_linesearch_order <order> - 1, 2, 3. Most types only support certain orders (bt supports 2 or 3) 757 . -snes_linesearch_norms - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms()) 758 . -snes_linesearch_minlambda - The minimum step length 759 . -snes_linesearch_maxstep - The maximum step size 760 . -snes_linesearch_rtol - Relative tolerance for iterative line searches 761 . -snes_linesearch_atol - Absolute tolerance for iterative line searches 762 . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches 763 . -snes_linesearch_max_it - The number of iterations for iterative line searches 764 . -snes_linesearch_monitor [:filename] - Print progress of line searches 765 . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine 766 . -snes_linesearch_damping - The linesearch damping parameter 767 . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess. 768 . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method 769 - -snes_linesearch_precheck_picard_angle - Angle used in Picard precheck method 770 771 Logically Collective on SNESLineSearch 772 773 Level: intermediate 774 775 .seealso: `SNESLineSearchCreate()`, `SNESLineSearchSetOrder()`, `SNESLineSearchSetType()`, `SNESLineSearchSetTolerances()`, `SNESLineSearchSetDamping()`, `SNESLineSearchPreCheckPicard()`, 776 `SNESLineSearchType`, `SNESLineSearchSetComputeNorms()` 777 @*/ 778 PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch) 779 { 780 const char *deft = SNESLINESEARCHBASIC; 781 char type[256]; 782 PetscBool flg, set; 783 PetscViewer viewer; 784 785 PetscFunctionBegin; 786 PetscCall(SNESLineSearchRegisterAll()); 787 788 PetscObjectOptionsBegin((PetscObject)linesearch); 789 if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name; 790 PetscCall(PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg)); 791 if (flg) { 792 PetscCall(SNESLineSearchSetType(linesearch,type)); 793 } else if (!((PetscObject)linesearch)->type_name) { 794 PetscCall(SNESLineSearchSetType(linesearch,deft)); 795 } 796 797 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject) linesearch)->options,((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set)); 798 if (set) { 799 PetscCall(SNESLineSearchSetDefaultMonitor(linesearch,viewer)); 800 PetscCall(PetscViewerDestroy(&viewer)); 801 } 802 PetscCall(SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL)); 803 804 /* tolerances */ 805 PetscCall(PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL)); 806 PetscCall(PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL)); 807 PetscCall(PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL)); 808 PetscCall(PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL)); 809 PetscCall(PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL)); 810 PetscCall(PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL)); 811 812 /* damping parameters */ 813 PetscCall(PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL)); 814 815 PetscCall(PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL)); 816 817 /* precheck */ 818 PetscCall(PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set)); 819 if (set) { 820 if (flg) { 821 linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */ 822 823 PetscCall(PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction","none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL)); 824 PetscCall(SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle)); 825 } else { 826 PetscCall(SNESLineSearchSetPreCheck(linesearch,NULL,NULL)); 827 } 828 } 829 PetscCall(PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL)); 830 PetscCall(PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL)); 831 832 PetscTryTypeMethod(linesearch,setfromoptions,PetscOptionsObject); 833 834 PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)linesearch,PetscOptionsObject)); 835 PetscOptionsEnd(); 836 PetscFunctionReturn(0); 837 } 838 839 /*@ 840 SNESLineSearchView - Prints useful information about the line search 841 842 Input Parameters: 843 . linesearch - linesearch context 844 845 Logically Collective on SNESLineSearch 846 847 Level: intermediate 848 849 .seealso: `SNESLineSearchCreate()` 850 @*/ 851 PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer) 852 { 853 PetscBool iascii; 854 855 PetscFunctionBegin; 856 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 857 if (!viewer) { 858 PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer)); 859 } 860 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 861 PetscCheckSameComm(linesearch,1,viewer,2); 862 863 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 864 if (iascii) { 865 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer)); 866 PetscCall(PetscViewerASCIIPushTab(viewer)); 867 PetscTryTypeMethod(linesearch,view ,viewer); 868 PetscCall(PetscViewerASCIIPopTab(viewer)); 869 PetscCall(PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol)); 870 PetscCall(PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol)); 871 PetscCall(PetscViewerASCIIPrintf(viewer," maximum iterations=%" PetscInt_FMT "\n", linesearch->max_its)); 872 if (linesearch->ops->precheck) { 873 if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) { 874 PetscCall(PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n")); 875 } else { 876 PetscCall(PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n")); 877 } 878 } 879 if (linesearch->ops->postcheck) { 880 PetscCall(PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n")); 881 } 882 } 883 PetscFunctionReturn(0); 884 } 885 886 /*@C 887 SNESLineSearchGetType - Gets the linesearch type 888 889 Logically Collective on SNESLineSearch 890 891 Input Parameters: 892 . linesearch - linesearch context 893 894 Output Parameters: 895 - type - The type of line search, or NULL if not set 896 897 Level: intermediate 898 899 .seealso: `SNESLineSearchCreate()`, `SNESLineSearchType`, `SNESLineSearchSetFromOptions()`, `SNESLineSearchSetType()` 900 @*/ 901 PetscErrorCode SNESLineSearchGetType(SNESLineSearch linesearch, SNESLineSearchType *type) 902 { 903 PetscFunctionBegin; 904 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 905 PetscValidPointer(type,2); 906 *type = ((PetscObject)linesearch)->type_name; 907 PetscFunctionReturn(0); 908 } 909 910 /*@C 911 SNESLineSearchSetType - Sets the linesearch type 912 913 Logically Collective on SNESLineSearch 914 915 Input Parameters: 916 + linesearch - linesearch context 917 - type - The type of line search to be used 918 919 Available Types: 920 + SNESLINESEARCHBASIC - (or equivalently SNESLINESEARCHNONE) Simple damping line search, defaults to using the full Newton step 921 . SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function 922 . SNESLINESEARCHL2 - Secant line search over the L2 norm of the function 923 . SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x) 924 . SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch 925 - SNESLINESEARCHSHELL - User provided SNESLineSearch implementation 926 927 Options Database: 928 . -snes_linesearch_type <type> - basic (or equivalently none), bt, l2, cp, nleqerr, shell 929 930 Level: intermediate 931 932 .seealso: `SNESLineSearchCreate()`, `SNESLineSearchType`, `SNESLineSearchSetFromOptions()`, `SNESLineSearchGetType()` 933 @*/ 934 PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type) 935 { 936 PetscBool match; 937 PetscErrorCode (*r)(SNESLineSearch); 938 939 PetscFunctionBegin; 940 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 941 PetscValidCharPointer(type,2); 942 943 PetscCall(PetscObjectTypeCompare((PetscObject)linesearch,type,&match)); 944 if (match) PetscFunctionReturn(0); 945 946 PetscCall(PetscFunctionListFind(SNESLineSearchList,type,&r)); 947 PetscCheck(r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type); 948 /* Destroy the previous private linesearch context */ 949 if (linesearch->ops->destroy) { 950 PetscCall((*(linesearch)->ops->destroy)(linesearch)); 951 linesearch->ops->destroy = NULL; 952 } 953 /* Reinitialize function pointers in SNESLineSearchOps structure */ 954 linesearch->ops->apply = NULL; 955 linesearch->ops->view = NULL; 956 linesearch->ops->setfromoptions = NULL; 957 linesearch->ops->destroy = NULL; 958 959 PetscCall(PetscObjectChangeTypeName((PetscObject)linesearch,type)); 960 PetscCall((*r)(linesearch)); 961 PetscFunctionReturn(0); 962 } 963 964 /*@ 965 SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation. 966 967 Input Parameters: 968 + linesearch - linesearch context 969 - snes - The snes instance 970 971 Level: developer 972 973 Notes: 974 This happens automatically when the line search is obtained/created with 975 SNESGetLineSearch(). This routine is therefore mainly called within SNES 976 implementations. 977 978 Level: developer 979 980 .seealso: `SNESLineSearchGetSNES()`, `SNESLineSearchSetVecs()`, `SNES` 981 @*/ 982 PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes) 983 { 984 PetscFunctionBegin; 985 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 986 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 987 linesearch->snes = snes; 988 PetscFunctionReturn(0); 989 } 990 991 /*@ 992 SNESLineSearchGetSNES - Gets the SNES instance associated with the line search. 993 Having an associated SNES is necessary because most line search implementations must be able to 994 evaluate the function using SNESComputeFunction() for the associated SNES. This routine 995 is used in the line search implementations when one must get this associated SNES instance. 996 997 Input Parameters: 998 . linesearch - linesearch context 999 1000 Output Parameters: 1001 . snes - The snes instance 1002 1003 Level: developer 1004 1005 .seealso: `SNESLineSearchGetSNES()`, `SNESLineSearchSetVecs()`, `SNES` 1006 @*/ 1007 PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes) 1008 { 1009 PetscFunctionBegin; 1010 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1011 PetscValidPointer(snes,2); 1012 *snes = linesearch->snes; 1013 PetscFunctionReturn(0); 1014 } 1015 1016 /*@ 1017 SNESLineSearchGetLambda - Gets the last linesearch steplength discovered. 1018 1019 Input Parameters: 1020 . linesearch - linesearch context 1021 1022 Output Parameters: 1023 . lambda - The last steplength computed during SNESLineSearchApply() 1024 1025 Level: advanced 1026 1027 Notes: 1028 This is useful in methods where the solver is ill-scaled and 1029 requires some adaptive notion of the difference in scale between the 1030 solution and the function. For instance, SNESQN may be scaled by the 1031 line search lambda using the argument -snes_qn_scaling ls. 1032 1033 .seealso: `SNESLineSearchSetLambda()`, `SNESLineSearchGetDamping()`, `SNESLineSearchApply()` 1034 @*/ 1035 PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda) 1036 { 1037 PetscFunctionBegin; 1038 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1039 PetscValidRealPointer(lambda, 2); 1040 *lambda = linesearch->lambda; 1041 PetscFunctionReturn(0); 1042 } 1043 1044 /*@ 1045 SNESLineSearchSetLambda - Sets the linesearch steplength. 1046 1047 Input Parameters: 1048 + linesearch - linesearch context 1049 - lambda - The last steplength. 1050 1051 Notes: 1052 This routine is typically used within implementations of SNESLineSearchApply() 1053 to set the final steplength. This routine (and SNESLineSearchGetLambda()) were 1054 added in order to facilitate Quasi-Newton methods that use the previous steplength 1055 as an inner scaling parameter. 1056 1057 Level: advanced 1058 1059 .seealso: `SNESLineSearchGetLambda()` 1060 @*/ 1061 PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda) 1062 { 1063 PetscFunctionBegin; 1064 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1065 linesearch->lambda = lambda; 1066 PetscFunctionReturn(0); 1067 } 1068 1069 /*@ 1070 SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include 1071 tolerances for the relative and absolute change in the function norm, the change 1072 in lambda for iterative line searches, the minimum steplength, the maximum steplength, 1073 and the maximum number of iterations the line search procedure may take. 1074 1075 Input Parameter: 1076 . linesearch - linesearch context 1077 1078 Output Parameters: 1079 + steptol - The minimum steplength 1080 . maxstep - The maximum steplength 1081 . rtol - The relative tolerance for iterative line searches 1082 . atol - The absolute tolerance for iterative line searches 1083 . ltol - The change in lambda tolerance for iterative line searches 1084 - max_it - The maximum number of iterations of the line search 1085 1086 Level: intermediate 1087 1088 Notes: 1089 Different line searches may implement these parameters slightly differently as 1090 the type requires. 1091 1092 .seealso: `SNESLineSearchSetTolerances()` 1093 @*/ 1094 PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its) 1095 { 1096 PetscFunctionBegin; 1097 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1098 if (steptol) { 1099 PetscValidRealPointer(steptol, 2); 1100 *steptol = linesearch->steptol; 1101 } 1102 if (maxstep) { 1103 PetscValidRealPointer(maxstep, 3); 1104 *maxstep = linesearch->maxstep; 1105 } 1106 if (rtol) { 1107 PetscValidRealPointer(rtol, 4); 1108 *rtol = linesearch->rtol; 1109 } 1110 if (atol) { 1111 PetscValidRealPointer(atol, 5); 1112 *atol = linesearch->atol; 1113 } 1114 if (ltol) { 1115 PetscValidRealPointer(ltol, 6); 1116 *ltol = linesearch->ltol; 1117 } 1118 if (max_its) { 1119 PetscValidIntPointer(max_its, 7); 1120 *max_its = linesearch->max_its; 1121 } 1122 PetscFunctionReturn(0); 1123 } 1124 1125 /*@ 1126 SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include 1127 tolerances for the relative and absolute change in the function norm, the change 1128 in lambda for iterative line searches, the minimum steplength, the maximum steplength, 1129 and the maximum number of iterations the line search procedure may take. 1130 1131 Input Parameters: 1132 + linesearch - linesearch context 1133 . steptol - The minimum steplength 1134 . maxstep - The maximum steplength 1135 . rtol - The relative tolerance for iterative line searches 1136 . atol - The absolute tolerance for iterative line searches 1137 . ltol - The change in lambda tolerance for iterative line searches 1138 - max_it - The maximum number of iterations of the line search 1139 1140 Notes: 1141 The user may choose to not set any of the tolerances using PETSC_DEFAULT in 1142 place of an argument. 1143 1144 Level: intermediate 1145 1146 .seealso: `SNESLineSearchGetTolerances()` 1147 @*/ 1148 PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its) 1149 { 1150 PetscFunctionBegin; 1151 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1152 PetscValidLogicalCollectiveReal(linesearch,steptol,2); 1153 PetscValidLogicalCollectiveReal(linesearch,maxstep,3); 1154 PetscValidLogicalCollectiveReal(linesearch,rtol,4); 1155 PetscValidLogicalCollectiveReal(linesearch,atol,5); 1156 PetscValidLogicalCollectiveReal(linesearch,ltol,6); 1157 PetscValidLogicalCollectiveInt(linesearch,max_its,7); 1158 1159 if (steptol!= PETSC_DEFAULT) { 1160 PetscCheck(steptol >= 0.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol); 1161 linesearch->steptol = steptol; 1162 } 1163 1164 if (maxstep!= PETSC_DEFAULT) { 1165 PetscCheck(maxstep >= 0.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep); 1166 linesearch->maxstep = maxstep; 1167 } 1168 1169 if (rtol != PETSC_DEFAULT) { 1170 PetscCheck(rtol >= 0.0 && rtol < 1.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %14.12e must be non-negative and less than 1.0",(double)rtol); 1171 linesearch->rtol = rtol; 1172 } 1173 1174 if (atol != PETSC_DEFAULT) { 1175 PetscCheck(atol >= 0.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol); 1176 linesearch->atol = atol; 1177 } 1178 1179 if (ltol != PETSC_DEFAULT) { 1180 PetscCheck(ltol >= 0.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Lambda tolerance %14.12e must be non-negative",(double)ltol); 1181 linesearch->ltol = ltol; 1182 } 1183 1184 if (max_its != PETSC_DEFAULT) { 1185 PetscCheck(max_its >= 0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %" PetscInt_FMT " must be non-negative",max_its); 1186 linesearch->max_its = max_its; 1187 } 1188 PetscFunctionReturn(0); 1189 } 1190 1191 /*@ 1192 SNESLineSearchGetDamping - Gets the line search damping parameter. 1193 1194 Input Parameters: 1195 . linesearch - linesearch context 1196 1197 Output Parameters: 1198 . damping - The damping parameter 1199 1200 Level: advanced 1201 1202 .seealso: `SNESLineSearchGetStepTolerance()`, `SNESQN` 1203 @*/ 1204 1205 PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping) 1206 { 1207 PetscFunctionBegin; 1208 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1209 PetscValidRealPointer(damping, 2); 1210 *damping = linesearch->damping; 1211 PetscFunctionReturn(0); 1212 } 1213 1214 /*@ 1215 SNESLineSearchSetDamping - Sets the line search damping parameter. 1216 1217 Input Parameters: 1218 + linesearch - linesearch context 1219 - damping - The damping parameter 1220 1221 Options Database: 1222 . -snes_linesearch_damping 1223 Level: intermediate 1224 1225 Notes: 1226 The basic (also known as the none) line search merely takes the update step scaled by the damping parameter. 1227 The use of the damping parameter in the l2 and cp line searches is much more subtle; 1228 it is used as a starting point in calculating the secant step. However, the eventual 1229 step may be of greater length than the damping parameter. In the bt line search it is 1230 used as the maximum possible step length, as the bt line search only backtracks. 1231 1232 .seealso: `SNESLineSearchGetDamping()` 1233 @*/ 1234 PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping) 1235 { 1236 PetscFunctionBegin; 1237 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1238 linesearch->damping = damping; 1239 PetscFunctionReturn(0); 1240 } 1241 1242 /*@ 1243 SNESLineSearchGetOrder - Gets the line search approximation order. 1244 1245 Input Parameters: 1246 . linesearch - linesearch context 1247 1248 Output Parameters: 1249 . order - The order 1250 1251 Possible Values for order: 1252 + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order 1253 . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order 1254 - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order 1255 1256 Level: intermediate 1257 1258 .seealso: `SNESLineSearchSetOrder()` 1259 @*/ 1260 1261 PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order) 1262 { 1263 PetscFunctionBegin; 1264 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1265 PetscValidIntPointer(order, 2); 1266 *order = linesearch->order; 1267 PetscFunctionReturn(0); 1268 } 1269 1270 /*@ 1271 SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search 1272 1273 Input Parameters: 1274 + linesearch - linesearch context 1275 - order - The damping parameter 1276 1277 Level: intermediate 1278 1279 Possible Values for order: 1280 + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order 1281 . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order 1282 - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order 1283 1284 Notes: 1285 Variable orders are supported by the following line searches: 1286 + bt - cubic and quadratic 1287 - cp - linear and quadratic 1288 1289 .seealso: `SNESLineSearchGetOrder()`, `SNESLineSearchSetDamping()` 1290 @*/ 1291 PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order) 1292 { 1293 PetscFunctionBegin; 1294 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1295 linesearch->order = order; 1296 PetscFunctionReturn(0); 1297 } 1298 1299 /*@ 1300 SNESLineSearchGetNorms - Gets the norms for for X, Y, and F. 1301 1302 Input Parameter: 1303 . linesearch - linesearch context 1304 1305 Output Parameters: 1306 + xnorm - The norm of the current solution 1307 . fnorm - The norm of the current function 1308 - ynorm - The norm of the current update 1309 1310 Notes: 1311 This function is mainly called from SNES implementations. 1312 1313 Level: developer 1314 1315 .seealso: `SNESLineSearchSetNorms()` `SNESLineSearchGetVecs()` 1316 @*/ 1317 PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm) 1318 { 1319 PetscFunctionBegin; 1320 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1321 if (xnorm) *xnorm = linesearch->xnorm; 1322 if (fnorm) *fnorm = linesearch->fnorm; 1323 if (ynorm) *ynorm = linesearch->ynorm; 1324 PetscFunctionReturn(0); 1325 } 1326 1327 /*@ 1328 SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F. 1329 1330 Input Parameters: 1331 + linesearch - linesearch context 1332 . xnorm - The norm of the current solution 1333 . fnorm - The norm of the current function 1334 - ynorm - The norm of the current update 1335 1336 Level: advanced 1337 1338 .seealso: `SNESLineSearchGetNorms()`, `SNESLineSearchSetVecs()` 1339 @*/ 1340 PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm) 1341 { 1342 PetscFunctionBegin; 1343 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1344 linesearch->xnorm = xnorm; 1345 linesearch->fnorm = fnorm; 1346 linesearch->ynorm = ynorm; 1347 PetscFunctionReturn(0); 1348 } 1349 1350 /*@ 1351 SNESLineSearchComputeNorms - Computes the norms of X, F, and Y. 1352 1353 Input Parameters: 1354 . linesearch - linesearch context 1355 1356 Options Database Keys: 1357 . -snes_linesearch_norms - turn norm computation on or off 1358 1359 Level: intermediate 1360 1361 .seealso: `SNESLineSearchGetNorms`, `SNESLineSearchSetNorms()`, `SNESLineSearchSetComputeNorms()` 1362 @*/ 1363 PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch) 1364 { 1365 SNES snes; 1366 1367 PetscFunctionBegin; 1368 if (linesearch->norms) { 1369 if (linesearch->ops->vinorm) { 1370 PetscCall(SNESLineSearchGetSNES(linesearch, &snes)); 1371 PetscCall(VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm)); 1372 PetscCall(VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm)); 1373 PetscCall((*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm)); 1374 } else { 1375 PetscCall(VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm)); 1376 PetscCall(VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm)); 1377 PetscCall(VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm)); 1378 PetscCall(VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm)); 1379 PetscCall(VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm)); 1380 PetscCall(VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm)); 1381 } 1382 } 1383 PetscFunctionReturn(0); 1384 } 1385 1386 /*@ 1387 SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search. 1388 1389 Input Parameters: 1390 + linesearch - linesearch context 1391 - flg - indicates whether or not to compute norms 1392 1393 Options Database Keys: 1394 . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic (none) linesearch 1395 1396 Notes: 1397 This is most relevant to the SNESLINESEARCHBASIC (or equivalently SNESLINESEARCHNONE) line search type since most line searches have a stopping criteria involving the norm. 1398 1399 Level: intermediate 1400 1401 .seealso: `SNESLineSearchGetNorms()`, `SNESLineSearchSetNorms()`, `SNESLineSearchComputeNorms()`, `SNESLINESEARCHBASIC` 1402 @*/ 1403 PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg) 1404 { 1405 PetscFunctionBegin; 1406 linesearch->norms = flg; 1407 PetscFunctionReturn(0); 1408 } 1409 1410 /*@ 1411 SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context 1412 1413 Input Parameter: 1414 . linesearch - linesearch context 1415 1416 Output Parameters: 1417 + X - Solution vector 1418 . F - Function vector 1419 . Y - Search direction vector 1420 . W - Solution work vector 1421 - G - Function work vector 1422 1423 Notes: 1424 At the beginning of a line search application, X should contain a 1425 solution and the vector F the function computed at X. At the end of the 1426 line search application, X should contain the new solution, and F the 1427 function evaluated at the new solution. 1428 1429 These vectors are owned by the SNESLineSearch and should not be destroyed by the caller 1430 1431 Level: advanced 1432 1433 .seealso: `SNESLineSearchGetNorms()`, `SNESLineSearchSetVecs()` 1434 @*/ 1435 PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G) 1436 { 1437 PetscFunctionBegin; 1438 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1439 if (X) { 1440 PetscValidPointer(X, 2); 1441 *X = linesearch->vec_sol; 1442 } 1443 if (F) { 1444 PetscValidPointer(F, 3); 1445 *F = linesearch->vec_func; 1446 } 1447 if (Y) { 1448 PetscValidPointer(Y, 4); 1449 *Y = linesearch->vec_update; 1450 } 1451 if (W) { 1452 PetscValidPointer(W, 5); 1453 *W = linesearch->vec_sol_new; 1454 } 1455 if (G) { 1456 PetscValidPointer(G, 6); 1457 *G = linesearch->vec_func_new; 1458 } 1459 PetscFunctionReturn(0); 1460 } 1461 1462 /*@ 1463 SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context 1464 1465 Input Parameters: 1466 + linesearch - linesearch context 1467 . X - Solution vector 1468 . F - Function vector 1469 . Y - Search direction vector 1470 . W - Solution work vector 1471 - G - Function work vector 1472 1473 Level: advanced 1474 1475 .seealso: `SNESLineSearchSetNorms()`, `SNESLineSearchGetVecs()` 1476 @*/ 1477 PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G) 1478 { 1479 PetscFunctionBegin; 1480 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1481 if (X) { 1482 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 1483 linesearch->vec_sol = X; 1484 } 1485 if (F) { 1486 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 1487 linesearch->vec_func = F; 1488 } 1489 if (Y) { 1490 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 1491 linesearch->vec_update = Y; 1492 } 1493 if (W) { 1494 PetscValidHeaderSpecific(W,VEC_CLASSID,5); 1495 linesearch->vec_sol_new = W; 1496 } 1497 if (G) { 1498 PetscValidHeaderSpecific(G,VEC_CLASSID,6); 1499 linesearch->vec_func_new = G; 1500 } 1501 PetscFunctionReturn(0); 1502 } 1503 1504 /*@C 1505 SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all 1506 SNES options in the database. 1507 1508 Logically Collective on SNESLineSearch 1509 1510 Input Parameters: 1511 + snes - the SNES context 1512 - prefix - the prefix to prepend to all option names 1513 1514 Notes: 1515 A hyphen (-) must NOT be given at the beginning of the prefix name. 1516 The first character of all runtime options is AUTOMATICALLY the hyphen. 1517 1518 Level: advanced 1519 1520 .seealso: `SNESGetOptionsPrefix()` 1521 @*/ 1522 PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[]) 1523 { 1524 PetscFunctionBegin; 1525 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1526 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix)); 1527 PetscFunctionReturn(0); 1528 } 1529 1530 /*@C 1531 SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all 1532 SNESLineSearch options in the database. 1533 1534 Not Collective 1535 1536 Input Parameter: 1537 . linesearch - the SNESLineSearch context 1538 1539 Output Parameter: 1540 . prefix - pointer to the prefix string used 1541 1542 Notes: 1543 On the fortran side, the user should pass in a string 'prefix' of 1544 sufficient length to hold the prefix. 1545 1546 Level: advanced 1547 1548 .seealso: `SNESAppendOptionsPrefix()` 1549 @*/ 1550 PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[]) 1551 { 1552 PetscFunctionBegin; 1553 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1554 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix)); 1555 PetscFunctionReturn(0); 1556 } 1557 1558 /*@C 1559 SNESLineSearchSetWorkVecs - Gets work vectors for the line search. 1560 1561 Input Parameters: 1562 + linesearch - the SNESLineSearch context 1563 - nwork - the number of work vectors 1564 1565 Level: developer 1566 1567 .seealso: `SNESSetWorkVecs()` 1568 @*/ 1569 PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork) 1570 { 1571 PetscFunctionBegin; 1572 if (linesearch->vec_sol) { 1573 PetscCall(VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work)); 1574 } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!"); 1575 PetscFunctionReturn(0); 1576 } 1577 1578 /*@ 1579 SNESLineSearchGetReason - Gets the success/failure status of the last line search application 1580 1581 Input Parameters: 1582 . linesearch - linesearch context 1583 1584 Output Parameters: 1585 . result - The success or failure status 1586 1587 Notes: 1588 This is typically called after SNESLineSearchApply() in order to determine if the line-search failed 1589 (and set the SNES convergence accordingly). 1590 1591 Level: intermediate 1592 1593 .seealso: `SNESLineSearchSetReason()`, `SNESLineSearchReason` 1594 @*/ 1595 PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result) 1596 { 1597 PetscFunctionBegin; 1598 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1599 PetscValidPointer(result, 2); 1600 *result = linesearch->result; 1601 PetscFunctionReturn(0); 1602 } 1603 1604 /*@ 1605 SNESLineSearchSetReason - Sets the success/failure status of the last line search application 1606 1607 Input Parameters: 1608 + linesearch - linesearch context 1609 - result - The success or failure status 1610 1611 Notes: 1612 This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set 1613 the success or failure of the line search method. 1614 1615 Level: developer 1616 1617 .seealso: `SNESLineSearchGetSResult()` 1618 @*/ 1619 PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result) 1620 { 1621 PetscFunctionBegin; 1622 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1623 linesearch->result = result; 1624 PetscFunctionReturn(0); 1625 } 1626 1627 /*@C 1628 SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation. 1629 1630 Input Parameters: 1631 + snes - nonlinear context obtained from SNESCreate() 1632 . projectfunc - function for projecting the function to the bounds 1633 - normfunc - function for computing the norm of an active set 1634 1635 Logically Collective on SNES 1636 1637 Calling sequence of projectfunc: 1638 .vb 1639 projectfunc (SNES snes, Vec X) 1640 .ve 1641 1642 Input parameters for projectfunc: 1643 + snes - nonlinear context 1644 - X - current solution 1645 1646 Output parameters for projectfunc: 1647 . X - Projected solution 1648 1649 Calling sequence of normfunc: 1650 .vb 1651 projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm) 1652 .ve 1653 1654 Input parameters for normfunc: 1655 + snes - nonlinear context 1656 . X - current solution 1657 - F - current residual 1658 1659 Output parameters for normfunc: 1660 . fnorm - VI-specific norm of the function 1661 1662 Notes: 1663 The VI solvers require projection of the solution to the feasible set. projectfunc should implement this. 1664 1665 The VI solvers require special evaluation of the function norm such that the norm is only calculated 1666 on the inactive set. This should be implemented by normfunc. 1667 1668 Level: developer 1669 1670 .seealso: `SNESLineSearchGetVIFunctions()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchSetPreCheck()` 1671 @*/ 1672 PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc) 1673 { 1674 PetscFunctionBegin; 1675 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1676 if (projectfunc) linesearch->ops->viproject = projectfunc; 1677 if (normfunc) linesearch->ops->vinorm = normfunc; 1678 PetscFunctionReturn(0); 1679 } 1680 1681 /*@C 1682 SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation. 1683 1684 Input Parameter: 1685 . linesearch - the line search context, obtain with SNESGetLineSearch() 1686 1687 Output Parameters: 1688 + projectfunc - function for projecting the function to the bounds 1689 - normfunc - function for computing the norm of an active set 1690 1691 Logically Collective on SNES 1692 1693 Level: developer 1694 1695 .seealso: `SNESLineSearchSetVIFunctions()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchGetPreCheck()` 1696 @*/ 1697 PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc) 1698 { 1699 PetscFunctionBegin; 1700 if (projectfunc) *projectfunc = linesearch->ops->viproject; 1701 if (normfunc) *normfunc = linesearch->ops->vinorm; 1702 PetscFunctionReturn(0); 1703 } 1704 1705 /*@C 1706 SNESLineSearchRegister - See SNESLineSearchRegister() 1707 1708 Level: advanced 1709 @*/ 1710 PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch)) 1711 { 1712 PetscFunctionBegin; 1713 PetscCall(SNESInitializePackage()); 1714 PetscCall(PetscFunctionListAdd(&SNESLineSearchList,sname,function)); 1715 PetscFunctionReturn(0); 1716 } 1717