Actual source code: linesearch.c

petsc-master 2018-05-20
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: SNESGetLineSearch(), 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: SNESGetLineSearch(), 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:
 99:     Only a single monitor function can be set for each SNESLineSearch object

101:    Level: intermediate

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

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

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

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

129:    Collective on SNESLineSearch

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

135:    Level: intermediate

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

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

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

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

163:    Logically Collective on Comm

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

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

171:    Level: developer

173:    Notes:
174:    The preferred calling sequence for users is to use SNESGetLineSearch() to acquire the SNESLineSearch instance
175:    already associated with the SNES.  This function is for developer use.

177: .keywords: LineSearch, create, context

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

182: PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
183: {
185:   SNESLineSearch linesearch;

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

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

194:   linesearch->vec_sol_new  = NULL;
195:   linesearch->vec_func_new = NULL;
196:   linesearch->vec_sol      = NULL;
197:   linesearch->vec_func     = NULL;
198:   linesearch->vec_update   = NULL;

200:   linesearch->lambda       = 1.0;
201:   linesearch->fnorm        = 1.0;
202:   linesearch->ynorm        = 1.0;
203:   linesearch->xnorm        = 1.0;
204:   linesearch->result       = SNES_LINESEARCH_SUCCEEDED;
205:   linesearch->norms        = PETSC_TRUE;
206:   linesearch->keeplambda   = PETSC_FALSE;
207:   linesearch->damping      = 1.0;
208:   linesearch->maxstep      = 1e8;
209:   linesearch->steptol      = 1e-12;
210:   linesearch->rtol         = 1e-8;
211:   linesearch->atol         = 1e-15;
212:   linesearch->ltol         = 1e-8;
213:   linesearch->precheckctx  = NULL;
214:   linesearch->postcheckctx = NULL;
215:   linesearch->max_its      = 1;
216:   linesearch->setupcalled  = PETSC_FALSE;
217:   *outlinesearch           = linesearch;
218:   return(0);
219: }

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

225:    Collective on SNESLineSearch

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

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

237:    Level: advanced

239: .keywords: SNESLineSearch, SetUp

241: .seealso: SNESGetLineSearch(), SNESLineSearchReset()
242: @*/

244: PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
245: {

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


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

273:    Collective on SNESLineSearch

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

278:    Notes:
279:     Usually only called by SNESReset()

281:    Level: developer

283: .keywords: SNESLineSearch, Reset

285: .seealso: SNESGetLineSearch(), SNESLineSearchSetUp()
286: @*/

288: PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
289: {

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

295:   VecDestroy(&linesearch->vec_sol_new);
296:   VecDestroy(&linesearch->vec_func_new);

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

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

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

308:    Input Parameters:
309: .  linesearch - the SNESLineSearch context
310: +  func       - function evaluation routine

312:    Level: developer

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

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

319: .seealso: SNESGetLineSearch(), SNESSetFunction()
320: @*/
321: PetscErrorCode  SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
322: {
325:   linesearch->ops->snesfunc = func;
326:   return(0);
327: }

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

334:    Logically Collective on SNESLineSearch

336:    Input Parameters:
337: +  linesearch - the SNESLineSearch context
338: .  func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for the calling sequence
339: -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)

341:    Level: intermediate

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

345: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
346: @*/
347: PetscErrorCode  SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
348: {
351:   if (func) linesearch->ops->precheck = func;
352:   if (ctx) linesearch->precheckctx = ctx;
353:   return(0);
354: }

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

359:    Input Parameters:
360: .  linesearch - the SNESLineSearch context

362:    Output Parameters:
363: +  func       - [optional] function evaluation routine, see SNESLineSearchPreCheck() for calling sequence
364: -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)

366:    Level: intermediate

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

370: .seealso: SNESGetLineSearch(), SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck()
371: @*/
372: PetscErrorCode  SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
373: {
376:   if (func) *func = linesearch->ops->precheck;
377:   if (ctx) *ctx = linesearch->precheckctx;
378:   return(0);
379: }

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

385:    Logically Collective on SNESLineSearch

387:    Input Parameters:
388: +  linesearch - the SNESLineSearch context
389: .  func - [optional] function evaluation routine, see SNESLineSearchPostCheck()  for the calling sequence
390: -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)

392:    Level: intermediate

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

396: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchGetPostCheck()
397: @*/
398: PetscErrorCode  SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
399: {
402:   if (func) linesearch->ops->postcheck = func;
403:   if (ctx) linesearch->postcheckctx = ctx;
404:   return(0);
405: }

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

410:    Input Parameters:
411: .  linesearch - the SNESLineSearch context

413:    Output Parameters:
414: +  func - [optional] function evaluation routine, see for the calling sequence SNESLineSearchPostCheck()
415: -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)

417:    Level: intermediate

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

421: .seealso: SNESGetLineSearch(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck()
422: @*/
423: PetscErrorCode  SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
424: {
427:   if (func) *func = linesearch->ops->postcheck;
428:   if (ctx) *ctx = linesearch->postcheckctx;
429:   return(0);
430: }

432: /*@
433:    SNESLineSearchPreCheck - Prepares the line search for being applied.

435:    Logically Collective on SNESLineSearch

437:    Input Parameters:
438: +  linesearch - The linesearch instance.
439: .  X - The current solution
440: -  Y - The step direction

442:    Output Parameters:
443: .  changed - Indicator that the precheck routine has changed anything

445:    Level: developer

447: .keywords: SNESLineSearch, Create

449: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck()
450: @*/
451: PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
452: {

456:   *changed = PETSC_FALSE;
457:   if (linesearch->ops->precheck) {
458:     (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);
460:   }
461:   return(0);
462: }

464: /*@
465:    SNESLineSearchPostCheck - Prepares the line search for being applied.

467:    Logically Collective on SNESLineSearch

469:    Input Parameters:
470: +  linesearch - The linesearch context
471: .  X - The last solution
472: .  Y - The step direction
473: -  W - The updated solution, W = X + lambda*Y for some lambda

475:    Output Parameters:
476: +  changed_Y - Indicator if the direction Y has been changed.
477: -  changed_W - Indicator if the new candidate solution W has been changed.

479:    Level: developer

481: .keywords: SNESLineSearch, Create

483: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPrecheck(), SNESLineSearchGetPrecheck()
484: @*/
485: PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
486: {

490:   *changed_Y = PETSC_FALSE;
491:   *changed_W = PETSC_FALSE;
492:   if (linesearch->ops->postcheck) {
493:     (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);
496:   }
497:   return(0);
498: }

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

503:    Logically Collective on SNESLineSearch

505:    Input Arguments:
506: +  linesearch - linesearch context
507: .  X - base state for this step
508: .  Y - initial correction
509: -  ctx - context for this function

511:    Output Arguments:
512: +  Y - correction, possibly modified
513: -  changed - flag indicating that Y was modified

515:    Options Database Key:
516: +  -snes_linesearch_precheck_picard - activate this routine
517: -  -snes_linesearch_precheck_picard_angle - angle

519:    Level: advanced

521:    Notes:
522:    This function should be passed to SNESLineSearchSetPreCheck()

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

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

531: .seealso: SNESGetLineSearch(), SNESLineSearchSetPreCheck()
532: @*/
533: PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
534: {
536:   PetscReal      angle = *(PetscReal*)linesearch->precheckctx;
537:   Vec            Ylast;
538:   PetscScalar    dot;
539:   PetscInt       iter;
540:   PetscReal      ynorm,ylastnorm,theta,angle_radians;
541:   SNES           snes;

544:   SNESLineSearchGetSNES(linesearch, &snes);
545:   PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);
546:   if (!Ylast) {
547:     VecDuplicate(Y,&Ylast);
548:     PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);
549:     PetscObjectDereference((PetscObject)Ylast);
550:   }
551:   SNESGetIterationNumber(snes,&iter);
552:   if (iter < 2) {
553:     VecCopy(Y,Ylast);
554:     *changed = PETSC_FALSE;
555:     return(0);
556:   }

558:   VecDot(Y,Ylast,&dot);
559:   VecNorm(Y,NORM_2,&ynorm);
560:   VecNorm(Ylast,NORM_2,&ylastnorm);
561:   /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
562:   theta         = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
563:   angle_radians = angle * PETSC_PI / 180.;
564:   if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
565:     /* Modify the step Y */
566:     PetscReal alpha,ydiffnorm;
567:     VecAXPY(Ylast,-1.0,Y);
568:     VecNorm(Ylast,NORM_2,&ydiffnorm);
569:     alpha = ylastnorm / ydiffnorm;
570:     VecCopy(Y,Ylast);
571:     VecScale(Y,alpha);
572:     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);
573:   } else {
574:     PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);
575:     VecCopy(Y,Ylast);
576:     *changed = PETSC_FALSE;
577:   }
578:   return(0);
579: }

581: /*@
582:    SNESLineSearchApply - Computes the line-search update.

584:    Collective on SNESLineSearch

586:    Input Parameters:
587: +  linesearch - The linesearch context
588: .  X - The current solution
589: .  F - The current function
590: .  fnorm - The current norm
591: -  Y - The search direction

593:    Output Parameters:
594: +  X - The new solution
595: .  F - The new function
596: -  fnorm - The new function norm

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

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

614:    Level: Intermediate

616: .keywords: SNESLineSearch, Create

618: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(),
619:           SNESLineSearchType, SNESLineSearchSetType()
620: @*/
621: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
622: {


631:   linesearch->result = SNES_LINESEARCH_SUCCEEDED;

633:   linesearch->vec_sol    = X;
634:   linesearch->vec_update = Y;
635:   linesearch->vec_func   = F;

637:   SNESLineSearchSetUp(linesearch);

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

641:   if (fnorm) linesearch->fnorm = *fnorm;
642:   else {
643:     VecNorm(F, NORM_2, &linesearch->fnorm);
644:   }

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

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

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

652:   if (fnorm) *fnorm = linesearch->fnorm;
653:   return(0);
654: }

656: /*@
657:    SNESLineSearchDestroy - Destroys the line search instance.

659:    Collective on SNESLineSearch

661:    Input Parameters:
662: .  linesearch - The linesearch context

664:    Level: developer

666: .keywords: SNESLineSearch, Destroy

668: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
669: @*/
670: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
671: {

675:   if (!*linesearch) return(0);
677:   if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; return(0);}
678:   PetscObjectSAWsViewOff((PetscObject)*linesearch);
679:   SNESLineSearchReset(*linesearch);
680:   if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
681:   PetscViewerDestroy(&(*linesearch)->monitor);
682:   SNESLineSearchMonitorCancel((*linesearch));
683:   PetscHeaderDestroy(linesearch);
684:   return(0);
685: }

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

690:    Input Parameters:
691: +  linesearch - the linesearch object
692: -  viewer - an ASCII PetscViewer or NULL to turn off monitor

694:    Logically Collective on SNESLineSearch

696:    Options Database:
697: .   -snes_linesearch_monitor [:filename] - enables the monitor

699:    Level: intermediate

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

705: .seealso: SNESGetLineSearch(), SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor()
706: @*/
707: PetscErrorCode  SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
708: {

712:   if (viewer) {PetscObjectReference((PetscObject)viewer);}
713:   PetscViewerDestroy(&linesearch->monitor);
714:   linesearch->monitor = viewer;
715:   return(0);
716: }

718: /*@
719:    SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.

721:    Input Parameter:
722: .  linesearch - linesearch context

724:    Output Parameter:
725: .  monitor - monitor context

727:    Logically Collective on SNES

729:    Options Database Keys:
730: .   -snes_linesearch_monitor - enables the monitor

732:    Level: intermediate

734: .seealso: SNESGetLineSearch(), SNESLineSearchSetDefaultMonitor(), PetscViewer
735: @*/
736: PetscErrorCode  SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
737: {
740:   if (monitor) {
742:     *monitor = linesearch->monitor;
743:   }
744:   return(0);
745: }

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

750:    Collective on SNESLineSearch

752:    Input Parameters:
753: +  ls - LineSearch object you wish to monitor
754: .  name - the monitor type one is seeking
755: .  help - message indicating what monitoring is done
756: .  manual - manual page for the monitor
757: .  monitor - the monitor function
758: -  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

760:    Level: developer

762: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
763:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
764:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
765:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
766:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
767:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
768:           PetscOptionsFList(), PetscOptionsEList()
769: @*/
770: PetscErrorCode  SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
771: {
772:   PetscErrorCode    ierr;
773:   PetscViewer       viewer;
774:   PetscViewerFormat format;
775:   PetscBool         flg;

778:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject)ls)->prefix,name,&viewer,&format,&flg);
779:   if (flg) {
780:     PetscViewerAndFormat *vf;
781:     PetscViewerAndFormatCreate(viewer,format,&vf);
782:     PetscObjectDereference((PetscObject)viewer);
783:     if (monitorsetup) {
784:       (*monitorsetup)(ls,vf);
785:     }
786:     SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
787:   }
788:   return(0);
789: }

791: /*@
792:    SNESLineSearchSetFromOptions - Sets options for the line search

794:    Input Parameters:
795: .  linesearch - linesearch context

797:    Options Database Keys:
798: + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
799: . -snes_linesearch_order <order> - 1, 2, 3.  Most types only support certain orders (bt supports 2 or 3)
800: . -snes_linesearch_norms   - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms())
801: . -snes_linesearch_minlambda - The minimum step length
802: . -snes_linesearch_maxstep - The maximum step size
803: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
804: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
805: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
806: . -snes_linesearch_max_it - The number of iterations for iterative line searches
807: . -snes_linesearch_monitor [:filename] - Print progress of line searches
808: . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
809: . -snes_linesearch_damping - The linesearch damping parameter
810: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
811: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
812: - -snes_linesearch_precheck_picard_angle - Angle used in picard precheck method

814:    Logically Collective on SNESLineSearch

816:    Level: intermediate

818: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(),
819:           SNESLineSearchType, SNESLineSearchSetComputeNorms()
820: @*/
821: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
822: {
823:   PetscErrorCode    ierr;
824:   const char        *deft = SNESLINESEARCHBASIC;
825:   char              type[256];
826:   PetscBool         flg, set;
827:   PetscViewer       viewer;

830:   SNESLineSearchRegisterAll();

832:   PetscObjectOptionsBegin((PetscObject)linesearch);
833:   if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
834:   PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
835:   if (flg) {
836:     SNESLineSearchSetType(linesearch,type);
837:   } else if (!((PetscObject)linesearch)->type_name) {
838:     SNESLineSearchSetType(linesearch,deft);
839:   }

841:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);
842:   if (set) {
843:     SNESLineSearchSetDefaultMonitor(linesearch,viewer);
844:     PetscViewerDestroy(&viewer);
845:   }
846:   SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);

848:   /* tolerances */
849:   PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);
850:   PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);
851:   PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);
852:   PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);
853:   PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);
854:   PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);

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

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

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

867:       PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
868:                               "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);
869:       SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
870:     } else {
871:       SNESLineSearchSetPreCheck(linesearch,NULL,NULL);
872:     }
873:   }
874:   PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);
875:   PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);

877:   if (linesearch->ops->setfromoptions) {
878:     (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);
879:   }

881:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);
882:   PetscOptionsEnd();
883:   return(0);
884: }

886: /*@
887:    SNESLineSearchView - Prints useful information about the line search

889:    Input Parameters:
890: .  linesearch - linesearch context

892:    Logically Collective on SNESLineSearch

894:    Level: intermediate

896: .seealso: SNESLineSearchCreate()
897: @*/
898: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
899: {
901:   PetscBool      iascii;

905:   if (!viewer) {
906:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);
907:   }

911:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
912:   if (iascii) {
913:     PetscInt     tabs;
914:     PetscViewerASCIIGetTab(viewer, &tabs);
915:     PetscViewerASCIISetTab(viewer, ((PetscObject)linesearch)->tablevel);
916:     PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);
917:     if (linesearch->ops->view) {
918:       PetscViewerASCIIPushTab(viewer);
919:       (*linesearch->ops->view)(linesearch,viewer);
920:       PetscViewerASCIIPopTab(viewer);
921:     }
922:     PetscViewerASCIIPrintf(viewer,"  maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);
923:     PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);
924:     PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D\n", linesearch->max_its);
925:     if (linesearch->ops->precheck) {
926:       if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
927:         PetscViewerASCIIPrintf(viewer,"  using precheck step to speed up Picard convergence\n", linesearch->max_its);
928:       } else {
929:         PetscViewerASCIIPrintf(viewer,"  using user-defined precheck step\n", linesearch->max_its);
930:       }
931:     }
932:     if (linesearch->ops->postcheck) {
933:       PetscViewerASCIIPrintf(viewer,"  using user-defined postcheck step\n", linesearch->max_its);
934:     }
935:     PetscViewerASCIISetTab(viewer, tabs);
936:   }
937:   return(0);
938: }

940: /*@C
941:    SNESLineSearchSetType - Sets the linesearch type

943:    Logically Collective on SNESLineSearch

945:    Input Parameters:
946: +  linesearch - linesearch context
947: -  type - The type of line search to be used

949:    Available Types:
950: +  SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
951: .  SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
952: .  SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
953: .  SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
954: .  SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
955: -  SNESLINESEARCHSHELL - User provided SNESLineSearch implementation

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

960:    Level: intermediate

962: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions()
963: @*/
964: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
965: {
966:   PetscErrorCode ierr,(*r)(SNESLineSearch);
967:   PetscBool      match;


973:   PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
974:   if (match) return(0);

976:   PetscFunctionListFind(SNESLineSearchList,type,&r);
977:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
978:   /* Destroy the previous private linesearch context */
979:   if (linesearch->ops->destroy) {
980:     (*(linesearch)->ops->destroy)(linesearch);

982:     linesearch->ops->destroy = NULL;
983:   }
984:   /* Reinitialize function pointers in SNESLineSearchOps structure */
985:   linesearch->ops->apply          = 0;
986:   linesearch->ops->view           = 0;
987:   linesearch->ops->setfromoptions = 0;
988:   linesearch->ops->destroy        = 0;

990:   PetscObjectChangeTypeName((PetscObject)linesearch,type);
991:   (*r)(linesearch);
992:   return(0);
993: }

995: /*@
996:    SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.

998:    Input Parameters:
999: +  linesearch - linesearch context
1000: -  snes - The snes instance

1002:    Level: developer

1004:    Notes:
1005:    This happens automatically when the line search is obtained/created with
1006:    SNESGetLineSearch().  This routine is therefore mainly called within SNES
1007:    implementations.

1009:    Level: developer

1011: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1012: @*/
1013: PetscErrorCode  SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
1014: {
1018:   linesearch->snes = snes;
1019:   return(0);
1020: }

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

1028:    Input Parameters:
1029: .  linesearch - linesearch context

1031:    Output Parameters:
1032: .  snes - The snes instance

1034:    Level: developer

1036: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1037: @*/
1038: PetscErrorCode  SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1039: {
1043:   *snes = linesearch->snes;
1044:   return(0);
1045: }

1047: /*@
1048:    SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.

1050:    Input Parameters:
1051: .  linesearch - linesearch context

1053:    Output Parameters:
1054: .  lambda - The last steplength computed during SNESLineSearchApply()

1056:    Level: advanced

1058:    Notes:
1059:    This is useful in methods where the solver is ill-scaled and
1060:    requires some adaptive notion of the difference in scale between the
1061:    solution and the function.  For instance, SNESQN may be scaled by the
1062:    line search lambda using the argument -snes_qn_scaling ls.

1064: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1065: @*/
1066: PetscErrorCode  SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1067: {
1071:   *lambda = linesearch->lambda;
1072:   return(0);
1073: }

1075: /*@
1076:    SNESLineSearchSetLambda - Sets the linesearch steplength.

1078:    Input Parameters:
1079: +  linesearch - linesearch context
1080: -  lambda - The last steplength.

1082:    Notes:
1083:    This routine is typically used within implementations of SNESLineSearchApply()
1084:    to set the final steplength.  This routine (and SNESLineSearchGetLambda()) were
1085:    added in order to facilitate Quasi-Newton methods that use the previous steplength
1086:    as an inner scaling parameter.

1088:    Level: advanced

1090: .seealso: SNESLineSearchGetLambda()
1091: @*/
1092: PetscErrorCode  SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1093: {
1096:   linesearch->lambda = lambda;
1097:   return(0);
1098: }

1100: /*@
1101:    SNESLineSearchGetTolerances - Gets the tolerances for the linesearch.  These include
1102:    tolerances for the relative and absolute change in the function norm, the change
1103:    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1104:    and the maximum number of iterations the line search procedure may take.

1106:    Input Parameters:
1107: .  linesearch - linesearch context

1109:    Output Parameters:
1110: +  steptol - The minimum steplength
1111: .  maxstep - The maximum steplength
1112: .  rtol    - The relative tolerance for iterative line searches
1113: .  atol    - The absolute tolerance for iterative line searches
1114: .  ltol    - The change in lambda tolerance for iterative line searches
1115: -  max_it  - The maximum number of iterations of the line search

1117:    Level: intermediate

1119:    Notes:
1120:    Different line searches may implement these parameters slightly differently as
1121:    the type requires.

1123: .seealso: SNESLineSearchSetTolerances()
1124: @*/
1125: PetscErrorCode  SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1126: {
1129:   if (steptol) {
1131:     *steptol = linesearch->steptol;
1132:   }
1133:   if (maxstep) {
1135:     *maxstep = linesearch->maxstep;
1136:   }
1137:   if (rtol) {
1139:     *rtol = linesearch->rtol;
1140:   }
1141:   if (atol) {
1143:     *atol = linesearch->atol;
1144:   }
1145:   if (ltol) {
1147:     *ltol = linesearch->ltol;
1148:   }
1149:   if (max_its) {
1151:     *max_its = linesearch->max_its;
1152:   }
1153:   return(0);
1154: }

1156: /*@
1157:    SNESLineSearchSetTolerances -  Gets the tolerances for the linesearch.  These include
1158:    tolerances for the relative and absolute change in the function norm, the change
1159:    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1160:    and the maximum number of iterations the line search procedure may take.

1162:    Input Parameters:
1163: +  linesearch - linesearch context
1164: .  steptol - The minimum steplength
1165: .  maxstep - The maximum steplength
1166: .  rtol    - The relative tolerance for iterative line searches
1167: .  atol    - The absolute tolerance for iterative line searches
1168: .  ltol    - The change in lambda tolerance for iterative line searches
1169: -  max_it  - The maximum number of iterations of the line search

1171:    Notes:
1172:    The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1173:    place of an argument.

1175:    Level: intermediate

1177: .seealso: SNESLineSearchGetTolerances()
1178: @*/
1179: PetscErrorCode  SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1180: {

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

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

1200:   if (rtol != PETSC_DEFAULT) {
1201:     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);
1202:     linesearch->rtol = rtol;
1203:   }

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

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

1215:   if (max_its != PETSC_DEFAULT) {
1216:     if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1217:     linesearch->max_its = max_its;
1218:   }
1219:   return(0);
1220: }

1222: /*@
1223:    SNESLineSearchGetDamping - Gets the line search damping parameter.

1225:    Input Parameters:
1226: .  linesearch - linesearch context

1228:    Output Parameters:
1229: .  damping - The damping parameter

1231:    Level: advanced

1233: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1234: @*/

1236: PetscErrorCode  SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1237: {
1241:   *damping = linesearch->damping;
1242:   return(0);
1243: }

1245: /*@
1246:    SNESLineSearchSetDamping - Sets the line search damping paramter.

1248:    Input Parameters:
1249: +  linesearch - linesearch context
1250: -  damping - The damping parameter

1252:    Options Database:
1253: .   -snes_linesearch_damping
1254:    Level: intermediate

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

1263: .seealso: SNESLineSearchGetDamping()
1264: @*/
1265: PetscErrorCode  SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1266: {
1269:   linesearch->damping = damping;
1270:   return(0);
1271: }

1273: /*@
1274:    SNESLineSearchGetOrder - Gets the line search approximation order.

1276:    Input Parameters:
1277: .  linesearch - linesearch context

1279:    Output Parameters:
1280: .  order - The order

1282:    Possible Values for order:
1283: +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1284: .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1285: -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order

1287:    Level: intermediate

1289: .seealso: SNESLineSearchSetOrder()
1290: @*/

1292: PetscErrorCode  SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1293: {
1297:   *order = linesearch->order;
1298:   return(0);
1299: }

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

1304:    Input Parameters:
1305: .  linesearch - linesearch context
1306: .  order - The damping parameter

1308:    Level: intermediate

1310:    Possible Values for order:
1311: +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1312: .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1313: -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order

1315:    Notes:
1316:    Variable orders are supported by the following line searches:
1317: +  bt - cubic and quadratic
1318: -  cp - linear and quadratic

1320: .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1321: @*/
1322: PetscErrorCode  SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1323: {
1326:   linesearch->order = order;
1327:   return(0);
1328: }

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

1333:    Input Parameters:
1334: .  linesearch - linesearch context

1336:    Output Parameters:
1337: +  xnorm - The norm of the current solution
1338: .  fnorm - The norm of the current function
1339: -  ynorm - The norm of the current update

1341:    Notes:
1342:    This function is mainly called from SNES implementations.

1344:    Level: developer

1346: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1347: @*/
1348: PetscErrorCode  SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1349: {
1352:   if (xnorm) *xnorm = linesearch->xnorm;
1353:   if (fnorm) *fnorm = linesearch->fnorm;
1354:   if (ynorm) *ynorm = linesearch->ynorm;
1355:   return(0);
1356: }

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

1361:    Input Parameters:
1362: +  linesearch - linesearch context
1363: .  xnorm - The norm of the current solution
1364: .  fnorm - The norm of the current function
1365: -  ynorm - The norm of the current update

1367:    Level: advanced

1369: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1370: @*/
1371: PetscErrorCode  SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1372: {
1375:   linesearch->xnorm = xnorm;
1376:   linesearch->fnorm = fnorm;
1377:   linesearch->ynorm = ynorm;
1378:   return(0);
1379: }

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

1384:    Input Parameters:
1385: .  linesearch - linesearch context

1387:    Options Database Keys:
1388: .   -snes_linesearch_norms - turn norm computation on or off

1390:    Level: intermediate

1392: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1393: @*/
1394: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1395: {
1397:   SNES           snes;

1400:   if (linesearch->norms) {
1401:     if (linesearch->ops->vinorm) {
1402:       SNESLineSearchGetSNES(linesearch, &snes);
1403:       VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1404:       VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1405:       (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1406:     } else {
1407:       VecNormBegin(linesearch->vec_func,   NORM_2, &linesearch->fnorm);
1408:       VecNormBegin(linesearch->vec_sol,    NORM_2, &linesearch->xnorm);
1409:       VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1410:       VecNormEnd(linesearch->vec_func,     NORM_2, &linesearch->fnorm);
1411:       VecNormEnd(linesearch->vec_sol,      NORM_2, &linesearch->xnorm);
1412:       VecNormEnd(linesearch->vec_update,   NORM_2, &linesearch->ynorm);
1413:     }
1414:   }
1415:   return(0);
1416: }

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

1421:    Input Parameters:
1422: +  linesearch  - linesearch context
1423: -  flg  - indicates whether or not to compute norms

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

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

1431:    Level: intermediate

1433: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1434: @*/
1435: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1436: {
1438:   linesearch->norms = flg;
1439:   return(0);
1440: }

1442: /*@
1443:    SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context

1445:    Input Parameters:
1446: .  linesearch - linesearch context

1448:    Output Parameters:
1449: +  X - Solution vector
1450: .  F - Function vector
1451: .  Y - Search direction vector
1452: .  W - Solution work vector
1453: -  G - Function work vector

1455:    Notes:
1456:    At the beginning of a line search application, X should contain a
1457:    solution and the vector F the function computed at X.  At the end of the
1458:    line search application, X should contain the new solution, and F the
1459:    function evaluated at the new solution.

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

1463:    Level: advanced

1465: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1466: @*/
1467: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1468: {
1471:   if (X) {
1473:     *X = linesearch->vec_sol;
1474:   }
1475:   if (F) {
1477:     *F = linesearch->vec_func;
1478:   }
1479:   if (Y) {
1481:     *Y = linesearch->vec_update;
1482:   }
1483:   if (W) {
1485:     *W = linesearch->vec_sol_new;
1486:   }
1487:   if (G) {
1489:     *G = linesearch->vec_func_new;
1490:   }
1491:   return(0);
1492: }

1494: /*@
1495:    SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context

1497:    Input Parameters:
1498: +  linesearch - linesearch context
1499: .  X - Solution vector
1500: .  F - Function vector
1501: .  Y - Search direction vector
1502: .  W - Solution work vector
1503: -  G - Function work vector

1505:    Level: advanced

1507: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1508: @*/
1509: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1510: {
1513:   if (X) {
1515:     linesearch->vec_sol = X;
1516:   }
1517:   if (F) {
1519:     linesearch->vec_func = F;
1520:   }
1521:   if (Y) {
1523:     linesearch->vec_update = Y;
1524:   }
1525:   if (W) {
1527:     linesearch->vec_sol_new = W;
1528:   }
1529:   if (G) {
1531:     linesearch->vec_func_new = G;
1532:   }
1533:   return(0);
1534: }

1536: /*@C
1537:    SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1538:    SNES options in the database.

1540:    Logically Collective on SNESLineSearch

1542:    Input Parameters:
1543: +  snes - the SNES context
1544: -  prefix - the prefix to prepend to all option names

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

1550:    Level: advanced

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

1554: .seealso: SNESGetOptionsPrefix()
1555: @*/
1556: PetscErrorCode  SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1557: {

1562:   PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1563:   return(0);
1564: }

1566: /*@C
1567:    SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1568:    SNESLineSearch options in the database.

1570:    Not Collective

1572:    Input Parameter:
1573: .  linesearch - the SNESLineSearch context

1575:    Output Parameter:
1576: .  prefix - pointer to the prefix string used

1578:    Notes:
1579:    On the fortran side, the user should pass in a string 'prefix' of
1580:    sufficient length to hold the prefix.

1582:    Level: advanced

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

1586: .seealso: SNESAppendOptionsPrefix()
1587: @*/
1588: PetscErrorCode  SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1589: {

1594:   PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1595:   return(0);
1596: }

1598: /*@C
1599:    SNESLineSearchSetWorkVecs - Gets work vectors for the line search.

1601:    Input Parameter:
1602: +  linesearch - the SNESLineSearch context
1603: -  nwork - the number of work vectors

1605:    Level: developer

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

1609: .keywords: SNESLineSearch, work, vector

1611: .seealso: SNESSetWorkVecs()
1612: @*/
1613: PetscErrorCode  SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1614: {

1618:   if (linesearch->vec_sol) {
1619:     VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1620:   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1621:   return(0);
1622: }

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

1627:    Input Parameters:
1628: .  linesearch - linesearch context

1630:    Output Parameters:
1631: .  result - The success or failure status

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

1637:    Level: intermediate

1639: .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1640: @*/
1641: PetscErrorCode  SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1642: {
1646:   *result = linesearch->result;
1647:   return(0);
1648: }

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

1653:    Input Parameters:
1654: +  linesearch - linesearch context
1655: -  result - The success or failure status

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

1661:    Level: developer

1663: .seealso: SNESLineSearchGetSResult()
1664: @*/
1665: PetscErrorCode  SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1666: {
1669:   linesearch->result = result;
1670:   return(0);
1671: }

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

1676:    Input Parameters:
1677: +  snes - nonlinear context obtained from SNESCreate()
1678: .  projectfunc - function for projecting the function to the bounds
1679: -  normfunc - function for computing the norm of an active set

1681:    Logically Collective on SNES

1683:    Calling sequence of projectfunc:
1684: .vb
1685:    projectfunc (SNES snes, Vec X)
1686: .ve

1688:     Input parameters for projectfunc:
1689: +   snes - nonlinear context
1690: -   X - current solution

1692:     Output parameters for projectfunc:
1693: .   X - Projected solution

1695:    Calling sequence of normfunc:
1696: .vb
1697:    projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1698: .ve

1700:     Input parameters for normfunc:
1701: +   snes - nonlinear context
1702: .   X - current solution
1703: -   F - current residual

1705:     Output parameters for normfunc:
1706: .   fnorm - VI-specific norm of the function

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

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

1714:     Level: developer

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

1718: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1719: @*/
1720: extern PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1721: {
1724:   if (projectfunc) linesearch->ops->viproject = projectfunc;
1725:   if (normfunc) linesearch->ops->vinorm = normfunc;
1726:   return(0);
1727: }

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

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

1735:    Output Parameters:
1736: +  projectfunc - function for projecting the function to the bounds
1737: -  normfunc - function for computing the norm of an active set

1739:    Logically Collective on SNES

1741:     Level: developer

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

1745: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1746: @*/
1747: extern PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1748: {
1750:   if (projectfunc) *projectfunc = linesearch->ops->viproject;
1751:   if (normfunc) *normfunc = linesearch->ops->vinorm;
1752:   return(0);
1753: }

1755: /*@C
1756:   SNESLineSearchRegister - See SNESLineSearchRegister()

1758:   Level: advanced
1759: @*/
1760: PetscErrorCode  SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1761: {

1765:   PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1766:   return(0);
1767: }