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