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