Actual source code: linesearch.c

petsc-3.9.0 2018-04-07
Report Typos and Errors
  1:  #include <petsc/private/linesearchimpl.h>

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

  6: PetscClassId  SNESLINESEARCH_CLASSID;
  7: PetscLogEvent SNESLINESEARCH_Apply;

  9: /*@
 10:    SNESLineSearchMonitorCancel - Clears all the monitor functions for a SNESLineSearch object.

 12:    Logically Collective on SNESLineSearch

 14:    Input Parameters:
 15: .  ls - the SNESLineSearch context

 17:    Options Database Key:
 18: .  -snes_linesearch_monitor_cancel - cancels all monitors that have been hardwired
 19:     into a code by calls to SNESLineSearchMonitorSet(), but does not cancel those
 20:     set via the options database

 22:    Notes:
 23:    There is no way to clear one specific monitor from a SNESLineSearch object.

 25:    This does not clear the monitor set with SNESLineSearchSetDefaultMonitor() use SNESLineSearchSetDefaultMonitor(ls,NULL) to cancel
 26:    that one.

 28:    Level: intermediate

 30: .keywords: SNESLineSearch, nonlinear, set, monitor

 32: .seealso: SNESLineSearchMonitorDefault(), SNESLineSearchMonitorSet()
 33: @*/
 34: PetscErrorCode  SNESLineSearchMonitorCancel(SNESLineSearch ls)
 35: {
 37:   PetscInt       i;

 41:   for (i=0; i<ls->numbermonitors; i++) {
 42:     if (ls->monitordestroy[i]) {
 43:       (*ls->monitordestroy[i])(&ls->monitorcontext[i]);
 44:     }
 45:   }
 46:   ls->numbermonitors = 0;
 47:   return(0);
 48: }

 50: /*@
 51:    SNESLineSearchMonitor - runs the user provided monitor routines, if they exist

 53:    Collective on SNES

 55:    Input Parameters:
 56: .  ls - the linesearch object

 58:    Notes:
 59:    This routine is called by the SNES implementations.
 60:    It does not typically need to be called by the user.

 62:    Level: developer

 64: .seealso: SNESLineSearchMonitorSet()
 65: @*/
 66: PetscErrorCode  SNESLineSearchMonitor(SNESLineSearch ls)
 67: {
 69:   PetscInt       i,n = ls->numbermonitors;

 72:   for (i=0; i<n; i++) {
 73:     (*ls->monitorftns[i])(ls,ls->monitorcontext[i]);
 74:   }
 75:   return(0);
 76: }

 78: /*@C
 79:    SNESLineSearchMonitorSet - Sets an ADDITIONAL function that is to be used at every
 80:    iteration of the nonlinear solver to display the iteration's
 81:    progress.

 83:    Logically Collective on SNESLineSearch

 85:    Input Parameters:
 86: +  ls - the SNESLineSearch context
 87: .  f - the monitor function
 88: .  mctx - [optional] user-defined context for private data for the
 89:           monitor routine (use NULL if no context is desired)
 90: -  monitordestroy - [optional] routine that frees monitor context
 91:           (may be NULL)

 93:    Notes:
 94:    Several different monitoring routines may be set by calling
 95:    SNESLineSearchMonitorSet() multiple times; all will be called in the
 96:    order in which they were set.

 98:    Fortran notes: Only a single monitor function can be set for each SNESLineSearch object

100:    Level: intermediate

102: .keywords: SNESLineSearch, nonlinear, set, monitor

104: .seealso: SNESLineSearchMonitorDefault(), SNESLineSearchMonitorCancel()
105: @*/
106: PetscErrorCode  SNESLineSearchMonitorSet(SNESLineSearch ls,PetscErrorCode (*f)(SNESLineSearch,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
107: {
109:   PetscInt       i;
110:   PetscBool      identical;

114:   for (i=0; i<ls->numbermonitors;i++) {
115:     PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))ls->monitorftns[i],ls->monitorcontext[i],ls->monitordestroy[i],&identical);
116:     if (identical) return(0);
117:   }
118:   if (ls->numbermonitors >= MAXSNESLSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
119:   ls->monitorftns[ls->numbermonitors]          = f;
120:   ls->monitordestroy[ls->numbermonitors]   = monitordestroy;
121:   ls->monitorcontext[ls->numbermonitors++] = (void*)mctx;
122:   return(0);
123: }

125: /*@C
126:    SNESLineSearchMonitorSolutionUpdate - Monitors each update a new function value the linesearch tries

128:    Collective on SNESLineSearch

130:    Input Parameters:
131: +  ls - the SNES linesearch object
132: -  vf - the context for the monitor, in this case it is an ASCII PetscViewer and format

134:    Level: intermediate

136: .keywords: SNES, nonlinear, default, monitor, norm

138: .seealso: SNESMonitorSet(), SNESMonitorSolution()
139: @*/
140: PetscErrorCode  SNESLineSearchMonitorSolutionUpdate(SNESLineSearch ls,PetscViewerAndFormat *vf)
141: {
143:   PetscViewer    viewer = vf->viewer;
144:   Vec            Y,W,G;

147:   SNESLineSearchGetVecs(ls,NULL,NULL,&Y,&W,&G);
148:   PetscViewerPushFormat(viewer,vf->format);
149:   PetscViewerASCIIPrintf(viewer,"LineSearch attempted update to solution \n");
150:   VecView(Y,viewer);
151:   PetscViewerASCIIPrintf(viewer,"LineSearch attempted new solution \n");
152:   VecView(W,viewer);
153:   PetscViewerASCIIPrintf(viewer,"LineSearch attempted updated function value\n");
154:   VecView(G,viewer);
155:   PetscViewerPopFormat(viewer);
156:   return(0);
157: }

159: /*@
160:    SNESLineSearchCreate - Creates the line search context.

162:    Logically Collective on Comm

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

167:    Output Parameters:
168: .  outlinesearch - the new linesearch context

170:    Level: developer

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.

176: .keywords: LineSearch, create, context

178: .seealso: LineSearchDestroy(), SNESGetLineSearch()
179: @*/

181: PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
182: {
184:   SNESLineSearch linesearch;

188:   SNESInitializePackage();
189:   *outlinesearch = NULL;

191:   PetscHeaderCreate(linesearch,SNESLINESEARCH_CLASSID, "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView);

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;

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:   return(0);
218: }

220: /*@
221:    SNESLineSearchSetUp - Prepares the line search for being applied by allocating
222:    any required vectors.

224:    Collective on SNESLineSearch

226:    Input Parameters:
227: .  linesearch - The LineSearch instance.

229:    Notes:
230:    For most cases, this needn't be called by users or outside of SNESLineSearchApply().
231:    The only current case where this is called outside of this is for the VI
232:    solvers, which modify the solution and work vectors before the first call
233:    of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be
234:    allocated upfront.

236:    Level: advanced

238: .keywords: SNESLineSearch, SetUp

240: .seealso: SNESLineSearchReset()
241: @*/

243: PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
244: {

248:   if (!((PetscObject)linesearch)->type_name) {
249:     SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);
250:   }
251:   if (!linesearch->setupcalled) {
252:     if (!linesearch->vec_sol_new) {
253:       VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);
254:     }
255:     if (!linesearch->vec_func_new) {
256:       VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);
257:     }
258:     if (linesearch->ops->setup) {
259:       (*linesearch->ops->setup)(linesearch);
260:     }
261:     if (!linesearch->ops->snesfunc) {SNESLineSearchSetFunction(linesearch,SNESComputeFunction);}
262:     linesearch->lambda      = linesearch->damping;
263:     linesearch->setupcalled = PETSC_TRUE;
264:   }
265:   return(0);
266: }


269: /*@
270:    SNESLineSearchReset - Undoes the SNESLineSearchSetUp() and deletes any Vecs or Mats allocated by the line search.

272:    Collective on SNESLineSearch

274:    Input Parameters:
275: .  linesearch - The LineSearch instance.

277:    Notes: Usually only called by SNESReset()

279:    Level: developer

281: .keywords: SNESLineSearch, Reset

283: .seealso: SNESLineSearchSetUp()
284: @*/

286: PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
287: {

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

293:   VecDestroy(&linesearch->vec_sol_new);
294:   VecDestroy(&linesearch->vec_func_new);

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

298:   linesearch->nwork       = 0;
299:   linesearch->setupcalled = PETSC_FALSE;
300:   return(0);
301: }

303: /*@C
304:    SNESLineSearchSetFunction - Sets the function evaluation used by the SNES line search

306:    Input Parameters:
307: .  linesearch - the SNESLineSearch context
308: +  func       - function evaluation routine

310:    Level: developer

312:    Notes: This is used internally by PETSc and not called by users

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

316: .seealso: SNESSetFunction()
317: @*/
318: PetscErrorCode  SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
319: {
322:   linesearch->ops->snesfunc = func;
323:   return(0);
324: }


327: /*MC
328:     SNESLineSearchPreCheckFunction - form of function passed to check the search direction before line search is called

330:      Synopsis:
331:      #include <petscsnes.h>
332:      SNESLineSearchPreCheckFunction(SNESLineSearch snes,Vec x,Vec y, PetscBool *changed);

334:        Input Parameters:
335: +      x - solution vector
336: .      y - search direction vector
337: -      changed - flag to indicate the precheck changed x or y.

339:      Note: This is NOTE a PETSc function, rather it documents the calling sequence of functions passed to SNESLineSearchSetPreCheck()
340:            and SNESLineSearchGetPreCheck()

342:    Level: advanced

344: .seealso:   SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck()
345: M*/

347: /*@C
348:    SNESLineSearchSetPreCheck - Sets a user function that is called after the initial search direction has been computed but
349:          before the line search routine has been applied. Allows the user to adjust the result of (usually a linear solve) that
350:          determined the search direction.

352:    Logically Collective on SNESLineSearch

354:    Input Parameters:
355: +  linesearch - the SNESLineSearch context
356: .  func - [optional] function evaluation routine, see SNESLineSearchPreCheckFunction for the calling sequence
357: -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)

359:    Level: intermediate

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

363: .seealso: SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
364: @*/
365: PetscErrorCode  SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
366: {
369:   if (func) linesearch->ops->precheck = func;
370:   if (ctx) linesearch->precheckctx = ctx;
371:   return(0);
372: }

374: /*@C
375:    SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine.

377:    Input Parameters:
378: .  linesearch - the SNESLineSearch context

380:    Output Parameters:
381: +  func       - [optional] function evaluation routine, see SNESLineSearchPreCheckFunction for calling sequence
382: -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)

384:    Level: intermediate

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

388: .seealso: SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck()
389: @*/
390: PetscErrorCode  SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
391: {
394:   if (func) *func = linesearch->ops->precheck;
395:   if (ctx) *ctx = linesearch->precheckctx;
396:   return(0);
397: }

399: /*MC
400:     SNESLineSearchPostCheckFunction - form of function that is called after line search is complete

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

406:      Input Parameters:
407: +      x - old solution vector
408: .      y - search direction vector
409: .      w - new solution vector
410: .      changed_y - indicates that the line search changed y
411: -      changed_w - indicates that the line search changed w

413:      Note: This is NOTE a PETSc function, rather it documents the calling sequence of functions passed to SNESLineSearchSetPostCheck()
414:            and SNESLineSearchGetPostCheck()

416:    Level: advanced

418: .seealso:   SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchGetPostCheck()
419: M*/

421: /*@C
422:    SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step
423:        direction and length. Allows the user a chance to change or override the decision of the line search routine

425:    Logically Collective on SNESLineSearch

427:    Input Parameters:
428: +  linesearch - the SNESLineSearch context
429: .  func - [optional] function evaluation routine, see SNESLineSearchPostCheckFunction for the calling sequence
430: -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)

432:    Level: intermediate

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

436: .seealso: SNESLineSearchSetPreCheck()
437: @*/
438: PetscErrorCode  SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
439: {
442:   if (func) linesearch->ops->postcheck = func;
443:   if (ctx) linesearch->postcheckctx = ctx;
444:   return(0);
445: }

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

450:    Input Parameters:
451: .  linesearch - the SNESLineSearch context

453:    Output Parameters:
454: +  func - [optional] function evaluation routine, see for the calling sequence SNESLineSearchPostCheckFunction
455: -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)

457:    Level: intermediate

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

461: .seealso: SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck()
462: @*/
463: PetscErrorCode  SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
464: {
467:   if (func) *func = linesearch->ops->postcheck;
468:   if (ctx) *ctx = linesearch->postcheckctx;
469:   return(0);
470: }

472: /*@
473:    SNESLineSearchPreCheck - Prepares the line search for being applied.

475:    Logically Collective on SNESLineSearch

477:    Input Parameters:
478: +  linesearch - The linesearch instance.
479: .  X - The current solution
480: -  Y - The step direction

482:    Output Parameters:
483: .  changed - Indicator that the precheck routine has changed anything

485:    Level: developer

487: .keywords: SNESLineSearch, Create

489: .seealso: SNESLineSearchPostCheck()
490: @*/
491: PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
492: {

496:   *changed = PETSC_FALSE;
497:   if (linesearch->ops->precheck) {
498:     (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);
500:   }
501:   return(0);
502: }

504: /*@
505:    SNESLineSearchPostCheck - Prepares the line search for being applied.

507:    Logically Collective on SNESLineSearch

509:    Input Parameters:
510: +  linesearch - The linesearch context
511: .  X - The last solution
512: .  Y - The step direction
513: -  W - The updated solution, W = X + lambda*Y for some lambda

515:    Output Parameters:
516: +  changed_Y - Indicator if the direction Y has been changed.
517: -  changed_W - Indicator if the new candidate solution W has been changed.

519:    Level: developer

521: .keywords: SNESLineSearch, Create

523: .seealso: SNESLineSearchPreCheck()
524: @*/
525: PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
526: {

530:   *changed_Y = PETSC_FALSE;
531:   *changed_W = PETSC_FALSE;
532:   if (linesearch->ops->postcheck) {
533:     (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);
536:   }
537:   return(0);
538: }

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

543:    Logically Collective on SNESLineSearch

545:    Input Arguments:
546: +  linesearch - linesearch context
547: .  X - base state for this step
548: .  Y - initial correction
549: -  ctx - context for this function

551:    Output Arguments:
552: +  Y - correction, possibly modified
553: -  changed - flag indicating that Y was modified

555:    Options Database Key:
556: +  -snes_linesearch_precheck_picard - activate this routine
557: -  -snes_linesearch_precheck_picard_angle - angle

559:    Level: advanced

561:    Notes:
562:    This function should be passed to SNESLineSearchSetPreCheck()

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

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

571: .seealso: SNESLineSearchSetPreCheck()
572: @*/
573: PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
574: {
576:   PetscReal      angle = *(PetscReal*)linesearch->precheckctx;
577:   Vec            Ylast;
578:   PetscScalar    dot;
579:   PetscInt       iter;
580:   PetscReal      ynorm,ylastnorm,theta,angle_radians;
581:   SNES           snes;

584:   SNESLineSearchGetSNES(linesearch, &snes);
585:   PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);
586:   if (!Ylast) {
587:     VecDuplicate(Y,&Ylast);
588:     PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);
589:     PetscObjectDereference((PetscObject)Ylast);
590:   }
591:   SNESGetIterationNumber(snes,&iter);
592:   if (iter < 2) {
593:     VecCopy(Y,Ylast);
594:     *changed = PETSC_FALSE;
595:     return(0);
596:   }

598:   VecDot(Y,Ylast,&dot);
599:   VecNorm(Y,NORM_2,&ynorm);
600:   VecNorm(Ylast,NORM_2,&ylastnorm);
601:   /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
602:   theta         = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
603:   angle_radians = angle * PETSC_PI / 180.;
604:   if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
605:     /* Modify the step Y */
606:     PetscReal alpha,ydiffnorm;
607:     VecAXPY(Ylast,-1.0,Y);
608:     VecNorm(Ylast,NORM_2,&ydiffnorm);
609:     alpha = ylastnorm / ydiffnorm;
610:     VecCopy(Y,Ylast);
611:     VecScale(Y,alpha);
612:     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);
613:   } else {
614:     PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);
615:     VecCopy(Y,Ylast);
616:     *changed = PETSC_FALSE;
617:   }
618:   return(0);
619: }

621: /*@
622:    SNESLineSearchApply - Computes the line-search update.

624:    Collective on SNESLineSearch

626:    Input Parameters:
627: +  linesearch - The linesearch context
628: .  X - The current solution
629: .  F - The current function
630: .  fnorm - The current norm
631: -  Y - The search direction

633:    Output Parameters:
634: +  X - The new solution
635: .  F - The new function
636: -  fnorm - The new function norm

638:    Options Database Keys:
639: + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell
640: . -snes_linesearch_monitor [:filename] - Print progress of line searches
641: . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping)
642: . -snes_linesearch_norms   - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms())
643: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
644: - -snes_linesearch_max_it - The number of iterations for iterative line searches

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

654:    Level: Intermediate

656: .keywords: SNESLineSearch, Create

658: .seealso: SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(),
659:           SNESLineSearchType, SNESLineSearchSetType()
660: @*/
661: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
662: {


671:   linesearch->result = SNES_LINESEARCH_SUCCEEDED;

673:   linesearch->vec_sol    = X;
674:   linesearch->vec_update = Y;
675:   linesearch->vec_func   = F;

677:   SNESLineSearchSetUp(linesearch);

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

681:   if (fnorm) linesearch->fnorm = *fnorm;
682:   else {
683:     VecNorm(F, NORM_2, &linesearch->fnorm);
684:   }

686:   PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y);

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

690:   PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y);

692:   if (fnorm) *fnorm = linesearch->fnorm;
693:   return(0);
694: }

696: /*@
697:    SNESLineSearchDestroy - Destroys the line search instance.

699:    Collective on SNESLineSearch

701:    Input Parameters:
702: .  linesearch - The linesearch context

704:    Level: Intermediate

706: .keywords: SNESLineSearch, Destroy

708: .seealso: SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
709: @*/
710: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
711: {

715:   if (!*linesearch) return(0);
717:   if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; return(0);}
718:   PetscObjectSAWsViewOff((PetscObject)*linesearch);
719:   SNESLineSearchReset(*linesearch);
720:   if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
721:   PetscViewerDestroy(&(*linesearch)->monitor);
722:   SNESLineSearchMonitorCancel((*linesearch));
723:   PetscHeaderDestroy(linesearch);
724:   return(0);
725: }

727: /*@
728:    SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.

730:    Input Parameters:
731: +  linesearch - the linesearch object
732: -  viewer - an ASCII PetscViewer or NULL to turn off monitor

734:    Logically Collective on SNESLineSearch

736:    Options Database:
737: .   -snes_linesearch_monitor [:filename] - enables the monitor

739:    Level: intermediate

741:    Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with
742:      SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the
743:      line search that are not visible to the other monitors.

745: .seealso: SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor()
746: @*/
747: PetscErrorCode  SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
748: {

752:   if (viewer) {PetscObjectReference((PetscObject)viewer);}
753:   PetscViewerDestroy(&linesearch->monitor);
754:   linesearch->monitor = viewer;
755:   return(0);
756: }

758: /*@
759:    SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.

761:    Input Parameter:
762: .  linesearch - linesearch context

764:    Output Parameter:
765: .  monitor - monitor context

767:    Logically Collective on SNES

769:    Options Database Keys:
770: .   -snes_linesearch_monitor - enables the monitor

772:    Level: intermediate

774: .seealso: SNESLineSearchSetDefaultMonitor(), PetscViewer
775: @*/
776: PetscErrorCode  SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
777: {
780:   if (monitor) {
782:     *monitor = linesearch->monitor;
783:   }
784:   return(0);
785: }

787: /*@C
788:    SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user

790:    Collective on SNESLineSearch

792:    Input Parameters:
793: +  ls - LineSearch object you wish to monitor
794: .  name - the monitor type one is seeking
795: .  help - message indicating what monitoring is done
796: .  manual - manual page for the monitor
797: .  monitor - the monitor function
798: -  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

800:    Level: developer

802: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
803:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
804:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
805:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
806:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
807:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
808:           PetscOptionsFList(), PetscOptionsEList()
809: @*/
810: PetscErrorCode  SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
811: {
812:   PetscErrorCode    ierr;
813:   PetscViewer       viewer;
814:   PetscViewerFormat format;
815:   PetscBool         flg;

818:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject)ls)->prefix,name,&viewer,&format,&flg);
819:   if (flg) {
820:     PetscViewerAndFormat *vf;
821:     PetscViewerAndFormatCreate(viewer,format,&vf);
822:     PetscObjectDereference((PetscObject)viewer);
823:     if (monitorsetup) {
824:       (*monitorsetup)(ls,vf);
825:     }
826:     SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
827:   }
828:   return(0);
829: }

831: /*@
832:    SNESLineSearchSetFromOptions - Sets options for the line search

834:    Input Parameters:
835: .  linesearch - linesearch context

837:    Options Database Keys:
838: + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
839: . -snes_linesearch_order <order> - 1, 2, 3.  Most types only support certain orders (bt supports 2 or 3)
840: . -snes_linesearch_norms   - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms())
841: . -snes_linesearch_minlambda - The minimum step length
842: . -snes_linesearch_maxstep - The maximum step size
843: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
844: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
845: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
846: . -snes_linesearch_max_it - The number of iterations for iterative line searches
847: . -snes_linesearch_monitor [:filename] - Print progress of line searches
848: . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
849: . -snes_linesearch_damping - The linesearch damping parameter
850: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
851: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
852: - -snes_linesearch_precheck_picard_angle - Angle used in picard precheck method

854:    Logically Collective on SNESLineSearch

856:    Level: intermediate

858: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(),
859:           SNESLineSearchType, SNESLineSearchSetComputeNorms()
860: @*/
861: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
862: {
863:   PetscErrorCode    ierr;
864:   const char        *deft = SNESLINESEARCHBASIC;
865:   char              type[256];
866:   PetscBool         flg, set;
867:   PetscViewer       viewer;

870:   SNESLineSearchRegisterAll();

872:   PetscObjectOptionsBegin((PetscObject)linesearch);
873:   if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
874:   PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
875:   if (flg) {
876:     SNESLineSearchSetType(linesearch,type);
877:   } else if (!((PetscObject)linesearch)->type_name) {
878:     SNESLineSearchSetType(linesearch,deft);
879:   }

881:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);
882:   if (set) {
883:     SNESLineSearchSetDefaultMonitor(linesearch,viewer);
884:     PetscViewerDestroy(&viewer);
885:   }
886:   SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);

888:   /* tolerances */
889:   PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);
890:   PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);
891:   PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);
892:   PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);
893:   PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);
894:   PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);

896:   /* damping parameters */
897:   PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);

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

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

907:       PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
908:                               "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);
909:       SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
910:     } else {
911:       SNESLineSearchSetPreCheck(linesearch,NULL,NULL);
912:     }
913:   }
914:   PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);
915:   PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);

917:   if (linesearch->ops->setfromoptions) {
918:     (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);
919:   }

921:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);
922:   PetscOptionsEnd();
923:   return(0);
924: }

926: /*@
927:    SNESLineSearchView - Prints useful information about the line search

929:    Input Parameters:
930: .  linesearch - linesearch context

932:    Logically Collective on SNESLineSearch

934:    Level: intermediate

936: .seealso: SNESLineSearchCreate()
937: @*/
938: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
939: {
941:   PetscBool      iascii;

945:   if (!viewer) {
946:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);
947:   }

951:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
952:   if (iascii) {
953:     PetscInt     tabs;
954:     PetscViewerASCIIGetTab(viewer, &tabs);
955:     PetscViewerASCIISetTab(viewer, ((PetscObject)linesearch)->tablevel);
956:     PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);
957:     if (linesearch->ops->view) {
958:       PetscViewerASCIIPushTab(viewer);
959:       (*linesearch->ops->view)(linesearch,viewer);
960:       PetscViewerASCIIPopTab(viewer);
961:     }
962:     PetscViewerASCIIPrintf(viewer,"  maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);
963:     PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);
964:     PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D\n", linesearch->max_its);
965:     if (linesearch->ops->precheck) {
966:       if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
967:         PetscViewerASCIIPrintf(viewer,"  using precheck step to speed up Picard convergence\n", linesearch->max_its);
968:       } else {
969:         PetscViewerASCIIPrintf(viewer,"  using user-defined precheck step\n", linesearch->max_its);
970:       }
971:     }
972:     if (linesearch->ops->postcheck) {
973:       PetscViewerASCIIPrintf(viewer,"  using user-defined postcheck step\n", linesearch->max_its);
974:     }
975:     PetscViewerASCIISetTab(viewer, tabs);
976:   }
977:   return(0);
978: }

980: /*@C
981:    SNESLineSearchSetType - Sets the linesearch type

983:    Logically Collective on SNESLineSearch

985:    Input Parameters:
986: +  linesearch - linesearch context
987: -  type - The type of line search to be used

989:    Available Types:
990: +  SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
991: .  SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
992: .  SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
993: .  SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
994: .  SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
995: -  SNESLINESEARCHSHELL - User provided SNESLineSearch implementation

997:    Options Database:
998: .  -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell

1000:    Level: intermediate

1002: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions()
1003: @*/
1004: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
1005: {
1006:   PetscErrorCode ierr,(*r)(SNESLineSearch);
1007:   PetscBool      match;


1013:   PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
1014:   if (match) return(0);

1016:   PetscFunctionListFind(SNESLineSearchList,type,&r);
1017:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
1018:   /* Destroy the previous private linesearch context */
1019:   if (linesearch->ops->destroy) {
1020:     (*(linesearch)->ops->destroy)(linesearch);

1022:     linesearch->ops->destroy = NULL;
1023:   }
1024:   /* Reinitialize function pointers in SNESLineSearchOps structure */
1025:   linesearch->ops->apply          = 0;
1026:   linesearch->ops->view           = 0;
1027:   linesearch->ops->setfromoptions = 0;
1028:   linesearch->ops->destroy        = 0;

1030:   PetscObjectChangeTypeName((PetscObject)linesearch,type);
1031:   (*r)(linesearch);
1032:   return(0);
1033: }

1035: /*@
1036:    SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.

1038:    Input Parameters:
1039: +  linesearch - linesearch context
1040: -  snes - The snes instance

1042:    Level: developer

1044:    Notes:
1045:    This happens automatically when the line search is obtained/created with
1046:    SNESGetLineSearch().  This routine is therefore mainly called within SNES
1047:    implementations.

1049:    Level: developer

1051: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1052: @*/
1053: PetscErrorCode  SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
1054: {
1058:   linesearch->snes = snes;
1059:   return(0);
1060: }

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

1068:    Input Parameters:
1069: .  linesearch - linesearch context

1071:    Output Parameters:
1072: .  snes - The snes instance

1074:    Level: developer

1076: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1077: @*/
1078: PetscErrorCode  SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1079: {
1083:   *snes = linesearch->snes;
1084:   return(0);
1085: }

1087: /*@
1088:    SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.

1090:    Input Parameters:
1091: .  linesearch - linesearch context

1093:    Output Parameters:
1094: .  lambda - The last steplength computed during SNESLineSearchApply()

1096:    Level: advanced

1098:    Notes:
1099:    This is useful in methods where the solver is ill-scaled and
1100:    requires some adaptive notion of the difference in scale between the
1101:    solution and the function.  For instance, SNESQN may be scaled by the
1102:    line search lambda using the argument -snes_qn_scaling ls.

1104: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1105: @*/
1106: PetscErrorCode  SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1107: {
1111:   *lambda = linesearch->lambda;
1112:   return(0);
1113: }

1115: /*@
1116:    SNESLineSearchSetLambda - Sets the linesearch steplength.

1118:    Input Parameters:
1119: +  linesearch - linesearch context
1120: -  lambda - The last steplength.

1122:    Notes:
1123:    This routine is typically used within implementations of SNESLineSearchApply()
1124:    to set the final steplength.  This routine (and SNESLineSearchGetLambda()) were
1125:    added in order to facilitate Quasi-Newton methods that use the previous steplength
1126:    as an inner scaling parameter.

1128:    Level: advanced

1130: .seealso: SNESLineSearchGetLambda()
1131: @*/
1132: PetscErrorCode  SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1133: {
1136:   linesearch->lambda = lambda;
1137:   return(0);
1138: }

1140: /*@
1141:    SNESLineSearchGetTolerances - Gets the tolerances for the linesearch.  These include
1142:    tolerances for the relative and absolute change in the function norm, the change
1143:    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1144:    and the maximum number of iterations the line search procedure may take.

1146:    Input Parameters:
1147: .  linesearch - linesearch context

1149:    Output Parameters:
1150: +  steptol - The minimum steplength
1151: .  maxstep - The maximum steplength
1152: .  rtol    - The relative tolerance for iterative line searches
1153: .  atol    - The absolute tolerance for iterative line searches
1154: .  ltol    - The change in lambda tolerance for iterative line searches
1155: -  max_it  - The maximum number of iterations of the line search

1157:    Level: intermediate

1159:    Notes:
1160:    Different line searches may implement these parameters slightly differently as
1161:    the type requires.

1163: .seealso: SNESLineSearchSetTolerances()
1164: @*/
1165: PetscErrorCode  SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1166: {
1169:   if (steptol) {
1171:     *steptol = linesearch->steptol;
1172:   }
1173:   if (maxstep) {
1175:     *maxstep = linesearch->maxstep;
1176:   }
1177:   if (rtol) {
1179:     *rtol = linesearch->rtol;
1180:   }
1181:   if (atol) {
1183:     *atol = linesearch->atol;
1184:   }
1185:   if (ltol) {
1187:     *ltol = linesearch->ltol;
1188:   }
1189:   if (max_its) {
1191:     *max_its = linesearch->max_its;
1192:   }
1193:   return(0);
1194: }

1196: /*@
1197:    SNESLineSearchSetTolerances -  Gets the tolerances for the linesearch.  These include
1198:    tolerances for the relative and absolute change in the function norm, the change
1199:    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1200:    and the maximum number of iterations the line search procedure may take.

1202:    Input Parameters:
1203: +  linesearch - linesearch context
1204: .  steptol - The minimum steplength
1205: .  maxstep - The maximum steplength
1206: .  rtol    - The relative tolerance for iterative line searches
1207: .  atol    - The absolute tolerance for iterative line searches
1208: .  ltol    - The change in lambda tolerance for iterative line searches
1209: -  max_it  - The maximum number of iterations of the line search

1211:    Notes:
1212:    The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1213:    place of an argument.

1215:    Level: intermediate

1217: .seealso: SNESLineSearchGetTolerances()
1218: @*/
1219: PetscErrorCode  SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1220: {

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

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

1240:   if (rtol != PETSC_DEFAULT) {
1241:     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);
1242:     linesearch->rtol = rtol;
1243:   }

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

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

1255:   if (max_its != PETSC_DEFAULT) {
1256:     if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1257:     linesearch->max_its = max_its;
1258:   }
1259:   return(0);
1260: }

1262: /*@
1263:    SNESLineSearchGetDamping - Gets the line search damping parameter.

1265:    Input Parameters:
1266: .  linesearch - linesearch context

1268:    Output Parameters:
1269: .  damping - The damping parameter

1271:    Level: advanced

1273: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1274: @*/

1276: PetscErrorCode  SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1277: {
1281:   *damping = linesearch->damping;
1282:   return(0);
1283: }

1285: /*@
1286:    SNESLineSearchSetDamping - Sets the line search damping paramter.

1288:    Input Parameters:
1289: +  linesearch - linesearch context
1290: -  damping - The damping parameter

1292:    Options Database:
1293: .   -snes_linesearch_damping
1294:    Level: intermediate

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

1303: .seealso: SNESLineSearchGetDamping()
1304: @*/
1305: PetscErrorCode  SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1306: {
1309:   linesearch->damping = damping;
1310:   return(0);
1311: }

1313: /*@
1314:    SNESLineSearchGetOrder - Gets the line search approximation order.

1316:    Input Parameters:
1317: .  linesearch - linesearch context

1319:    Output Parameters:
1320: .  order - The order

1322:    Possible Values for order:
1323: +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1324: .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1325: -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order

1327:    Level: intermediate

1329: .seealso: SNESLineSearchSetOrder()
1330: @*/

1332: PetscErrorCode  SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1333: {
1337:   *order = linesearch->order;
1338:   return(0);
1339: }

1341: /*@
1342:    SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search

1344:    Input Parameters:
1345: .  linesearch - linesearch context
1346: .  order - The damping parameter

1348:    Level: intermediate

1350:    Possible Values for order:
1351: +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1352: .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1353: -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order

1355:    Notes:
1356:    Variable orders are supported by the following line searches:
1357: +  bt - cubic and quadratic
1358: -  cp - linear and quadratic

1360: .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1361: @*/
1362: PetscErrorCode  SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1363: {
1366:   linesearch->order = order;
1367:   return(0);
1368: }

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

1373:    Input Parameters:
1374: .  linesearch - linesearch context

1376:    Output Parameters:
1377: +  xnorm - The norm of the current solution
1378: .  fnorm - The norm of the current function
1379: -  ynorm - The norm of the current update

1381:    Notes:
1382:    This function is mainly called from SNES implementations.

1384:    Level: developer

1386: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1387: @*/
1388: PetscErrorCode  SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1389: {
1392:   if (xnorm) *xnorm = linesearch->xnorm;
1393:   if (fnorm) *fnorm = linesearch->fnorm;
1394:   if (ynorm) *ynorm = linesearch->ynorm;
1395:   return(0);
1396: }

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

1401:    Input Parameters:
1402: +  linesearch - linesearch context
1403: .  xnorm - The norm of the current solution
1404: .  fnorm - The norm of the current function
1405: -  ynorm - The norm of the current update

1407:    Level: advanced

1409: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1410: @*/
1411: PetscErrorCode  SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1412: {
1415:   linesearch->xnorm = xnorm;
1416:   linesearch->fnorm = fnorm;
1417:   linesearch->ynorm = ynorm;
1418:   return(0);
1419: }

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

1424:    Input Parameters:
1425: .  linesearch - linesearch context

1427:    Options Database Keys:
1428: .   -snes_linesearch_norms - turn norm computation on or off

1430:    Level: intermediate

1432: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1433: @*/
1434: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1435: {
1437:   SNES           snes;

1440:   if (linesearch->norms) {
1441:     if (linesearch->ops->vinorm) {
1442:       SNESLineSearchGetSNES(linesearch, &snes);
1443:       VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1444:       VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1445:       (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1446:     } else {
1447:       VecNormBegin(linesearch->vec_func,   NORM_2, &linesearch->fnorm);
1448:       VecNormBegin(linesearch->vec_sol,    NORM_2, &linesearch->xnorm);
1449:       VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1450:       VecNormEnd(linesearch->vec_func,     NORM_2, &linesearch->fnorm);
1451:       VecNormEnd(linesearch->vec_sol,      NORM_2, &linesearch->xnorm);
1452:       VecNormEnd(linesearch->vec_update,   NORM_2, &linesearch->ynorm);
1453:     }
1454:   }
1455:   return(0);
1456: }

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

1461:    Input Parameters:
1462: +  linesearch  - linesearch context
1463: -  flg  - indicates whether or not to compute norms

1465:    Options Database Keys:
1466: .   -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch

1468:    Notes:
1469:    This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm.

1471:    Level: intermediate

1473: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1474: @*/
1475: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1476: {
1478:   linesearch->norms = flg;
1479:   return(0);
1480: }

1482: /*@
1483:    SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context

1485:    Input Parameters:
1486: .  linesearch - linesearch context

1488:    Output Parameters:
1489: +  X - Solution vector
1490: .  F - Function vector
1491: .  Y - Search direction vector
1492: .  W - Solution work vector
1493: -  G - Function work vector

1495:    Notes:
1496:    At the beginning of a line search application, X should contain a
1497:    solution and the vector F the function computed at X.  At the end of the
1498:    line search application, X should contain the new solution, and F the
1499:    function evaluated at the new solution.

1501:    These vectors are owned by the SNESLineSearch and should not be destroyed by the caller

1503:    Level: advanced

1505: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1506: @*/
1507: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1508: {
1511:   if (X) {
1513:     *X = linesearch->vec_sol;
1514:   }
1515:   if (F) {
1517:     *F = linesearch->vec_func;
1518:   }
1519:   if (Y) {
1521:     *Y = linesearch->vec_update;
1522:   }
1523:   if (W) {
1525:     *W = linesearch->vec_sol_new;
1526:   }
1527:   if (G) {
1529:     *G = linesearch->vec_func_new;
1530:   }
1531:   return(0);
1532: }

1534: /*@
1535:    SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context

1537:    Input Parameters:
1538: +  linesearch - linesearch context
1539: .  X - Solution vector
1540: .  F - Function vector
1541: .  Y - Search direction vector
1542: .  W - Solution work vector
1543: -  G - Function work vector

1545:    Level: advanced

1547: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1548: @*/
1549: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1550: {
1553:   if (X) {
1555:     linesearch->vec_sol = X;
1556:   }
1557:   if (F) {
1559:     linesearch->vec_func = F;
1560:   }
1561:   if (Y) {
1563:     linesearch->vec_update = Y;
1564:   }
1565:   if (W) {
1567:     linesearch->vec_sol_new = W;
1568:   }
1569:   if (G) {
1571:     linesearch->vec_func_new = G;
1572:   }
1573:   return(0);
1574: }

1576: /*@C
1577:    SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1578:    SNES options in the database.

1580:    Logically Collective on SNESLineSearch

1582:    Input Parameters:
1583: +  snes - the SNES context
1584: -  prefix - the prefix to prepend to all option names

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

1590:    Level: advanced

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

1594: .seealso: SNESGetOptionsPrefix()
1595: @*/
1596: PetscErrorCode  SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1597: {

1602:   PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1603:   return(0);
1604: }

1606: /*@C
1607:    SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1608:    SNESLineSearch options in the database.

1610:    Not Collective

1612:    Input Parameter:
1613: .  linesearch - the SNESLineSearch context

1615:    Output Parameter:
1616: .  prefix - pointer to the prefix string used

1618:    Notes:
1619:    On the fortran side, the user should pass in a string 'prefix' of
1620:    sufficient length to hold the prefix.

1622:    Level: advanced

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

1626: .seealso: SNESAppendOptionsPrefix()
1627: @*/
1628: PetscErrorCode  SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1629: {

1634:   PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1635:   return(0);
1636: }

1638: /*@C
1639:    SNESLineSearchSetWorkVecs - Gets work vectors for the line search.

1641:    Input Parameter:
1642: +  linesearch - the SNESLineSearch context
1643: -  nwork - the number of work vectors

1645:    Level: developer

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

1649: .keywords: SNESLineSearch, work, vector

1651: .seealso: SNESSetWorkVecs()
1652: @*/
1653: PetscErrorCode  SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1654: {

1658:   if (linesearch->vec_sol) {
1659:     VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1660:   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1661:   return(0);
1662: }

1664: /*@
1665:    SNESLineSearchGetReason - Gets the success/failure status of the last line search application

1667:    Input Parameters:
1668: .  linesearch - linesearch context

1670:    Output Parameters:
1671: .  result - The success or failure status

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

1677:    Level: intermediate

1679: .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1680: @*/
1681: PetscErrorCode  SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1682: {
1686:   *result = linesearch->result;
1687:   return(0);
1688: }

1690: /*@
1691:    SNESLineSearchSetReason - Sets the success/failure status of the last line search application

1693:    Input Parameters:
1694: +  linesearch - linesearch context
1695: -  result - The success or failure status

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

1701:    Level: developer

1703: .seealso: SNESLineSearchGetSResult()
1704: @*/
1705: PetscErrorCode  SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1706: {
1709:   linesearch->result = result;
1710:   return(0);
1711: }

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

1716:    Input Parameters:
1717: +  snes - nonlinear context obtained from SNESCreate()
1718: .  projectfunc - function for projecting the function to the bounds
1719: -  normfunc - function for computing the norm of an active set

1721:    Logically Collective on SNES

1723:    Calling sequence of projectfunc:
1724: .vb
1725:    projectfunc (SNES snes, Vec X)
1726: .ve

1728:     Input parameters for projectfunc:
1729: +   snes - nonlinear context
1730: -   X - current solution

1732:     Output parameters for projectfunc:
1733: .   X - Projected solution

1735:    Calling sequence of normfunc:
1736: .vb
1737:    projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1738: .ve

1740:     Input parameters for normfunc:
1741: +   snes - nonlinear context
1742: .   X - current solution
1743: -   F - current residual

1745:     Output parameters for normfunc:
1746: .   fnorm - VI-specific norm of the function

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

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

1754:     Level: developer

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

1758: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1759: @*/
1760: extern PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1761: {
1764:   if (projectfunc) linesearch->ops->viproject = projectfunc;
1765:   if (normfunc) linesearch->ops->vinorm = normfunc;
1766:   return(0);
1767: }

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

1772:    Input Parameters:
1773: .  linesearch - the line search context, obtain with SNESGetLineSearch()

1775:    Output Parameters:
1776: +  projectfunc - function for projecting the function to the bounds
1777: -  normfunc - function for computing the norm of an active set

1779:    Logically Collective on SNES

1781:     Level: developer

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

1785: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1786: @*/
1787: extern PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1788: {
1790:   if (projectfunc) *projectfunc = linesearch->ops->viproject;
1791:   if (normfunc) *normfunc = linesearch->ops->vinorm;
1792:   return(0);
1793: }

1795: /*@C
1796:   SNESLineSearchRegister - See SNESLineSearchRegister()

1798:   Level: advanced
1799: @*/
1800: PetscErrorCode  SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1801: {

1805:   PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1806:   return(0);
1807: }