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