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