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 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);CHKERRQ(ierr); 914 if (linesearch->ops->view) { 915 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 916 ierr = (*linesearch->ops->view)(linesearch,viewer);CHKERRQ(ierr); 917 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 918 } 919 ierr = PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);CHKERRQ(ierr); 920 ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);CHKERRQ(ierr); 921 ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", linesearch->max_its);CHKERRQ(ierr); 922 if (linesearch->ops->precheck) { 923 if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) { 924 ierr = PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n", linesearch->max_its);CHKERRQ(ierr); 925 } else { 926 ierr = PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n", linesearch->max_its);CHKERRQ(ierr); 927 } 928 } 929 if (linesearch->ops->postcheck) { 930 ierr = PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n", linesearch->max_its);CHKERRQ(ierr); 931 } 932 } 933 PetscFunctionReturn(0); 934 } 935 936 /*@C 937 SNESLineSearchSetType - Sets the linesearch type 938 939 Logically Collective on SNESLineSearch 940 941 Input Parameters: 942 + linesearch - linesearch context 943 - type - The type of line search to be used 944 945 Available Types: 946 + SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step 947 . SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function 948 . SNESLINESEARCHL2 - Secant line search over the L2 norm of the function 949 . SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x) 950 . SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch 951 - SNESLINESEARCHSHELL - User provided SNESLineSearch implementation 952 953 Options Database: 954 . -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell 955 956 Level: intermediate 957 958 .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions() 959 @*/ 960 PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type) 961 { 962 PetscErrorCode ierr,(*r)(SNESLineSearch); 963 PetscBool match; 964 965 PetscFunctionBegin; 966 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 967 PetscValidCharPointer(type,2); 968 969 ierr = PetscObjectTypeCompare((PetscObject)linesearch,type,&match);CHKERRQ(ierr); 970 if (match) PetscFunctionReturn(0); 971 972 ierr = PetscFunctionListFind(SNESLineSearchList,type,&r);CHKERRQ(ierr); 973 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type); 974 /* Destroy the previous private linesearch context */ 975 if (linesearch->ops->destroy) { 976 ierr = (*(linesearch)->ops->destroy)(linesearch);CHKERRQ(ierr); 977 978 linesearch->ops->destroy = NULL; 979 } 980 /* Reinitialize function pointers in SNESLineSearchOps structure */ 981 linesearch->ops->apply = 0; 982 linesearch->ops->view = 0; 983 linesearch->ops->setfromoptions = 0; 984 linesearch->ops->destroy = 0; 985 986 ierr = PetscObjectChangeTypeName((PetscObject)linesearch,type);CHKERRQ(ierr); 987 ierr = (*r)(linesearch);CHKERRQ(ierr); 988 PetscFunctionReturn(0); 989 } 990 991 /*@ 992 SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation. 993 994 Input Parameters: 995 + linesearch - linesearch context 996 - snes - The snes instance 997 998 Level: developer 999 1000 Notes: 1001 This happens automatically when the line search is obtained/created with 1002 SNESGetLineSearch(). This routine is therefore mainly called within SNES 1003 implementations. 1004 1005 Level: developer 1006 1007 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES 1008 @*/ 1009 PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes) 1010 { 1011 PetscFunctionBegin; 1012 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1013 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 1014 linesearch->snes = snes; 1015 PetscFunctionReturn(0); 1016 } 1017 1018 /*@ 1019 SNESLineSearchGetSNES - Gets the SNES instance associated with the line search. 1020 Having an associated SNES is necessary because most line search implementations must be able to 1021 evaluate the function using SNESComputeFunction() for the associated SNES. This routine 1022 is used in the line search implementations when one must get this associated SNES instance. 1023 1024 Input Parameters: 1025 . linesearch - linesearch context 1026 1027 Output Parameters: 1028 . snes - The snes instance 1029 1030 Level: developer 1031 1032 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES 1033 @*/ 1034 PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes) 1035 { 1036 PetscFunctionBegin; 1037 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1038 PetscValidPointer(snes, 2); 1039 *snes = linesearch->snes; 1040 PetscFunctionReturn(0); 1041 } 1042 1043 /*@ 1044 SNESLineSearchGetLambda - Gets the last linesearch steplength discovered. 1045 1046 Input Parameters: 1047 . linesearch - linesearch context 1048 1049 Output Parameters: 1050 . lambda - The last steplength computed during SNESLineSearchApply() 1051 1052 Level: advanced 1053 1054 Notes: 1055 This is useful in methods where the solver is ill-scaled and 1056 requires some adaptive notion of the difference in scale between the 1057 solution and the function. For instance, SNESQN may be scaled by the 1058 line search lambda using the argument -snes_qn_scaling ls. 1059 1060 .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply() 1061 @*/ 1062 PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda) 1063 { 1064 PetscFunctionBegin; 1065 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1066 PetscValidPointer(lambda, 2); 1067 *lambda = linesearch->lambda; 1068 PetscFunctionReturn(0); 1069 } 1070 1071 /*@ 1072 SNESLineSearchSetLambda - Sets the linesearch steplength. 1073 1074 Input Parameters: 1075 + linesearch - linesearch context 1076 - lambda - The last steplength. 1077 1078 Notes: 1079 This routine is typically used within implementations of SNESLineSearchApply() 1080 to set the final steplength. This routine (and SNESLineSearchGetLambda()) were 1081 added in order to facilitate Quasi-Newton methods that use the previous steplength 1082 as an inner scaling parameter. 1083 1084 Level: advanced 1085 1086 .seealso: SNESLineSearchGetLambda() 1087 @*/ 1088 PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda) 1089 { 1090 PetscFunctionBegin; 1091 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1092 linesearch->lambda = lambda; 1093 PetscFunctionReturn(0); 1094 } 1095 1096 /*@ 1097 SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include 1098 tolerances for the relative and absolute change in the function norm, the change 1099 in lambda for iterative line searches, the minimum steplength, the maximum steplength, 1100 and the maximum number of iterations the line search procedure may take. 1101 1102 Input Parameters: 1103 . linesearch - linesearch context 1104 1105 Output Parameters: 1106 + steptol - The minimum steplength 1107 . maxstep - The maximum steplength 1108 . rtol - The relative tolerance for iterative line searches 1109 . atol - The absolute tolerance for iterative line searches 1110 . ltol - The change in lambda tolerance for iterative line searches 1111 - max_it - The maximum number of iterations of the line search 1112 1113 Level: intermediate 1114 1115 Notes: 1116 Different line searches may implement these parameters slightly differently as 1117 the type requires. 1118 1119 .seealso: SNESLineSearchSetTolerances() 1120 @*/ 1121 PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its) 1122 { 1123 PetscFunctionBegin; 1124 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1125 if (steptol) { 1126 PetscValidPointer(steptol, 2); 1127 *steptol = linesearch->steptol; 1128 } 1129 if (maxstep) { 1130 PetscValidPointer(maxstep, 3); 1131 *maxstep = linesearch->maxstep; 1132 } 1133 if (rtol) { 1134 PetscValidPointer(rtol, 4); 1135 *rtol = linesearch->rtol; 1136 } 1137 if (atol) { 1138 PetscValidPointer(atol, 5); 1139 *atol = linesearch->atol; 1140 } 1141 if (ltol) { 1142 PetscValidPointer(ltol, 6); 1143 *ltol = linesearch->ltol; 1144 } 1145 if (max_its) { 1146 PetscValidPointer(max_its, 7); 1147 *max_its = linesearch->max_its; 1148 } 1149 PetscFunctionReturn(0); 1150 } 1151 1152 /*@ 1153 SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include 1154 tolerances for the relative and absolute change in the function norm, the change 1155 in lambda for iterative line searches, the minimum steplength, the maximum steplength, 1156 and the maximum number of iterations the line search procedure may take. 1157 1158 Input Parameters: 1159 + linesearch - linesearch context 1160 . steptol - The minimum steplength 1161 . maxstep - The maximum steplength 1162 . rtol - The relative tolerance for iterative line searches 1163 . atol - The absolute tolerance for iterative line searches 1164 . ltol - The change in lambda tolerance for iterative line searches 1165 - max_it - The maximum number of iterations of the line search 1166 1167 Notes: 1168 The user may choose to not set any of the tolerances using PETSC_DEFAULT in 1169 place of an argument. 1170 1171 Level: intermediate 1172 1173 .seealso: SNESLineSearchGetTolerances() 1174 @*/ 1175 PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its) 1176 { 1177 PetscFunctionBegin; 1178 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1179 PetscValidLogicalCollectiveReal(linesearch,steptol,2); 1180 PetscValidLogicalCollectiveReal(linesearch,maxstep,3); 1181 PetscValidLogicalCollectiveReal(linesearch,rtol,4); 1182 PetscValidLogicalCollectiveReal(linesearch,atol,5); 1183 PetscValidLogicalCollectiveReal(linesearch,ltol,6); 1184 PetscValidLogicalCollectiveInt(linesearch,max_its,7); 1185 1186 if (steptol!= PETSC_DEFAULT) { 1187 if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol); 1188 linesearch->steptol = steptol; 1189 } 1190 1191 if (maxstep!= PETSC_DEFAULT) { 1192 if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep); 1193 linesearch->maxstep = maxstep; 1194 } 1195 1196 if (rtol != PETSC_DEFAULT) { 1197 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); 1198 linesearch->rtol = rtol; 1199 } 1200 1201 if (atol != PETSC_DEFAULT) { 1202 if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol); 1203 linesearch->atol = atol; 1204 } 1205 1206 if (ltol != PETSC_DEFAULT) { 1207 if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %14.12e must be non-negative",(double)ltol); 1208 linesearch->ltol = ltol; 1209 } 1210 1211 if (max_its != PETSC_DEFAULT) { 1212 if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its); 1213 linesearch->max_its = max_its; 1214 } 1215 PetscFunctionReturn(0); 1216 } 1217 1218 /*@ 1219 SNESLineSearchGetDamping - Gets the line search damping parameter. 1220 1221 Input Parameters: 1222 . linesearch - linesearch context 1223 1224 Output Parameters: 1225 . damping - The damping parameter 1226 1227 Level: advanced 1228 1229 .seealso: SNESLineSearchGetStepTolerance(), SNESQN 1230 @*/ 1231 1232 PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping) 1233 { 1234 PetscFunctionBegin; 1235 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1236 PetscValidPointer(damping, 2); 1237 *damping = linesearch->damping; 1238 PetscFunctionReturn(0); 1239 } 1240 1241 /*@ 1242 SNESLineSearchSetDamping - Sets the line search damping paramter. 1243 1244 Input Parameters: 1245 + linesearch - linesearch context 1246 - damping - The damping parameter 1247 1248 Options Database: 1249 . -snes_linesearch_damping 1250 Level: intermediate 1251 1252 Notes: 1253 The basic line search merely takes the update step scaled by the damping parameter. 1254 The use of the damping parameter in the l2 and cp line searches is much more subtle; 1255 it is used as a starting point in calculating the secant step. However, the eventual 1256 step may be of greater length than the damping parameter. In the bt line search it is 1257 used as the maximum possible step length, as the bt line search only backtracks. 1258 1259 .seealso: SNESLineSearchGetDamping() 1260 @*/ 1261 PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping) 1262 { 1263 PetscFunctionBegin; 1264 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1265 linesearch->damping = damping; 1266 PetscFunctionReturn(0); 1267 } 1268 1269 /*@ 1270 SNESLineSearchGetOrder - Gets the line search approximation order. 1271 1272 Input Parameters: 1273 . linesearch - linesearch context 1274 1275 Output Parameters: 1276 . order - The order 1277 1278 Possible Values for order: 1279 + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order 1280 . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order 1281 - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order 1282 1283 Level: intermediate 1284 1285 .seealso: SNESLineSearchSetOrder() 1286 @*/ 1287 1288 PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order) 1289 { 1290 PetscFunctionBegin; 1291 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1292 PetscValidPointer(order, 2); 1293 *order = linesearch->order; 1294 PetscFunctionReturn(0); 1295 } 1296 1297 /*@ 1298 SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search 1299 1300 Input Parameters: 1301 . linesearch - linesearch context 1302 . order - The damping parameter 1303 1304 Level: intermediate 1305 1306 Possible Values for order: 1307 + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order 1308 . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order 1309 - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order 1310 1311 Notes: 1312 Variable orders are supported by the following line searches: 1313 + bt - cubic and quadratic 1314 - cp - linear and quadratic 1315 1316 .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping() 1317 @*/ 1318 PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order) 1319 { 1320 PetscFunctionBegin; 1321 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1322 linesearch->order = order; 1323 PetscFunctionReturn(0); 1324 } 1325 1326 /*@ 1327 SNESLineSearchGetNorms - Gets the norms for for X, Y, and F. 1328 1329 Input Parameters: 1330 . linesearch - linesearch context 1331 1332 Output Parameters: 1333 + xnorm - The norm of the current solution 1334 . fnorm - The norm of the current function 1335 - ynorm - The norm of the current update 1336 1337 Notes: 1338 This function is mainly called from SNES implementations. 1339 1340 Level: developer 1341 1342 .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs() 1343 @*/ 1344 PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm) 1345 { 1346 PetscFunctionBegin; 1347 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1348 if (xnorm) *xnorm = linesearch->xnorm; 1349 if (fnorm) *fnorm = linesearch->fnorm; 1350 if (ynorm) *ynorm = linesearch->ynorm; 1351 PetscFunctionReturn(0); 1352 } 1353 1354 /*@ 1355 SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F. 1356 1357 Input Parameters: 1358 + linesearch - linesearch context 1359 . xnorm - The norm of the current solution 1360 . fnorm - The norm of the current function 1361 - ynorm - The norm of the current update 1362 1363 Level: advanced 1364 1365 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs() 1366 @*/ 1367 PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm) 1368 { 1369 PetscFunctionBegin; 1370 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1371 linesearch->xnorm = xnorm; 1372 linesearch->fnorm = fnorm; 1373 linesearch->ynorm = ynorm; 1374 PetscFunctionReturn(0); 1375 } 1376 1377 /*@ 1378 SNESLineSearchComputeNorms - Computes the norms of X, F, and Y. 1379 1380 Input Parameters: 1381 . linesearch - linesearch context 1382 1383 Options Database Keys: 1384 . -snes_linesearch_norms - turn norm computation on or off 1385 1386 Level: intermediate 1387 1388 .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms() 1389 @*/ 1390 PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch) 1391 { 1392 PetscErrorCode ierr; 1393 SNES snes; 1394 1395 PetscFunctionBegin; 1396 if (linesearch->norms) { 1397 if (linesearch->ops->vinorm) { 1398 ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr); 1399 ierr = VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 1400 ierr = VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 1401 ierr = (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);CHKERRQ(ierr); 1402 } else { 1403 ierr = VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 1404 ierr = VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 1405 ierr = VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 1406 ierr = VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 1407 ierr = VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 1408 ierr = VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 1409 } 1410 } 1411 PetscFunctionReturn(0); 1412 } 1413 1414 /*@ 1415 SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search. 1416 1417 Input Parameters: 1418 + linesearch - linesearch context 1419 - flg - indicates whether or not to compute norms 1420 1421 Options Database Keys: 1422 . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch 1423 1424 Notes: 1425 This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm. 1426 1427 Level: intermediate 1428 1429 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC 1430 @*/ 1431 PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg) 1432 { 1433 PetscFunctionBegin; 1434 linesearch->norms = flg; 1435 PetscFunctionReturn(0); 1436 } 1437 1438 /*@ 1439 SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context 1440 1441 Input Parameters: 1442 . linesearch - linesearch context 1443 1444 Output Parameters: 1445 + X - Solution vector 1446 . F - Function vector 1447 . Y - Search direction vector 1448 . W - Solution work vector 1449 - G - Function work vector 1450 1451 Notes: 1452 At the beginning of a line search application, X should contain a 1453 solution and the vector F the function computed at X. At the end of the 1454 line search application, X should contain the new solution, and F the 1455 function evaluated at the new solution. 1456 1457 These vectors are owned by the SNESLineSearch and should not be destroyed by the caller 1458 1459 Level: advanced 1460 1461 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs() 1462 @*/ 1463 PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G) 1464 { 1465 PetscFunctionBegin; 1466 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1467 if (X) { 1468 PetscValidPointer(X, 2); 1469 *X = linesearch->vec_sol; 1470 } 1471 if (F) { 1472 PetscValidPointer(F, 3); 1473 *F = linesearch->vec_func; 1474 } 1475 if (Y) { 1476 PetscValidPointer(Y, 4); 1477 *Y = linesearch->vec_update; 1478 } 1479 if (W) { 1480 PetscValidPointer(W, 5); 1481 *W = linesearch->vec_sol_new; 1482 } 1483 if (G) { 1484 PetscValidPointer(G, 6); 1485 *G = linesearch->vec_func_new; 1486 } 1487 PetscFunctionReturn(0); 1488 } 1489 1490 /*@ 1491 SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context 1492 1493 Input Parameters: 1494 + linesearch - linesearch context 1495 . X - Solution vector 1496 . F - Function vector 1497 . Y - Search direction vector 1498 . W - Solution work vector 1499 - G - Function work vector 1500 1501 Level: advanced 1502 1503 .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs() 1504 @*/ 1505 PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G) 1506 { 1507 PetscFunctionBegin; 1508 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1509 if (X) { 1510 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 1511 linesearch->vec_sol = X; 1512 } 1513 if (F) { 1514 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 1515 linesearch->vec_func = F; 1516 } 1517 if (Y) { 1518 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 1519 linesearch->vec_update = Y; 1520 } 1521 if (W) { 1522 PetscValidHeaderSpecific(W,VEC_CLASSID,5); 1523 linesearch->vec_sol_new = W; 1524 } 1525 if (G) { 1526 PetscValidHeaderSpecific(G,VEC_CLASSID,6); 1527 linesearch->vec_func_new = G; 1528 } 1529 PetscFunctionReturn(0); 1530 } 1531 1532 /*@C 1533 SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all 1534 SNES options in the database. 1535 1536 Logically Collective on SNESLineSearch 1537 1538 Input Parameters: 1539 + snes - the SNES context 1540 - prefix - the prefix to prepend to all option names 1541 1542 Notes: 1543 A hyphen (-) must NOT be given at the beginning of the prefix name. 1544 The first character of all runtime options is AUTOMATICALLY the hyphen. 1545 1546 Level: advanced 1547 1548 .keywords: SNESLineSearch, append, options, prefix, database 1549 1550 .seealso: SNESGetOptionsPrefix() 1551 @*/ 1552 PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[]) 1553 { 1554 PetscErrorCode ierr; 1555 1556 PetscFunctionBegin; 1557 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1558 ierr = PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr); 1559 PetscFunctionReturn(0); 1560 } 1561 1562 /*@C 1563 SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all 1564 SNESLineSearch options in the database. 1565 1566 Not Collective 1567 1568 Input Parameter: 1569 . linesearch - the SNESLineSearch context 1570 1571 Output Parameter: 1572 . prefix - pointer to the prefix string used 1573 1574 Notes: 1575 On the fortran side, the user should pass in a string 'prefix' of 1576 sufficient length to hold the prefix. 1577 1578 Level: advanced 1579 1580 .keywords: SNESLineSearch, get, options, prefix, database 1581 1582 .seealso: SNESAppendOptionsPrefix() 1583 @*/ 1584 PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[]) 1585 { 1586 PetscErrorCode ierr; 1587 1588 PetscFunctionBegin; 1589 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1590 ierr = PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr); 1591 PetscFunctionReturn(0); 1592 } 1593 1594 /*@C 1595 SNESLineSearchSetWorkVecs - Gets work vectors for the line search. 1596 1597 Input Parameter: 1598 + linesearch - the SNESLineSearch context 1599 - nwork - the number of work vectors 1600 1601 Level: developer 1602 1603 .keywords: SNESLineSearch, work, vector 1604 1605 .seealso: SNESSetWorkVecs() 1606 @*/ 1607 PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork) 1608 { 1609 PetscErrorCode ierr; 1610 1611 PetscFunctionBegin; 1612 if (linesearch->vec_sol) { 1613 ierr = VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);CHKERRQ(ierr); 1614 } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!"); 1615 PetscFunctionReturn(0); 1616 } 1617 1618 /*@ 1619 SNESLineSearchGetReason - Gets the success/failure status of the last line search application 1620 1621 Input Parameters: 1622 . linesearch - linesearch context 1623 1624 Output Parameters: 1625 . result - The success or failure status 1626 1627 Notes: 1628 This is typically called after SNESLineSearchApply() in order to determine if the line-search failed 1629 (and set the SNES convergence accordingly). 1630 1631 Level: intermediate 1632 1633 .seealso: SNESLineSearchSetReason(), SNESLineSearchReason 1634 @*/ 1635 PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result) 1636 { 1637 PetscFunctionBegin; 1638 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1639 PetscValidPointer(result, 2); 1640 *result = linesearch->result; 1641 PetscFunctionReturn(0); 1642 } 1643 1644 /*@ 1645 SNESLineSearchSetReason - Sets the success/failure status of the last line search application 1646 1647 Input Parameters: 1648 + linesearch - linesearch context 1649 - result - The success or failure status 1650 1651 Notes: 1652 This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set 1653 the success or failure of the line search method. 1654 1655 Level: developer 1656 1657 .seealso: SNESLineSearchGetSResult() 1658 @*/ 1659 PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result) 1660 { 1661 PetscFunctionBegin; 1662 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1663 linesearch->result = result; 1664 PetscFunctionReturn(0); 1665 } 1666 1667 /*@C 1668 SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation. 1669 1670 Input Parameters: 1671 + snes - nonlinear context obtained from SNESCreate() 1672 . projectfunc - function for projecting the function to the bounds 1673 - normfunc - function for computing the norm of an active set 1674 1675 Logically Collective on SNES 1676 1677 Calling sequence of projectfunc: 1678 .vb 1679 projectfunc (SNES snes, Vec X) 1680 .ve 1681 1682 Input parameters for projectfunc: 1683 + snes - nonlinear context 1684 - X - current solution 1685 1686 Output parameters for projectfunc: 1687 . X - Projected solution 1688 1689 Calling sequence of normfunc: 1690 .vb 1691 projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm) 1692 .ve 1693 1694 Input parameters for normfunc: 1695 + snes - nonlinear context 1696 . X - current solution 1697 - F - current residual 1698 1699 Output parameters for normfunc: 1700 . fnorm - VI-specific norm of the function 1701 1702 Notes: 1703 The VI solvers require projection of the solution to the feasible set. projectfunc should implement this. 1704 1705 The VI solvers require special evaluation of the function norm such that the norm is only calculated 1706 on the inactive set. This should be implemented by normfunc. 1707 1708 Level: developer 1709 1710 .keywords: SNES, line search, VI, nonlinear, set, line search 1711 1712 .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck() 1713 @*/ 1714 PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc) 1715 { 1716 PetscFunctionBegin; 1717 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1718 if (projectfunc) linesearch->ops->viproject = projectfunc; 1719 if (normfunc) linesearch->ops->vinorm = normfunc; 1720 PetscFunctionReturn(0); 1721 } 1722 1723 /*@C 1724 SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation. 1725 1726 Input Parameters: 1727 . linesearch - the line search context, obtain with SNESGetLineSearch() 1728 1729 Output Parameters: 1730 + projectfunc - function for projecting the function to the bounds 1731 - normfunc - function for computing the norm of an active set 1732 1733 Logically Collective on SNES 1734 1735 Level: developer 1736 1737 .keywords: SNES, line search, VI, nonlinear, get, line search 1738 1739 .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck() 1740 @*/ 1741 PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc) 1742 { 1743 PetscFunctionBegin; 1744 if (projectfunc) *projectfunc = linesearch->ops->viproject; 1745 if (normfunc) *normfunc = linesearch->ops->vinorm; 1746 PetscFunctionReturn(0); 1747 } 1748 1749 /*@C 1750 SNESLineSearchRegister - See SNESLineSearchRegister() 1751 1752 Level: advanced 1753 @*/ 1754 PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch)) 1755 { 1756 PetscErrorCode ierr; 1757 1758 PetscFunctionBegin; 1759 ierr = PetscFunctionListAdd(&SNESLineSearchList,sname,function);CHKERRQ(ierr); 1760 PetscFunctionReturn(0); 1761 } 1762