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 = (ydiffnorm > .001*ylastnorm) ? ylastnorm / ydiffnorm : 1000.0; 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 *changed = PETSC_TRUE; 574 } else { 575 ierr = PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);CHKERRQ(ierr); 576 ierr = VecCopy(Y,Ylast);CHKERRQ(ierr); 577 *changed = PETSC_FALSE; 578 } 579 PetscFunctionReturn(0); 580 } 581 582 /*@ 583 SNESLineSearchApply - Computes the line-search update. 584 585 Collective on SNESLineSearch 586 587 Input Parameters: 588 + linesearch - The linesearch context 589 . X - The current solution 590 . F - The current function 591 . fnorm - The current norm 592 - Y - The search direction 593 594 Output Parameters: 595 + X - The new solution 596 . F - The new function 597 - fnorm - The new function norm 598 599 Options Database Keys: 600 + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell 601 . -snes_linesearch_monitor [:filename] - Print progress of line searches 602 . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping) 603 . -snes_linesearch_norms - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms()) 604 . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess 605 - -snes_linesearch_max_it - The number of iterations for iterative line searches 606 607 Notes: 608 This is typically called from within a SNESSolve() implementation in order to 609 help with convergence of the nonlinear method. Various SNES types use line searches 610 in different ways, but the overarching theme is that a line search is used to determine 611 an optimal damping parameter of a step at each iteration of the method. Each 612 application of the line search may invoke SNESComputeFunction() several times, and 613 therefore may be fairly expensive. 614 615 Level: Intermediate 616 617 .keywords: SNESLineSearch, Create 618 619 .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(), 620 SNESLineSearchType, SNESLineSearchSetType() 621 @*/ 622 PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y) 623 { 624 PetscErrorCode ierr; 625 626 PetscFunctionBegin; 627 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 628 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 629 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 630 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 631 632 linesearch->result = SNES_LINESEARCH_SUCCEEDED; 633 634 linesearch->vec_sol = X; 635 linesearch->vec_update = Y; 636 linesearch->vec_func = F; 637 638 ierr = SNESLineSearchSetUp(linesearch);CHKERRQ(ierr); 639 640 if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */ 641 642 if (fnorm) linesearch->fnorm = *fnorm; 643 else { 644 ierr = VecNorm(F, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 645 } 646 647 ierr = PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y);CHKERRQ(ierr); 648 649 ierr = (*linesearch->ops->apply)(linesearch);CHKERRQ(ierr); 650 651 ierr = PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y);CHKERRQ(ierr); 652 653 if (fnorm) *fnorm = linesearch->fnorm; 654 PetscFunctionReturn(0); 655 } 656 657 /*@ 658 SNESLineSearchDestroy - Destroys the line search instance. 659 660 Collective on SNESLineSearch 661 662 Input Parameters: 663 . linesearch - The linesearch context 664 665 Level: developer 666 667 .keywords: SNESLineSearch, Destroy 668 669 .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy() 670 @*/ 671 PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch) 672 { 673 PetscErrorCode ierr; 674 675 PetscFunctionBegin; 676 if (!*linesearch) PetscFunctionReturn(0); 677 PetscValidHeaderSpecific((*linesearch),SNESLINESEARCH_CLASSID,1); 678 if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; PetscFunctionReturn(0);} 679 ierr = PetscObjectSAWsViewOff((PetscObject)*linesearch);CHKERRQ(ierr); 680 ierr = SNESLineSearchReset(*linesearch);CHKERRQ(ierr); 681 if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch); 682 ierr = PetscViewerDestroy(&(*linesearch)->monitor);CHKERRQ(ierr); 683 ierr = SNESLineSearchMonitorCancel((*linesearch));CHKERRQ(ierr); 684 ierr = PetscHeaderDestroy(linesearch);CHKERRQ(ierr); 685 PetscFunctionReturn(0); 686 } 687 688 /*@ 689 SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search. 690 691 Input Parameters: 692 + linesearch - the linesearch object 693 - viewer - an ASCII PetscViewer or NULL to turn off monitor 694 695 Logically Collective on SNESLineSearch 696 697 Options Database: 698 . -snes_linesearch_monitor [:filename] - enables the monitor 699 700 Level: intermediate 701 702 Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with 703 SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the 704 line search that are not visible to the other monitors. 705 706 .seealso: SNESGetLineSearch(), SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor() 707 @*/ 708 PetscErrorCode SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer) 709 { 710 PetscErrorCode ierr; 711 712 PetscFunctionBegin; 713 if (viewer) {ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);} 714 ierr = PetscViewerDestroy(&linesearch->monitor);CHKERRQ(ierr); 715 linesearch->monitor = viewer; 716 PetscFunctionReturn(0); 717 } 718 719 /*@ 720 SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor. 721 722 Input Parameter: 723 . linesearch - linesearch context 724 725 Output Parameter: 726 . monitor - monitor context 727 728 Logically Collective on SNES 729 730 Options Database Keys: 731 . -snes_linesearch_monitor - enables the monitor 732 733 Level: intermediate 734 735 .seealso: SNESGetLineSearch(), SNESLineSearchSetDefaultMonitor(), PetscViewer 736 @*/ 737 PetscErrorCode SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor) 738 { 739 PetscFunctionBegin; 740 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 741 if (monitor) { 742 PetscValidPointer(monitor, 2); 743 *monitor = linesearch->monitor; 744 } 745 PetscFunctionReturn(0); 746 } 747 748 /*@C 749 SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 750 751 Collective on SNESLineSearch 752 753 Input Parameters: 754 + ls - LineSearch object you wish to monitor 755 . name - the monitor type one is seeking 756 . help - message indicating what monitoring is done 757 . manual - manual page for the monitor 758 . monitor - the monitor function 759 - 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 760 761 Level: developer 762 763 .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 764 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 765 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 766 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 767 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 768 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 769 PetscOptionsFList(), PetscOptionsEList() 770 @*/ 771 PetscErrorCode SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*)) 772 { 773 PetscErrorCode ierr; 774 PetscViewer viewer; 775 PetscViewerFormat format; 776 PetscBool flg; 777 778 PetscFunctionBegin; 779 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject) ls)->options,((PetscObject)ls)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 780 if (flg) { 781 PetscViewerAndFormat *vf; 782 ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 783 ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 784 if (monitorsetup) { 785 ierr = (*monitorsetup)(ls,vf);CHKERRQ(ierr); 786 } 787 ierr = SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 788 } 789 PetscFunctionReturn(0); 790 } 791 792 /*@ 793 SNESLineSearchSetFromOptions - Sets options for the line search 794 795 Input Parameters: 796 . linesearch - linesearch context 797 798 Options Database Keys: 799 + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell 800 . -snes_linesearch_order <order> - 1, 2, 3. Most types only support certain orders (bt supports 2 or 3) 801 . -snes_linesearch_norms - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms()) 802 . -snes_linesearch_minlambda - The minimum step length 803 . -snes_linesearch_maxstep - The maximum step size 804 . -snes_linesearch_rtol - Relative tolerance for iterative line searches 805 . -snes_linesearch_atol - Absolute tolerance for iterative line searches 806 . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches 807 . -snes_linesearch_max_it - The number of iterations for iterative line searches 808 . -snes_linesearch_monitor [:filename] - Print progress of line searches 809 . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine 810 . -snes_linesearch_damping - The linesearch damping parameter 811 . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess. 812 . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method 813 - -snes_linesearch_precheck_picard_angle - Angle used in Picard precheck method 814 815 Logically Collective on SNESLineSearch 816 817 Level: intermediate 818 819 .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(), 820 SNESLineSearchType, SNESLineSearchSetComputeNorms() 821 @*/ 822 PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch) 823 { 824 PetscErrorCode ierr; 825 const char *deft = SNESLINESEARCHBASIC; 826 char type[256]; 827 PetscBool flg, set; 828 PetscViewer viewer; 829 830 PetscFunctionBegin; 831 ierr = SNESLineSearchRegisterAll();CHKERRQ(ierr); 832 833 ierr = PetscObjectOptionsBegin((PetscObject)linesearch);CHKERRQ(ierr); 834 if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name; 835 ierr = PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);CHKERRQ(ierr); 836 if (flg) { 837 ierr = SNESLineSearchSetType(linesearch,type);CHKERRQ(ierr); 838 } else if (!((PetscObject)linesearch)->type_name) { 839 ierr = SNESLineSearchSetType(linesearch,deft);CHKERRQ(ierr); 840 } 841 842 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject) linesearch)->options,((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);CHKERRQ(ierr); 843 if (set) { 844 ierr = SNESLineSearchSetDefaultMonitor(linesearch,viewer);CHKERRQ(ierr); 845 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 846 } 847 ierr = SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);CHKERRQ(ierr); 848 849 /* tolerances */ 850 ierr = PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);CHKERRQ(ierr); 851 ierr = PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);CHKERRQ(ierr); 852 ierr = PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);CHKERRQ(ierr); 853 ierr = PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);CHKERRQ(ierr); 854 ierr = PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);CHKERRQ(ierr); 855 ierr = PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);CHKERRQ(ierr); 856 857 /* damping parameters */ 858 ierr = PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);CHKERRQ(ierr); 859 860 ierr = PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL);CHKERRQ(ierr); 861 862 /* precheck */ 863 ierr = PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr); 864 if (set) { 865 if (flg) { 866 linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */ 867 868 ierr = PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction", 869 "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);CHKERRQ(ierr); 870 ierr = SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);CHKERRQ(ierr); 871 } else { 872 ierr = SNESLineSearchSetPreCheck(linesearch,NULL,NULL);CHKERRQ(ierr); 873 } 874 } 875 ierr = PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);CHKERRQ(ierr); 876 ierr = PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);CHKERRQ(ierr); 877 878 if (linesearch->ops->setfromoptions) { 879 (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);CHKERRQ(ierr); 880 } 881 882 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);CHKERRQ(ierr); 883 ierr = PetscOptionsEnd();CHKERRQ(ierr); 884 PetscFunctionReturn(0); 885 } 886 887 /*@ 888 SNESLineSearchView - Prints useful information about the line search 889 890 Input Parameters: 891 . linesearch - linesearch context 892 893 Logically Collective on SNESLineSearch 894 895 Level: intermediate 896 897 .seealso: SNESLineSearchCreate() 898 @*/ 899 PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer) 900 { 901 PetscErrorCode ierr; 902 PetscBool iascii; 903 904 PetscFunctionBegin; 905 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 906 if (!viewer) { 907 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);CHKERRQ(ierr); 908 } 909 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 910 PetscCheckSameComm(linesearch,1,viewer,2); 911 912 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 913 if (iascii) { 914 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);CHKERRQ(ierr); 915 if (linesearch->ops->view) { 916 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 917 ierr = (*linesearch->ops->view)(linesearch,viewer);CHKERRQ(ierr); 918 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 919 } 920 ierr = PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);CHKERRQ(ierr); 921 ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);CHKERRQ(ierr); 922 ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", linesearch->max_its);CHKERRQ(ierr); 923 if (linesearch->ops->precheck) { 924 if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) { 925 ierr = PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n", linesearch->max_its);CHKERRQ(ierr); 926 } else { 927 ierr = PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n", linesearch->max_its);CHKERRQ(ierr); 928 } 929 } 930 if (linesearch->ops->postcheck) { 931 ierr = PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n", linesearch->max_its);CHKERRQ(ierr); 932 } 933 } 934 PetscFunctionReturn(0); 935 } 936 937 /*@C 938 SNESLineSearchSetType - Sets the linesearch type 939 940 Logically Collective on SNESLineSearch 941 942 Input Parameters: 943 + linesearch - linesearch context 944 - type - The type of line search to be used 945 946 Available Types: 947 + SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step 948 . SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function 949 . SNESLINESEARCHL2 - Secant line search over the L2 norm of the function 950 . SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x) 951 . SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch 952 - SNESLINESEARCHSHELL - User provided SNESLineSearch implementation 953 954 Options Database: 955 . -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell 956 957 Level: intermediate 958 959 .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions() 960 @*/ 961 PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type) 962 { 963 PetscErrorCode ierr,(*r)(SNESLineSearch); 964 PetscBool match; 965 966 PetscFunctionBegin; 967 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 968 PetscValidCharPointer(type,2); 969 970 ierr = PetscObjectTypeCompare((PetscObject)linesearch,type,&match);CHKERRQ(ierr); 971 if (match) PetscFunctionReturn(0); 972 973 ierr = PetscFunctionListFind(SNESLineSearchList,type,&r);CHKERRQ(ierr); 974 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type); 975 /* Destroy the previous private linesearch context */ 976 if (linesearch->ops->destroy) { 977 ierr = (*(linesearch)->ops->destroy)(linesearch);CHKERRQ(ierr); 978 979 linesearch->ops->destroy = NULL; 980 } 981 /* Reinitialize function pointers in SNESLineSearchOps structure */ 982 linesearch->ops->apply = 0; 983 linesearch->ops->view = 0; 984 linesearch->ops->setfromoptions = 0; 985 linesearch->ops->destroy = 0; 986 987 ierr = PetscObjectChangeTypeName((PetscObject)linesearch,type);CHKERRQ(ierr); 988 ierr = (*r)(linesearch);CHKERRQ(ierr); 989 PetscFunctionReturn(0); 990 } 991 992 /*@ 993 SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation. 994 995 Input Parameters: 996 + linesearch - linesearch context 997 - snes - The snes instance 998 999 Level: developer 1000 1001 Notes: 1002 This happens automatically when the line search is obtained/created with 1003 SNESGetLineSearch(). This routine is therefore mainly called within SNES 1004 implementations. 1005 1006 Level: developer 1007 1008 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES 1009 @*/ 1010 PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes) 1011 { 1012 PetscFunctionBegin; 1013 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1014 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 1015 linesearch->snes = snes; 1016 PetscFunctionReturn(0); 1017 } 1018 1019 /*@ 1020 SNESLineSearchGetSNES - Gets the SNES instance associated with the line search. 1021 Having an associated SNES is necessary because most line search implementations must be able to 1022 evaluate the function using SNESComputeFunction() for the associated SNES. This routine 1023 is used in the line search implementations when one must get this associated SNES instance. 1024 1025 Input Parameters: 1026 . linesearch - linesearch context 1027 1028 Output Parameters: 1029 . snes - The snes instance 1030 1031 Level: developer 1032 1033 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES 1034 @*/ 1035 PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes) 1036 { 1037 PetscFunctionBegin; 1038 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1039 PetscValidPointer(snes, 2); 1040 *snes = linesearch->snes; 1041 PetscFunctionReturn(0); 1042 } 1043 1044 /*@ 1045 SNESLineSearchGetLambda - Gets the last linesearch steplength discovered. 1046 1047 Input Parameters: 1048 . linesearch - linesearch context 1049 1050 Output Parameters: 1051 . lambda - The last steplength computed during SNESLineSearchApply() 1052 1053 Level: advanced 1054 1055 Notes: 1056 This is useful in methods where the solver is ill-scaled and 1057 requires some adaptive notion of the difference in scale between the 1058 solution and the function. For instance, SNESQN may be scaled by the 1059 line search lambda using the argument -snes_qn_scaling ls. 1060 1061 .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply() 1062 @*/ 1063 PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda) 1064 { 1065 PetscFunctionBegin; 1066 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1067 PetscValidPointer(lambda, 2); 1068 *lambda = linesearch->lambda; 1069 PetscFunctionReturn(0); 1070 } 1071 1072 /*@ 1073 SNESLineSearchSetLambda - Sets the linesearch steplength. 1074 1075 Input Parameters: 1076 + linesearch - linesearch context 1077 - lambda - The last steplength. 1078 1079 Notes: 1080 This routine is typically used within implementations of SNESLineSearchApply() 1081 to set the final steplength. This routine (and SNESLineSearchGetLambda()) were 1082 added in order to facilitate Quasi-Newton methods that use the previous steplength 1083 as an inner scaling parameter. 1084 1085 Level: advanced 1086 1087 .seealso: SNESLineSearchGetLambda() 1088 @*/ 1089 PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda) 1090 { 1091 PetscFunctionBegin; 1092 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1093 linesearch->lambda = lambda; 1094 PetscFunctionReturn(0); 1095 } 1096 1097 /*@ 1098 SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include 1099 tolerances for the relative and absolute change in the function norm, the change 1100 in lambda for iterative line searches, the minimum steplength, the maximum steplength, 1101 and the maximum number of iterations the line search procedure may take. 1102 1103 Input Parameters: 1104 . linesearch - linesearch context 1105 1106 Output Parameters: 1107 + steptol - The minimum steplength 1108 . maxstep - The maximum steplength 1109 . rtol - The relative tolerance for iterative line searches 1110 . atol - The absolute tolerance for iterative line searches 1111 . ltol - The change in lambda tolerance for iterative line searches 1112 - max_it - The maximum number of iterations of the line search 1113 1114 Level: intermediate 1115 1116 Notes: 1117 Different line searches may implement these parameters slightly differently as 1118 the type requires. 1119 1120 .seealso: SNESLineSearchSetTolerances() 1121 @*/ 1122 PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its) 1123 { 1124 PetscFunctionBegin; 1125 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1126 if (steptol) { 1127 PetscValidPointer(steptol, 2); 1128 *steptol = linesearch->steptol; 1129 } 1130 if (maxstep) { 1131 PetscValidPointer(maxstep, 3); 1132 *maxstep = linesearch->maxstep; 1133 } 1134 if (rtol) { 1135 PetscValidPointer(rtol, 4); 1136 *rtol = linesearch->rtol; 1137 } 1138 if (atol) { 1139 PetscValidPointer(atol, 5); 1140 *atol = linesearch->atol; 1141 } 1142 if (ltol) { 1143 PetscValidPointer(ltol, 6); 1144 *ltol = linesearch->ltol; 1145 } 1146 if (max_its) { 1147 PetscValidPointer(max_its, 7); 1148 *max_its = linesearch->max_its; 1149 } 1150 PetscFunctionReturn(0); 1151 } 1152 1153 /*@ 1154 SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include 1155 tolerances for the relative and absolute change in the function norm, the change 1156 in lambda for iterative line searches, the minimum steplength, the maximum steplength, 1157 and the maximum number of iterations the line search procedure may take. 1158 1159 Input Parameters: 1160 + linesearch - linesearch context 1161 . steptol - The minimum steplength 1162 . maxstep - The maximum steplength 1163 . rtol - The relative tolerance for iterative line searches 1164 . atol - The absolute tolerance for iterative line searches 1165 . ltol - The change in lambda tolerance for iterative line searches 1166 - max_it - The maximum number of iterations of the line search 1167 1168 Notes: 1169 The user may choose to not set any of the tolerances using PETSC_DEFAULT in 1170 place of an argument. 1171 1172 Level: intermediate 1173 1174 .seealso: SNESLineSearchGetTolerances() 1175 @*/ 1176 PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its) 1177 { 1178 PetscFunctionBegin; 1179 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1180 PetscValidLogicalCollectiveReal(linesearch,steptol,2); 1181 PetscValidLogicalCollectiveReal(linesearch,maxstep,3); 1182 PetscValidLogicalCollectiveReal(linesearch,rtol,4); 1183 PetscValidLogicalCollectiveReal(linesearch,atol,5); 1184 PetscValidLogicalCollectiveReal(linesearch,ltol,6); 1185 PetscValidLogicalCollectiveInt(linesearch,max_its,7); 1186 1187 if (steptol!= PETSC_DEFAULT) { 1188 if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol); 1189 linesearch->steptol = steptol; 1190 } 1191 1192 if (maxstep!= PETSC_DEFAULT) { 1193 if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep); 1194 linesearch->maxstep = maxstep; 1195 } 1196 1197 if (rtol != PETSC_DEFAULT) { 1198 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); 1199 linesearch->rtol = rtol; 1200 } 1201 1202 if (atol != PETSC_DEFAULT) { 1203 if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol); 1204 linesearch->atol = atol; 1205 } 1206 1207 if (ltol != PETSC_DEFAULT) { 1208 if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %14.12e must be non-negative",(double)ltol); 1209 linesearch->ltol = ltol; 1210 } 1211 1212 if (max_its != PETSC_DEFAULT) { 1213 if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its); 1214 linesearch->max_its = max_its; 1215 } 1216 PetscFunctionReturn(0); 1217 } 1218 1219 /*@ 1220 SNESLineSearchGetDamping - Gets the line search damping parameter. 1221 1222 Input Parameters: 1223 . linesearch - linesearch context 1224 1225 Output Parameters: 1226 . damping - The damping parameter 1227 1228 Level: advanced 1229 1230 .seealso: SNESLineSearchGetStepTolerance(), SNESQN 1231 @*/ 1232 1233 PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping) 1234 { 1235 PetscFunctionBegin; 1236 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1237 PetscValidPointer(damping, 2); 1238 *damping = linesearch->damping; 1239 PetscFunctionReturn(0); 1240 } 1241 1242 /*@ 1243 SNESLineSearchSetDamping - Sets the line search damping paramter. 1244 1245 Input Parameters: 1246 + linesearch - linesearch context 1247 - damping - The damping parameter 1248 1249 Options Database: 1250 . -snes_linesearch_damping 1251 Level: intermediate 1252 1253 Notes: 1254 The basic line search merely takes the update step scaled by the damping parameter. 1255 The use of the damping parameter in the l2 and cp line searches is much more subtle; 1256 it is used as a starting point in calculating the secant step. However, the eventual 1257 step may be of greater length than the damping parameter. In the bt line search it is 1258 used as the maximum possible step length, as the bt line search only backtracks. 1259 1260 .seealso: SNESLineSearchGetDamping() 1261 @*/ 1262 PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping) 1263 { 1264 PetscFunctionBegin; 1265 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1266 linesearch->damping = damping; 1267 PetscFunctionReturn(0); 1268 } 1269 1270 /*@ 1271 SNESLineSearchGetOrder - Gets the line search approximation order. 1272 1273 Input Parameters: 1274 . linesearch - linesearch context 1275 1276 Output Parameters: 1277 . order - The order 1278 1279 Possible Values for order: 1280 + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order 1281 . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order 1282 - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order 1283 1284 Level: intermediate 1285 1286 .seealso: SNESLineSearchSetOrder() 1287 @*/ 1288 1289 PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order) 1290 { 1291 PetscFunctionBegin; 1292 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1293 PetscValidPointer(order, 2); 1294 *order = linesearch->order; 1295 PetscFunctionReturn(0); 1296 } 1297 1298 /*@ 1299 SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search 1300 1301 Input Parameters: 1302 . linesearch - linesearch context 1303 . order - The damping parameter 1304 1305 Level: intermediate 1306 1307 Possible Values for order: 1308 + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order 1309 . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order 1310 - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order 1311 1312 Notes: 1313 Variable orders are supported by the following line searches: 1314 + bt - cubic and quadratic 1315 - cp - linear and quadratic 1316 1317 .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping() 1318 @*/ 1319 PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order) 1320 { 1321 PetscFunctionBegin; 1322 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1323 linesearch->order = order; 1324 PetscFunctionReturn(0); 1325 } 1326 1327 /*@ 1328 SNESLineSearchGetNorms - Gets the norms for for X, Y, and F. 1329 1330 Input Parameters: 1331 . linesearch - linesearch context 1332 1333 Output Parameters: 1334 + xnorm - The norm of the current solution 1335 . fnorm - The norm of the current function 1336 - ynorm - The norm of the current update 1337 1338 Notes: 1339 This function is mainly called from SNES implementations. 1340 1341 Level: developer 1342 1343 .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs() 1344 @*/ 1345 PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm) 1346 { 1347 PetscFunctionBegin; 1348 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1349 if (xnorm) *xnorm = linesearch->xnorm; 1350 if (fnorm) *fnorm = linesearch->fnorm; 1351 if (ynorm) *ynorm = linesearch->ynorm; 1352 PetscFunctionReturn(0); 1353 } 1354 1355 /*@ 1356 SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F. 1357 1358 Input Parameters: 1359 + linesearch - linesearch context 1360 . xnorm - The norm of the current solution 1361 . fnorm - The norm of the current function 1362 - ynorm - The norm of the current update 1363 1364 Level: advanced 1365 1366 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs() 1367 @*/ 1368 PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm) 1369 { 1370 PetscFunctionBegin; 1371 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1372 linesearch->xnorm = xnorm; 1373 linesearch->fnorm = fnorm; 1374 linesearch->ynorm = ynorm; 1375 PetscFunctionReturn(0); 1376 } 1377 1378 /*@ 1379 SNESLineSearchComputeNorms - Computes the norms of X, F, and Y. 1380 1381 Input Parameters: 1382 . linesearch - linesearch context 1383 1384 Options Database Keys: 1385 . -snes_linesearch_norms - turn norm computation on or off 1386 1387 Level: intermediate 1388 1389 .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms() 1390 @*/ 1391 PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch) 1392 { 1393 PetscErrorCode ierr; 1394 SNES snes; 1395 1396 PetscFunctionBegin; 1397 if (linesearch->norms) { 1398 if (linesearch->ops->vinorm) { 1399 ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr); 1400 ierr = VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 1401 ierr = VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 1402 ierr = (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);CHKERRQ(ierr); 1403 } else { 1404 ierr = VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 1405 ierr = VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 1406 ierr = VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 1407 ierr = VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 1408 ierr = VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 1409 ierr = VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 1410 } 1411 } 1412 PetscFunctionReturn(0); 1413 } 1414 1415 /*@ 1416 SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search. 1417 1418 Input Parameters: 1419 + linesearch - linesearch context 1420 - flg - indicates whether or not to compute norms 1421 1422 Options Database Keys: 1423 . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch 1424 1425 Notes: 1426 This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm. 1427 1428 Level: intermediate 1429 1430 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC 1431 @*/ 1432 PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg) 1433 { 1434 PetscFunctionBegin; 1435 linesearch->norms = flg; 1436 PetscFunctionReturn(0); 1437 } 1438 1439 /*@ 1440 SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context 1441 1442 Input Parameters: 1443 . linesearch - linesearch context 1444 1445 Output Parameters: 1446 + X - Solution vector 1447 . F - Function vector 1448 . Y - Search direction vector 1449 . W - Solution work vector 1450 - G - Function work vector 1451 1452 Notes: 1453 At the beginning of a line search application, X should contain a 1454 solution and the vector F the function computed at X. At the end of the 1455 line search application, X should contain the new solution, and F the 1456 function evaluated at the new solution. 1457 1458 These vectors are owned by the SNESLineSearch and should not be destroyed by the caller 1459 1460 Level: advanced 1461 1462 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs() 1463 @*/ 1464 PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G) 1465 { 1466 PetscFunctionBegin; 1467 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1468 if (X) { 1469 PetscValidPointer(X, 2); 1470 *X = linesearch->vec_sol; 1471 } 1472 if (F) { 1473 PetscValidPointer(F, 3); 1474 *F = linesearch->vec_func; 1475 } 1476 if (Y) { 1477 PetscValidPointer(Y, 4); 1478 *Y = linesearch->vec_update; 1479 } 1480 if (W) { 1481 PetscValidPointer(W, 5); 1482 *W = linesearch->vec_sol_new; 1483 } 1484 if (G) { 1485 PetscValidPointer(G, 6); 1486 *G = linesearch->vec_func_new; 1487 } 1488 PetscFunctionReturn(0); 1489 } 1490 1491 /*@ 1492 SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context 1493 1494 Input Parameters: 1495 + linesearch - linesearch context 1496 . X - Solution vector 1497 . F - Function vector 1498 . Y - Search direction vector 1499 . W - Solution work vector 1500 - G - Function work vector 1501 1502 Level: advanced 1503 1504 .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs() 1505 @*/ 1506 PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G) 1507 { 1508 PetscFunctionBegin; 1509 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1510 if (X) { 1511 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 1512 linesearch->vec_sol = X; 1513 } 1514 if (F) { 1515 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 1516 linesearch->vec_func = F; 1517 } 1518 if (Y) { 1519 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 1520 linesearch->vec_update = Y; 1521 } 1522 if (W) { 1523 PetscValidHeaderSpecific(W,VEC_CLASSID,5); 1524 linesearch->vec_sol_new = W; 1525 } 1526 if (G) { 1527 PetscValidHeaderSpecific(G,VEC_CLASSID,6); 1528 linesearch->vec_func_new = G; 1529 } 1530 PetscFunctionReturn(0); 1531 } 1532 1533 /*@C 1534 SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all 1535 SNES options in the database. 1536 1537 Logically Collective on SNESLineSearch 1538 1539 Input Parameters: 1540 + snes - the SNES context 1541 - prefix - the prefix to prepend to all option names 1542 1543 Notes: 1544 A hyphen (-) must NOT be given at the beginning of the prefix name. 1545 The first character of all runtime options is AUTOMATICALLY the hyphen. 1546 1547 Level: advanced 1548 1549 .keywords: SNESLineSearch, append, options, prefix, database 1550 1551 .seealso: SNESGetOptionsPrefix() 1552 @*/ 1553 PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[]) 1554 { 1555 PetscErrorCode ierr; 1556 1557 PetscFunctionBegin; 1558 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1559 ierr = PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr); 1560 PetscFunctionReturn(0); 1561 } 1562 1563 /*@C 1564 SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all 1565 SNESLineSearch options in the database. 1566 1567 Not Collective 1568 1569 Input Parameter: 1570 . linesearch - the SNESLineSearch context 1571 1572 Output Parameter: 1573 . prefix - pointer to the prefix string used 1574 1575 Notes: 1576 On the fortran side, the user should pass in a string 'prefix' of 1577 sufficient length to hold the prefix. 1578 1579 Level: advanced 1580 1581 .keywords: SNESLineSearch, get, options, prefix, database 1582 1583 .seealso: SNESAppendOptionsPrefix() 1584 @*/ 1585 PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[]) 1586 { 1587 PetscErrorCode ierr; 1588 1589 PetscFunctionBegin; 1590 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1591 ierr = PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr); 1592 PetscFunctionReturn(0); 1593 } 1594 1595 /*@C 1596 SNESLineSearchSetWorkVecs - Gets work vectors for the line search. 1597 1598 Input Parameter: 1599 + linesearch - the SNESLineSearch context 1600 - nwork - the number of work vectors 1601 1602 Level: developer 1603 1604 .keywords: SNESLineSearch, work, vector 1605 1606 .seealso: SNESSetWorkVecs() 1607 @*/ 1608 PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork) 1609 { 1610 PetscErrorCode ierr; 1611 1612 PetscFunctionBegin; 1613 if (linesearch->vec_sol) { 1614 ierr = VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);CHKERRQ(ierr); 1615 } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!"); 1616 PetscFunctionReturn(0); 1617 } 1618 1619 /*@ 1620 SNESLineSearchGetReason - Gets the success/failure status of the last line search application 1621 1622 Input Parameters: 1623 . linesearch - linesearch context 1624 1625 Output Parameters: 1626 . result - The success or failure status 1627 1628 Notes: 1629 This is typically called after SNESLineSearchApply() in order to determine if the line-search failed 1630 (and set the SNES convergence accordingly). 1631 1632 Level: intermediate 1633 1634 .seealso: SNESLineSearchSetReason(), SNESLineSearchReason 1635 @*/ 1636 PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result) 1637 { 1638 PetscFunctionBegin; 1639 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1640 PetscValidPointer(result, 2); 1641 *result = linesearch->result; 1642 PetscFunctionReturn(0); 1643 } 1644 1645 /*@ 1646 SNESLineSearchSetReason - Sets the success/failure status of the last line search application 1647 1648 Input Parameters: 1649 + linesearch - linesearch context 1650 - result - The success or failure status 1651 1652 Notes: 1653 This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set 1654 the success or failure of the line search method. 1655 1656 Level: developer 1657 1658 .seealso: SNESLineSearchGetSResult() 1659 @*/ 1660 PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result) 1661 { 1662 PetscFunctionBegin; 1663 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1664 linesearch->result = result; 1665 PetscFunctionReturn(0); 1666 } 1667 1668 /*@C 1669 SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation. 1670 1671 Input Parameters: 1672 + snes - nonlinear context obtained from SNESCreate() 1673 . projectfunc - function for projecting the function to the bounds 1674 - normfunc - function for computing the norm of an active set 1675 1676 Logically Collective on SNES 1677 1678 Calling sequence of projectfunc: 1679 .vb 1680 projectfunc (SNES snes, Vec X) 1681 .ve 1682 1683 Input parameters for projectfunc: 1684 + snes - nonlinear context 1685 - X - current solution 1686 1687 Output parameters for projectfunc: 1688 . X - Projected solution 1689 1690 Calling sequence of normfunc: 1691 .vb 1692 projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm) 1693 .ve 1694 1695 Input parameters for normfunc: 1696 + snes - nonlinear context 1697 . X - current solution 1698 - F - current residual 1699 1700 Output parameters for normfunc: 1701 . fnorm - VI-specific norm of the function 1702 1703 Notes: 1704 The VI solvers require projection of the solution to the feasible set. projectfunc should implement this. 1705 1706 The VI solvers require special evaluation of the function norm such that the norm is only calculated 1707 on the inactive set. This should be implemented by normfunc. 1708 1709 Level: developer 1710 1711 .keywords: SNES, line search, VI, nonlinear, set, line search 1712 1713 .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck() 1714 @*/ 1715 PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc) 1716 { 1717 PetscFunctionBegin; 1718 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1719 if (projectfunc) linesearch->ops->viproject = projectfunc; 1720 if (normfunc) linesearch->ops->vinorm = normfunc; 1721 PetscFunctionReturn(0); 1722 } 1723 1724 /*@C 1725 SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation. 1726 1727 Input Parameters: 1728 . linesearch - the line search context, obtain with SNESGetLineSearch() 1729 1730 Output Parameters: 1731 + projectfunc - function for projecting the function to the bounds 1732 - normfunc - function for computing the norm of an active set 1733 1734 Logically Collective on SNES 1735 1736 Level: developer 1737 1738 .keywords: SNES, line search, VI, nonlinear, get, line search 1739 1740 .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck() 1741 @*/ 1742 PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc) 1743 { 1744 PetscFunctionBegin; 1745 if (projectfunc) *projectfunc = linesearch->ops->viproject; 1746 if (normfunc) *normfunc = linesearch->ops->vinorm; 1747 PetscFunctionReturn(0); 1748 } 1749 1750 /*@C 1751 SNESLineSearchRegister - See SNESLineSearchRegister() 1752 1753 Level: advanced 1754 @*/ 1755 PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch)) 1756 { 1757 PetscErrorCode ierr; 1758 1759 PetscFunctionBegin; 1760 ierr = SNESInitializePackage();CHKERRQ(ierr); 1761 ierr = PetscFunctionListAdd(&SNESLineSearchList,sname,function);CHKERRQ(ierr); 1762 PetscFunctionReturn(0); 1763 } 1764