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