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