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