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