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: Only a single monitor function can be set for each SNESLineSearch object 99 100 Level: intermediate 101 102 .keywords: SNESLineSearch, nonlinear, set, monitor 103 104 .seealso: SNESGetLineSearch(), SNESLineSearchMonitorDefault(), SNESLineSearchMonitorCancel() 105 @*/ 106 PetscErrorCode SNESLineSearchMonitorSet(SNESLineSearch ls,PetscErrorCode (*f)(SNESLineSearch,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 107 { 108 PetscErrorCode ierr; 109 PetscInt i; 110 PetscBool identical; 111 112 PetscFunctionBegin; 113 PetscValidHeaderSpecific(ls,SNESLINESEARCH_CLASSID,1); 114 for (i=0; i<ls->numbermonitors;i++) { 115 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))ls->monitorftns[i],ls->monitorcontext[i],ls->monitordestroy[i],&identical);CHKERRQ(ierr); 116 if (identical) PetscFunctionReturn(0); 117 } 118 if (ls->numbermonitors >= MAXSNESLSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 119 ls->monitorftns[ls->numbermonitors] = f; 120 ls->monitordestroy[ls->numbermonitors] = monitordestroy; 121 ls->monitorcontext[ls->numbermonitors++] = (void*)mctx; 122 PetscFunctionReturn(0); 123 } 124 125 /*@C 126 SNESLineSearchMonitorSolutionUpdate - Monitors each update a new function value the linesearch tries 127 128 Collective on SNESLineSearch 129 130 Input Parameters: 131 + ls - the SNES linesearch object 132 - vf - the context for the monitor, in this case it is an ASCII PetscViewer and format 133 134 Level: intermediate 135 136 .keywords: SNES, nonlinear, default, monitor, norm 137 138 .seealso: SNESGetLineSearch(), SNESMonitorSet(), SNESMonitorSolution() 139 @*/ 140 PetscErrorCode SNESLineSearchMonitorSolutionUpdate(SNESLineSearch ls,PetscViewerAndFormat *vf) 141 { 142 PetscErrorCode ierr; 143 PetscViewer viewer = vf->viewer; 144 Vec Y,W,G; 145 146 PetscFunctionBegin; 147 ierr = SNESLineSearchGetVecs(ls,NULL,NULL,&Y,&W,&G);CHKERRQ(ierr); 148 ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr); 149 ierr = PetscViewerASCIIPrintf(viewer,"LineSearch attempted update to solution \n");CHKERRQ(ierr); 150 ierr = VecView(Y,viewer);CHKERRQ(ierr); 151 ierr = PetscViewerASCIIPrintf(viewer,"LineSearch attempted new solution \n");CHKERRQ(ierr); 152 ierr = VecView(W,viewer);CHKERRQ(ierr); 153 ierr = PetscViewerASCIIPrintf(viewer,"LineSearch attempted updated function value\n");CHKERRQ(ierr); 154 ierr = VecView(G,viewer);CHKERRQ(ierr); 155 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 156 PetscFunctionReturn(0); 157 } 158 159 /*@ 160 SNESLineSearchCreate - Creates the line search context. 161 162 Logically Collective on Comm 163 164 Input Parameters: 165 . comm - MPI communicator for the line search (typically from the associated SNES context). 166 167 Output Parameters: 168 . outlinesearch - the new linesearch context 169 170 Level: developer 171 172 Notes: 173 The preferred calling sequence for users is to use SNESGetLineSearch() to acquire the SNESLineSearch instance 174 already associated with the SNES. This function is for developer use. 175 176 .keywords: LineSearch, create, context 177 178 .seealso: LineSearchDestroy(), SNESGetLineSearch() 179 @*/ 180 181 PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch) 182 { 183 PetscErrorCode ierr; 184 SNESLineSearch linesearch; 185 186 PetscFunctionBegin; 187 PetscValidPointer(outlinesearch,2); 188 ierr = SNESInitializePackage();CHKERRQ(ierr); 189 *outlinesearch = NULL; 190 191 ierr = PetscHeaderCreate(linesearch,SNESLINESEARCH_CLASSID, "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView);CHKERRQ(ierr); 192 193 linesearch->vec_sol_new = NULL; 194 linesearch->vec_func_new = NULL; 195 linesearch->vec_sol = NULL; 196 linesearch->vec_func = NULL; 197 linesearch->vec_update = NULL; 198 199 linesearch->lambda = 1.0; 200 linesearch->fnorm = 1.0; 201 linesearch->ynorm = 1.0; 202 linesearch->xnorm = 1.0; 203 linesearch->result = SNES_LINESEARCH_SUCCEEDED; 204 linesearch->norms = PETSC_TRUE; 205 linesearch->keeplambda = PETSC_FALSE; 206 linesearch->damping = 1.0; 207 linesearch->maxstep = 1e8; 208 linesearch->steptol = 1e-12; 209 linesearch->rtol = 1e-8; 210 linesearch->atol = 1e-15; 211 linesearch->ltol = 1e-8; 212 linesearch->precheckctx = NULL; 213 linesearch->postcheckctx = NULL; 214 linesearch->max_its = 1; 215 linesearch->setupcalled = PETSC_FALSE; 216 *outlinesearch = linesearch; 217 PetscFunctionReturn(0); 218 } 219 220 /*@ 221 SNESLineSearchSetUp - Prepares the line search for being applied by allocating 222 any required vectors. 223 224 Collective on SNESLineSearch 225 226 Input Parameters: 227 . linesearch - The LineSearch instance. 228 229 Notes: 230 For most cases, this needn't be called by users or outside of SNESLineSearchApply(). 231 The only current case where this is called outside of this is for the VI 232 solvers, which modify the solution and work vectors before the first call 233 of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be 234 allocated upfront. 235 236 Level: advanced 237 238 .keywords: SNESLineSearch, SetUp 239 240 .seealso: SNESGetLineSearch(), SNESLineSearchReset() 241 @*/ 242 243 PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch) 244 { 245 PetscErrorCode ierr; 246 247 PetscFunctionBegin; 248 if (!((PetscObject)linesearch)->type_name) { 249 ierr = SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);CHKERRQ(ierr); 250 } 251 if (!linesearch->setupcalled) { 252 if (!linesearch->vec_sol_new) { 253 ierr = VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);CHKERRQ(ierr); 254 } 255 if (!linesearch->vec_func_new) { 256 ierr = VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);CHKERRQ(ierr); 257 } 258 if (linesearch->ops->setup) { 259 ierr = (*linesearch->ops->setup)(linesearch);CHKERRQ(ierr); 260 } 261 if (!linesearch->ops->snesfunc) {ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunction);CHKERRQ(ierr);} 262 linesearch->lambda = linesearch->damping; 263 linesearch->setupcalled = PETSC_TRUE; 264 } 265 PetscFunctionReturn(0); 266 } 267 268 269 /*@ 270 SNESLineSearchReset - Undoes the SNESLineSearchSetUp() and deletes any Vecs or Mats allocated by the line search. 271 272 Collective on SNESLineSearch 273 274 Input Parameters: 275 . linesearch - The LineSearch instance. 276 277 Notes: Usually only called by SNESReset() 278 279 Level: developer 280 281 .keywords: SNESLineSearch, Reset 282 283 .seealso: SNESGetLineSearch(), SNESLineSearchSetUp() 284 @*/ 285 286 PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch) 287 { 288 PetscErrorCode ierr; 289 290 PetscFunctionBegin; 291 if (linesearch->ops->reset) (*linesearch->ops->reset)(linesearch); 292 293 ierr = VecDestroy(&linesearch->vec_sol_new);CHKERRQ(ierr); 294 ierr = VecDestroy(&linesearch->vec_func_new);CHKERRQ(ierr); 295 296 ierr = VecDestroyVecs(linesearch->nwork, &linesearch->work);CHKERRQ(ierr); 297 298 linesearch->nwork = 0; 299 linesearch->setupcalled = PETSC_FALSE; 300 PetscFunctionReturn(0); 301 } 302 303 /*@C 304 SNESLineSearchSetFunction - Sets the function evaluation used by the SNES line search 305 306 Input Parameters: 307 . linesearch - the SNESLineSearch context 308 + func - function evaluation routine 309 310 Level: developer 311 312 Notes: This is used internally by PETSc and not called by users 313 314 .keywords: get, linesearch, pre-check 315 316 .seealso: SNESGetLineSearch(), SNESSetFunction() 317 @*/ 318 PetscErrorCode SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec)) 319 { 320 PetscFunctionBegin; 321 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 322 linesearch->ops->snesfunc = func; 323 PetscFunctionReturn(0); 324 } 325 326 /*@C 327 SNESLineSearchSetPreCheck - Sets a user function that is called after the initial search direction has been computed but 328 before the line search routine has been applied. Allows the user to adjust the result of (usually a linear solve) that 329 determined the search direction. 330 331 Logically Collective on SNESLineSearch 332 333 Input Parameters: 334 + linesearch - the SNESLineSearch context 335 . func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for the calling sequence 336 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 337 338 Level: intermediate 339 340 .keywords: set, linesearch, pre-check 341 342 .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck() 343 @*/ 344 PetscErrorCode SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx) 345 { 346 PetscFunctionBegin; 347 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 348 if (func) linesearch->ops->precheck = func; 349 if (ctx) linesearch->precheckctx = ctx; 350 PetscFunctionReturn(0); 351 } 352 353 /*@C 354 SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine. 355 356 Input Parameters: 357 . linesearch - the SNESLineSearch context 358 359 Output Parameters: 360 + func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for calling sequence 361 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 362 363 Level: intermediate 364 365 .keywords: get, linesearch, pre-check 366 367 .seealso: SNESGetLineSearch(), SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck() 368 @*/ 369 PetscErrorCode SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx) 370 { 371 PetscFunctionBegin; 372 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 373 if (func) *func = linesearch->ops->precheck; 374 if (ctx) *ctx = linesearch->precheckctx; 375 PetscFunctionReturn(0); 376 } 377 378 /*@C 379 SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step 380 direction and length. Allows the user a chance to change or override the decision of the line search routine 381 382 Logically Collective on SNESLineSearch 383 384 Input Parameters: 385 + linesearch - the SNESLineSearch context 386 . func - [optional] function evaluation routine, see SNESLineSearchPostCheck() for the calling sequence 387 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 388 389 Level: intermediate 390 391 .keywords: set, linesearch, post-check 392 393 .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchGetPostCheck() 394 @*/ 395 PetscErrorCode SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx) 396 { 397 PetscFunctionBegin; 398 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 399 if (func) linesearch->ops->postcheck = func; 400 if (ctx) linesearch->postcheckctx = ctx; 401 PetscFunctionReturn(0); 402 } 403 404 /*@C 405 SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine. 406 407 Input Parameters: 408 . linesearch - the SNESLineSearch context 409 410 Output Parameters: 411 + func - [optional] function evaluation routine, see for the calling sequence SNESLineSearchPostCheck() 412 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 413 414 Level: intermediate 415 416 .keywords: get, linesearch, post-check 417 418 .seealso: SNESGetLineSearch(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck() 419 @*/ 420 PetscErrorCode SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx) 421 { 422 PetscFunctionBegin; 423 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 424 if (func) *func = linesearch->ops->postcheck; 425 if (ctx) *ctx = linesearch->postcheckctx; 426 PetscFunctionReturn(0); 427 } 428 429 /*@ 430 SNESLineSearchPreCheck - Prepares the line search for being applied. 431 432 Logically Collective on SNESLineSearch 433 434 Input Parameters: 435 + linesearch - The linesearch instance. 436 . X - The current solution 437 - Y - The step direction 438 439 Output Parameters: 440 . changed - Indicator that the precheck routine has changed anything 441 442 Level: developer 443 444 .keywords: SNESLineSearch, Create 445 446 .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck() 447 @*/ 448 PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed) 449 { 450 PetscErrorCode ierr; 451 452 PetscFunctionBegin; 453 *changed = PETSC_FALSE; 454 if (linesearch->ops->precheck) { 455 ierr = (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);CHKERRQ(ierr); 456 PetscValidLogicalCollectiveBool(linesearch,*changed,4); 457 } 458 PetscFunctionReturn(0); 459 } 460 461 /*@ 462 SNESLineSearchPostCheck - Prepares the line search for being applied. 463 464 Logically Collective on SNESLineSearch 465 466 Input Parameters: 467 + linesearch - The linesearch context 468 . X - The last solution 469 . Y - The step direction 470 - W - The updated solution, W = X + lambda*Y for some lambda 471 472 Output Parameters: 473 + changed_Y - Indicator if the direction Y has been changed. 474 - changed_W - Indicator if the new candidate solution W has been changed. 475 476 Level: developer 477 478 .keywords: SNESLineSearch, Create 479 480 .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPrecheck(), SNESLineSearchGetPrecheck() 481 @*/ 482 PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W) 483 { 484 PetscErrorCode ierr; 485 486 PetscFunctionBegin; 487 *changed_Y = PETSC_FALSE; 488 *changed_W = PETSC_FALSE; 489 if (linesearch->ops->postcheck) { 490 ierr = (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);CHKERRQ(ierr); 491 PetscValidLogicalCollectiveBool(linesearch,*changed_Y,5); 492 PetscValidLogicalCollectiveBool(linesearch,*changed_W,6); 493 } 494 PetscFunctionReturn(0); 495 } 496 497 /*@C 498 SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration 499 500 Logically Collective on SNESLineSearch 501 502 Input Arguments: 503 + linesearch - linesearch context 504 . X - base state for this step 505 . Y - initial correction 506 - ctx - context for this function 507 508 Output Arguments: 509 + Y - correction, possibly modified 510 - changed - flag indicating that Y was modified 511 512 Options Database Key: 513 + -snes_linesearch_precheck_picard - activate this routine 514 - -snes_linesearch_precheck_picard_angle - angle 515 516 Level: advanced 517 518 Notes: 519 This function should be passed to SNESLineSearchSetPreCheck() 520 521 The justification for this method involves the linear convergence of a Picard iteration 522 so the Picard linearization should be provided in place of the "Jacobian". This correction 523 is generally not useful when using a Newton linearization. 524 525 Reference: 526 Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology. 527 528 .seealso: SNESGetLineSearch(), SNESLineSearchSetPreCheck() 529 @*/ 530 PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx) 531 { 532 PetscErrorCode ierr; 533 PetscReal angle = *(PetscReal*)linesearch->precheckctx; 534 Vec Ylast; 535 PetscScalar dot; 536 PetscInt iter; 537 PetscReal ynorm,ylastnorm,theta,angle_radians; 538 SNES snes; 539 540 PetscFunctionBegin; 541 ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr); 542 ierr = PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);CHKERRQ(ierr); 543 if (!Ylast) { 544 ierr = VecDuplicate(Y,&Ylast);CHKERRQ(ierr); 545 ierr = PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);CHKERRQ(ierr); 546 ierr = PetscObjectDereference((PetscObject)Ylast);CHKERRQ(ierr); 547 } 548 ierr = SNESGetIterationNumber(snes,&iter);CHKERRQ(ierr); 549 if (iter < 2) { 550 ierr = VecCopy(Y,Ylast);CHKERRQ(ierr); 551 *changed = PETSC_FALSE; 552 PetscFunctionReturn(0); 553 } 554 555 ierr = VecDot(Y,Ylast,&dot);CHKERRQ(ierr); 556 ierr = VecNorm(Y,NORM_2,&ynorm);CHKERRQ(ierr); 557 ierr = VecNorm(Ylast,NORM_2,&ylastnorm);CHKERRQ(ierr); 558 /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */ 559 theta = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0)); 560 angle_radians = angle * PETSC_PI / 180.; 561 if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) { 562 /* Modify the step Y */ 563 PetscReal alpha,ydiffnorm; 564 ierr = VecAXPY(Ylast,-1.0,Y);CHKERRQ(ierr); 565 ierr = VecNorm(Ylast,NORM_2,&ydiffnorm);CHKERRQ(ierr); 566 alpha = ylastnorm / ydiffnorm; 567 ierr = VecCopy(Y,Ylast);CHKERRQ(ierr); 568 ierr = VecScale(Y,alpha);CHKERRQ(ierr); 569 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); 570 } else { 571 ierr = PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);CHKERRQ(ierr); 572 ierr = VecCopy(Y,Ylast);CHKERRQ(ierr); 573 *changed = PETSC_FALSE; 574 } 575 PetscFunctionReturn(0); 576 } 577 578 /*@ 579 SNESLineSearchApply - Computes the line-search update. 580 581 Collective on SNESLineSearch 582 583 Input Parameters: 584 + linesearch - The linesearch context 585 . X - The current solution 586 . F - The current function 587 . fnorm - The current norm 588 - Y - The search direction 589 590 Output Parameters: 591 + X - The new solution 592 . F - The new function 593 - fnorm - The new function norm 594 595 Options Database Keys: 596 + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell 597 . -snes_linesearch_monitor [:filename] - Print progress of line searches 598 . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping) 599 . -snes_linesearch_norms - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms()) 600 . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess 601 - -snes_linesearch_max_it - The number of iterations for iterative line searches 602 603 Notes: 604 This is typically called from within a SNESSolve() implementation in order to 605 help with convergence of the nonlinear method. Various SNES types use line searches 606 in different ways, but the overarching theme is that a line search is used to determine 607 an optimal damping parameter of a step at each iteration of the method. Each 608 application of the line search may invoke SNESComputeFunction() several times, and 609 therefore may be fairly expensive. 610 611 Level: Intermediate 612 613 .keywords: SNESLineSearch, Create 614 615 .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(), 616 SNESLineSearchType, SNESLineSearchSetType() 617 @*/ 618 PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y) 619 { 620 PetscErrorCode ierr; 621 622 PetscFunctionBegin; 623 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 624 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 625 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 626 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 627 628 linesearch->result = SNES_LINESEARCH_SUCCEEDED; 629 630 linesearch->vec_sol = X; 631 linesearch->vec_update = Y; 632 linesearch->vec_func = F; 633 634 ierr = SNESLineSearchSetUp(linesearch);CHKERRQ(ierr); 635 636 if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */ 637 638 if (fnorm) linesearch->fnorm = *fnorm; 639 else { 640 ierr = VecNorm(F, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 641 } 642 643 ierr = PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y);CHKERRQ(ierr); 644 645 ierr = (*linesearch->ops->apply)(linesearch);CHKERRQ(ierr); 646 647 ierr = PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y);CHKERRQ(ierr); 648 649 if (fnorm) *fnorm = linesearch->fnorm; 650 PetscFunctionReturn(0); 651 } 652 653 /*@ 654 SNESLineSearchDestroy - Destroys the line search instance. 655 656 Collective on SNESLineSearch 657 658 Input Parameters: 659 . linesearch - The linesearch context 660 661 Level: developer 662 663 .keywords: SNESLineSearch, Destroy 664 665 .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy() 666 @*/ 667 PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch) 668 { 669 PetscErrorCode ierr; 670 671 PetscFunctionBegin; 672 if (!*linesearch) PetscFunctionReturn(0); 673 PetscValidHeaderSpecific((*linesearch),SNESLINESEARCH_CLASSID,1); 674 if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; PetscFunctionReturn(0);} 675 ierr = PetscObjectSAWsViewOff((PetscObject)*linesearch);CHKERRQ(ierr); 676 ierr = SNESLineSearchReset(*linesearch);CHKERRQ(ierr); 677 if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch); 678 ierr = PetscViewerDestroy(&(*linesearch)->monitor);CHKERRQ(ierr); 679 ierr = SNESLineSearchMonitorCancel((*linesearch));CHKERRQ(ierr); 680 ierr = PetscHeaderDestroy(linesearch);CHKERRQ(ierr); 681 PetscFunctionReturn(0); 682 } 683 684 /*@ 685 SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search. 686 687 Input Parameters: 688 + linesearch - the linesearch object 689 - viewer - an ASCII PetscViewer or NULL to turn off monitor 690 691 Logically Collective on SNESLineSearch 692 693 Options Database: 694 . -snes_linesearch_monitor [:filename] - enables the monitor 695 696 Level: intermediate 697 698 Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with 699 SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the 700 line search that are not visible to the other monitors. 701 702 .seealso: SNESGetLineSearch(), SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor() 703 @*/ 704 PetscErrorCode SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer) 705 { 706 PetscErrorCode ierr; 707 708 PetscFunctionBegin; 709 if (viewer) {ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);} 710 ierr = PetscViewerDestroy(&linesearch->monitor);CHKERRQ(ierr); 711 linesearch->monitor = viewer; 712 PetscFunctionReturn(0); 713 } 714 715 /*@ 716 SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor. 717 718 Input Parameter: 719 . linesearch - linesearch context 720 721 Output Parameter: 722 . monitor - monitor context 723 724 Logically Collective on SNES 725 726 Options Database Keys: 727 . -snes_linesearch_monitor - enables the monitor 728 729 Level: intermediate 730 731 .seealso: SNESGetLineSearch(), SNESLineSearchSetDefaultMonitor(), PetscViewer 732 @*/ 733 PetscErrorCode SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor) 734 { 735 PetscFunctionBegin; 736 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 737 if (monitor) { 738 PetscValidPointer(monitor, 2); 739 *monitor = linesearch->monitor; 740 } 741 PetscFunctionReturn(0); 742 } 743 744 /*@C 745 SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 746 747 Collective on SNESLineSearch 748 749 Input Parameters: 750 + ls - LineSearch object you wish to monitor 751 . name - the monitor type one is seeking 752 . help - message indicating what monitoring is done 753 . manual - manual page for the monitor 754 . monitor - the monitor function 755 - 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 756 757 Level: developer 758 759 .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 760 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 761 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 762 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 763 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 764 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 765 PetscOptionsFList(), PetscOptionsEList() 766 @*/ 767 PetscErrorCode SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*)) 768 { 769 PetscErrorCode ierr; 770 PetscViewer viewer; 771 PetscViewerFormat format; 772 PetscBool flg; 773 774 PetscFunctionBegin; 775 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject)ls)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 776 if (flg) { 777 PetscViewerAndFormat *vf; 778 ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 779 ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 780 if (monitorsetup) { 781 ierr = (*monitorsetup)(ls,vf);CHKERRQ(ierr); 782 } 783 ierr = SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 784 } 785 PetscFunctionReturn(0); 786 } 787 788 /*@ 789 SNESLineSearchSetFromOptions - Sets options for the line search 790 791 Input Parameters: 792 . linesearch - linesearch context 793 794 Options Database Keys: 795 + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell 796 . -snes_linesearch_order <order> - 1, 2, 3. Most types only support certain orders (bt supports 2 or 3) 797 . -snes_linesearch_norms - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms()) 798 . -snes_linesearch_minlambda - The minimum step length 799 . -snes_linesearch_maxstep - The maximum step size 800 . -snes_linesearch_rtol - Relative tolerance for iterative line searches 801 . -snes_linesearch_atol - Absolute tolerance for iterative line searches 802 . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches 803 . -snes_linesearch_max_it - The number of iterations for iterative line searches 804 . -snes_linesearch_monitor [:filename] - Print progress of line searches 805 . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine 806 . -snes_linesearch_damping - The linesearch damping parameter 807 . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess. 808 . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method 809 - -snes_linesearch_precheck_picard_angle - Angle used in picard precheck method 810 811 Logically Collective on SNESLineSearch 812 813 Level: intermediate 814 815 .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(), 816 SNESLineSearchType, SNESLineSearchSetComputeNorms() 817 @*/ 818 PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch) 819 { 820 PetscErrorCode ierr; 821 const char *deft = SNESLINESEARCHBASIC; 822 char type[256]; 823 PetscBool flg, set; 824 PetscViewer viewer; 825 826 PetscFunctionBegin; 827 ierr = SNESLineSearchRegisterAll();CHKERRQ(ierr); 828 829 ierr = PetscObjectOptionsBegin((PetscObject)linesearch);CHKERRQ(ierr); 830 if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name; 831 ierr = PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);CHKERRQ(ierr); 832 if (flg) { 833 ierr = SNESLineSearchSetType(linesearch,type);CHKERRQ(ierr); 834 } else if (!((PetscObject)linesearch)->type_name) { 835 ierr = SNESLineSearchSetType(linesearch,deft);CHKERRQ(ierr); 836 } 837 838 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);CHKERRQ(ierr); 839 if (set) { 840 ierr = SNESLineSearchSetDefaultMonitor(linesearch,viewer);CHKERRQ(ierr); 841 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 842 } 843 ierr = SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);CHKERRQ(ierr); 844 845 /* tolerances */ 846 ierr = PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);CHKERRQ(ierr); 847 ierr = PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);CHKERRQ(ierr); 848 ierr = PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);CHKERRQ(ierr); 849 ierr = PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);CHKERRQ(ierr); 850 ierr = PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);CHKERRQ(ierr); 851 ierr = PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);CHKERRQ(ierr); 852 853 /* damping parameters */ 854 ierr = PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);CHKERRQ(ierr); 855 856 ierr = PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL);CHKERRQ(ierr); 857 858 /* precheck */ 859 ierr = PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr); 860 if (set) { 861 if (flg) { 862 linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */ 863 864 ierr = PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction", 865 "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);CHKERRQ(ierr); 866 ierr = SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);CHKERRQ(ierr); 867 } else { 868 ierr = SNESLineSearchSetPreCheck(linesearch,NULL,NULL);CHKERRQ(ierr); 869 } 870 } 871 ierr = PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);CHKERRQ(ierr); 872 ierr = PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);CHKERRQ(ierr); 873 874 if (linesearch->ops->setfromoptions) { 875 (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);CHKERRQ(ierr); 876 } 877 878 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);CHKERRQ(ierr); 879 ierr = PetscOptionsEnd();CHKERRQ(ierr); 880 PetscFunctionReturn(0); 881 } 882 883 /*@ 884 SNESLineSearchView - Prints useful information about the line search 885 886 Input Parameters: 887 . linesearch - linesearch context 888 889 Logically Collective on SNESLineSearch 890 891 Level: intermediate 892 893 .seealso: SNESLineSearchCreate() 894 @*/ 895 PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer) 896 { 897 PetscErrorCode ierr; 898 PetscBool iascii; 899 900 PetscFunctionBegin; 901 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 902 if (!viewer) { 903 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);CHKERRQ(ierr); 904 } 905 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 906 PetscCheckSameComm(linesearch,1,viewer,2); 907 908 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 909 if (iascii) { 910 PetscInt tabs; 911 ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr); 912 ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)linesearch)->tablevel);CHKERRQ(ierr); 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 ierr = PetscViewerASCIISetTab(viewer, tabs);CHKERRQ(ierr); 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 Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations 1605 1606 .keywords: SNESLineSearch, work, vector 1607 1608 .seealso: SNESSetWorkVecs() 1609 @*/ 1610 PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork) 1611 { 1612 PetscErrorCode ierr; 1613 1614 PetscFunctionBegin; 1615 if (linesearch->vec_sol) { 1616 ierr = VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);CHKERRQ(ierr); 1617 } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!"); 1618 PetscFunctionReturn(0); 1619 } 1620 1621 /*@ 1622 SNESLineSearchGetReason - Gets the success/failure status of the last line search application 1623 1624 Input Parameters: 1625 . linesearch - linesearch context 1626 1627 Output Parameters: 1628 . result - The success or failure status 1629 1630 Notes: 1631 This is typically called after SNESLineSearchApply() in order to determine if the line-search failed 1632 (and set the SNES convergence accordingly). 1633 1634 Level: intermediate 1635 1636 .seealso: SNESLineSearchSetReason(), SNESLineSearchReason 1637 @*/ 1638 PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result) 1639 { 1640 PetscFunctionBegin; 1641 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1642 PetscValidPointer(result, 2); 1643 *result = linesearch->result; 1644 PetscFunctionReturn(0); 1645 } 1646 1647 /*@ 1648 SNESLineSearchSetReason - Sets the success/failure status of the last line search application 1649 1650 Input Parameters: 1651 + linesearch - linesearch context 1652 - result - The success or failure status 1653 1654 Notes: 1655 This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set 1656 the success or failure of the line search method. 1657 1658 Level: developer 1659 1660 .seealso: SNESLineSearchGetSResult() 1661 @*/ 1662 PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result) 1663 { 1664 PetscFunctionBegin; 1665 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1666 linesearch->result = result; 1667 PetscFunctionReturn(0); 1668 } 1669 1670 /*@C 1671 SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation. 1672 1673 Input Parameters: 1674 + snes - nonlinear context obtained from SNESCreate() 1675 . projectfunc - function for projecting the function to the bounds 1676 - normfunc - function for computing the norm of an active set 1677 1678 Logically Collective on SNES 1679 1680 Calling sequence of projectfunc: 1681 .vb 1682 projectfunc (SNES snes, Vec X) 1683 .ve 1684 1685 Input parameters for projectfunc: 1686 + snes - nonlinear context 1687 - X - current solution 1688 1689 Output parameters for projectfunc: 1690 . X - Projected solution 1691 1692 Calling sequence of normfunc: 1693 .vb 1694 projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm) 1695 .ve 1696 1697 Input parameters for normfunc: 1698 + snes - nonlinear context 1699 . X - current solution 1700 - F - current residual 1701 1702 Output parameters for normfunc: 1703 . fnorm - VI-specific norm of the function 1704 1705 Notes: 1706 The VI solvers require projection of the solution to the feasible set. projectfunc should implement this. 1707 1708 The VI solvers require special evaluation of the function norm such that the norm is only calculated 1709 on the inactive set. This should be implemented by normfunc. 1710 1711 Level: developer 1712 1713 .keywords: SNES, line search, VI, nonlinear, set, line search 1714 1715 .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck() 1716 @*/ 1717 extern PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc) 1718 { 1719 PetscFunctionBegin; 1720 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1721 if (projectfunc) linesearch->ops->viproject = projectfunc; 1722 if (normfunc) linesearch->ops->vinorm = normfunc; 1723 PetscFunctionReturn(0); 1724 } 1725 1726 /*@C 1727 SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation. 1728 1729 Input Parameters: 1730 . linesearch - the line search context, obtain with SNESGetLineSearch() 1731 1732 Output Parameters: 1733 + projectfunc - function for projecting the function to the bounds 1734 - normfunc - function for computing the norm of an active set 1735 1736 Logically Collective on SNES 1737 1738 Level: developer 1739 1740 .keywords: SNES, line search, VI, nonlinear, get, line search 1741 1742 .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck() 1743 @*/ 1744 extern PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc) 1745 { 1746 PetscFunctionBegin; 1747 if (projectfunc) *projectfunc = linesearch->ops->viproject; 1748 if (normfunc) *normfunc = linesearch->ops->vinorm; 1749 PetscFunctionReturn(0); 1750 } 1751 1752 /*@C 1753 SNESLineSearchRegister - See SNESLineSearchRegister() 1754 1755 Level: advanced 1756 @*/ 1757 PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch)) 1758 { 1759 PetscErrorCode ierr; 1760 1761 PetscFunctionBegin; 1762 ierr = PetscFunctionListAdd(&SNESLineSearchList,sname,function);CHKERRQ(ierr); 1763 PetscFunctionReturn(0); 1764 } 1765