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