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