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 = PetscViewerASCIIAddTab(viewer, ((PetscObject)linesearch)->tablevel);CHKERRQ(ierr); 954 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);CHKERRQ(ierr); 955 if (linesearch->ops->view) { 956 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 957 ierr = (*linesearch->ops->view)(linesearch,viewer);CHKERRQ(ierr); 958 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 959 } 960 ierr = PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);CHKERRQ(ierr); 961 ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);CHKERRQ(ierr); 962 ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", linesearch->max_its);CHKERRQ(ierr); 963 if (linesearch->ops->precheck) { 964 if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) { 965 ierr = PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n", linesearch->max_its);CHKERRQ(ierr); 966 } else { 967 ierr = PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n", linesearch->max_its);CHKERRQ(ierr); 968 } 969 } 970 if (linesearch->ops->postcheck) { 971 ierr = PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n", linesearch->max_its);CHKERRQ(ierr); 972 } 973 ierr = PetscViewerASCIISubtractTab(viewer, ((PetscObject)linesearch)->tablevel);CHKERRQ(ierr); 974 } 975 PetscFunctionReturn(0); 976 } 977 978 /*@C 979 SNESLineSearchSetType - Sets the linesearch type 980 981 Logically Collective on SNESLineSearch 982 983 Input Parameters: 984 + linesearch - linesearch context 985 - type - The type of line search to be used 986 987 Available Types: 988 + SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step 989 . SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function 990 . SNESLINESEARCHL2 - Secant line search over the L2 norm of the function 991 . SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x) 992 . SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch 993 - SNESLINESEARCHSHELL - User provided SNESLineSearch implementation 994 995 Options Database: 996 . -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell 997 998 Level: intermediate 999 1000 .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions() 1001 @*/ 1002 PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type) 1003 { 1004 PetscErrorCode ierr,(*r)(SNESLineSearch); 1005 PetscBool match; 1006 1007 PetscFunctionBegin; 1008 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1009 PetscValidCharPointer(type,2); 1010 1011 ierr = PetscObjectTypeCompare((PetscObject)linesearch,type,&match);CHKERRQ(ierr); 1012 if (match) PetscFunctionReturn(0); 1013 1014 ierr = PetscFunctionListFind(SNESLineSearchList,type,&r);CHKERRQ(ierr); 1015 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type); 1016 /* Destroy the previous private linesearch context */ 1017 if (linesearch->ops->destroy) { 1018 ierr = (*(linesearch)->ops->destroy)(linesearch);CHKERRQ(ierr); 1019 1020 linesearch->ops->destroy = NULL; 1021 } 1022 /* Reinitialize function pointers in SNESLineSearchOps structure */ 1023 linesearch->ops->apply = 0; 1024 linesearch->ops->view = 0; 1025 linesearch->ops->setfromoptions = 0; 1026 linesearch->ops->destroy = 0; 1027 1028 ierr = PetscObjectChangeTypeName((PetscObject)linesearch,type);CHKERRQ(ierr); 1029 ierr = (*r)(linesearch);CHKERRQ(ierr); 1030 PetscFunctionReturn(0); 1031 } 1032 1033 /*@ 1034 SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation. 1035 1036 Input Parameters: 1037 + linesearch - linesearch context 1038 - snes - The snes instance 1039 1040 Level: developer 1041 1042 Notes: 1043 This happens automatically when the line search is obtained/created with 1044 SNESGetLineSearch(). This routine is therefore mainly called within SNES 1045 implementations. 1046 1047 Level: developer 1048 1049 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES 1050 @*/ 1051 PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes) 1052 { 1053 PetscFunctionBegin; 1054 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1055 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 1056 linesearch->snes = snes; 1057 PetscFunctionReturn(0); 1058 } 1059 1060 /*@ 1061 SNESLineSearchGetSNES - Gets the SNES instance associated with the line search. 1062 Having an associated SNES is necessary because most line search implementations must be able to 1063 evaluate the function using SNESComputeFunction() for the associated SNES. This routine 1064 is used in the line search implementations when one must get this associated SNES instance. 1065 1066 Input Parameters: 1067 . linesearch - linesearch context 1068 1069 Output Parameters: 1070 . snes - The snes instance 1071 1072 Level: developer 1073 1074 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES 1075 @*/ 1076 PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes) 1077 { 1078 PetscFunctionBegin; 1079 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1080 PetscValidPointer(snes, 2); 1081 *snes = linesearch->snes; 1082 PetscFunctionReturn(0); 1083 } 1084 1085 /*@ 1086 SNESLineSearchGetLambda - Gets the last linesearch steplength discovered. 1087 1088 Input Parameters: 1089 . linesearch - linesearch context 1090 1091 Output Parameters: 1092 . lambda - The last steplength computed during SNESLineSearchApply() 1093 1094 Level: advanced 1095 1096 Notes: 1097 This is useful in methods where the solver is ill-scaled and 1098 requires some adaptive notion of the difference in scale between the 1099 solution and the function. For instance, SNESQN may be scaled by the 1100 line search lambda using the argument -snes_qn_scaling ls. 1101 1102 .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply() 1103 @*/ 1104 PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda) 1105 { 1106 PetscFunctionBegin; 1107 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1108 PetscValidPointer(lambda, 2); 1109 *lambda = linesearch->lambda; 1110 PetscFunctionReturn(0); 1111 } 1112 1113 /*@ 1114 SNESLineSearchSetLambda - Sets the linesearch steplength. 1115 1116 Input Parameters: 1117 + linesearch - linesearch context 1118 - lambda - The last steplength. 1119 1120 Notes: 1121 This routine is typically used within implementations of SNESLineSearchApply() 1122 to set the final steplength. This routine (and SNESLineSearchGetLambda()) were 1123 added in order to facilitate Quasi-Newton methods that use the previous steplength 1124 as an inner scaling parameter. 1125 1126 Level: advanced 1127 1128 .seealso: SNESLineSearchGetLambda() 1129 @*/ 1130 PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda) 1131 { 1132 PetscFunctionBegin; 1133 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1134 linesearch->lambda = lambda; 1135 PetscFunctionReturn(0); 1136 } 1137 1138 /*@ 1139 SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include 1140 tolerances for the relative and absolute change in the function norm, the change 1141 in lambda for iterative line searches, the minimum steplength, the maximum steplength, 1142 and the maximum number of iterations the line search procedure may take. 1143 1144 Input Parameters: 1145 . linesearch - linesearch context 1146 1147 Output Parameters: 1148 + steptol - The minimum steplength 1149 . maxstep - The maximum steplength 1150 . rtol - The relative tolerance for iterative line searches 1151 . atol - The absolute tolerance for iterative line searches 1152 . ltol - The change in lambda tolerance for iterative line searches 1153 - max_it - The maximum number of iterations of the line search 1154 1155 Level: intermediate 1156 1157 Notes: 1158 Different line searches may implement these parameters slightly differently as 1159 the type requires. 1160 1161 .seealso: SNESLineSearchSetTolerances() 1162 @*/ 1163 PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its) 1164 { 1165 PetscFunctionBegin; 1166 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1167 if (steptol) { 1168 PetscValidPointer(steptol, 2); 1169 *steptol = linesearch->steptol; 1170 } 1171 if (maxstep) { 1172 PetscValidPointer(maxstep, 3); 1173 *maxstep = linesearch->maxstep; 1174 } 1175 if (rtol) { 1176 PetscValidPointer(rtol, 4); 1177 *rtol = linesearch->rtol; 1178 } 1179 if (atol) { 1180 PetscValidPointer(atol, 5); 1181 *atol = linesearch->atol; 1182 } 1183 if (ltol) { 1184 PetscValidPointer(ltol, 6); 1185 *ltol = linesearch->ltol; 1186 } 1187 if (max_its) { 1188 PetscValidPointer(max_its, 7); 1189 *max_its = linesearch->max_its; 1190 } 1191 PetscFunctionReturn(0); 1192 } 1193 1194 /*@ 1195 SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include 1196 tolerances for the relative and absolute change in the function norm, the change 1197 in lambda for iterative line searches, the minimum steplength, the maximum steplength, 1198 and the maximum number of iterations the line search procedure may take. 1199 1200 Input Parameters: 1201 + linesearch - linesearch context 1202 . steptol - The minimum steplength 1203 . maxstep - The maximum steplength 1204 . rtol - The relative tolerance for iterative line searches 1205 . atol - The absolute tolerance for iterative line searches 1206 . ltol - The change in lambda tolerance for iterative line searches 1207 - max_it - The maximum number of iterations of the line search 1208 1209 Notes: 1210 The user may choose to not set any of the tolerances using PETSC_DEFAULT in 1211 place of an argument. 1212 1213 Level: intermediate 1214 1215 .seealso: SNESLineSearchGetTolerances() 1216 @*/ 1217 PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its) 1218 { 1219 PetscFunctionBegin; 1220 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1221 PetscValidLogicalCollectiveReal(linesearch,steptol,2); 1222 PetscValidLogicalCollectiveReal(linesearch,maxstep,3); 1223 PetscValidLogicalCollectiveReal(linesearch,rtol,4); 1224 PetscValidLogicalCollectiveReal(linesearch,atol,5); 1225 PetscValidLogicalCollectiveReal(linesearch,ltol,6); 1226 PetscValidLogicalCollectiveInt(linesearch,max_its,7); 1227 1228 if (steptol!= PETSC_DEFAULT) { 1229 if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol); 1230 linesearch->steptol = steptol; 1231 } 1232 1233 if (maxstep!= PETSC_DEFAULT) { 1234 if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep); 1235 linesearch->maxstep = maxstep; 1236 } 1237 1238 if (rtol != PETSC_DEFAULT) { 1239 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); 1240 linesearch->rtol = rtol; 1241 } 1242 1243 if (atol != PETSC_DEFAULT) { 1244 if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol); 1245 linesearch->atol = atol; 1246 } 1247 1248 if (ltol != PETSC_DEFAULT) { 1249 if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %14.12e must be non-negative",(double)ltol); 1250 linesearch->ltol = ltol; 1251 } 1252 1253 if (max_its != PETSC_DEFAULT) { 1254 if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its); 1255 linesearch->max_its = max_its; 1256 } 1257 PetscFunctionReturn(0); 1258 } 1259 1260 /*@ 1261 SNESLineSearchGetDamping - Gets the line search damping parameter. 1262 1263 Input Parameters: 1264 . linesearch - linesearch context 1265 1266 Output Parameters: 1267 . damping - The damping parameter 1268 1269 Level: advanced 1270 1271 .seealso: SNESLineSearchGetStepTolerance(), SNESQN 1272 @*/ 1273 1274 PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping) 1275 { 1276 PetscFunctionBegin; 1277 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1278 PetscValidPointer(damping, 2); 1279 *damping = linesearch->damping; 1280 PetscFunctionReturn(0); 1281 } 1282 1283 /*@ 1284 SNESLineSearchSetDamping - Sets the line search damping paramter. 1285 1286 Input Parameters: 1287 + linesearch - linesearch context 1288 - damping - The damping parameter 1289 1290 Options Database: 1291 . -snes_linesearch_damping 1292 Level: intermediate 1293 1294 Notes: 1295 The basic line search merely takes the update step scaled by the damping parameter. 1296 The use of the damping parameter in the l2 and cp line searches is much more subtle; 1297 it is used as a starting point in calculating the secant step. However, the eventual 1298 step may be of greater length than the damping parameter. In the bt line search it is 1299 used as the maximum possible step length, as the bt line search only backtracks. 1300 1301 .seealso: SNESLineSearchGetDamping() 1302 @*/ 1303 PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping) 1304 { 1305 PetscFunctionBegin; 1306 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1307 linesearch->damping = damping; 1308 PetscFunctionReturn(0); 1309 } 1310 1311 /*@ 1312 SNESLineSearchGetOrder - Gets the line search approximation order. 1313 1314 Input Parameters: 1315 . linesearch - linesearch context 1316 1317 Output Parameters: 1318 . order - The order 1319 1320 Possible Values for order: 1321 + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order 1322 . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order 1323 - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order 1324 1325 Level: intermediate 1326 1327 .seealso: SNESLineSearchSetOrder() 1328 @*/ 1329 1330 PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order) 1331 { 1332 PetscFunctionBegin; 1333 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1334 PetscValidPointer(order, 2); 1335 *order = linesearch->order; 1336 PetscFunctionReturn(0); 1337 } 1338 1339 /*@ 1340 SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search 1341 1342 Input Parameters: 1343 . linesearch - linesearch context 1344 . order - The damping parameter 1345 1346 Level: intermediate 1347 1348 Possible Values for order: 1349 + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order 1350 . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order 1351 - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order 1352 1353 Notes: 1354 Variable orders are supported by the following line searches: 1355 + bt - cubic and quadratic 1356 - cp - linear and quadratic 1357 1358 .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping() 1359 @*/ 1360 PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order) 1361 { 1362 PetscFunctionBegin; 1363 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1364 linesearch->order = order; 1365 PetscFunctionReturn(0); 1366 } 1367 1368 /*@ 1369 SNESLineSearchGetNorms - Gets the norms for for X, Y, and F. 1370 1371 Input Parameters: 1372 . linesearch - linesearch context 1373 1374 Output Parameters: 1375 + xnorm - The norm of the current solution 1376 . fnorm - The norm of the current function 1377 - ynorm - The norm of the current update 1378 1379 Notes: 1380 This function is mainly called from SNES implementations. 1381 1382 Level: developer 1383 1384 .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs() 1385 @*/ 1386 PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm) 1387 { 1388 PetscFunctionBegin; 1389 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1390 if (xnorm) *xnorm = linesearch->xnorm; 1391 if (fnorm) *fnorm = linesearch->fnorm; 1392 if (ynorm) *ynorm = linesearch->ynorm; 1393 PetscFunctionReturn(0); 1394 } 1395 1396 /*@ 1397 SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F. 1398 1399 Input Parameters: 1400 + linesearch - linesearch context 1401 . xnorm - The norm of the current solution 1402 . fnorm - The norm of the current function 1403 - ynorm - The norm of the current update 1404 1405 Level: advanced 1406 1407 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs() 1408 @*/ 1409 PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm) 1410 { 1411 PetscFunctionBegin; 1412 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1413 linesearch->xnorm = xnorm; 1414 linesearch->fnorm = fnorm; 1415 linesearch->ynorm = ynorm; 1416 PetscFunctionReturn(0); 1417 } 1418 1419 /*@ 1420 SNESLineSearchComputeNorms - Computes the norms of X, F, and Y. 1421 1422 Input Parameters: 1423 . linesearch - linesearch context 1424 1425 Options Database Keys: 1426 . -snes_linesearch_norms - turn norm computation on or off 1427 1428 Level: intermediate 1429 1430 .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms() 1431 @*/ 1432 PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch) 1433 { 1434 PetscErrorCode ierr; 1435 SNES snes; 1436 1437 PetscFunctionBegin; 1438 if (linesearch->norms) { 1439 if (linesearch->ops->vinorm) { 1440 ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr); 1441 ierr = VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 1442 ierr = VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 1443 ierr = (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);CHKERRQ(ierr); 1444 } else { 1445 ierr = VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 1446 ierr = VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 1447 ierr = VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 1448 ierr = VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 1449 ierr = VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 1450 ierr = VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 1451 } 1452 } 1453 PetscFunctionReturn(0); 1454 } 1455 1456 /*@ 1457 SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search. 1458 1459 Input Parameters: 1460 + linesearch - linesearch context 1461 - flg - indicates whether or not to compute norms 1462 1463 Options Database Keys: 1464 . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch 1465 1466 Notes: 1467 This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm. 1468 1469 Level: intermediate 1470 1471 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC 1472 @*/ 1473 PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg) 1474 { 1475 PetscFunctionBegin; 1476 linesearch->norms = flg; 1477 PetscFunctionReturn(0); 1478 } 1479 1480 /*@ 1481 SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context 1482 1483 Input Parameters: 1484 . linesearch - linesearch context 1485 1486 Output Parameters: 1487 + X - Solution vector 1488 . F - Function vector 1489 . Y - Search direction vector 1490 . W - Solution work vector 1491 - G - Function work vector 1492 1493 Notes: 1494 At the beginning of a line search application, X should contain a 1495 solution and the vector F the function computed at X. At the end of the 1496 line search application, X should contain the new solution, and F the 1497 function evaluated at the new solution. 1498 1499 These vectors are owned by the SNESLineSearch and should not be destroyed by the caller 1500 1501 Level: advanced 1502 1503 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs() 1504 @*/ 1505 PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G) 1506 { 1507 PetscFunctionBegin; 1508 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1509 if (X) { 1510 PetscValidPointer(X, 2); 1511 *X = linesearch->vec_sol; 1512 } 1513 if (F) { 1514 PetscValidPointer(F, 3); 1515 *F = linesearch->vec_func; 1516 } 1517 if (Y) { 1518 PetscValidPointer(Y, 4); 1519 *Y = linesearch->vec_update; 1520 } 1521 if (W) { 1522 PetscValidPointer(W, 5); 1523 *W = linesearch->vec_sol_new; 1524 } 1525 if (G) { 1526 PetscValidPointer(G, 6); 1527 *G = linesearch->vec_func_new; 1528 } 1529 PetscFunctionReturn(0); 1530 } 1531 1532 /*@ 1533 SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context 1534 1535 Input Parameters: 1536 + linesearch - linesearch context 1537 . X - Solution vector 1538 . F - Function vector 1539 . Y - Search direction vector 1540 . W - Solution work vector 1541 - G - Function work vector 1542 1543 Level: advanced 1544 1545 .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs() 1546 @*/ 1547 PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G) 1548 { 1549 PetscFunctionBegin; 1550 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1551 if (X) { 1552 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 1553 linesearch->vec_sol = X; 1554 } 1555 if (F) { 1556 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 1557 linesearch->vec_func = F; 1558 } 1559 if (Y) { 1560 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 1561 linesearch->vec_update = Y; 1562 } 1563 if (W) { 1564 PetscValidHeaderSpecific(W,VEC_CLASSID,5); 1565 linesearch->vec_sol_new = W; 1566 } 1567 if (G) { 1568 PetscValidHeaderSpecific(G,VEC_CLASSID,6); 1569 linesearch->vec_func_new = G; 1570 } 1571 PetscFunctionReturn(0); 1572 } 1573 1574 /*@C 1575 SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all 1576 SNES options in the database. 1577 1578 Logically Collective on SNESLineSearch 1579 1580 Input Parameters: 1581 + snes - the SNES context 1582 - prefix - the prefix to prepend to all option names 1583 1584 Notes: 1585 A hyphen (-) must NOT be given at the beginning of the prefix name. 1586 The first character of all runtime options is AUTOMATICALLY the hyphen. 1587 1588 Level: advanced 1589 1590 .keywords: SNESLineSearch, append, options, prefix, database 1591 1592 .seealso: SNESGetOptionsPrefix() 1593 @*/ 1594 PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[]) 1595 { 1596 PetscErrorCode ierr; 1597 1598 PetscFunctionBegin; 1599 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1600 ierr = PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr); 1601 PetscFunctionReturn(0); 1602 } 1603 1604 /*@C 1605 SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all 1606 SNESLineSearch options in the database. 1607 1608 Not Collective 1609 1610 Input Parameter: 1611 . linesearch - the SNESLineSearch context 1612 1613 Output Parameter: 1614 . prefix - pointer to the prefix string used 1615 1616 Notes: 1617 On the fortran side, the user should pass in a string 'prefix' of 1618 sufficient length to hold the prefix. 1619 1620 Level: advanced 1621 1622 .keywords: SNESLineSearch, get, options, prefix, database 1623 1624 .seealso: SNESAppendOptionsPrefix() 1625 @*/ 1626 PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[]) 1627 { 1628 PetscErrorCode ierr; 1629 1630 PetscFunctionBegin; 1631 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1632 ierr = PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr); 1633 PetscFunctionReturn(0); 1634 } 1635 1636 /*@C 1637 SNESLineSearchSetWorkVecs - Gets work vectors for the line search. 1638 1639 Input Parameter: 1640 + linesearch - the SNESLineSearch context 1641 - nwork - the number of work vectors 1642 1643 Level: developer 1644 1645 Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations 1646 1647 .keywords: SNESLineSearch, work, vector 1648 1649 .seealso: SNESSetWorkVecs() 1650 @*/ 1651 PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork) 1652 { 1653 PetscErrorCode ierr; 1654 1655 PetscFunctionBegin; 1656 if (linesearch->vec_sol) { 1657 ierr = VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);CHKERRQ(ierr); 1658 } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!"); 1659 PetscFunctionReturn(0); 1660 } 1661 1662 /*@ 1663 SNESLineSearchGetReason - Gets the success/failure status of the last line search application 1664 1665 Input Parameters: 1666 . linesearch - linesearch context 1667 1668 Output Parameters: 1669 . result - The success or failure status 1670 1671 Notes: 1672 This is typically called after SNESLineSearchApply() in order to determine if the line-search failed 1673 (and set the SNES convergence accordingly). 1674 1675 Level: intermediate 1676 1677 .seealso: SNESLineSearchSetReason(), SNESLineSearchReason 1678 @*/ 1679 PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result) 1680 { 1681 PetscFunctionBegin; 1682 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1683 PetscValidPointer(result, 2); 1684 *result = linesearch->result; 1685 PetscFunctionReturn(0); 1686 } 1687 1688 /*@ 1689 SNESLineSearchSetReason - Sets the success/failure status of the last line search application 1690 1691 Input Parameters: 1692 + linesearch - linesearch context 1693 - result - The success or failure status 1694 1695 Notes: 1696 This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set 1697 the success or failure of the line search method. 1698 1699 Level: developer 1700 1701 .seealso: SNESLineSearchGetSResult() 1702 @*/ 1703 PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result) 1704 { 1705 PetscFunctionBegin; 1706 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1707 linesearch->result = result; 1708 PetscFunctionReturn(0); 1709 } 1710 1711 /*@C 1712 SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation. 1713 1714 Input Parameters: 1715 + snes - nonlinear context obtained from SNESCreate() 1716 . projectfunc - function for projecting the function to the bounds 1717 - normfunc - function for computing the norm of an active set 1718 1719 Logically Collective on SNES 1720 1721 Calling sequence of projectfunc: 1722 .vb 1723 projectfunc (SNES snes, Vec X) 1724 .ve 1725 1726 Input parameters for projectfunc: 1727 + snes - nonlinear context 1728 - X - current solution 1729 1730 Output parameters for projectfunc: 1731 . X - Projected solution 1732 1733 Calling sequence of normfunc: 1734 .vb 1735 projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm) 1736 .ve 1737 1738 Input parameters for normfunc: 1739 + snes - nonlinear context 1740 . X - current solution 1741 - F - current residual 1742 1743 Output parameters for normfunc: 1744 . fnorm - VI-specific norm of the function 1745 1746 Notes: 1747 The VI solvers require projection of the solution to the feasible set. projectfunc should implement this. 1748 1749 The VI solvers require special evaluation of the function norm such that the norm is only calculated 1750 on the inactive set. This should be implemented by normfunc. 1751 1752 Level: developer 1753 1754 .keywords: SNES, line search, VI, nonlinear, set, line search 1755 1756 .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck() 1757 @*/ 1758 extern PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc) 1759 { 1760 PetscFunctionBegin; 1761 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1762 if (projectfunc) linesearch->ops->viproject = projectfunc; 1763 if (normfunc) linesearch->ops->vinorm = normfunc; 1764 PetscFunctionReturn(0); 1765 } 1766 1767 /*@C 1768 SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation. 1769 1770 Input Parameters: 1771 . linesearch - the line search context, obtain with SNESGetLineSearch() 1772 1773 Output Parameters: 1774 + projectfunc - function for projecting the function to the bounds 1775 - normfunc - function for computing the norm of an active set 1776 1777 Logically Collective on SNES 1778 1779 Level: developer 1780 1781 .keywords: SNES, line search, VI, nonlinear, get, line search 1782 1783 .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck() 1784 @*/ 1785 extern PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc) 1786 { 1787 PetscFunctionBegin; 1788 if (projectfunc) *projectfunc = linesearch->ops->viproject; 1789 if (normfunc) *normfunc = linesearch->ops->vinorm; 1790 PetscFunctionReturn(0); 1791 } 1792 1793 /*@C 1794 SNESLineSearchRegister - See SNESLineSearchRegister() 1795 1796 Level: advanced 1797 @*/ 1798 PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch)) 1799 { 1800 PetscErrorCode ierr; 1801 1802 PetscFunctionBegin; 1803 ierr = PetscFunctionListAdd(&SNESLineSearchList,sname,function);CHKERRQ(ierr); 1804 PetscFunctionReturn(0); 1805 } 1806