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 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 Parameter: 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 Parameter: 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 Parameters: 480 + linesearch - linesearch context 481 . X - base state for this step 482 . Y - initial correction 483 - ctx - context for this function 484 485 Output Parameters: 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 - Y - The search direction 564 565 Input/Output Parameters: 566 + X - The current solution, on output the new solution 567 . F - The current function, on output the new function 568 - fnorm - The current norm, on output the new function norm 569 570 Options Database Keys: 571 + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell 572 . -snes_linesearch_monitor [:filename] - Print progress of line searches 573 . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping) 574 . -snes_linesearch_norms - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms()) 575 . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess 576 - -snes_linesearch_max_it - The number of iterations for iterative line searches 577 578 Notes: 579 This is typically called from within a SNESSolve() implementation in order to 580 help with convergence of the nonlinear method. Various SNES types use line searches 581 in different ways, but the overarching theme is that a line search is used to determine 582 an optimal damping parameter of a step at each iteration of the method. Each 583 application of the line search may invoke SNESComputeFunction() several times, and 584 therefore may be fairly expensive. 585 586 Level: Intermediate 587 588 .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(), 589 SNESLineSearchType, SNESLineSearchSetType() 590 @*/ 591 PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y) 592 { 593 PetscErrorCode ierr; 594 595 PetscFunctionBegin; 596 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 597 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 598 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 599 PetscValidHeaderSpecific(Y,VEC_CLASSID,5); 600 601 linesearch->result = SNES_LINESEARCH_SUCCEEDED; 602 603 linesearch->vec_sol = X; 604 linesearch->vec_update = Y; 605 linesearch->vec_func = F; 606 607 ierr = SNESLineSearchSetUp(linesearch);CHKERRQ(ierr); 608 609 if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */ 610 611 if (fnorm) linesearch->fnorm = *fnorm; 612 else { 613 ierr = VecNorm(F, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 614 } 615 616 ierr = PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y);CHKERRQ(ierr); 617 618 ierr = (*linesearch->ops->apply)(linesearch);CHKERRQ(ierr); 619 620 ierr = PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y);CHKERRQ(ierr); 621 622 if (fnorm) *fnorm = linesearch->fnorm; 623 PetscFunctionReturn(0); 624 } 625 626 /*@ 627 SNESLineSearchDestroy - Destroys the line search instance. 628 629 Collective on SNESLineSearch 630 631 Input Parameters: 632 . linesearch - The linesearch context 633 634 Level: developer 635 636 .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy() 637 @*/ 638 PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch) 639 { 640 PetscErrorCode ierr; 641 642 PetscFunctionBegin; 643 if (!*linesearch) PetscFunctionReturn(0); 644 PetscValidHeaderSpecific((*linesearch),SNESLINESEARCH_CLASSID,1); 645 if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = NULL; PetscFunctionReturn(0);} 646 ierr = PetscObjectSAWsViewOff((PetscObject)*linesearch);CHKERRQ(ierr); 647 ierr = SNESLineSearchReset(*linesearch);CHKERRQ(ierr); 648 if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch); 649 ierr = PetscViewerDestroy(&(*linesearch)->monitor);CHKERRQ(ierr); 650 ierr = SNESLineSearchMonitorCancel((*linesearch));CHKERRQ(ierr); 651 ierr = PetscHeaderDestroy(linesearch);CHKERRQ(ierr); 652 PetscFunctionReturn(0); 653 } 654 655 /*@ 656 SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search. 657 658 Input Parameters: 659 + linesearch - the linesearch object 660 - viewer - an ASCII PetscViewer or NULL to turn off monitor 661 662 Logically Collective on SNESLineSearch 663 664 Options Database: 665 . -snes_linesearch_monitor [:filename] - enables the monitor 666 667 Level: intermediate 668 669 Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with 670 SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the 671 line search that are not visible to the other monitors. 672 673 .seealso: SNESGetLineSearch(), SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor() 674 @*/ 675 PetscErrorCode SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer) 676 { 677 PetscErrorCode ierr; 678 679 PetscFunctionBegin; 680 if (viewer) {ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);} 681 ierr = PetscViewerDestroy(&linesearch->monitor);CHKERRQ(ierr); 682 linesearch->monitor = viewer; 683 PetscFunctionReturn(0); 684 } 685 686 /*@ 687 SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor. 688 689 Input Parameter: 690 . linesearch - linesearch context 691 692 Output Parameter: 693 . monitor - monitor context 694 695 Logically Collective on SNES 696 697 Options Database Keys: 698 . -snes_linesearch_monitor - enables the monitor 699 700 Level: intermediate 701 702 .seealso: SNESGetLineSearch(), SNESLineSearchSetDefaultMonitor(), PetscViewer 703 @*/ 704 PetscErrorCode SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor) 705 { 706 PetscFunctionBegin; 707 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 708 *monitor = linesearch->monitor; 709 PetscFunctionReturn(0); 710 } 711 712 /*@C 713 SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 714 715 Collective on SNESLineSearch 716 717 Input Parameters: 718 + ls - LineSearch object you wish to monitor 719 . name - the monitor type one is seeking 720 . help - message indicating what monitoring is done 721 . manual - manual page for the monitor 722 . monitor - the monitor function 723 - 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 724 725 Level: developer 726 727 .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 728 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 729 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 730 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 731 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 732 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 733 PetscOptionsFList(), PetscOptionsEList() 734 @*/ 735 PetscErrorCode SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*)) 736 { 737 PetscErrorCode ierr; 738 PetscViewer viewer; 739 PetscViewerFormat format; 740 PetscBool flg; 741 742 PetscFunctionBegin; 743 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject) ls)->options,((PetscObject)ls)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr); 744 if (flg) { 745 PetscViewerAndFormat *vf; 746 ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr); 747 ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr); 748 if (monitorsetup) { 749 ierr = (*monitorsetup)(ls,vf);CHKERRQ(ierr); 750 } 751 ierr = SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr); 752 } 753 PetscFunctionReturn(0); 754 } 755 756 /*@ 757 SNESLineSearchSetFromOptions - Sets options for the line search 758 759 Input Parameter: 760 . linesearch - linesearch context 761 762 Options Database Keys: 763 + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell 764 . -snes_linesearch_order <order> - 1, 2, 3. Most types only support certain orders (bt supports 2 or 3) 765 . -snes_linesearch_norms - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms()) 766 . -snes_linesearch_minlambda - The minimum step length 767 . -snes_linesearch_maxstep - The maximum step size 768 . -snes_linesearch_rtol - Relative tolerance for iterative line searches 769 . -snes_linesearch_atol - Absolute tolerance for iterative line searches 770 . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches 771 . -snes_linesearch_max_it - The number of iterations for iterative line searches 772 . -snes_linesearch_monitor [:filename] - Print progress of line searches 773 . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine 774 . -snes_linesearch_damping - The linesearch damping parameter 775 . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess. 776 . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method 777 - -snes_linesearch_precheck_picard_angle - Angle used in Picard precheck method 778 779 Logically Collective on SNESLineSearch 780 781 Level: intermediate 782 783 .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(), 784 SNESLineSearchType, SNESLineSearchSetComputeNorms() 785 @*/ 786 PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch) 787 { 788 PetscErrorCode ierr; 789 const char *deft = SNESLINESEARCHBASIC; 790 char type[256]; 791 PetscBool flg, set; 792 PetscViewer viewer; 793 794 PetscFunctionBegin; 795 ierr = SNESLineSearchRegisterAll();CHKERRQ(ierr); 796 797 ierr = PetscObjectOptionsBegin((PetscObject)linesearch);CHKERRQ(ierr); 798 if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name; 799 ierr = PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);CHKERRQ(ierr); 800 if (flg) { 801 ierr = SNESLineSearchSetType(linesearch,type);CHKERRQ(ierr); 802 } else if (!((PetscObject)linesearch)->type_name) { 803 ierr = SNESLineSearchSetType(linesearch,deft);CHKERRQ(ierr); 804 } 805 806 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject) linesearch)->options,((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);CHKERRQ(ierr); 807 if (set) { 808 ierr = SNESLineSearchSetDefaultMonitor(linesearch,viewer);CHKERRQ(ierr); 809 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 810 } 811 ierr = SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);CHKERRQ(ierr); 812 813 /* tolerances */ 814 ierr = PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);CHKERRQ(ierr); 815 ierr = PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);CHKERRQ(ierr); 816 ierr = PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);CHKERRQ(ierr); 817 ierr = PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);CHKERRQ(ierr); 818 ierr = PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);CHKERRQ(ierr); 819 ierr = PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);CHKERRQ(ierr); 820 821 /* damping parameters */ 822 ierr = PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);CHKERRQ(ierr); 823 824 ierr = PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL);CHKERRQ(ierr); 825 826 /* precheck */ 827 ierr = PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr); 828 if (set) { 829 if (flg) { 830 linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */ 831 832 ierr = PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction", 833 "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);CHKERRQ(ierr); 834 ierr = SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);CHKERRQ(ierr); 835 } else { 836 ierr = SNESLineSearchSetPreCheck(linesearch,NULL,NULL);CHKERRQ(ierr); 837 } 838 } 839 ierr = PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);CHKERRQ(ierr); 840 ierr = PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);CHKERRQ(ierr); 841 842 if (linesearch->ops->setfromoptions) { 843 (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);CHKERRQ(ierr); 844 } 845 846 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);CHKERRQ(ierr); 847 ierr = PetscOptionsEnd();CHKERRQ(ierr); 848 PetscFunctionReturn(0); 849 } 850 851 /*@ 852 SNESLineSearchView - Prints useful information about the line search 853 854 Input Parameters: 855 . linesearch - linesearch context 856 857 Logically Collective on SNESLineSearch 858 859 Level: intermediate 860 861 .seealso: SNESLineSearchCreate() 862 @*/ 863 PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer) 864 { 865 PetscErrorCode ierr; 866 PetscBool iascii; 867 868 PetscFunctionBegin; 869 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 870 if (!viewer) { 871 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);CHKERRQ(ierr); 872 } 873 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 874 PetscCheckSameComm(linesearch,1,viewer,2); 875 876 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 877 if (iascii) { 878 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);CHKERRQ(ierr); 879 if (linesearch->ops->view) { 880 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 881 ierr = (*linesearch->ops->view)(linesearch,viewer);CHKERRQ(ierr); 882 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 883 } 884 ierr = PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);CHKERRQ(ierr); 885 ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);CHKERRQ(ierr); 886 ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", linesearch->max_its);CHKERRQ(ierr); 887 if (linesearch->ops->precheck) { 888 if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) { 889 ierr = PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n", linesearch->max_its);CHKERRQ(ierr); 890 } else { 891 ierr = PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n", linesearch->max_its);CHKERRQ(ierr); 892 } 893 } 894 if (linesearch->ops->postcheck) { 895 ierr = PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n", linesearch->max_its);CHKERRQ(ierr); 896 } 897 } 898 PetscFunctionReturn(0); 899 } 900 901 /*@C 902 SNESLineSearchGetType - Gets the linesearch type 903 904 Logically Collective on SNESLineSearch 905 906 Input Parameters: 907 . linesearch - linesearch context 908 909 Output Parameters: 910 - type - The type of line search, or NULL if not set 911 912 Level: intermediate 913 914 .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchSetType() 915 @*/ 916 PetscErrorCode SNESLineSearchGetType(SNESLineSearch linesearch, SNESLineSearchType *type) 917 { 918 PetscFunctionBegin; 919 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 920 PetscValidCharPointer(type,2); 921 *type = ((PetscObject)linesearch)->type_name; 922 PetscFunctionReturn(0); 923 } 924 925 /*@C 926 SNESLineSearchSetType - Sets the linesearch type 927 928 Logically Collective on SNESLineSearch 929 930 Input Parameters: 931 + linesearch - linesearch context 932 - type - The type of line search to be used 933 934 Available Types: 935 + SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step 936 . SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function 937 . SNESLINESEARCHL2 - Secant line search over the L2 norm of the function 938 . SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x) 939 . SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch 940 - SNESLINESEARCHSHELL - User provided SNESLineSearch implementation 941 942 Options Database: 943 . -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell 944 945 Level: intermediate 946 947 .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchGetType() 948 @*/ 949 PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type) 950 { 951 PetscErrorCode ierr,(*r)(SNESLineSearch); 952 PetscBool match; 953 954 PetscFunctionBegin; 955 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 956 PetscValidCharPointer(type,2); 957 958 ierr = PetscObjectTypeCompare((PetscObject)linesearch,type,&match);CHKERRQ(ierr); 959 if (match) PetscFunctionReturn(0); 960 961 ierr = PetscFunctionListFind(SNESLineSearchList,type,&r);CHKERRQ(ierr); 962 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type); 963 /* Destroy the previous private linesearch context */ 964 if (linesearch->ops->destroy) { 965 ierr = (*(linesearch)->ops->destroy)(linesearch);CHKERRQ(ierr); 966 linesearch->ops->destroy = NULL; 967 } 968 /* Reinitialize function pointers in SNESLineSearchOps structure */ 969 linesearch->ops->apply = NULL; 970 linesearch->ops->view = NULL; 971 linesearch->ops->setfromoptions = NULL; 972 linesearch->ops->destroy = NULL; 973 974 ierr = PetscObjectChangeTypeName((PetscObject)linesearch,type);CHKERRQ(ierr); 975 ierr = (*r)(linesearch);CHKERRQ(ierr); 976 PetscFunctionReturn(0); 977 } 978 979 /*@ 980 SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation. 981 982 Input Parameters: 983 + linesearch - linesearch context 984 - snes - The snes instance 985 986 Level: developer 987 988 Notes: 989 This happens automatically when the line search is obtained/created with 990 SNESGetLineSearch(). This routine is therefore mainly called within SNES 991 implementations. 992 993 Level: developer 994 995 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES 996 @*/ 997 PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes) 998 { 999 PetscFunctionBegin; 1000 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1001 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 1002 linesearch->snes = snes; 1003 PetscFunctionReturn(0); 1004 } 1005 1006 /*@ 1007 SNESLineSearchGetSNES - Gets the SNES instance associated with the line search. 1008 Having an associated SNES is necessary because most line search implementations must be able to 1009 evaluate the function using SNESComputeFunction() for the associated SNES. This routine 1010 is used in the line search implementations when one must get this associated SNES instance. 1011 1012 Input Parameters: 1013 . linesearch - linesearch context 1014 1015 Output Parameters: 1016 . snes - The snes instance 1017 1018 Level: developer 1019 1020 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES 1021 @*/ 1022 PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes) 1023 { 1024 PetscFunctionBegin; 1025 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1026 PetscValidPointer(snes, 2); 1027 *snes = linesearch->snes; 1028 PetscFunctionReturn(0); 1029 } 1030 1031 /*@ 1032 SNESLineSearchGetLambda - Gets the last linesearch steplength discovered. 1033 1034 Input Parameters: 1035 . linesearch - linesearch context 1036 1037 Output Parameters: 1038 . lambda - The last steplength computed during SNESLineSearchApply() 1039 1040 Level: advanced 1041 1042 Notes: 1043 This is useful in methods where the solver is ill-scaled and 1044 requires some adaptive notion of the difference in scale between the 1045 solution and the function. For instance, SNESQN may be scaled by the 1046 line search lambda using the argument -snes_qn_scaling ls. 1047 1048 .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply() 1049 @*/ 1050 PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda) 1051 { 1052 PetscFunctionBegin; 1053 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1054 PetscValidRealPointer(lambda, 2); 1055 *lambda = linesearch->lambda; 1056 PetscFunctionReturn(0); 1057 } 1058 1059 /*@ 1060 SNESLineSearchSetLambda - Sets the linesearch steplength. 1061 1062 Input Parameters: 1063 + linesearch - linesearch context 1064 - lambda - The last steplength. 1065 1066 Notes: 1067 This routine is typically used within implementations of SNESLineSearchApply() 1068 to set the final steplength. This routine (and SNESLineSearchGetLambda()) were 1069 added in order to facilitate Quasi-Newton methods that use the previous steplength 1070 as an inner scaling parameter. 1071 1072 Level: advanced 1073 1074 .seealso: SNESLineSearchGetLambda() 1075 @*/ 1076 PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda) 1077 { 1078 PetscFunctionBegin; 1079 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1080 linesearch->lambda = lambda; 1081 PetscFunctionReturn(0); 1082 } 1083 1084 /*@ 1085 SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include 1086 tolerances for the relative and absolute change in the function norm, the change 1087 in lambda for iterative line searches, the minimum steplength, the maximum steplength, 1088 and the maximum number of iterations the line search procedure may take. 1089 1090 Input Parameter: 1091 . linesearch - linesearch context 1092 1093 Output Parameters: 1094 + steptol - The minimum steplength 1095 . maxstep - The maximum steplength 1096 . rtol - The relative tolerance for iterative line searches 1097 . atol - The absolute tolerance for iterative line searches 1098 . ltol - The change in lambda tolerance for iterative line searches 1099 - max_it - The maximum number of iterations of the line search 1100 1101 Level: intermediate 1102 1103 Notes: 1104 Different line searches may implement these parameters slightly differently as 1105 the type requires. 1106 1107 .seealso: SNESLineSearchSetTolerances() 1108 @*/ 1109 PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its) 1110 { 1111 PetscFunctionBegin; 1112 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1113 if (steptol) { 1114 PetscValidRealPointer(steptol, 2); 1115 *steptol = linesearch->steptol; 1116 } 1117 if (maxstep) { 1118 PetscValidRealPointer(maxstep, 3); 1119 *maxstep = linesearch->maxstep; 1120 } 1121 if (rtol) { 1122 PetscValidRealPointer(rtol, 4); 1123 *rtol = linesearch->rtol; 1124 } 1125 if (atol) { 1126 PetscValidRealPointer(atol, 5); 1127 *atol = linesearch->atol; 1128 } 1129 if (ltol) { 1130 PetscValidRealPointer(ltol, 6); 1131 *ltol = linesearch->ltol; 1132 } 1133 if (max_its) { 1134 PetscValidIntPointer(max_its, 7); 1135 *max_its = linesearch->max_its; 1136 } 1137 PetscFunctionReturn(0); 1138 } 1139 1140 /*@ 1141 SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include 1142 tolerances for the relative and absolute change in the function norm, the change 1143 in lambda for iterative line searches, the minimum steplength, the maximum steplength, 1144 and the maximum number of iterations the line search procedure may take. 1145 1146 Input Parameters: 1147 + linesearch - linesearch context 1148 . steptol - The minimum steplength 1149 . maxstep - The maximum steplength 1150 . rtol - The relative tolerance for iterative line searches 1151 . atol - The absolute tolerance for iterative line searches 1152 . ltol - The change in lambda tolerance for iterative line searches 1153 - max_it - The maximum number of iterations of the line search 1154 1155 Notes: 1156 The user may choose to not set any of the tolerances using PETSC_DEFAULT in 1157 place of an argument. 1158 1159 Level: intermediate 1160 1161 .seealso: SNESLineSearchGetTolerances() 1162 @*/ 1163 PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its) 1164 { 1165 PetscFunctionBegin; 1166 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1167 PetscValidLogicalCollectiveReal(linesearch,steptol,2); 1168 PetscValidLogicalCollectiveReal(linesearch,maxstep,3); 1169 PetscValidLogicalCollectiveReal(linesearch,rtol,4); 1170 PetscValidLogicalCollectiveReal(linesearch,atol,5); 1171 PetscValidLogicalCollectiveReal(linesearch,ltol,6); 1172 PetscValidLogicalCollectiveInt(linesearch,max_its,7); 1173 1174 if (steptol!= PETSC_DEFAULT) { 1175 if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol); 1176 linesearch->steptol = steptol; 1177 } 1178 1179 if (maxstep!= PETSC_DEFAULT) { 1180 if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep); 1181 linesearch->maxstep = maxstep; 1182 } 1183 1184 if (rtol != PETSC_DEFAULT) { 1185 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); 1186 linesearch->rtol = rtol; 1187 } 1188 1189 if (atol != PETSC_DEFAULT) { 1190 if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol); 1191 linesearch->atol = atol; 1192 } 1193 1194 if (ltol != PETSC_DEFAULT) { 1195 if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Lambda tolerance %14.12e must be non-negative",(double)ltol); 1196 linesearch->ltol = ltol; 1197 } 1198 1199 if (max_its != PETSC_DEFAULT) { 1200 if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its); 1201 linesearch->max_its = max_its; 1202 } 1203 PetscFunctionReturn(0); 1204 } 1205 1206 /*@ 1207 SNESLineSearchGetDamping - Gets the line search damping parameter. 1208 1209 Input Parameters: 1210 . linesearch - linesearch context 1211 1212 Output Parameters: 1213 . damping - The damping parameter 1214 1215 Level: advanced 1216 1217 .seealso: SNESLineSearchGetStepTolerance(), SNESQN 1218 @*/ 1219 1220 PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping) 1221 { 1222 PetscFunctionBegin; 1223 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1224 PetscValidRealPointer(damping, 2); 1225 *damping = linesearch->damping; 1226 PetscFunctionReturn(0); 1227 } 1228 1229 /*@ 1230 SNESLineSearchSetDamping - Sets the line search damping parameter. 1231 1232 Input Parameters: 1233 + linesearch - linesearch context 1234 - damping - The damping parameter 1235 1236 Options Database: 1237 . -snes_linesearch_damping 1238 Level: intermediate 1239 1240 Notes: 1241 The basic line search merely takes the update step scaled by the damping parameter. 1242 The use of the damping parameter in the l2 and cp line searches is much more subtle; 1243 it is used as a starting point in calculating the secant step. However, the eventual 1244 step may be of greater length than the damping parameter. In the bt line search it is 1245 used as the maximum possible step length, as the bt line search only backtracks. 1246 1247 .seealso: SNESLineSearchGetDamping() 1248 @*/ 1249 PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping) 1250 { 1251 PetscFunctionBegin; 1252 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1253 linesearch->damping = damping; 1254 PetscFunctionReturn(0); 1255 } 1256 1257 /*@ 1258 SNESLineSearchGetOrder - Gets the line search approximation order. 1259 1260 Input Parameters: 1261 . linesearch - linesearch context 1262 1263 Output Parameters: 1264 . order - The order 1265 1266 Possible Values for order: 1267 + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order 1268 . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order 1269 - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order 1270 1271 Level: intermediate 1272 1273 .seealso: SNESLineSearchSetOrder() 1274 @*/ 1275 1276 PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order) 1277 { 1278 PetscFunctionBegin; 1279 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1280 PetscValidIntPointer(order, 2); 1281 *order = linesearch->order; 1282 PetscFunctionReturn(0); 1283 } 1284 1285 /*@ 1286 SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search 1287 1288 Input Parameters: 1289 + linesearch - linesearch context 1290 - order - The damping parameter 1291 1292 Level: intermediate 1293 1294 Possible Values for order: 1295 + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order 1296 . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order 1297 - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order 1298 1299 Notes: 1300 Variable orders are supported by the following line searches: 1301 + bt - cubic and quadratic 1302 - cp - linear and quadratic 1303 1304 .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping() 1305 @*/ 1306 PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order) 1307 { 1308 PetscFunctionBegin; 1309 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1310 linesearch->order = order; 1311 PetscFunctionReturn(0); 1312 } 1313 1314 /*@ 1315 SNESLineSearchGetNorms - Gets the norms for for X, Y, and F. 1316 1317 Input Parameter: 1318 . linesearch - linesearch context 1319 1320 Output Parameters: 1321 + xnorm - The norm of the current solution 1322 . fnorm - The norm of the current function 1323 - ynorm - The norm of the current update 1324 1325 Notes: 1326 This function is mainly called from SNES implementations. 1327 1328 Level: developer 1329 1330 .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs() 1331 @*/ 1332 PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm) 1333 { 1334 PetscFunctionBegin; 1335 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1336 if (xnorm) *xnorm = linesearch->xnorm; 1337 if (fnorm) *fnorm = linesearch->fnorm; 1338 if (ynorm) *ynorm = linesearch->ynorm; 1339 PetscFunctionReturn(0); 1340 } 1341 1342 /*@ 1343 SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F. 1344 1345 Input Parameters: 1346 + linesearch - linesearch context 1347 . xnorm - The norm of the current solution 1348 . fnorm - The norm of the current function 1349 - ynorm - The norm of the current update 1350 1351 Level: advanced 1352 1353 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs() 1354 @*/ 1355 PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm) 1356 { 1357 PetscFunctionBegin; 1358 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1359 linesearch->xnorm = xnorm; 1360 linesearch->fnorm = fnorm; 1361 linesearch->ynorm = ynorm; 1362 PetscFunctionReturn(0); 1363 } 1364 1365 /*@ 1366 SNESLineSearchComputeNorms - Computes the norms of X, F, and Y. 1367 1368 Input Parameters: 1369 . linesearch - linesearch context 1370 1371 Options Database Keys: 1372 . -snes_linesearch_norms - turn norm computation on or off 1373 1374 Level: intermediate 1375 1376 .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms() 1377 @*/ 1378 PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch) 1379 { 1380 PetscErrorCode ierr; 1381 SNES snes; 1382 1383 PetscFunctionBegin; 1384 if (linesearch->norms) { 1385 if (linesearch->ops->vinorm) { 1386 ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr); 1387 ierr = VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 1388 ierr = VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 1389 ierr = (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);CHKERRQ(ierr); 1390 } else { 1391 ierr = VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 1392 ierr = VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 1393 ierr = VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 1394 ierr = VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 1395 ierr = VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 1396 ierr = VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 1397 } 1398 } 1399 PetscFunctionReturn(0); 1400 } 1401 1402 /*@ 1403 SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search. 1404 1405 Input Parameters: 1406 + linesearch - linesearch context 1407 - flg - indicates whether or not to compute norms 1408 1409 Options Database Keys: 1410 . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch 1411 1412 Notes: 1413 This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm. 1414 1415 Level: intermediate 1416 1417 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC 1418 @*/ 1419 PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg) 1420 { 1421 PetscFunctionBegin; 1422 linesearch->norms = flg; 1423 PetscFunctionReturn(0); 1424 } 1425 1426 /*@ 1427 SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context 1428 1429 Input Parameter: 1430 . linesearch - linesearch context 1431 1432 Output Parameters: 1433 + X - Solution vector 1434 . F - Function vector 1435 . Y - Search direction vector 1436 . W - Solution work vector 1437 - G - Function work vector 1438 1439 Notes: 1440 At the beginning of a line search application, X should contain a 1441 solution and the vector F the function computed at X. At the end of the 1442 line search application, X should contain the new solution, and F the 1443 function evaluated at the new solution. 1444 1445 These vectors are owned by the SNESLineSearch and should not be destroyed by the caller 1446 1447 Level: advanced 1448 1449 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs() 1450 @*/ 1451 PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G) 1452 { 1453 PetscFunctionBegin; 1454 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1455 if (X) { 1456 PetscValidPointer(X, 2); 1457 *X = linesearch->vec_sol; 1458 } 1459 if (F) { 1460 PetscValidPointer(F, 3); 1461 *F = linesearch->vec_func; 1462 } 1463 if (Y) { 1464 PetscValidPointer(Y, 4); 1465 *Y = linesearch->vec_update; 1466 } 1467 if (W) { 1468 PetscValidPointer(W, 5); 1469 *W = linesearch->vec_sol_new; 1470 } 1471 if (G) { 1472 PetscValidPointer(G, 6); 1473 *G = linesearch->vec_func_new; 1474 } 1475 PetscFunctionReturn(0); 1476 } 1477 1478 /*@ 1479 SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context 1480 1481 Input Parameters: 1482 + linesearch - linesearch context 1483 . X - Solution vector 1484 . F - Function vector 1485 . Y - Search direction vector 1486 . W - Solution work vector 1487 - G - Function work vector 1488 1489 Level: advanced 1490 1491 .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs() 1492 @*/ 1493 PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G) 1494 { 1495 PetscFunctionBegin; 1496 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1497 if (X) { 1498 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 1499 linesearch->vec_sol = X; 1500 } 1501 if (F) { 1502 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 1503 linesearch->vec_func = F; 1504 } 1505 if (Y) { 1506 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 1507 linesearch->vec_update = Y; 1508 } 1509 if (W) { 1510 PetscValidHeaderSpecific(W,VEC_CLASSID,5); 1511 linesearch->vec_sol_new = W; 1512 } 1513 if (G) { 1514 PetscValidHeaderSpecific(G,VEC_CLASSID,6); 1515 linesearch->vec_func_new = G; 1516 } 1517 PetscFunctionReturn(0); 1518 } 1519 1520 /*@C 1521 SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all 1522 SNES options in the database. 1523 1524 Logically Collective on SNESLineSearch 1525 1526 Input Parameters: 1527 + snes - the SNES context 1528 - prefix - the prefix to prepend to all option names 1529 1530 Notes: 1531 A hyphen (-) must NOT be given at the beginning of the prefix name. 1532 The first character of all runtime options is AUTOMATICALLY the hyphen. 1533 1534 Level: advanced 1535 1536 .seealso: SNESGetOptionsPrefix() 1537 @*/ 1538 PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[]) 1539 { 1540 PetscErrorCode ierr; 1541 1542 PetscFunctionBegin; 1543 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1544 ierr = PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr); 1545 PetscFunctionReturn(0); 1546 } 1547 1548 /*@C 1549 SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all 1550 SNESLineSearch options in the database. 1551 1552 Not Collective 1553 1554 Input Parameter: 1555 . linesearch - the SNESLineSearch context 1556 1557 Output Parameter: 1558 . prefix - pointer to the prefix string used 1559 1560 Notes: 1561 On the fortran side, the user should pass in a string 'prefix' of 1562 sufficient length to hold the prefix. 1563 1564 Level: advanced 1565 1566 .seealso: SNESAppendOptionsPrefix() 1567 @*/ 1568 PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[]) 1569 { 1570 PetscErrorCode ierr; 1571 1572 PetscFunctionBegin; 1573 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1574 ierr = PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr); 1575 PetscFunctionReturn(0); 1576 } 1577 1578 /*@C 1579 SNESLineSearchSetWorkVecs - Gets work vectors for the line search. 1580 1581 Input Parameters: 1582 + linesearch - the SNESLineSearch context 1583 - nwork - the number of work vectors 1584 1585 Level: developer 1586 1587 .seealso: SNESSetWorkVecs() 1588 @*/ 1589 PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork) 1590 { 1591 PetscErrorCode ierr; 1592 1593 PetscFunctionBegin; 1594 if (linesearch->vec_sol) { 1595 ierr = VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);CHKERRQ(ierr); 1596 } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!"); 1597 PetscFunctionReturn(0); 1598 } 1599 1600 /*@ 1601 SNESLineSearchGetReason - Gets the success/failure status of the last line search application 1602 1603 Input Parameters: 1604 . linesearch - linesearch context 1605 1606 Output Parameters: 1607 . result - The success or failure status 1608 1609 Notes: 1610 This is typically called after SNESLineSearchApply() in order to determine if the line-search failed 1611 (and set the SNES convergence accordingly). 1612 1613 Level: intermediate 1614 1615 .seealso: SNESLineSearchSetReason(), SNESLineSearchReason 1616 @*/ 1617 PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result) 1618 { 1619 PetscFunctionBegin; 1620 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1621 PetscValidPointer(result, 2); 1622 *result = linesearch->result; 1623 PetscFunctionReturn(0); 1624 } 1625 1626 /*@ 1627 SNESLineSearchSetReason - Sets the success/failure status of the last line search application 1628 1629 Input Parameters: 1630 + linesearch - linesearch context 1631 - result - The success or failure status 1632 1633 Notes: 1634 This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set 1635 the success or failure of the line search method. 1636 1637 Level: developer 1638 1639 .seealso: SNESLineSearchGetSResult() 1640 @*/ 1641 PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result) 1642 { 1643 PetscFunctionBegin; 1644 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1645 linesearch->result = result; 1646 PetscFunctionReturn(0); 1647 } 1648 1649 /*@C 1650 SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation. 1651 1652 Input Parameters: 1653 + snes - nonlinear context obtained from SNESCreate() 1654 . projectfunc - function for projecting the function to the bounds 1655 - normfunc - function for computing the norm of an active set 1656 1657 Logically Collective on SNES 1658 1659 Calling sequence of projectfunc: 1660 .vb 1661 projectfunc (SNES snes, Vec X) 1662 .ve 1663 1664 Input parameters for projectfunc: 1665 + snes - nonlinear context 1666 - X - current solution 1667 1668 Output parameters for projectfunc: 1669 . X - Projected solution 1670 1671 Calling sequence of normfunc: 1672 .vb 1673 projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm) 1674 .ve 1675 1676 Input parameters for normfunc: 1677 + snes - nonlinear context 1678 . X - current solution 1679 - F - current residual 1680 1681 Output parameters for normfunc: 1682 . fnorm - VI-specific norm of the function 1683 1684 Notes: 1685 The VI solvers require projection of the solution to the feasible set. projectfunc should implement this. 1686 1687 The VI solvers require special evaluation of the function norm such that the norm is only calculated 1688 on the inactive set. This should be implemented by normfunc. 1689 1690 Level: developer 1691 1692 .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck() 1693 @*/ 1694 PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc) 1695 { 1696 PetscFunctionBegin; 1697 PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1); 1698 if (projectfunc) linesearch->ops->viproject = projectfunc; 1699 if (normfunc) linesearch->ops->vinorm = normfunc; 1700 PetscFunctionReturn(0); 1701 } 1702 1703 /*@C 1704 SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation. 1705 1706 Input Parameter: 1707 . linesearch - the line search context, obtain with SNESGetLineSearch() 1708 1709 Output Parameters: 1710 + projectfunc - function for projecting the function to the bounds 1711 - normfunc - function for computing the norm of an active set 1712 1713 Logically Collective on SNES 1714 1715 Level: developer 1716 1717 .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck() 1718 @*/ 1719 PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc) 1720 { 1721 PetscFunctionBegin; 1722 if (projectfunc) *projectfunc = linesearch->ops->viproject; 1723 if (normfunc) *normfunc = linesearch->ops->vinorm; 1724 PetscFunctionReturn(0); 1725 } 1726 1727 /*@C 1728 SNESLineSearchRegister - See SNESLineSearchRegister() 1729 1730 Level: advanced 1731 @*/ 1732 PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch)) 1733 { 1734 PetscErrorCode ierr; 1735 1736 PetscFunctionBegin; 1737 ierr = SNESInitializePackage();CHKERRQ(ierr); 1738 ierr = PetscFunctionListAdd(&SNESLineSearchList,sname,function);CHKERRQ(ierr); 1739 PetscFunctionReturn(0); 1740 } 1741