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