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