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