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