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