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