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