Actual source code: linesearch.c

petsc-dev 2014-02-02
Report Typos and Errors
  1: #include <petsc-private/linesearchimpl.h> /*I "petscsnes.h" I*/

  3: PetscBool         SNESLineSearchRegisterAllCalled = PETSC_FALSE;
  4: PetscFunctionList SNESLineSearchList              = NULL;

  6: PetscClassId  SNESLINESEARCH_CLASSID;
  7: PetscLogEvent SNESLineSearch_Apply;

 11: /*@
 12:    SNESLineSearchCreate - Creates the line search context.

 14:    Logically Collective on Comm

 16:    Input Parameters:
 17: .  comm - MPI communicator for the line search (typically from the associated SNES context).

 19:    Output Parameters:
 20: .  outlinesearch - the new linesearch context

 22:    Level: beginner

 24: .keywords: LineSearch, create, context

 26: .seealso: LineSearchDestroy()
 27: @*/

 29: PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
 30: {
 32:   SNESLineSearch linesearch;

 36:   SNESInitializePackage();
 37:   *outlinesearch = NULL;

 39:   PetscHeaderCreate(linesearch,_p_LineSearch,struct _LineSearchOps,SNESLINESEARCH_CLASSID, "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView);

 41:   linesearch->ops->precheck  = NULL;
 42:   linesearch->ops->postcheck = NULL;

 44:   linesearch->vec_sol_new  = NULL;
 45:   linesearch->vec_func_new = NULL;
 46:   linesearch->vec_sol      = NULL;
 47:   linesearch->vec_func     = NULL;
 48:   linesearch->vec_update   = NULL;

 50:   linesearch->lambda       = 1.0;
 51:   linesearch->fnorm        = 1.0;
 52:   linesearch->ynorm        = 1.0;
 53:   linesearch->xnorm        = 1.0;
 54:   linesearch->success      = PETSC_TRUE;
 55:   linesearch->norms        = PETSC_TRUE;
 56:   linesearch->keeplambda   = PETSC_FALSE;
 57:   linesearch->damping      = 1.0;
 58:   linesearch->maxstep      = 1e8;
 59:   linesearch->steptol      = 1e-12;
 60:   linesearch->rtol         = 1e-8;
 61:   linesearch->atol         = 1e-15;
 62:   linesearch->ltol         = 1e-8;
 63:   linesearch->precheckctx  = NULL;
 64:   linesearch->postcheckctx = NULL;
 65:   linesearch->max_its      = 1;
 66:   linesearch->setupcalled  = PETSC_FALSE;
 67:   *outlinesearch           = linesearch;
 68:   return(0);
 69: }

 73: /*@
 74:    SNESLineSearchSetUp - Prepares the line search for being applied by allocating
 75:    any required vectors.

 77:    Collective on SNESLineSearch

 79:    Input Parameters:
 80: .  linesearch - The LineSearch instance.

 82:    Notes:
 83:    For most cases, this needn't be called outside of SNESLineSearchApply().
 84:    The only current case where this is called outside of this is for the VI
 85:    solvers, which modify the solution and work vectors before the first call
 86:    of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be
 87:    allocated upfront.

 89:    Level: advanced

 91: .keywords: SNESLineSearch, SetUp

 93: .seealso: SNESLineSearchReset()
 94: @*/

 96: PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
 97: {

101:   if (!((PetscObject)linesearch)->type_name) {
102:     SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);
103:   }
104:   if (!linesearch->setupcalled) {
105:     if (!linesearch->vec_sol_new) {
106:       VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);
107:     }
108:     if (!linesearch->vec_func_new) {
109:       VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);
110:     }
111:     if (linesearch->ops->setup) {
112:       (*linesearch->ops->setup)(linesearch);
113:     }
114:     if (!linesearch->ops->snesfunc) {SNESLineSearchSetFunction(linesearch,SNESComputeFunction);}
115:     linesearch->lambda      = linesearch->damping;
116:     linesearch->setupcalled = PETSC_TRUE;
117:   }
118:   return(0);
119: }


124: /*@
125:    SNESLineSearchReset - Undoes the SetUp and deletes any Vecs or Mats allocated by the line search.

127:    Collective on SNESLineSearch

129:    Input Parameters:
130: .  linesearch - The LineSearch instance.

132:    Level: intermediate

134: .keywords: SNESLineSearch, Reset

136: .seealso: SNESLineSearchSetUp()
137: @*/

139: PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
140: {

144:   if (linesearch->ops->reset) (*linesearch->ops->reset)(linesearch);

146:   VecDestroy(&linesearch->vec_sol_new);
147:   VecDestroy(&linesearch->vec_func_new);

149:   VecDestroyVecs(linesearch->nwork, &linesearch->work);

151:   linesearch->nwork       = 0;
152:   linesearch->setupcalled = PETSC_FALSE;
153:   return(0);
154: }

158: /*@C
159:    SNESLineSearchSetPreCheck - Sets the function evaluation context on the

161:    Input Parameters:
162: .  linesearch - the SNESLineSearch context

164:    Output Parameters:
165: +  func       - [optional] function evaluation routine

167:    Level: developer

169: .keywords: get, linesearch, pre-check

171: .seealso: SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck()
172: @*/
173: PetscErrorCode  SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
174: {
177:   linesearch->ops->snesfunc = func;
178:   return(0);
179: }


182: /*MC
183:     SNESLineSearchPreCheckFunction - functional form passed to check before line search is called

185:      Synopsis:
186:      #include <petscsnes.h>
187:      SNESLineSearchPreCheckFunction(SNESLineSearch snes,Vec x,Vec y, PetscBool *changed);

189:        Input Parameters:
190: +      x - solution vector
191: .      y - search direction vector
192: -      changed - flag to indicate the precheck changed x or y.

194:    Level: advanced

196: .seealso:   SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck()
197: M*/

201: /*@C
202:    SNESLineSearchSetPreCheck - Sets a pre-check function for the line search routine.

204:    Logically Collective on SNESLineSearch

206:    Input Parameters:
207: +  linesearch - the SNESLineSearch context
208: .  SNESLineSearchPreCheckFunction - [optional] function evaluation routine
209: -  ctx        - [optional] user-defined context for private data for the
210:                 function evaluation routine (may be NULL)


213:    Level: intermediate

215: .keywords: set, linesearch, pre-check

217: .seealso: SNESLineSearchSetPostCheck()
218: @*/
219: PetscErrorCode  SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*SNESLineSearchPreCheckFunction)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
220: {
223:   if (SNESLineSearchPreCheckFunction) linesearch->ops->precheck = SNESLineSearchPreCheckFunction;
224:   if (ctx) linesearch->precheckctx = ctx;
225:   return(0);
226: }

230: /*@C
231:    SNESLineSearchSetPreCheck - Gets the pre-check function for the line search routine.

233:    Input Parameters:
234: .  linesearch - the SNESLineSearch context

236:    Output Parameters:
237: +  func       - [optional] function evaluation routine
238: -  ctx        - [optional] user-defined context for private data for the
239:                 function evaluation routine (may be NULL)

241:    Level: intermediate

243: .keywords: get, linesearch, pre-check

245: .seealso: SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck()
246: @*/
247: PetscErrorCode  SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**SNESLineSearchPreCheckFunction)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
248: {
251:   if (SNESLineSearchPreCheckFunction) *SNESLineSearchPreCheckFunction = linesearch->ops->precheck;
252:   if (ctx) *ctx = linesearch->precheckctx;
253:   return(0);
254: }

256: /*MC
257:     SNESLineSearchPostheckFunction - functional form that is called after line search is complete

259:      Synopsis:
260:      #include <petscsnes.h>
261:      SNESLineSearchPostheckFunction(SNESLineSearch linesearch,Vec x,Vec y,  Vec w, *changed_y, PetscBool *changed_w);

263:      Input Parameters:
264: +      x - old solution vector
265: .      y - search direction vector
266: .      w - new solution vector
267: .      changed_y - indicates that the line search changed y
268: -      changed_w - indicates that the line search changed w

270:    Level: advanced

272: .seealso:   SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck()
273: M*/

277: /*@C
278:    SNESLineSearchSetPostCheck - Sets a post-check function for the line search routine.

280:    Logically Collective on SNESLineSearch

282:    Input Parameters:
283: +  linesearch - the SNESLineSearch context
284: .  SNESLineSearchPostCheckFunction - [optional] function evaluation routine
285: -  ctx        - [optional] user-defined context for private data for the
286:                 function evaluation routine (may be NULL)

288:    Level: intermediate

290: .keywords: set, linesearch, post-check

292: .seealso: SNESLineSearchSetPreCheck()
293: @*/
294: PetscErrorCode  SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*SNESLineSearchPostCheckFunction)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
295: {
298:   if (SNESLineSearchPostCheckFunction) linesearch->ops->postcheck = SNESLineSearchPostCheckFunction;
299:   if (ctx) linesearch->postcheckctx = ctx;
300:   return(0);
301: }

305: /*@C
306:    SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.

308:    Input Parameters:
309: .  linesearch - the SNESLineSearch context

311:    Output Parameters:
312: +  SNESLineSearchPostCheckFunction - [optional] function evaluation routine
313: -  ctx        - [optional] user-defined context for private data for the
314:                 function evaluation routine (may be NULL)

316:    Level: intermediate

318: .keywords: get, linesearch, post-check

320: .seealso: SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck()
321: @*/
322: PetscErrorCode  SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**SNESLineSearchPostCheckFunction)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
323: {
326:   if (SNESLineSearchPostCheckFunction) *SNESLineSearchPostCheckFunction = linesearch->ops->postcheck;
327:   if (ctx) *ctx = linesearch->postcheckctx;
328:   return(0);
329: }

333: /*@
334:    SNESLineSearchPreCheck - Prepares the line search for being applied.

336:    Logically Collective on SNESLineSearch

338:    Input Parameters:
339: +  linesearch - The linesearch instance.
340: .  X - The current solution
341: -  Y - The step direction

343:    Output Parameters:
344: .  changed - Indicator that the precheck routine has changed anything

346:    Level: Beginner

348: .keywords: SNESLineSearch, Create

350: .seealso: SNESLineSearchPostCheck()
351: @*/
352: PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
353: {

357:   *changed = PETSC_FALSE;
358:   if (linesearch->ops->precheck) {
359:     (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);
361:   }
362:   return(0);
363: }

367: /*@
368:    SNESLineSearchPostCheck - Prepares the line search for being applied.

370:    Logically Collective on SNESLineSearch

372:    Input Parameters:
373: +  linesearch - The linesearch context
374: .  X - The last solution
375: .  Y - The step direction
376: -  W - The updated solution, W = X + lambda*Y for some lambda

378:    Output Parameters:
379: +  changed_Y - Indicator if the direction Y has been changed.
380: -  changed_W - Indicator if the new candidate solution W has been changed.

382:    Level: Intermediate

384: .keywords: SNESLineSearch, Create

386: .seealso: SNESLineSearchPreCheck()
387: @*/
388: PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
389: {

393:   *changed_Y = PETSC_FALSE;
394:   *changed_W = PETSC_FALSE;
395:   if (linesearch->ops->postcheck) {
396:     (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);
399:   }
400:   return(0);
401: }

405: /*@C
406:    SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration

408:    Logically Collective on SNESLineSearch

410:    Input Arguments:
411: +  linesearch - linesearch context
412: .  X - base state for this step
413: .  Y - initial correction

415:    Output Arguments:
416: +  Y - correction, possibly modified
417: -  changed - flag indicating that Y was modified

419:    Options Database Key:
420: +  -snes_linesearch_precheck_picard - activate this routine
421: -  -snes_linesearch_precheck_picard_angle - angle

423:    Level: advanced

425:    Notes:
426:    This function should be passed to SNESLineSearchSetPreCheck()

428:    The justification for this method involves the linear convergence of a Picard iteration
429:    so the Picard linearization should be provided in place of the "Jacobian". This correction
430:    is generally not useful when using a Newton linearization.

432:    Reference:
433:    Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.

435: .seealso: SNESLineSearchSetPreCheck()
436: @*/
437: PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
438: {
440:   PetscReal      angle = *(PetscReal*)linesearch->precheckctx;
441:   Vec            Ylast;
442:   PetscScalar    dot;
443:   PetscInt       iter;
444:   PetscReal      ynorm,ylastnorm,theta,angle_radians;
445:   SNES           snes;

448:   SNESLineSearchGetSNES(linesearch, &snes);
449:   PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);
450:   if (!Ylast) {
451:     VecDuplicate(Y,&Ylast);
452:     PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);
453:     PetscObjectDereference((PetscObject)Ylast);
454:   }
455:   SNESGetIterationNumber(snes,&iter);
456:   if (iter < 2) {
457:     VecCopy(Y,Ylast);
458:     *changed = PETSC_FALSE;
459:     return(0);
460:   }

462:   VecDot(Y,Ylast,&dot);
463:   VecNorm(Y,NORM_2,&ynorm);
464:   VecNorm(Ylast,NORM_2,&ylastnorm);
465:   /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
466:   theta         = acos((double)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
467:   angle_radians = angle * PETSC_PI / 180.;
468:   if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
469:     /* Modify the step Y */
470:     PetscReal alpha,ydiffnorm;
471:     VecAXPY(Ylast,-1.0,Y);
472:     VecNorm(Ylast,NORM_2,&ydiffnorm);
473:     alpha = ylastnorm / ydiffnorm;
474:     VecCopy(Y,Ylast);
475:     VecScale(Y,alpha);
476:     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);
477:   } else {
478:     PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);
479:     VecCopy(Y,Ylast);
480:     *changed = PETSC_FALSE;
481:   }
482:   return(0);
483: }

487: /*@
488:    SNESLineSearchApply - Computes the line-search update.

490:    Collective on SNESLineSearch

492:    Input Parameters:
493: +  linesearch - The linesearch context
494: .  X - The current solution
495: .  F - The current function
496: .  fnorm - The current norm
497: -  Y - The search direction

499:    Output Parameters:
500: +  X - The new solution
501: .  F - The new function
502: -  fnorm - The new function norm

504:    Options Database Keys:
505: + -snes_linesearch_type - basic, bt, l2, cp, shell
506: . -snes_linesearch_monitor - Print progress of line searches
507: . -snes_linesearch_damping - The linesearch damping parameter
508: . -snes_linesearch_norms   - Turn on/off the linesearch norms
509: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
510: - -snes_linesearch_max_it - The number of iterations for iterative line searches

512:    Notes:
513:    This is typically called from within a SNESSolve() implementation in order to
514:    help with convergence of the nonlinear method.  Various SNES types use line searches
515:    in different ways, but the overarching theme is that a line search is used to determine
516:    an optimal damping parameter of a step at each iteration of the method.  Each
517:    application of the line search may invoke SNESComputeFunction several times, and
518:    therefore may be fairly expensive.

520:    Level: Intermediate

522: .keywords: SNESLineSearch, Create

524: .seealso: SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction()
525: @*/
526: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
527: {


536:   linesearch->success = PETSC_TRUE;

538:   linesearch->vec_sol    = X;
539:   linesearch->vec_update = Y;
540:   linesearch->vec_func   = F;

542:   SNESLineSearchSetUp(linesearch);

544:   if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */

546:   if (fnorm) linesearch->fnorm = *fnorm;
547:   else {
548:     VecNorm(F, NORM_2, &linesearch->fnorm);
549:   }

551:   PetscLogEventBegin(SNESLineSearch_Apply,linesearch,X,F,Y);

553:   (*linesearch->ops->apply)(linesearch);

555:   PetscLogEventEnd(SNESLineSearch_Apply,linesearch,X,F,Y);

557:   if (fnorm) *fnorm = linesearch->fnorm;
558:   return(0);
559: }

563: /*@
564:    SNESLineSearchDestroy - Destroys the line search instance.

566:    Collective on SNESLineSearch

568:    Input Parameters:
569: .  linesearch - The linesearch context

571:    Level: Intermediate

573: .keywords: SNESLineSearch, Destroy

575: .seealso: SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
576: @*/
577: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
578: {

582:   if (!*linesearch) return(0);
584:   if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; return(0);}
585:   PetscObjectSAWsViewOff((PetscObject)*linesearch);
586:   SNESLineSearchReset(*linesearch);
587:   if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
588:   PetscViewerDestroy(&(*linesearch)->monitor);
589:   PetscHeaderDestroy(linesearch);
590:   return(0);
591: }

595: /*@
596:    SNESLineSearchSetMonitor - Turns on/off printing useful information and debugging output about the line search.

598:    Input Parameters:
599: +  snes - nonlinear context obtained from SNESCreate()
600: -  flg - PETSC_TRUE to monitor the line search

602:    Logically Collective on SNES

604:    Options Database:
605: .   -snes_linesearch_monitor - enables the monitor

607:    Level: intermediate


610: .seealso: SNESLineSearchGetMonitor(), PetscViewer
611: @*/
612: PetscErrorCode  SNESLineSearchSetMonitor(SNESLineSearch linesearch, PetscBool flg)
613: {

617:   if (flg && !linesearch->monitor) {
618:     PetscViewerASCIIOpen(PetscObjectComm((PetscObject)linesearch),"stdout",&linesearch->monitor);
619:   } else if (!flg && linesearch->monitor) {
620:     PetscViewerDestroy(&linesearch->monitor);
621:   }
622:   return(0);
623: }

627: /*@
628:    SNESLineSearchGetMonitor - Gets the PetscViewer instance for the line search monitor.

630:    Input Parameters:
631: .  linesearch - linesearch context

633:    Input Parameters:
634: .  monitor - monitor context

636:    Logically Collective on SNES


639:    Options Database Keys:
640: .   -snes_linesearch_monitor - enables the monitor

642:    Level: intermediate


645: .seealso: SNESLineSearchSetMonitor(), PetscViewer
646: @*/
647: PetscErrorCode  SNESLineSearchGetMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
648: {
651:   if (monitor) {
653:     *monitor = linesearch->monitor;
654:   }
655:   return(0);
656: }

660: /*@
661:    SNESLineSearchSetFromOptions - Sets options for the line search

663:    Input Parameters:
664: .  linesearch - linesearch context

666:    Options Database Keys:
667: + -snes_linesearch_type <type> - basic, bt, l2, cp, shell
668: . -snes_linesearch_order <order> - 1, 2, 3.  Most types only support certain orders (bt supports 2 or 3)
669: . -snes_linesearch_norms   - Turn on/off the linesearch norms for the basic linesearch type
670: . -snes_linesearch_minlambda - The minimum step length
671: . -snes_linesearch_maxstep - The maximum step size
672: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
673: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
674: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
675: . -snes_linesearch_max_it - The number of iterations for iterative line searches
676: . -snes_linesearch_monitor - Print progress of line searches
677: . -snes_linesearch_damping - The linesearch damping parameter
678: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
679: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
680: - -snes_linesearch_precheck_picard_angle - Angle used in picard precheck method

682:    Logically Collective on SNESLineSearch

684:    Level: intermediate

686: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard()
687: @*/
688: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
689: {
691:   const char     *deft = SNESLINESEARCHBASIC;
692:   char           type[256];
693:   PetscBool      flg, set;

696:   if (!SNESLineSearchRegisterAllCalled) {SNESLineSearchRegisterAll();}

698:   PetscObjectOptionsBegin((PetscObject)linesearch);
699:   if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
700:   PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
701:   if (flg) {
702:     SNESLineSearchSetType(linesearch,type);
703:   } else if (!((PetscObject)linesearch)->type_name) {
704:     SNESLineSearchSetType(linesearch,deft);
705:   }

707:   PetscOptionsBool("-snes_linesearch_monitor","Print progress of line searches","SNESSNESLineSearchSetMonitor",
708:                           linesearch->monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);
709:   if (set) {SNESLineSearchSetMonitor(linesearch,flg);}

711:   /* tolerances */
712:   PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,0);
713:   PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,0);
714:   PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,0);
715:   PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,0);
716:   PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,0);
717:   PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,0);

719:   /* damping parameters */
720:   PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,0);

722:   PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,0);

724:   /* precheck */
725:   PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);
726:   if (set) {
727:     if (flg) {
728:       linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */

730:       PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
731:                               "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);
732:       SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
733:     } else {
734:       SNESLineSearchSetPreCheck(linesearch,NULL,NULL);
735:     }
736:   }
737:   PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,0);
738:   PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,0);

740:   if (linesearch->ops->setfromoptions) {
741:     (*linesearch->ops->setfromoptions)(linesearch);
742:   }

744:   PetscObjectProcessOptionsHandlers((PetscObject)linesearch);
745:   PetscOptionsEnd();
746:   return(0);
747: }

751: /*@
752:    SNESLineSearchView - Prints useful information about the line search not
753:    related to an individual call.

755:    Input Parameters:
756: .  linesearch - linesearch context

758:    Logically Collective on SNESLineSearch

760:    Level: intermediate

762: .seealso: SNESLineSearchCreate()
763: @*/
764: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
765: {
767:   PetscBool      iascii;

771:   if (!viewer) {
772:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);
773:   }

777:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
778:   if (iascii) {
779:     PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);
780:     if (linesearch->ops->view) {
781:       PetscViewerASCIIPushTab(viewer);
782:       (*linesearch->ops->view)(linesearch,viewer);
783:       PetscViewerASCIIPopTab(viewer);
784:     }
785:     PetscViewerASCIIPrintf(viewer,"  maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);
786:     PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);
787:     PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D\n", linesearch->max_its);
788:     if (linesearch->ops->precheck) {
789:       if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
790:         PetscViewerASCIIPrintf(viewer,"  using precheck step to speed up Picard convergence\n", linesearch->max_its);
791:       } else {
792:         PetscViewerASCIIPrintf(viewer,"  using user-defined precheck step\n", linesearch->max_its);
793:       }
794:     }
795:     if (linesearch->ops->postcheck) {
796:       PetscViewerASCIIPrintf(viewer,"  using user-defined postcheck step\n", linesearch->max_its);
797:     }
798:   }
799:   return(0);
800: }

804: /*@C
805:    SNESLineSearchSetType - Sets the linesearch type

807:    Input Parameters:
808: +  linesearch - linesearch context
809: -  type - The type of line search to be used

811:    Available Types:
812: +  basic - Simple damping line search.
813: .  bt - Backtracking line search over the L2 norm of the function
814: .  l2 - Secant line search over the L2 norm of the function
815: .  cp - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
816: -  shell - User provided SNESLineSearch implementation

818:    Logically Collective on SNESLineSearch

820:    Level: intermediate


823: .seealso: SNESLineSearchCreate()
824: @*/
825: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
826: {
827:   PetscErrorCode ierr,(*r)(SNESLineSearch);
828:   PetscBool      match;


834:   PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
835:   if (match) return(0);

837:   PetscFunctionListFind(SNESLineSearchList,type,&r);
838:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
839:   /* Destroy the previous private linesearch context */
840:   if (linesearch->ops->destroy) {
841:     (*(linesearch)->ops->destroy)(linesearch);

843:     linesearch->ops->destroy = NULL;
844:   }
845:   /* Reinitialize function pointers in SNESLineSearchOps structure */
846:   linesearch->ops->apply          = 0;
847:   linesearch->ops->view           = 0;
848:   linesearch->ops->setfromoptions = 0;
849:   linesearch->ops->destroy        = 0;

851:   PetscObjectChangeTypeName((PetscObject)linesearch,type);
852:   (*r)(linesearch);
853:   return(0);
854: }

858: /*@
859:    SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.

861:    Input Parameters:
862: +  linesearch - linesearch context
863: -  snes - The snes instance

865:    Level: developer

867:    Notes:
868:    This happens automatically when the line search is gotten/created with
869:    SNESGetLineSearch().  This routine is therefore mainly called within SNES
870:    implementations.

872:    Level: developer

874: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
875: @*/
876: PetscErrorCode  SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
877: {
881:   linesearch->snes = snes;
882:   return(0);
883: }

887: /*@
888:    SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
889:    Having an associated SNES is necessary because most line search implementations must be able to
890:    evaluate the function using SNESComputeFunction() for the associated SNES.  This routine
891:    is used in the line search implementations when one must get this associated SNES instance.

893:    Input Parameters:
894: .  linesearch - linesearch context

896:    Output Parameters:
897: .  snes - The snes instance

899:    Level: developer

901: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
902: @*/
903: PetscErrorCode  SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
904: {
908:   *snes = linesearch->snes;
909:   return(0);
910: }

914: /*@
915:    SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.

917:    Input Parameters:
918: .  linesearch - linesearch context

920:    Output Parameters:
921: .  lambda - The last steplength computed during SNESLineSearchApply()

923:    Level: advanced

925:    Notes:
926:    This is useful in methods where the solver is ill-scaled and
927:    requires some adaptive notion of the difference in scale between the
928:    solution and the function.  For instance, SNESQN may be scaled by the
929:    line search lambda using the argument -snes_qn_scaling ls.


932: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
933: @*/
934: PetscErrorCode  SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
935: {
939:   *lambda = linesearch->lambda;
940:   return(0);
941: }

945: /*@
946:    SNESLineSearchSetLambda - Sets the linesearch steplength.

948:    Input Parameters:
949: +  linesearch - linesearch context
950: -  lambda - The last steplength.

952:    Notes:
953:    This routine is typically used within implementations of SNESLineSearchApply
954:    to set the final steplength.  This routine (and SNESLineSearchGetLambda()) were
955:    added in order to facilitate Quasi-Newton methods that use the previous steplength
956:    as an inner scaling parameter.

958:    Level: advanced

960: .seealso: SNESLineSearchGetLambda()
961: @*/
962: PetscErrorCode  SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
963: {
966:   linesearch->lambda = lambda;
967:   return(0);
968: }

970: #undef  __FUNCT__
972: /*@
973:    SNESLineSearchGetTolerances - Gets the tolerances for the linesearch.  These include
974:    tolerances for the relative and absolute change in the function norm, the change
975:    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
976:    and the maximum number of iterations the line search procedure may take.

978:    Input Parameters:
979: .  linesearch - linesearch context

981:    Output Parameters:
982: +  steptol - The minimum steplength
983: .  maxstep - The maximum steplength
984: .  rtol    - The relative tolerance for iterative line searches
985: .  atol    - The absolute tolerance for iterative line searches
986: .  ltol    - The change in lambda tolerance for iterative line searches
987: -  max_it  - The maximum number of iterations of the line search

989:    Level: intermediate

991:    Notes:
992:    Different line searches may implement these parameters slightly differently as
993:    the type requires.

995: .seealso: SNESLineSearchSetTolerances()
996: @*/
997: PetscErrorCode  SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
998: {
1001:   if (steptol) {
1003:     *steptol = linesearch->steptol;
1004:   }
1005:   if (maxstep) {
1007:     *maxstep = linesearch->maxstep;
1008:   }
1009:   if (rtol) {
1011:     *rtol = linesearch->rtol;
1012:   }
1013:   if (atol) {
1015:     *atol = linesearch->atol;
1016:   }
1017:   if (ltol) {
1019:     *ltol = linesearch->ltol;
1020:   }
1021:   if (max_its) {
1023:     *max_its = linesearch->max_its;
1024:   }
1025:   return(0);
1026: }

1028: #undef  __FUNCT__
1030: /*@
1031:    SNESLineSearchSetTolerances -  Gets the tolerances for the linesearch.  These include
1032:    tolerances for the relative and absolute change in the function norm, the change
1033:    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1034:    and the maximum number of iterations the line search procedure may take.

1036:    Input Parameters:
1037: +  linesearch - linesearch context
1038: .  steptol - The minimum steplength
1039: .  maxstep - The maximum steplength
1040: .  rtol    - The relative tolerance for iterative line searches
1041: .  atol    - The absolute tolerance for iterative line searches
1042: .  ltol    - The change in lambda tolerance for iterative line searches
1043: -  max_it  - The maximum number of iterations of the line search

1045:    Notes:
1046:    The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1047:    place of an argument.

1049:    Level: intermediate

1051: .seealso: SNESLineSearchGetTolerances()
1052: @*/
1053: PetscErrorCode  SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1054: {

1064:   if (steptol!= PETSC_DEFAULT) {
1065:     if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
1066:     linesearch->steptol = steptol;
1067:   }

1069:   if (maxstep!= PETSC_DEFAULT) {
1070:     if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1071:     linesearch->maxstep = maxstep;
1072:   }

1074:   if (rtol != PETSC_DEFAULT) {
1075:     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);
1076:     linesearch->rtol = rtol;
1077:   }

1079:   if (atol != PETSC_DEFAULT) {
1080:     if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1081:     linesearch->atol = atol;
1082:   }

1084:   if (ltol != PETSC_DEFAULT) {
1085:     if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %14.12e must be non-negative",(double)ltol);
1086:     linesearch->ltol = ltol;
1087:   }

1089:   if (max_its != PETSC_DEFAULT) {
1090:     if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1091:     linesearch->max_its = max_its;
1092:   }
1093:   return(0);
1094: }

1098: /*@
1099:    SNESLineSearchGetDamping - Gets the line search damping parameter.

1101:    Input Parameters:
1102: .  linesearch - linesearch context

1104:    Output Parameters:
1105: .  damping - The damping parameter

1107:    Level: advanced

1109: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1110: @*/

1112: PetscErrorCode  SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1113: {
1117:   *damping = linesearch->damping;
1118:   return(0);
1119: }

1123: /*@
1124:    SNESLineSearchSetDamping - Sets the line search damping paramter.

1126:    Input Parameters:
1127: .  linesearch - linesearch context
1128: .  damping - The damping parameter

1130:    Level: intermediate

1132:    Notes:
1133:    The basic line search merely takes the update step scaled by the damping parameter.
1134:    The use of the damping parameter in the l2 and cp line searches is much more subtle;
1135:    it is used as a starting point in calculating the secant step. However, the eventual
1136:    step may be of greater length than the damping parameter.  In the bt line search it is
1137:    used as the maximum possible step length, as the bt line search only backtracks.

1139: .seealso: SNESLineSearchGetDamping()
1140: @*/
1141: PetscErrorCode  SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1142: {
1145:   linesearch->damping = damping;
1146:   return(0);
1147: }

1151: /*@
1152:    SNESLineSearchGetOrder - Gets the line search approximation order.

1154:    Input Parameters:
1155: .  linesearch - linesearch context

1157:    Output Parameters:
1158: .  order - The order

1160:    Possible Values for order:
1161: +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1162: .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1163: -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order

1165:    Level: intermediate

1167: .seealso: SNESLineSearchSetOrder()
1168: @*/

1170: PetscErrorCode  SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1171: {
1175:   *order = linesearch->order;
1176:   return(0);
1177: }

1181: /*@
1182:    SNESLineSearchSetOrder - Sets the line search damping paramter.

1184:    Input Parameters:
1185: .  linesearch - linesearch context
1186: .  order - The damping parameter

1188:    Level: intermediate

1190:    Possible Values for order:
1191: +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1192: .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1193: -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order

1195:    Notes:
1196:    Variable orders are supported by the following line searches:
1197: +  bt - cubic and quadratic
1198: -  cp - linear and quadratic

1200: .seealso: SNESLineSearchGetOrder()
1201: @*/
1202: PetscErrorCode  SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1203: {
1206:   linesearch->order = order;
1207:   return(0);
1208: }

1212: /*@
1213:    SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.

1215:    Input Parameters:
1216: .  linesearch - linesearch context

1218:    Output Parameters:
1219: +  xnorm - The norm of the current solution
1220: .  fnorm - The norm of the current function
1221: -  ynorm - The norm of the current update

1223:    Notes:
1224:    This function is mainly called from SNES implementations.

1226:    Level: developer

1228: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1229: @*/
1230: PetscErrorCode  SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1231: {
1234:   if (xnorm) *xnorm = linesearch->xnorm;
1235:   if (fnorm) *fnorm = linesearch->fnorm;
1236:   if (ynorm) *ynorm = linesearch->ynorm;
1237:   return(0);
1238: }

1242: /*@
1243:    SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.

1245:    Input Parameters:
1246: +  linesearch - linesearch context
1247: .  xnorm - The norm of the current solution
1248: .  fnorm - The norm of the current function
1249: -  ynorm - The norm of the current update

1251:    Level: advanced

1253: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1254: @*/
1255: PetscErrorCode  SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1256: {
1259:   linesearch->xnorm = xnorm;
1260:   linesearch->fnorm = fnorm;
1261:   linesearch->ynorm = ynorm;
1262:   return(0);
1263: }

1267: /*@
1268:    SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.

1270:    Input Parameters:
1271: .  linesearch - linesearch context

1273:    Options Database Keys:
1274: .   -snes_linesearch_norms - turn norm computation on or off

1276:    Level: intermediate

1278: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1279: @*/
1280: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1281: {
1283:   SNES           snes;

1286:   if (linesearch->norms) {
1287:     if (linesearch->ops->vinorm) {
1288:       SNESLineSearchGetSNES(linesearch, &snes);
1289:       VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1290:       VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1291:       (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1292:     } else {
1293:       VecNormBegin(linesearch->vec_func,   NORM_2, &linesearch->fnorm);
1294:       VecNormBegin(linesearch->vec_sol,    NORM_2, &linesearch->xnorm);
1295:       VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1296:       VecNormEnd(linesearch->vec_func,     NORM_2, &linesearch->fnorm);
1297:       VecNormEnd(linesearch->vec_sol,      NORM_2, &linesearch->xnorm);
1298:       VecNormEnd(linesearch->vec_update,   NORM_2, &linesearch->ynorm);
1299:     }
1300:   }
1301:   return(0);
1302: }

1306: /*@
1307:    SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.

1309:    Input Parameters:
1310: +  linesearch  - linesearch context
1311: -  flg  - indicates whether or not to compute norms

1313:    Options Database Keys:
1314: .   -snes_linesearch_norms - turn norm computation on or off

1316:    Notes:
1317:    This is most relevant to the SNESLINESEARCHBASIC line search type.

1319:    Level: intermediate

1321: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1322: @*/
1323: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1324: {
1326:   linesearch->norms = flg;
1327:   return(0);
1328: }

1332: /*@
1333:    SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context

1335:    Input Parameters:
1336: .  linesearch - linesearch context

1338:    Output Parameters:
1339: +  X - Solution vector
1340: .  F - Function vector
1341: .  Y - Search direction vector
1342: .  W - Solution work vector
1343: -  G - Function work vector

1345:    Notes:
1346:    At the beginning of a line search application, X should contain a
1347:    solution and the vector F the function computed at X.  At the end of the
1348:    line search application, X should contain the new solution, and F the
1349:    function evaluated at the new solution.

1351:    Level: advanced

1353: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1354: @*/
1355: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1356: {
1359:   if (X) {
1361:     *X = linesearch->vec_sol;
1362:   }
1363:   if (F) {
1365:     *F = linesearch->vec_func;
1366:   }
1367:   if (Y) {
1369:     *Y = linesearch->vec_update;
1370:   }
1371:   if (W) {
1373:     *W = linesearch->vec_sol_new;
1374:   }
1375:   if (G) {
1377:     *G = linesearch->vec_func_new;
1378:   }
1379:   return(0);
1380: }

1384: /*@
1385:    SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context

1387:    Input Parameters:
1388: +  linesearch - linesearch context
1389: .  X - Solution vector
1390: .  F - Function vector
1391: .  Y - Search direction vector
1392: .  W - Solution work vector
1393: -  G - Function work vector

1395:    Level: advanced

1397: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1398: @*/
1399: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1400: {
1403:   if (X) {
1405:     linesearch->vec_sol = X;
1406:   }
1407:   if (F) {
1409:     linesearch->vec_func = F;
1410:   }
1411:   if (Y) {
1413:     linesearch->vec_update = Y;
1414:   }
1415:   if (W) {
1417:     linesearch->vec_sol_new = W;
1418:   }
1419:   if (G) {
1421:     linesearch->vec_func_new = G;
1422:   }
1423:   return(0);
1424: }

1428: /*@C
1429:    SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1430:    SNES options in the database.

1432:    Logically Collective on SNESLineSearch

1434:    Input Parameters:
1435: +  snes - the SNES context
1436: -  prefix - the prefix to prepend to all option names

1438:    Notes:
1439:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1440:    The first character of all runtime options is AUTOMATICALLY the hyphen.

1442:    Level: advanced

1444: .keywords: SNESLineSearch, append, options, prefix, database

1446: .seealso: SNESGetOptionsPrefix()
1447: @*/
1448: PetscErrorCode  SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1449: {

1454:   PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1455:   return(0);
1456: }

1460: /*@C
1461:    SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1462:    SNESLineSearch options in the database.

1464:    Not Collective

1466:    Input Parameter:
1467: .  linesearch - the SNESLineSearch context

1469:    Output Parameter:
1470: .  prefix - pointer to the prefix string used

1472:    Notes:
1473:    On the fortran side, the user should pass in a string 'prefix' of
1474:    sufficient length to hold the prefix.

1476:    Level: advanced

1478: .keywords: SNESLineSearch, get, options, prefix, database

1480: .seealso: SNESAppendOptionsPrefix()
1481: @*/
1482: PetscErrorCode  SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1483: {

1488:   PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1489:   return(0);
1490: }

1494: /*@C
1495:    SNESLineSearchSetWorkVecs - Gets work vectors for the line search.

1497:    Input Parameter:
1498: +  linesearch - the SNESLineSearch context
1499: -  nwork - the number of work vectors

1501:    Level: developer

1503:    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations

1505: .keywords: SNESLineSearch, work, vector

1507: .seealso: SNESSetWorkVecs()
1508: @*/
1509: PetscErrorCode  SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1510: {

1514:   if (linesearch->vec_sol) {
1515:     VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1516:   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1517:   return(0);
1518: }

1522: /*@
1523:    SNESLineSearchGetSuccess - Gets the success/failure status of the last line search application

1525:    Input Parameters:
1526: .  linesearch - linesearch context

1528:    Output Parameters:
1529: .  success - The success or failure status

1531:    Notes:
1532:    This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1533:    (and set the SNES convergence accordingly).

1535:    Level: intermediate

1537: .seealso: SNESLineSearchSetSuccess()
1538: @*/
1539: PetscErrorCode  SNESLineSearchGetSuccess(SNESLineSearch linesearch, PetscBool *success)
1540: {
1544:   if (success) *success = linesearch->success;
1545:   return(0);
1546: }

1550: /*@
1551:    SNESLineSearchSetSuccess - Sets the success/failure status of the last line search application

1553:    Input Parameters:
1554: +  linesearch - linesearch context
1555: -  success - The success or failure status

1557:    Notes:
1558:    This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1559:    the success or failure of the line search method.

1561:    Level: developer

1563: .seealso: SNESLineSearchGetSuccess()
1564: @*/
1565: PetscErrorCode  SNESLineSearchSetSuccess(SNESLineSearch linesearch, PetscBool success)
1566: {
1569:   linesearch->success = success;
1570:   return(0);
1571: }

1575: /*@C
1576:    SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.

1578:    Input Parameters:
1579: +  snes - nonlinear context obtained from SNESCreate()
1580: .  projectfunc - function for projecting the function to the bounds
1581: -  normfunc - function for computing the norm of an active set

1583:    Logically Collective on SNES

1585:    Calling sequence of projectfunc:
1586: .vb
1587:    projectfunc (SNES snes, Vec X)
1588: .ve

1590:     Input parameters for projectfunc:
1591: +   snes - nonlinear context
1592: -   X - current solution

1594:     Output parameters for projectfunc:
1595: .   X - Projected solution

1597:    Calling sequence of normfunc:
1598: .vb
1599:    projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1600: .ve

1602:     Input parameters for normfunc:
1603: +   snes - nonlinear context
1604: .   X - current solution
1605: -   F - current residual

1607:     Output parameters for normfunc:
1608: .   fnorm - VI-specific norm of the function

1610:     Notes:
1611:     The VI solvers require projection of the solution to the feasible set.  projectfunc should implement this.

1613:     The VI solvers require special evaluation of the function norm such that the norm is only calculated
1614:     on the inactive set.  This should be implemented by normfunc.

1616:     Level: developer

1618: .keywords: SNES, line search, VI, nonlinear, set, line search

1620: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1621: @*/
1622: extern PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1623: {
1626:   if (projectfunc) linesearch->ops->viproject = projectfunc;
1627:   if (normfunc) linesearch->ops->vinorm = normfunc;
1628:   return(0);
1629: }

1633: /*@C
1634:    SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.

1636:    Input Parameters:
1637: .  snes - nonlinear context obtained from SNESCreate()

1639:    Output Parameters:
1640: +  projectfunc - function for projecting the function to the bounds
1641: -  normfunc - function for computing the norm of an active set

1643:    Logically Collective on SNES

1645:     Level: developer

1647: .keywords: SNES, line search, VI, nonlinear, get, line search

1649: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1650: @*/
1651: extern PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1652: {
1654:   if (projectfunc) *projectfunc = linesearch->ops->viproject;
1655:   if (normfunc) *normfunc = linesearch->ops->vinorm;
1656:   return(0);
1657: }

1661: /*@C
1662:   SNESLineSearchRegister - See SNESLineSearchRegister()

1664:   Level: advanced
1665: @*/
1666: PetscErrorCode  SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1667: {

1671:   PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1672:   return(0);
1673: }