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) PetscCall((*linesearch->ops->setup)(linesearch)); 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) PetscCall((*linesearch->ops->reset)(linesearch)); 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 PetscCall((*linesearch->ops->precheck)(linesearch, 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 PetscCall((*linesearch->ops->postcheck)(linesearch,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 PetscCall((*linesearch->ops->apply)(linesearch)); 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 if (linesearch->ops->setfromoptions) PetscCall((*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch)); 833 834 PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch)); 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 if (linesearch->ops->view) { 867 PetscCall(PetscViewerASCIIPushTab(viewer)); 868 PetscCall((*linesearch->ops->view)(linesearch,viewer)); 869 PetscCall(PetscViewerASCIIPopTab(viewer)); 870 } 871 PetscCall(PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol)); 872 PetscCall(PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol)); 873 PetscCall(PetscViewerASCIIPrintf(viewer," maximum iterations=%" PetscInt_FMT "\n", linesearch->max_its)); 874 if (linesearch->ops->precheck) { 875 if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) { 876 PetscCall(PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n")); 877 } else { 878 PetscCall(PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n")); 879 } 880 } 881 if (linesearch->ops->postcheck) { 882 PetscCall(PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n")); 883 } 884 } 885 PetscFunctionReturn(0); 886 } 887 888 /*@C 889 SNESLineSearchGetType - Gets the linesearch type 890 891 Logically Collective on SNESLineSearch 892 893 Input Parameters: 894 . linesearch - linesearch context 895 896 Output Parameters: 897 - type - The type of line search, or NULL if not set 898 899 Level: intermediate 900 901 .seealso: `SNESLineSearchCreate()`, `SNESLineSearchType`, `SNESLineSearchSetFromOptions()`, `SNESLineSearchSetType()` 902 @*/ 903 PetscErrorCode SNESLineSearchGetType(SNESLineSearch linesearch, SNESLineSearchType *type) 904 { 905 PetscFunctionBegin; 906 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 907 PetscValidPointer(type,2); 908 *type = ((PetscObject)linesearch)->type_name; 909 PetscFunctionReturn(0); 910 } 911 912 /*@C 913 SNESLineSearchSetType - Sets the linesearch type 914 915 Logically Collective on SNESLineSearch 916 917 Input Parameters: 918 + linesearch - linesearch context 919 - type - The type of line search to be used 920 921 Available Types: 922 + SNESLINESEARCHBASIC - (or equivalently SNESLINESEARCHNONE) Simple damping line search, defaults to using the full Newton step 923 . SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function 924 . SNESLINESEARCHL2 - Secant line search over the L2 norm of the function 925 . SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x) 926 . SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch 927 - SNESLINESEARCHSHELL - User provided SNESLineSearch implementation 928 929 Options Database: 930 . -snes_linesearch_type <type> - basic (or equivalently none), bt, l2, cp, nleqerr, shell 931 932 Level: intermediate 933 934 .seealso: `SNESLineSearchCreate()`, `SNESLineSearchType`, `SNESLineSearchSetFromOptions()`, `SNESLineSearchGetType()` 935 @*/ 936 PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type) 937 { 938 PetscBool match; 939 PetscErrorCode (*r)(SNESLineSearch); 940 941 PetscFunctionBegin; 942 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 943 PetscValidCharPointer(type,2); 944 945 PetscCall(PetscObjectTypeCompare((PetscObject)linesearch,type,&match)); 946 if (match) PetscFunctionReturn(0); 947 948 PetscCall(PetscFunctionListFind(SNESLineSearchList,type,&r)); 949 PetscCheck(r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type); 950 /* Destroy the previous private linesearch context */ 951 if (linesearch->ops->destroy) { 952 PetscCall((*(linesearch)->ops->destroy)(linesearch)); 953 linesearch->ops->destroy = NULL; 954 } 955 /* Reinitialize function pointers in SNESLineSearchOps structure */ 956 linesearch->ops->apply = NULL; 957 linesearch->ops->view = NULL; 958 linesearch->ops->setfromoptions = NULL; 959 linesearch->ops->destroy = NULL; 960 961 PetscCall(PetscObjectChangeTypeName((PetscObject)linesearch,type)); 962 PetscCall((*r)(linesearch)); 963 PetscFunctionReturn(0); 964 } 965 966 /*@ 967 SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation. 968 969 Input Parameters: 970 + linesearch - linesearch context 971 - snes - The snes instance 972 973 Level: developer 974 975 Notes: 976 This happens automatically when the line search is obtained/created with 977 SNESGetLineSearch(). This routine is therefore mainly called within SNES 978 implementations. 979 980 Level: developer 981 982 .seealso: `SNESLineSearchGetSNES()`, `SNESLineSearchSetVecs()`, `SNES` 983 @*/ 984 PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes) 985 { 986 PetscFunctionBegin; 987 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 988 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 989 linesearch->snes = snes; 990 PetscFunctionReturn(0); 991 } 992 993 /*@ 994 SNESLineSearchGetSNES - Gets the SNES instance associated with the line search. 995 Having an associated SNES is necessary because most line search implementations must be able to 996 evaluate the function using SNESComputeFunction() for the associated SNES. This routine 997 is used in the line search implementations when one must get this associated SNES instance. 998 999 Input Parameters: 1000 . linesearch - linesearch context 1001 1002 Output Parameters: 1003 . snes - The snes instance 1004 1005 Level: developer 1006 1007 .seealso: `SNESLineSearchGetSNES()`, `SNESLineSearchSetVecs()`, `SNES` 1008 @*/ 1009 PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes) 1010 { 1011 PetscFunctionBegin; 1012 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1013 PetscValidPointer(snes,2); 1014 *snes = linesearch->snes; 1015 PetscFunctionReturn(0); 1016 } 1017 1018 /*@ 1019 SNESLineSearchGetLambda - Gets the last linesearch steplength discovered. 1020 1021 Input Parameters: 1022 . linesearch - linesearch context 1023 1024 Output Parameters: 1025 . lambda - The last steplength computed during SNESLineSearchApply() 1026 1027 Level: advanced 1028 1029 Notes: 1030 This is useful in methods where the solver is ill-scaled and 1031 requires some adaptive notion of the difference in scale between the 1032 solution and the function. For instance, SNESQN may be scaled by the 1033 line search lambda using the argument -snes_qn_scaling ls. 1034 1035 .seealso: `SNESLineSearchSetLambda()`, `SNESLineSearchGetDamping()`, `SNESLineSearchApply()` 1036 @*/ 1037 PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda) 1038 { 1039 PetscFunctionBegin; 1040 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1041 PetscValidRealPointer(lambda, 2); 1042 *lambda = linesearch->lambda; 1043 PetscFunctionReturn(0); 1044 } 1045 1046 /*@ 1047 SNESLineSearchSetLambda - Sets the linesearch steplength. 1048 1049 Input Parameters: 1050 + linesearch - linesearch context 1051 - lambda - The last steplength. 1052 1053 Notes: 1054 This routine is typically used within implementations of SNESLineSearchApply() 1055 to set the final steplength. This routine (and SNESLineSearchGetLambda()) were 1056 added in order to facilitate Quasi-Newton methods that use the previous steplength 1057 as an inner scaling parameter. 1058 1059 Level: advanced 1060 1061 .seealso: `SNESLineSearchGetLambda()` 1062 @*/ 1063 PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda) 1064 { 1065 PetscFunctionBegin; 1066 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1067 linesearch->lambda = lambda; 1068 PetscFunctionReturn(0); 1069 } 1070 1071 /*@ 1072 SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include 1073 tolerances for the relative and absolute change in the function norm, the change 1074 in lambda for iterative line searches, the minimum steplength, the maximum steplength, 1075 and the maximum number of iterations the line search procedure may take. 1076 1077 Input Parameter: 1078 . linesearch - linesearch context 1079 1080 Output Parameters: 1081 + steptol - The minimum steplength 1082 . maxstep - The maximum steplength 1083 . rtol - The relative tolerance for iterative line searches 1084 . atol - The absolute tolerance for iterative line searches 1085 . ltol - The change in lambda tolerance for iterative line searches 1086 - max_it - The maximum number of iterations of the line search 1087 1088 Level: intermediate 1089 1090 Notes: 1091 Different line searches may implement these parameters slightly differently as 1092 the type requires. 1093 1094 .seealso: `SNESLineSearchSetTolerances()` 1095 @*/ 1096 PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its) 1097 { 1098 PetscFunctionBegin; 1099 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1100 if (steptol) { 1101 PetscValidRealPointer(steptol, 2); 1102 *steptol = linesearch->steptol; 1103 } 1104 if (maxstep) { 1105 PetscValidRealPointer(maxstep, 3); 1106 *maxstep = linesearch->maxstep; 1107 } 1108 if (rtol) { 1109 PetscValidRealPointer(rtol, 4); 1110 *rtol = linesearch->rtol; 1111 } 1112 if (atol) { 1113 PetscValidRealPointer(atol, 5); 1114 *atol = linesearch->atol; 1115 } 1116 if (ltol) { 1117 PetscValidRealPointer(ltol, 6); 1118 *ltol = linesearch->ltol; 1119 } 1120 if (max_its) { 1121 PetscValidIntPointer(max_its, 7); 1122 *max_its = linesearch->max_its; 1123 } 1124 PetscFunctionReturn(0); 1125 } 1126 1127 /*@ 1128 SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include 1129 tolerances for the relative and absolute change in the function norm, the change 1130 in lambda for iterative line searches, the minimum steplength, the maximum steplength, 1131 and the maximum number of iterations the line search procedure may take. 1132 1133 Input Parameters: 1134 + linesearch - linesearch context 1135 . steptol - The minimum steplength 1136 . maxstep - The maximum steplength 1137 . rtol - The relative tolerance for iterative line searches 1138 . atol - The absolute tolerance for iterative line searches 1139 . ltol - The change in lambda tolerance for iterative line searches 1140 - max_it - The maximum number of iterations of the line search 1141 1142 Notes: 1143 The user may choose to not set any of the tolerances using PETSC_DEFAULT in 1144 place of an argument. 1145 1146 Level: intermediate 1147 1148 .seealso: `SNESLineSearchGetTolerances()` 1149 @*/ 1150 PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its) 1151 { 1152 PetscFunctionBegin; 1153 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1154 PetscValidLogicalCollectiveReal(linesearch,steptol,2); 1155 PetscValidLogicalCollectiveReal(linesearch,maxstep,3); 1156 PetscValidLogicalCollectiveReal(linesearch,rtol,4); 1157 PetscValidLogicalCollectiveReal(linesearch,atol,5); 1158 PetscValidLogicalCollectiveReal(linesearch,ltol,6); 1159 PetscValidLogicalCollectiveInt(linesearch,max_its,7); 1160 1161 if (steptol!= PETSC_DEFAULT) { 1162 PetscCheck(steptol >= 0.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol); 1163 linesearch->steptol = steptol; 1164 } 1165 1166 if (maxstep!= PETSC_DEFAULT) { 1167 PetscCheck(maxstep >= 0.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep); 1168 linesearch->maxstep = maxstep; 1169 } 1170 1171 if (rtol != PETSC_DEFAULT) { 1172 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); 1173 linesearch->rtol = rtol; 1174 } 1175 1176 if (atol != PETSC_DEFAULT) { 1177 PetscCheck(atol >= 0.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol); 1178 linesearch->atol = atol; 1179 } 1180 1181 if (ltol != PETSC_DEFAULT) { 1182 PetscCheck(ltol >= 0.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Lambda tolerance %14.12e must be non-negative",(double)ltol); 1183 linesearch->ltol = ltol; 1184 } 1185 1186 if (max_its != PETSC_DEFAULT) { 1187 PetscCheck(max_its >= 0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %" PetscInt_FMT " must be non-negative",max_its); 1188 linesearch->max_its = max_its; 1189 } 1190 PetscFunctionReturn(0); 1191 } 1192 1193 /*@ 1194 SNESLineSearchGetDamping - Gets the line search damping parameter. 1195 1196 Input Parameters: 1197 . linesearch - linesearch context 1198 1199 Output Parameters: 1200 . damping - The damping parameter 1201 1202 Level: advanced 1203 1204 .seealso: `SNESLineSearchGetStepTolerance()`, `SNESQN` 1205 @*/ 1206 1207 PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping) 1208 { 1209 PetscFunctionBegin; 1210 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1211 PetscValidRealPointer(damping, 2); 1212 *damping = linesearch->damping; 1213 PetscFunctionReturn(0); 1214 } 1215 1216 /*@ 1217 SNESLineSearchSetDamping - Sets the line search damping parameter. 1218 1219 Input Parameters: 1220 + linesearch - linesearch context 1221 - damping - The damping parameter 1222 1223 Options Database: 1224 . -snes_linesearch_damping 1225 Level: intermediate 1226 1227 Notes: 1228 The basic (also known as the none) line search merely takes the update step scaled by the damping parameter. 1229 The use of the damping parameter in the l2 and cp line searches is much more subtle; 1230 it is used as a starting point in calculating the secant step. However, the eventual 1231 step may be of greater length than the damping parameter. In the bt line search it is 1232 used as the maximum possible step length, as the bt line search only backtracks. 1233 1234 .seealso: `SNESLineSearchGetDamping()` 1235 @*/ 1236 PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping) 1237 { 1238 PetscFunctionBegin; 1239 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1240 linesearch->damping = damping; 1241 PetscFunctionReturn(0); 1242 } 1243 1244 /*@ 1245 SNESLineSearchGetOrder - Gets the line search approximation order. 1246 1247 Input Parameters: 1248 . linesearch - linesearch context 1249 1250 Output Parameters: 1251 . order - The order 1252 1253 Possible Values for order: 1254 + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order 1255 . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order 1256 - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order 1257 1258 Level: intermediate 1259 1260 .seealso: `SNESLineSearchSetOrder()` 1261 @*/ 1262 1263 PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order) 1264 { 1265 PetscFunctionBegin; 1266 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1267 PetscValidIntPointer(order, 2); 1268 *order = linesearch->order; 1269 PetscFunctionReturn(0); 1270 } 1271 1272 /*@ 1273 SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search 1274 1275 Input Parameters: 1276 + linesearch - linesearch context 1277 - order - The damping parameter 1278 1279 Level: intermediate 1280 1281 Possible Values for order: 1282 + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order 1283 . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order 1284 - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order 1285 1286 Notes: 1287 Variable orders are supported by the following line searches: 1288 + bt - cubic and quadratic 1289 - cp - linear and quadratic 1290 1291 .seealso: `SNESLineSearchGetOrder()`, `SNESLineSearchSetDamping()` 1292 @*/ 1293 PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order) 1294 { 1295 PetscFunctionBegin; 1296 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1297 linesearch->order = order; 1298 PetscFunctionReturn(0); 1299 } 1300 1301 /*@ 1302 SNESLineSearchGetNorms - Gets the norms for for X, Y, and F. 1303 1304 Input Parameter: 1305 . linesearch - linesearch context 1306 1307 Output Parameters: 1308 + xnorm - The norm of the current solution 1309 . fnorm - The norm of the current function 1310 - ynorm - The norm of the current update 1311 1312 Notes: 1313 This function is mainly called from SNES implementations. 1314 1315 Level: developer 1316 1317 .seealso: `SNESLineSearchSetNorms()` `SNESLineSearchGetVecs()` 1318 @*/ 1319 PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm) 1320 { 1321 PetscFunctionBegin; 1322 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1323 if (xnorm) *xnorm = linesearch->xnorm; 1324 if (fnorm) *fnorm = linesearch->fnorm; 1325 if (ynorm) *ynorm = linesearch->ynorm; 1326 PetscFunctionReturn(0); 1327 } 1328 1329 /*@ 1330 SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F. 1331 1332 Input Parameters: 1333 + linesearch - linesearch context 1334 . xnorm - The norm of the current solution 1335 . fnorm - The norm of the current function 1336 - ynorm - The norm of the current update 1337 1338 Level: advanced 1339 1340 .seealso: `SNESLineSearchGetNorms()`, `SNESLineSearchSetVecs()` 1341 @*/ 1342 PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm) 1343 { 1344 PetscFunctionBegin; 1345 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1346 linesearch->xnorm = xnorm; 1347 linesearch->fnorm = fnorm; 1348 linesearch->ynorm = ynorm; 1349 PetscFunctionReturn(0); 1350 } 1351 1352 /*@ 1353 SNESLineSearchComputeNorms - Computes the norms of X, F, and Y. 1354 1355 Input Parameters: 1356 . linesearch - linesearch context 1357 1358 Options Database Keys: 1359 . -snes_linesearch_norms - turn norm computation on or off 1360 1361 Level: intermediate 1362 1363 .seealso: `SNESLineSearchGetNorms`, `SNESLineSearchSetNorms()`, `SNESLineSearchSetComputeNorms()` 1364 @*/ 1365 PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch) 1366 { 1367 SNES snes; 1368 1369 PetscFunctionBegin; 1370 if (linesearch->norms) { 1371 if (linesearch->ops->vinorm) { 1372 PetscCall(SNESLineSearchGetSNES(linesearch, &snes)); 1373 PetscCall(VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm)); 1374 PetscCall(VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm)); 1375 PetscCall((*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm)); 1376 } else { 1377 PetscCall(VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm)); 1378 PetscCall(VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm)); 1379 PetscCall(VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm)); 1380 PetscCall(VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm)); 1381 PetscCall(VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm)); 1382 PetscCall(VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm)); 1383 } 1384 } 1385 PetscFunctionReturn(0); 1386 } 1387 1388 /*@ 1389 SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search. 1390 1391 Input Parameters: 1392 + linesearch - linesearch context 1393 - flg - indicates whether or not to compute norms 1394 1395 Options Database Keys: 1396 . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic (none) linesearch 1397 1398 Notes: 1399 This is most relevant to the SNESLINESEARCHBASIC (or equivalently SNESLINESEARCHNONE) line search type since most line searches have a stopping criteria involving the norm. 1400 1401 Level: intermediate 1402 1403 .seealso: `SNESLineSearchGetNorms()`, `SNESLineSearchSetNorms()`, `SNESLineSearchComputeNorms()`, `SNESLINESEARCHBASIC` 1404 @*/ 1405 PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg) 1406 { 1407 PetscFunctionBegin; 1408 linesearch->norms = flg; 1409 PetscFunctionReturn(0); 1410 } 1411 1412 /*@ 1413 SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context 1414 1415 Input Parameter: 1416 . linesearch - linesearch context 1417 1418 Output Parameters: 1419 + X - Solution vector 1420 . F - Function vector 1421 . Y - Search direction vector 1422 . W - Solution work vector 1423 - G - Function work vector 1424 1425 Notes: 1426 At the beginning of a line search application, X should contain a 1427 solution and the vector F the function computed at X. At the end of the 1428 line search application, X should contain the new solution, and F the 1429 function evaluated at the new solution. 1430 1431 These vectors are owned by the SNESLineSearch and should not be destroyed by the caller 1432 1433 Level: advanced 1434 1435 .seealso: `SNESLineSearchGetNorms()`, `SNESLineSearchSetVecs()` 1436 @*/ 1437 PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G) 1438 { 1439 PetscFunctionBegin; 1440 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1441 if (X) { 1442 PetscValidPointer(X, 2); 1443 *X = linesearch->vec_sol; 1444 } 1445 if (F) { 1446 PetscValidPointer(F, 3); 1447 *F = linesearch->vec_func; 1448 } 1449 if (Y) { 1450 PetscValidPointer(Y, 4); 1451 *Y = linesearch->vec_update; 1452 } 1453 if (W) { 1454 PetscValidPointer(W, 5); 1455 *W = linesearch->vec_sol_new; 1456 } 1457 if (G) { 1458 PetscValidPointer(G, 6); 1459 *G = linesearch->vec_func_new; 1460 } 1461 PetscFunctionReturn(0); 1462 } 1463 1464 /*@ 1465 SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context 1466 1467 Input Parameters: 1468 + linesearch - linesearch context 1469 . X - Solution vector 1470 . F - Function vector 1471 . Y - Search direction vector 1472 . W - Solution work vector 1473 - G - Function work vector 1474 1475 Level: advanced 1476 1477 .seealso: `SNESLineSearchSetNorms()`, `SNESLineSearchGetVecs()` 1478 @*/ 1479 PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G) 1480 { 1481 PetscFunctionBegin; 1482 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1483 if (X) { 1484 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 1485 linesearch->vec_sol = X; 1486 } 1487 if (F) { 1488 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 1489 linesearch->vec_func = F; 1490 } 1491 if (Y) { 1492 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 1493 linesearch->vec_update = Y; 1494 } 1495 if (W) { 1496 PetscValidHeaderSpecific(W,VEC_CLASSID,5); 1497 linesearch->vec_sol_new = W; 1498 } 1499 if (G) { 1500 PetscValidHeaderSpecific(G,VEC_CLASSID,6); 1501 linesearch->vec_func_new = G; 1502 } 1503 PetscFunctionReturn(0); 1504 } 1505 1506 /*@C 1507 SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all 1508 SNES options in the database. 1509 1510 Logically Collective on SNESLineSearch 1511 1512 Input Parameters: 1513 + snes - the SNES context 1514 - prefix - the prefix to prepend to all option names 1515 1516 Notes: 1517 A hyphen (-) must NOT be given at the beginning of the prefix name. 1518 The first character of all runtime options is AUTOMATICALLY the hyphen. 1519 1520 Level: advanced 1521 1522 .seealso: `SNESGetOptionsPrefix()` 1523 @*/ 1524 PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[]) 1525 { 1526 PetscFunctionBegin; 1527 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1528 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix)); 1529 PetscFunctionReturn(0); 1530 } 1531 1532 /*@C 1533 SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all 1534 SNESLineSearch options in the database. 1535 1536 Not Collective 1537 1538 Input Parameter: 1539 . linesearch - the SNESLineSearch context 1540 1541 Output Parameter: 1542 . prefix - pointer to the prefix string used 1543 1544 Notes: 1545 On the fortran side, the user should pass in a string 'prefix' of 1546 sufficient length to hold the prefix. 1547 1548 Level: advanced 1549 1550 .seealso: `SNESAppendOptionsPrefix()` 1551 @*/ 1552 PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[]) 1553 { 1554 PetscFunctionBegin; 1555 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1556 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix)); 1557 PetscFunctionReturn(0); 1558 } 1559 1560 /*@C 1561 SNESLineSearchSetWorkVecs - Gets work vectors for the line search. 1562 1563 Input Parameters: 1564 + linesearch - the SNESLineSearch context 1565 - nwork - the number of work vectors 1566 1567 Level: developer 1568 1569 .seealso: `SNESSetWorkVecs()` 1570 @*/ 1571 PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork) 1572 { 1573 PetscFunctionBegin; 1574 if (linesearch->vec_sol) { 1575 PetscCall(VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work)); 1576 } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!"); 1577 PetscFunctionReturn(0); 1578 } 1579 1580 /*@ 1581 SNESLineSearchGetReason - Gets the success/failure status of the last line search application 1582 1583 Input Parameters: 1584 . linesearch - linesearch context 1585 1586 Output Parameters: 1587 . result - The success or failure status 1588 1589 Notes: 1590 This is typically called after SNESLineSearchApply() in order to determine if the line-search failed 1591 (and set the SNES convergence accordingly). 1592 1593 Level: intermediate 1594 1595 .seealso: `SNESLineSearchSetReason()`, `SNESLineSearchReason` 1596 @*/ 1597 PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result) 1598 { 1599 PetscFunctionBegin; 1600 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1601 PetscValidPointer(result, 2); 1602 *result = linesearch->result; 1603 PetscFunctionReturn(0); 1604 } 1605 1606 /*@ 1607 SNESLineSearchSetReason - Sets the success/failure status of the last line search application 1608 1609 Input Parameters: 1610 + linesearch - linesearch context 1611 - result - The success or failure status 1612 1613 Notes: 1614 This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set 1615 the success or failure of the line search method. 1616 1617 Level: developer 1618 1619 .seealso: `SNESLineSearchGetSResult()` 1620 @*/ 1621 PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result) 1622 { 1623 PetscFunctionBegin; 1624 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1625 linesearch->result = result; 1626 PetscFunctionReturn(0); 1627 } 1628 1629 /*@C 1630 SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation. 1631 1632 Input Parameters: 1633 + snes - nonlinear context obtained from SNESCreate() 1634 . projectfunc - function for projecting the function to the bounds 1635 - normfunc - function for computing the norm of an active set 1636 1637 Logically Collective on SNES 1638 1639 Calling sequence of projectfunc: 1640 .vb 1641 projectfunc (SNES snes, Vec X) 1642 .ve 1643 1644 Input parameters for projectfunc: 1645 + snes - nonlinear context 1646 - X - current solution 1647 1648 Output parameters for projectfunc: 1649 . X - Projected solution 1650 1651 Calling sequence of normfunc: 1652 .vb 1653 projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm) 1654 .ve 1655 1656 Input parameters for normfunc: 1657 + snes - nonlinear context 1658 . X - current solution 1659 - F - current residual 1660 1661 Output parameters for normfunc: 1662 . fnorm - VI-specific norm of the function 1663 1664 Notes: 1665 The VI solvers require projection of the solution to the feasible set. projectfunc should implement this. 1666 1667 The VI solvers require special evaluation of the function norm such that the norm is only calculated 1668 on the inactive set. This should be implemented by normfunc. 1669 1670 Level: developer 1671 1672 .seealso: `SNESLineSearchGetVIFunctions()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchSetPreCheck()` 1673 @*/ 1674 PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc) 1675 { 1676 PetscFunctionBegin; 1677 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1678 if (projectfunc) linesearch->ops->viproject = projectfunc; 1679 if (normfunc) linesearch->ops->vinorm = normfunc; 1680 PetscFunctionReturn(0); 1681 } 1682 1683 /*@C 1684 SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation. 1685 1686 Input Parameter: 1687 . linesearch - the line search context, obtain with SNESGetLineSearch() 1688 1689 Output Parameters: 1690 + projectfunc - function for projecting the function to the bounds 1691 - normfunc - function for computing the norm of an active set 1692 1693 Logically Collective on SNES 1694 1695 Level: developer 1696 1697 .seealso: `SNESLineSearchSetVIFunctions()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchGetPreCheck()` 1698 @*/ 1699 PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc) 1700 { 1701 PetscFunctionBegin; 1702 if (projectfunc) *projectfunc = linesearch->ops->viproject; 1703 if (normfunc) *normfunc = linesearch->ops->vinorm; 1704 PetscFunctionReturn(0); 1705 } 1706 1707 /*@C 1708 SNESLineSearchRegister - See SNESLineSearchRegister() 1709 1710 Level: advanced 1711 @*/ 1712 PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch)) 1713 { 1714 PetscFunctionBegin; 1715 PetscCall(SNESInitializePackage()); 1716 PetscCall(PetscFunctionListAdd(&SNESLineSearchList,sname,function)); 1717 PetscFunctionReturn(0); 1718 } 1719