1 #include <private/linesearchimpl.h> /*I "petsclinesearch.h" I*/ 2 3 PetscBool LineSearchRegisterAllCalled = PETSC_FALSE; 4 PetscFList LineSearchList = PETSC_NULL; 5 6 PetscClassId LineSearch_CLASSID; 7 PetscLogEvent LineSearch_Apply; 8 9 #undef __FUNCT__ 10 #define __FUNCT__ "LineSearchCreate" 11 /*@ 12 LineSearchCreate - Creates the line search. 13 14 Collective on LineSearch 15 16 Input Parameters: 17 . comm - MPI communicator for the line search 18 19 Output Parameters: 20 . outlinesearch - the line search instance. 21 22 Level: Beginner 23 24 .keywords: LineSearch, Create 25 26 .seealso: LineSearchDestroy() 27 @*/ 28 29 PetscErrorCode LineSearchCreate(MPI_Comm comm, LineSearch * outlinesearch) { 30 PetscErrorCode ierr; 31 LineSearch linesearch; 32 PetscFunctionBegin; 33 ierr = PetscHeaderCreate(linesearch, _p_LineSearch,struct _LineSearchOps,LineSearch_CLASSID, 0, 34 "LineSearch","Line-search method","LineSearch",comm,LineSearchDestroy,LineSearchView);CHKERRQ(ierr); 35 36 linesearch->ops->precheckstep = PETSC_NULL; 37 linesearch->ops->postcheckstep = PETSC_NULL; 38 39 linesearch->lambda = 1.0; 40 linesearch->fnorm = 1.0; 41 linesearch->ynorm = 1.0; 42 linesearch->xnorm = 1.0; 43 linesearch->success = PETSC_TRUE; 44 linesearch->norms = PETSC_TRUE; 45 linesearch->keeplambda = PETSC_FALSE; 46 linesearch->damping = 1.0; 47 linesearch->maxstep = 1e8; 48 linesearch->steptol = 1e-12; 49 linesearch->precheckctx = PETSC_NULL; 50 linesearch->postcheckctx = PETSC_NULL; 51 linesearch->max_its = 1; 52 linesearch->setupcalled = PETSC_FALSE; 53 *outlinesearch = linesearch; 54 PetscFunctionReturn(0); 55 } 56 57 #undef __FUNCT__ 58 #define __FUNCT__ "LineSearchSetUp" 59 /*@ 60 LineSearchSetUp - Prepares the line search for being applied. 61 62 Collective on LineSearch 63 64 Input Parameters: 65 . linesearch - The LineSearch instance. 66 67 Level: Intermediate 68 69 .keywords: LineSearch, SetUp 70 71 .seealso: LineSearchReset() 72 @*/ 73 74 PetscErrorCode LineSearchSetUp(LineSearch linesearch) { 75 PetscErrorCode ierr; 76 PetscFunctionBegin; 77 78 if (!((PetscObject)linesearch)->type_name) { 79 ierr = LineSearchSetType(linesearch,LINESEARCHBASIC);CHKERRQ(ierr); 80 } 81 82 if (!linesearch->setupcalled) { 83 ierr = VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);CHKERRQ(ierr); 84 ierr = VecDuplicate(linesearch->vec_func, &linesearch->vec_func_new);CHKERRQ(ierr); 85 if (linesearch->ops->setup) { 86 ierr = (*linesearch->ops->setup)(linesearch);CHKERRQ(ierr); 87 } 88 linesearch->lambda = linesearch->damping; 89 linesearch->setupcalled = PETSC_TRUE; 90 } 91 PetscFunctionReturn(0); 92 } 93 94 #undef __FUNCT__ 95 #define __FUNCT__ "LineSearchReset" 96 97 /*@ 98 LineSearchReset - Tears down the structures required for application 99 100 Collective on LineSearch 101 102 Input Parameters: 103 . linesearch - The LineSearch instance. 104 105 Level: Intermediate 106 107 .keywords: LineSearch, Create 108 109 .seealso: LineSearchSetUp() 110 @*/ 111 112 PetscErrorCode LineSearchReset(LineSearch linesearch) { 113 PetscErrorCode ierr; 114 PetscFunctionBegin; 115 if (linesearch->ops->reset) { 116 (*linesearch->ops->reset)(linesearch); 117 } 118 ierr = VecDestroy(&linesearch->vec_sol_new);CHKERRQ(ierr); 119 ierr = VecDestroy(&linesearch->vec_func_new);CHKERRQ(ierr); 120 121 ierr = VecDestroyVecs(linesearch->nwork, &linesearch->work);CHKERRQ(ierr); 122 linesearch->nwork = 0; 123 linesearch->setupcalled = PETSC_FALSE; 124 PetscFunctionReturn(0); 125 } 126 127 #undef __FUNCT__ 128 #define __FUNCT__ "LineSearchPreCheck" 129 /*@ 130 LineSearchPreCheck - Prepares the line search for being applied. 131 132 Collective on LineSearch 133 134 Input Parameters: 135 . linesearch - The linesearch instance. 136 137 Output Parameters: 138 . changed - Indicator if the pre-check has changed anything. 139 140 Level: Beginner 141 142 .keywords: LineSearch, Create 143 144 .seealso: LineSearchPostCheck() 145 @*/ 146 PetscErrorCode LineSearchPreCheck(LineSearch linesearch, PetscBool * changed) 147 { 148 PetscErrorCode ierr; 149 PetscFunctionBegin; 150 *changed = PETSC_FALSE; 151 if (linesearch->ops->precheckstep) { 152 ierr = (*linesearch->ops->precheckstep)(linesearch, linesearch->vec_sol, linesearch->vec_update, changed);CHKERRQ(ierr); 153 } 154 PetscFunctionReturn(0); 155 } 156 157 #undef __FUNCT__ 158 #define __FUNCT__ "LineSearchPostCheck" 159 /*@ 160 LineSearchPostCheck - Prepares the line search for being applied. 161 162 Collective on LineSearch 163 164 Input Parameters: 165 . linesearch - The linesearch instance. 166 167 Output Parameters: 168 + changed_W - Indicator if the solution has been changed. 169 - changed_Y - Indicator if the direction has been changed. 170 171 Level: Intermediate 172 173 .keywords: LineSearch, Create 174 175 .seealso: LineSearchPreCheck() 176 @*/ 177 PetscErrorCode LineSearchPostCheck(LineSearch linesearch, PetscBool * changed_W, PetscBool * changed_Y) 178 { 179 PetscErrorCode ierr; 180 PetscFunctionBegin; 181 *changed_Y = PETSC_FALSE; 182 *changed_W = PETSC_FALSE; 183 if (linesearch->ops->postcheckstep) { 184 ierr = (*linesearch->ops->postcheckstep)(linesearch, linesearch->vec_sol, linesearch->vec_sol_new, linesearch->vec_update, changed_W, changed_Y);CHKERRQ(ierr); 185 } 186 PetscFunctionReturn(0); 187 } 188 189 #undef __FUNCT__ 190 #define __FUNCT__ "LineSearchApply" 191 /*@ 192 LineSearchApply - Computes the line-search update 193 194 Collective on LineSearch 195 196 Input Parameters: 197 + linesearch - The linesearch instance. 198 . X - The current solution. 199 . F - The current function. 200 . fnorm - The current norm. 201 . Y - The search direction. 202 203 Output Parameters: 204 + X - The new solution. 205 . F - The new function. 206 - fnorm - The new function norm. 207 208 Level: Intermediate 209 210 .keywords: LineSearch, Create 211 212 .seealso: LineSearchCreate(), LineSearchPreCheck(), LineSearchPostCheck() 213 @*/ 214 PetscErrorCode LineSearchApply(LineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y) { 215 PetscErrorCode ierr; 216 PetscFunctionBegin; 217 218 /* check the pointers */ 219 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 220 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 221 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 222 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 223 224 linesearch->success = PETSC_TRUE; 225 226 linesearch->vec_sol = X; 227 linesearch->vec_update = Y; 228 linesearch->vec_func = F; 229 230 ierr = LineSearchSetUp(linesearch);CHKERRQ(ierr); 231 232 if (!linesearch->keeplambda) 233 linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */ 234 235 if (fnorm) { 236 linesearch->fnorm = *fnorm; 237 } else { 238 ierr = VecNorm(F, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 239 } 240 241 ierr = PetscLogEventBegin(LineSearch_Apply,linesearch,X,F,Y);CHKERRQ(ierr); 242 243 ierr = (*linesearch->ops->apply)(linesearch);CHKERRQ(ierr); 244 245 ierr = PetscLogEventEnd(LineSearch_Apply,linesearch,X,F,Y);CHKERRQ(ierr); 246 247 if (fnorm) 248 *fnorm = linesearch->fnorm; 249 PetscFunctionReturn(0); 250 } 251 252 #undef __FUNCT__ 253 #define __FUNCT__ "LineSearchDestroy" 254 /*@ 255 LineSearchDestroy - Destroys the line search instance. 256 257 Collective on LineSearch 258 259 Input Parameters: 260 . linesearch - The linesearch instance. 261 262 Level: Intermediate 263 264 .keywords: LineSearch, Create 265 266 .seealso: LineSearchCreate(), LineSearchReset() 267 @*/ 268 PetscErrorCode LineSearchDestroy(LineSearch * linesearch) { 269 PetscErrorCode ierr; 270 PetscFunctionBegin; 271 if (!*linesearch) PetscFunctionReturn(0); 272 PetscValidHeaderSpecific((*linesearch),LineSearch_CLASSID,1); 273 if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; PetscFunctionReturn(0);} 274 ierr = PetscObjectDepublish((*linesearch));CHKERRQ(ierr); 275 ierr = LineSearchReset(*linesearch); 276 if ((*linesearch)->ops->destroy) { 277 (*linesearch)->ops->destroy(*linesearch); 278 } 279 ierr = PetscViewerDestroy(&(*linesearch)->monitor);CHKERRQ(ierr); 280 ierr = PetscHeaderDestroy(linesearch);CHKERRQ(ierr); 281 PetscFunctionReturn(0); 282 } 283 284 #undef __FUNCT__ 285 #define __FUNCT__ "LineSearchSetMonitor" 286 /*@ 287 LineSearchSetMonitor - Turns on/off printing useful things about the line search. 288 289 Input Parameters: 290 + snes - nonlinear context obtained from SNESCreate() 291 - flg - PETSC_TRUE to monitor the line search 292 293 Logically Collective on SNES 294 295 Options Database: 296 . -linesearch_monitor - enables the monitor. 297 298 Level: intermediate 299 300 301 .seealso: LineSearchGetMonitor() 302 @*/ 303 PetscErrorCode LineSearchSetMonitor(LineSearch linesearch, PetscBool flg) 304 { 305 306 PetscErrorCode ierr; 307 PetscFunctionBegin; 308 if (flg && !linesearch->monitor) { 309 ierr = PetscViewerASCIIOpen(((PetscObject)linesearch)->comm,"stdout",&linesearch->monitor);CHKERRQ(ierr); 310 } else if (!flg && linesearch->monitor) { 311 ierr = PetscViewerDestroy(&linesearch->monitor);CHKERRQ(ierr); 312 } 313 PetscFunctionReturn(0); 314 } 315 316 #undef __FUNCT__ 317 #define __FUNCT__ "LineSearchGetMonitor" 318 /*@ 319 LineSearchGetMonitor - Gets the monitor instance for the line search 320 321 Input Parameters: 322 . linesearch - linesearch context. 323 324 Input Parameters: 325 . monitor - monitor context. 326 327 Logically Collective on SNES 328 329 330 Options Database Keys: 331 . -linesearch_monitor - enables the monitor. 332 333 Level: intermediate 334 335 336 .seealso: LineSearchSetMonitor() 337 @*/ 338 PetscErrorCode LineSearchGetMonitor(LineSearch linesearch, PetscViewer *monitor) 339 { 340 341 PetscFunctionBegin; 342 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 343 if (monitor) { 344 PetscValidPointer(monitor, 2); 345 *monitor = linesearch->monitor; 346 } 347 PetscFunctionReturn(0); 348 } 349 350 #undef __FUNCT__ 351 #define __FUNCT__ "LineSearchSetFromOptions" 352 /*@ 353 LineSearchSetFromOptions - Sets options for the line search 354 355 Input Parameters: 356 . linesearch - linesearch context. 357 358 Options Database Keys: 359 + -linesearch_type - The Line search method 360 . -linesearch_monitor - Print progress of line searches 361 . -linesearch_damping - The linesearch damping parameter. 362 . -linesearch_norms - Turn on/off the linesearch norms 363 . -linesearch_keeplambda - Keep the previous search length as the initial guess. 364 - -linesearch_max_it - The number of iterations for iterative line searches. 365 366 Logically Collective on LineSearch 367 368 Level: intermediate 369 370 371 .seealso: LineSearchCreate() 372 @*/ 373 PetscErrorCode LineSearchSetFromOptions(LineSearch linesearch) { 374 PetscErrorCode ierr; 375 const char *deft = LINESEARCHBASIC; 376 char type[256]; 377 PetscBool flg, set; 378 PetscFunctionBegin; 379 if (!LineSearchRegisterAllCalled) {ierr = LineSearchRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 380 381 ierr = PetscObjectOptionsBegin((PetscObject)linesearch);CHKERRQ(ierr); 382 if (((PetscObject)linesearch)->type_name) { 383 deft = ((PetscObject)linesearch)->type_name; 384 } 385 ierr = PetscOptionsList("-linesearch_type","Line-search method","LineSearchSetType",LineSearchList,deft,type,256,&flg);CHKERRQ(ierr); 386 if (flg) { 387 ierr = LineSearchSetType(linesearch,type);CHKERRQ(ierr); 388 } else if (!((PetscObject)linesearch)->type_name) { 389 ierr = LineSearchSetType(linesearch,deft);CHKERRQ(ierr); 390 } 391 if (linesearch->ops->setfromoptions) { 392 (*linesearch->ops->setfromoptions)(linesearch);CHKERRQ(ierr); 393 } 394 395 ierr = PetscOptionsBool("-linesearch_monitor","Print progress of line searches","SNESLineSearchSetMonitor", 396 linesearch->monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr); 397 if (set) {ierr = LineSearchSetMonitor(linesearch,flg);CHKERRQ(ierr);} 398 399 ierr = PetscOptionsReal("-linesearch_damping","Line search damping and initial step guess","LineSearchSetDamping",linesearch->damping,&linesearch->damping,0);CHKERRQ(ierr); 400 ierr = PetscOptionsBool("-linesearch_norms","Compute final norms in line search","LineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,0);CHKERRQ(ierr); 401 ierr = PetscOptionsBool("-linesearch_keeplambda","Use previous lambda as damping","LineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,0);CHKERRQ(ierr); 402 ierr = PetscOptionsInt("-linesearch_max_it","Maximum iterations for iterative line searches","",linesearch->max_its,&linesearch->max_its,0);CHKERRQ(ierr); 403 ierr = PetscObjectProcessOptionsHandlers((PetscObject)linesearch);CHKERRQ(ierr); 404 ierr = PetscOptionsEnd();CHKERRQ(ierr); 405 PetscFunctionReturn(0); 406 } 407 408 #undef __FUNCT__ 409 #define __FUNCT__ "LineSearchView" 410 /*@ 411 LineSearchView - Views useful information for the line search. 412 413 Input Parameters: 414 . linesearch - linesearch context. 415 416 Logically Collective on LineSearch 417 418 Level: intermediate 419 420 421 .seealso: LineSearchCreate() 422 @*/ 423 PetscErrorCode LineSearchView(LineSearch linesearch) { 424 PetscFunctionBegin; 425 426 PetscFunctionReturn(0); 427 } 428 429 #undef __FUNCT__ 430 #define __FUNCT__ "LineSearchSetType" 431 /*@ 432 LineSearchSetType - Sets the linesearch type 433 434 Input Parameters: 435 + linesearch - linesearch context. 436 - type - The type of line search to be used 437 438 Logically Collective on LineSearch 439 440 Level: intermediate 441 442 443 .seealso: LineSearchCreate() 444 @*/ 445 PetscErrorCode LineSearchSetType(LineSearch linesearch, const LineSearchType type) 446 { 447 448 PetscErrorCode ierr,(*r)(LineSearch); 449 PetscBool match; 450 451 PetscFunctionBegin; 452 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 453 PetscValidCharPointer(type,2); 454 455 ierr = PetscTypeCompare((PetscObject)linesearch,type,&match);CHKERRQ(ierr); 456 if (match) PetscFunctionReturn(0); 457 458 ierr = PetscFListFind(LineSearchList,((PetscObject)linesearch)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 459 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type); 460 /* Destroy the previous private linesearch context */ 461 if (linesearch->ops->destroy) { 462 ierr = (*(linesearch)->ops->destroy)(linesearch);CHKERRQ(ierr); 463 linesearch->ops->destroy = PETSC_NULL; 464 } 465 /* Reinitialize function pointers in LineSearchOps structure */ 466 linesearch->ops->apply = 0; 467 linesearch->ops->view = 0; 468 linesearch->ops->setfromoptions = 0; 469 linesearch->ops->destroy = 0; 470 471 ierr = PetscObjectChangeTypeName((PetscObject)linesearch,type);CHKERRQ(ierr); 472 ierr = (*r)(linesearch);CHKERRQ(ierr); 473 #if defined(PETSC_HAVE_AMS) 474 if (PetscAMSPublishAll) { 475 ierr = PetscObjectAMSPublish((PetscObject)linesearch);CHKERRQ(ierr); 476 } 477 #endif 478 PetscFunctionReturn(0); 479 } 480 481 #undef __FUNCT__ 482 #define __FUNCT__ "LineSearchSetSNES" 483 /*@ 484 LineSearchSetSNES - Sets the SNES for the linesearch for function evaluation 485 486 Input Parameters: 487 + linesearch - linesearch context. 488 - snes - The snes instance 489 490 Level: intermediate 491 492 493 .seealso: LineSearchGetSNES(), LineSearchSetVecs() 494 @*/ 495 PetscErrorCode LineSearchSetSNES(LineSearch linesearch, SNES snes){ 496 PetscFunctionBegin; 497 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 498 PetscValidHeaderSpecific(snes,SNES_CLASSID,2); 499 linesearch->snes = snes; 500 PetscFunctionReturn(0); 501 } 502 503 #undef __FUNCT__ 504 #define __FUNCT__ "LineSearchGetSNES" 505 /*@ 506 LineSearchGetSNES - Gets the SNES for the linesearch for function evaluation 507 508 Input Parameters: 509 . linesearch - linesearch context. 510 511 Output Parameters: 512 . snes - The snes instance 513 514 Level: intermediate 515 516 .seealso: LineSearchGetSNES(), LineSearchSetVecs() 517 @*/ 518 PetscErrorCode LineSearchGetSNES(LineSearch linesearch, SNES *snes){ 519 PetscFunctionBegin; 520 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 521 PetscValidPointer(snes, 2); 522 *snes = linesearch->snes; 523 PetscFunctionReturn(0); 524 } 525 526 #undef __FUNCT__ 527 #define __FUNCT__ "LineSearchGetLambda" 528 /*@ 529 LineSearchGetLambda - Gets the last linesearch steplength discovered. 530 531 Input Parameters: 532 . linesearch - linesearch context. 533 534 Output Parameters: 535 . lambda - The last steplength. 536 537 Level: intermediate 538 539 .seealso: LineSearchGetSNES(), LineSearchSetVecs() 540 @*/ 541 PetscErrorCode LineSearchGetLambda(LineSearch linesearch,PetscReal *lambda) 542 { 543 PetscFunctionBegin; 544 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 545 PetscValidPointer(lambda, 2); 546 *lambda = linesearch->lambda; 547 PetscFunctionReturn(0); 548 } 549 550 #undef __FUNCT__ 551 #define __FUNCT__ "LineSearchSetLambda" 552 /*@ 553 LineSearchSetLambda - Sets the linesearch steplength. 554 555 Input Parameters: 556 + linesearch - linesearch context. 557 - lambda - The last steplength. 558 559 Level: intermediate 560 561 .seealso: LineSearchGetLambda() 562 @*/ 563 PetscErrorCode LineSearchSetLambda(LineSearch linesearch, PetscReal lambda) 564 { 565 PetscFunctionBegin; 566 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 567 linesearch->lambda = lambda; 568 PetscFunctionReturn(0); 569 } 570 571 #undef __FUNCT__ 572 #define __FUNCT__ "LineSearchGetStepTolerance" 573 /*@ 574 LineSearchGetStepTolerance - Gets the line search step tolerance. 575 576 Input Parameters: 577 . linesearch - linesearch context. 578 579 Output Parameters: 580 . steptol - The last steplength. 581 582 Level: intermediate 583 584 .seealso: LineSearchSetStepTolerance() 585 @*/ 586 PetscErrorCode LineSearchGetStepTolerance(LineSearch linesearch ,PetscReal *steptol) 587 { 588 PetscFunctionBegin; 589 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 590 PetscValidPointer(steptol, 2); 591 *steptol = linesearch->steptol; 592 PetscFunctionReturn(0); 593 } 594 595 #undef __FUNCT__ 596 #define __FUNCT__ "LineSearchSetStepTolerance" 597 /*@ 598 LineSearchSetStepTolerance - Gets the line search step tolerance. 599 600 Input Parameters: 601 . linesearch - linesearch context. 602 . steptol - The last steplength. 603 604 Level: intermediate 605 606 .seealso: LineSearchGetStepTolerance() 607 @*/ 608 PetscErrorCode LineSearchSetStepTolerance(LineSearch linesearch,PetscReal steptol) 609 { 610 PetscFunctionBegin; 611 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 612 linesearch->steptol = steptol; 613 PetscFunctionReturn(0); 614 } 615 616 #undef __FUNCT__ 617 #define __FUNCT__ "LineSearchGetDamping" 618 /*@ 619 LineSearchGetDamping - Gets the line search damping paramter. 620 621 Input Parameters: 622 . linesearch - linesearch context. 623 624 Output Parameters: 625 . damping - The damping parameter. 626 627 Level: intermediate 628 629 .seealso: LineSearchGetStepTolerance() 630 @*/ 631 632 PetscErrorCode LineSearchGetDamping(LineSearch linesearch,PetscReal *damping) 633 { 634 PetscFunctionBegin; 635 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 636 PetscValidPointer(damping, 2); 637 *damping = linesearch->damping; 638 PetscFunctionReturn(0); 639 } 640 641 #undef __FUNCT__ 642 #define __FUNCT__ "LineSearchSetDamping" 643 /*@ 644 LineSearchSetDamping - Sets the line search damping paramter. 645 646 Input Parameters: 647 . linesearch - linesearch context. 648 . damping - The damping parameter. 649 650 Level: intermediate 651 652 .seealso: LineSearchGetDamping() 653 @*/ 654 PetscErrorCode LineSearchSetDamping(LineSearch linesearch,PetscReal damping) 655 { 656 PetscFunctionBegin; 657 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 658 linesearch->damping = damping; 659 PetscFunctionReturn(0); 660 } 661 662 #undef __FUNCT__ 663 #define __FUNCT__ "LineSearchGetMaxStep" 664 /*@ 665 LineSearchGetMaxStep - Gets the maximum allowable step size for the line search. 666 667 Input Parameters: 668 . linesearch - linesearch context. 669 670 Output Parameters: 671 . maxstep - The maximum step. 672 673 Level: intermediate 674 675 .seealso: LineSearchSetMaxStep() 676 @*/ 677 PetscErrorCode LineSearchGetMaxStep(LineSearch linesearch,PetscReal* maxstep) 678 { 679 PetscFunctionBegin; 680 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 681 PetscValidPointer(maxstep, 2); 682 *maxstep = linesearch->maxstep; 683 PetscFunctionReturn(0); 684 } 685 686 #undef __FUNCT__ 687 #define __FUNCT__ "LineSearchSetMaxStep" 688 /*@ 689 LineSearchSetMaxStep - Sets the maximum allowable step size for the line search. 690 691 Input Parameters: 692 . linesearch - linesearch context. 693 . maxstep - The maximum step. 694 695 Level: intermediate 696 697 .seealso: LineSearchGetStepTolerance() 698 @*/ 699 PetscErrorCode LineSearchSetMaxStep(LineSearch linesearch, PetscReal maxstep) 700 { 701 PetscFunctionBegin; 702 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 703 linesearch->maxstep = maxstep; 704 PetscFunctionReturn(0); 705 } 706 707 #undef __FUNCT__ 708 #define __FUNCT__ "LineSearchGetMaxIts" 709 /*@ 710 LineSearchGetMaxIts - Gets the maximum iterations for iterative line searches. 711 712 Input Parameters: 713 . linesearch - linesearch context. 714 715 Output Parameters: 716 . max_its - The maximum number of iterations. 717 718 Level: intermediate 719 720 .seealso: LineSearchSetMaxIts() 721 @*/ 722 PetscErrorCode LineSearchGetMaxIts(LineSearch linesearch, PetscInt * max_its) 723 { 724 PetscFunctionBegin; 725 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 726 PetscValidPointer(max_its, 2); 727 *max_its = linesearch->max_its; 728 PetscFunctionReturn(0); 729 } 730 731 #undef __FUNCT__ 732 #define __FUNCT__ "LineSearchSetMaxIts" 733 /*@ 734 LineSearchSetMaxIts - Sets the maximum iterations for iterative line searches. 735 736 Input Parameters: 737 . linesearch - linesearch context. 738 . max_its - The maximum number of iterations. 739 740 Level: intermediate 741 742 .seealso: LineSearchGetMaxIts() 743 @*/ 744 PetscErrorCode LineSearchSetMaxIts(LineSearch linesearch, PetscInt max_its) 745 { 746 PetscFunctionBegin; 747 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 748 linesearch->max_its = max_its; 749 PetscFunctionReturn(0); 750 } 751 752 #undef __FUNCT__ 753 #define __FUNCT__ "LineSearchGetNorms" 754 /*@ 755 LineSearchGetNorms - Gets the norms for for X, Y, and F. 756 757 Input Parameters: 758 . linesearch - linesearch context. 759 760 Output Parameters: 761 + xnorm - The norm of the current solution 762 . fnorm - The norm of the current function 763 - ynorm - The norm of the current update 764 765 Level: intermediate 766 767 .seealso: LineSearchSetNorms() LineSearchGetVecs() 768 @*/ 769 PetscErrorCode LineSearchGetNorms(LineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm) 770 { 771 PetscFunctionBegin; 772 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 773 if (xnorm) { 774 *xnorm = linesearch->xnorm; 775 } 776 if (fnorm) { 777 *fnorm = linesearch->fnorm; 778 } 779 if (ynorm) { 780 *ynorm = linesearch->ynorm; 781 } 782 PetscFunctionReturn(0); 783 } 784 785 #undef __FUNCT__ 786 #define __FUNCT__ "LineSearchSetNorms" 787 /*@ 788 LineSearchSetNorms - Gets the computed norms for for X, Y, and F. 789 790 Input Parameters: 791 + linesearch - linesearch context. 792 . xnorm - The norm of the current solution 793 . fnorm - The norm of the current function 794 - ynorm - The norm of the current update 795 796 Level: intermediate 797 798 .seealso: LineSearchGetNorms(), LineSearchSetVecs() 799 @*/ 800 PetscErrorCode LineSearchSetNorms(LineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm) 801 { 802 PetscFunctionBegin; 803 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 804 if (xnorm) { 805 linesearch->xnorm = xnorm; 806 } 807 if (fnorm) { 808 linesearch->fnorm = fnorm; 809 } 810 if (ynorm) { 811 linesearch->ynorm = ynorm; 812 } 813 PetscFunctionReturn(0); 814 } 815 816 #undef __FUNCT__ 817 #define __FUNCT__ "LineSearchComputeNorms" 818 /*@ 819 LineSearchComputeNorms - Computes the norms of X, F, and Y. 820 821 Input Parameters: 822 . linesearch - linesearch context. 823 824 Options Database Keys: 825 . -linesearch_norms - turn norm computation on or off. 826 827 Level: intermediate 828 829 .seealso: LineSearchGetNorms, LineSearchSetNorms() 830 @*/ 831 PetscErrorCode LineSearchComputeNorms(LineSearch linesearch) 832 { 833 PetscErrorCode ierr; 834 PetscFunctionBegin; 835 if (linesearch->norms) { 836 ierr = VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 837 ierr = VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 838 ierr = VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 839 ierr = VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);CHKERRQ(ierr); 840 ierr = VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr); 841 ierr = VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr); 842 } 843 PetscFunctionReturn(0); 844 } 845 846 #undef __FUNCT__ 847 #define __FUNCT__ "LineSearchGetVecs" 848 /*@ 849 LineSearchGetVecs - Gets the vectors from the LineSearch context 850 851 Input Parameters: 852 . linesearch - linesearch context. 853 854 Output Parameters: 855 + X - The old solution 856 . F - The old function 857 . Y - The search direction 858 . W - The new solution 859 - G - The new function 860 861 Level: intermediate 862 863 .seealso: LineSearchGetNorms(), LineSearchSetVecs() 864 @*/ 865 PetscErrorCode LineSearchGetVecs(LineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G) { 866 PetscFunctionBegin; 867 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 868 if (X) { 869 PetscValidPointer(X, 2); 870 *X = linesearch->vec_sol; 871 } 872 if (F) { 873 PetscValidPointer(F, 3); 874 *F = linesearch->vec_func; 875 } 876 if (Y) { 877 PetscValidPointer(Y, 4); 878 *Y = linesearch->vec_update; 879 } 880 if (W) { 881 PetscValidPointer(W, 5); 882 *W = linesearch->vec_sol_new; 883 } 884 if (G) { 885 PetscValidPointer(G, 6); 886 *G = linesearch->vec_func_new; 887 } 888 889 PetscFunctionReturn(0); 890 } 891 892 #undef __FUNCT__ 893 #define __FUNCT__ "LineSearchSetVecs" 894 /*@ 895 LineSearchSetVecs - Sets the vectors on the LineSearch context 896 897 Input Parameters: 898 + linesearch - linesearch context. 899 . X - The old solution 900 . F - The old function 901 . Y - The search direction 902 . W - The new solution 903 - G - The new function 904 905 Level: intermediate 906 907 .seealso: LineSearchSetNorms(), LineSearchGetVecs() 908 @*/ 909 PetscErrorCode LineSearchSetVecs(LineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G) { 910 PetscFunctionBegin; 911 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 912 if (X) { 913 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 914 linesearch->vec_sol = X; 915 } 916 if (F) { 917 PetscValidHeaderSpecific(F,VEC_CLASSID,3); 918 linesearch->vec_func = F; 919 } 920 if (Y) { 921 PetscValidHeaderSpecific(Y,VEC_CLASSID,4); 922 linesearch->vec_update = Y; 923 } 924 if (W) { 925 PetscValidHeaderSpecific(W,VEC_CLASSID,5); 926 linesearch->vec_sol_new = W; 927 } 928 if (G) { 929 PetscValidHeaderSpecific(G,VEC_CLASSID,6); 930 linesearch->vec_func_new = G; 931 } 932 933 PetscFunctionReturn(0); 934 } 935 936 #undef __FUNCT__ 937 #define __FUNCT__ "LineSearchAppendOptionsPrefix" 938 /*@C 939 LineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all 940 SNES options in the database. 941 942 Logically Collective on SNES 943 944 Input Parameters: 945 + snes - the SNES context 946 - prefix - the prefix to prepend to all option names 947 948 Notes: 949 A hyphen (-) must NOT be given at the beginning of the prefix name. 950 The first character of all runtime options is AUTOMATICALLY the hyphen. 951 952 Level: advanced 953 954 .keywords: LineSearch, append, options, prefix, database 955 956 .seealso: SNESGetOptionsPrefix() 957 @*/ 958 PetscErrorCode LineSearchAppendOptionsPrefix(LineSearch linesearch,const char prefix[]) 959 { 960 PetscErrorCode ierr; 961 962 PetscFunctionBegin; 963 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 964 ierr = PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr); 965 PetscFunctionReturn(0); 966 } 967 968 #undef __FUNCT__ 969 #define __FUNCT__ "LineSearchGetOptionsPrefix" 970 /*@C 971 LineSearchGetOptionsPrefix - Sets the prefix used for searching for all 972 LineSearch options in the database. 973 974 Not Collective 975 976 Input Parameter: 977 . snes - the SNES context 978 979 Output Parameter: 980 . prefix - pointer to the prefix string used 981 982 Notes: On the fortran side, the user should pass in a string 'prefix' of 983 sufficient length to hold the prefix. 984 985 Level: advanced 986 987 .keywords: LineSearch, get, options, prefix, database 988 989 .seealso: SNESAppendOptionsPrefix() 990 @*/ 991 PetscErrorCode LineSearchGetOptionsPrefix(LineSearch linesearch,const char *prefix[]) 992 { 993 PetscErrorCode ierr; 994 995 PetscFunctionBegin; 996 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 997 ierr = PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr); 998 PetscFunctionReturn(0); 999 } 1000 1001 #undef __FUNCT__ 1002 #define __FUNCT__ "LineSearchGetWork" 1003 /*@ 1004 LineSearchGetWork - Gets work vectors for the line search. 1005 1006 Input Parameter: 1007 + linesearch - the LineSearch context 1008 - nwork - the number of work vectors 1009 1010 Level: developer 1011 1012 .keywords: LineSearch, work, vector 1013 1014 .seealso: SNESDefaultGetWork() 1015 @*/ 1016 PetscErrorCode LineSearchGetWork(LineSearch linesearch, PetscInt nwork) 1017 { 1018 PetscErrorCode ierr; 1019 PetscFunctionBegin; 1020 if (linesearch->vec_sol) { 1021 ierr = VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);CHKERRQ(ierr); 1022 } else { 1023 SETERRQ(((PetscObject)linesearch)->comm, PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!"); 1024 } 1025 PetscFunctionReturn(0); 1026 } 1027 1028 1029 #undef __FUNCT__ 1030 #define __FUNCT__ "LineSearchGetSuccess" 1031 /*@ 1032 LineSearchGetSuccess - Gets the success/failure status of the last line search application 1033 1034 Input Parameters: 1035 . linesearch - linesearch context. 1036 1037 Output Parameters: 1038 . success - The success or failure status. 1039 1040 Level: intermediate 1041 1042 .seealso: LineSearchSetSuccess() 1043 @*/ 1044 PetscErrorCode LineSearchGetSuccess(LineSearch linesearch, PetscBool *success) 1045 { 1046 PetscFunctionBegin; 1047 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 1048 PetscValidPointer(success, 2); 1049 if (success) { 1050 *success = linesearch->success; 1051 } 1052 PetscFunctionReturn(0); 1053 } 1054 1055 #undef __FUNCT__ 1056 #define __FUNCT__ "LineSearchSetSuccess" 1057 /*@ 1058 LineSearchSetSuccess - Sets the success/failure status of the last line search application 1059 1060 Input Parameters: 1061 + linesearch - linesearch context. 1062 - success - The success or failure status. 1063 1064 Level: intermediate 1065 1066 .seealso: LineSearchGetSuccess() 1067 @*/ 1068 PetscErrorCode LineSearchSetSuccess(LineSearch linesearch, PetscBool success) 1069 { 1070 PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1); 1071 PetscFunctionBegin; 1072 linesearch->success = success; 1073 PetscFunctionReturn(0); 1074 } 1075 1076 #undef __FUNCT__ 1077 #define __FUNCT__ "LineSearchRegister" 1078 /*@C 1079 LineSearchRegister - See LineSearchRegisterDynamic() 1080 1081 Level: advanced 1082 @*/ 1083 PetscErrorCode LineSearchRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(LineSearch)) 1084 { 1085 char fullname[PETSC_MAX_PATH_LEN]; 1086 PetscErrorCode ierr; 1087 1088 PetscFunctionBegin; 1089 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 1090 ierr = PetscFListAdd(&LineSearchList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 1091 PetscFunctionReturn(0); 1092 } 1093