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