Actual source code: linesearch.c
  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: .seealso: SNESGetLineSearch(), SNESLineSearchMonitorDefault(), SNESLineSearchMonitorSet()
 31: @*/
 32: PetscErrorCode  SNESLineSearchMonitorCancel(SNESLineSearch ls)
 33: {
 35:   PetscInt       i;
 39:   for (i=0; i<ls->numbermonitors; i++) {
 40:     if (ls->monitordestroy[i]) {
 41:       (*ls->monitordestroy[i])(&ls->monitorcontext[i]);
 42:     }
 43:   }
 44:   ls->numbermonitors = 0;
 45:   return(0);
 46: }
 48: /*@
 49:    SNESLineSearchMonitor - runs the user provided monitor routines, if they exist
 51:    Collective on SNES
 53:    Input Parameters:
 54: .  ls - the linesearch object
 56:    Notes:
 57:    This routine is called by the SNES implementations.
 58:    It does not typically need to be called by the user.
 60:    Level: developer
 62: .seealso: SNESGetLineSearch(), SNESLineSearchMonitorSet()
 63: @*/
 64: PetscErrorCode  SNESLineSearchMonitor(SNESLineSearch ls)
 65: {
 67:   PetscInt       i,n = ls->numbermonitors;
 70:   for (i=0; i<n; i++) {
 71:     (*ls->monitorftns[i])(ls,ls->monitorcontext[i]);
 72:   }
 73:   return(0);
 74: }
 76: /*@C
 77:    SNESLineSearchMonitorSet - Sets an ADDITIONAL function that is to be used at every
 78:    iteration of the nonlinear solver to display the iteration's
 79:    progress.
 81:    Logically Collective on SNESLineSearch
 83:    Input Parameters:
 84: +  ls - the SNESLineSearch context
 85: .  f - the monitor function
 86: .  mctx - [optional] user-defined context for private data for the
 87:           monitor routine (use NULL if no context is desired)
 88: -  monitordestroy - [optional] routine that frees monitor context
 89:           (may be NULL)
 91:    Notes:
 92:    Several different monitoring routines may be set by calling
 93:    SNESLineSearchMonitorSet() multiple times; all will be called in the
 94:    order in which they were set.
 96:    Fortran Notes:
 97:     Only a single monitor function can be set for each SNESLineSearch object
 99:    Level: intermediate
101: .seealso: SNESGetLineSearch(), SNESLineSearchMonitorDefault(), SNESLineSearchMonitorCancel()
102: @*/
103: PetscErrorCode  SNESLineSearchMonitorSet(SNESLineSearch ls,PetscErrorCode (*f)(SNESLineSearch,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
104: {
106:   PetscInt       i;
107:   PetscBool      identical;
111:   for (i=0; i<ls->numbermonitors;i++) {
112:     PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))ls->monitorftns[i],ls->monitorcontext[i],ls->monitordestroy[i],&identical);
113:     if (identical) return(0);
114:   }
115:   if (ls->numbermonitors >= MAXSNESLSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
116:   ls->monitorftns[ls->numbermonitors]          = f;
117:   ls->monitordestroy[ls->numbermonitors]   = monitordestroy;
118:   ls->monitorcontext[ls->numbermonitors++] = (void*)mctx;
119:   return(0);
120: }
122: /*@C
123:    SNESLineSearchMonitorSolutionUpdate - Monitors each update a new function value the linesearch tries
125:    Collective on SNESLineSearch
127:    Input Parameters:
128: +  ls - the SNES linesearch object
129: -  vf - the context for the monitor, in this case it is an ASCII PetscViewer and format
131:    Level: intermediate
133: .seealso: SNESGetLineSearch(), SNESMonitorSet(), SNESMonitorSolution()
134: @*/
135: PetscErrorCode  SNESLineSearchMonitorSolutionUpdate(SNESLineSearch ls,PetscViewerAndFormat *vf)
136: {
138:   PetscViewer    viewer = vf->viewer;
139:   Vec            Y,W,G;
142:   SNESLineSearchGetVecs(ls,NULL,NULL,&Y,&W,&G);
143:   PetscViewerPushFormat(viewer,vf->format);
144:   PetscViewerASCIIPrintf(viewer,"LineSearch attempted update to solution \n");
145:   VecView(Y,viewer);
146:   PetscViewerASCIIPrintf(viewer,"LineSearch attempted new solution \n");
147:   VecView(W,viewer);
148:   PetscViewerASCIIPrintf(viewer,"LineSearch attempted updated function value\n");
149:   VecView(G,viewer);
150:   PetscViewerPopFormat(viewer);
151:   return(0);
152: }
154: /*@
155:    SNESLineSearchCreate - Creates the line search context.
157:    Logically Collective on Comm
159:    Input Parameters:
160: .  comm - MPI communicator for the line search (typically from the associated SNES context).
162:    Output Parameters:
163: .  outlinesearch - the new linesearch context
165:    Level: developer
167:    Notes:
168:    The preferred calling sequence for users is to use SNESGetLineSearch() to acquire the SNESLineSearch instance
169:    already associated with the SNES.  This function is for developer use.
171: .seealso: LineSearchDestroy(), SNESGetLineSearch()
172: @*/
174: PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
175: {
177:   SNESLineSearch linesearch;
181:   SNESInitializePackage();
182:   *outlinesearch = NULL;
184:   PetscHeaderCreate(linesearch,SNESLINESEARCH_CLASSID, "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView);
186:   linesearch->vec_sol_new  = NULL;
187:   linesearch->vec_func_new = NULL;
188:   linesearch->vec_sol      = NULL;
189:   linesearch->vec_func     = NULL;
190:   linesearch->vec_update   = NULL;
192:   linesearch->lambda       = 1.0;
193:   linesearch->fnorm        = 1.0;
194:   linesearch->ynorm        = 1.0;
195:   linesearch->xnorm        = 1.0;
196:   linesearch->result       = SNES_LINESEARCH_SUCCEEDED;
197:   linesearch->norms        = PETSC_TRUE;
198:   linesearch->keeplambda   = PETSC_FALSE;
199:   linesearch->damping      = 1.0;
200:   linesearch->maxstep      = 1e8;
201:   linesearch->steptol      = 1e-12;
202:   linesearch->rtol         = 1e-8;
203:   linesearch->atol         = 1e-15;
204:   linesearch->ltol         = 1e-8;
205:   linesearch->precheckctx  = NULL;
206:   linesearch->postcheckctx = NULL;
207:   linesearch->max_its      = 1;
208:   linesearch->setupcalled  = PETSC_FALSE;
209:   linesearch->monitor      = NULL;
210:   *outlinesearch           = linesearch;
211:   return(0);
212: }
214: /*@
215:    SNESLineSearchSetUp - Prepares the line search for being applied by allocating
216:    any required vectors.
218:    Collective on SNESLineSearch
220:    Input Parameters:
221: .  linesearch - The LineSearch instance.
223:    Notes:
224:    For most cases, this needn't be called by users or outside of SNESLineSearchApply().
225:    The only current case where this is called outside of this is for the VI
226:    solvers, which modify the solution and work vectors before the first call
227:    of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be
228:    allocated upfront.
230:    Level: advanced
232: .seealso: SNESGetLineSearch(), SNESLineSearchReset()
233: @*/
235: PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
236: {
240:   if (!((PetscObject)linesearch)->type_name) {
241:     SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);
242:   }
243:   if (!linesearch->setupcalled) {
244:     if (!linesearch->vec_sol_new) {
245:       VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);
246:     }
247:     if (!linesearch->vec_func_new) {
248:       VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);
249:     }
250:     if (linesearch->ops->setup) {
251:       (*linesearch->ops->setup)(linesearch);
252:     }
253:     if (!linesearch->ops->snesfunc) {SNESLineSearchSetFunction(linesearch,SNESComputeFunction);}
254:     linesearch->lambda      = linesearch->damping;
255:     linesearch->setupcalled = PETSC_TRUE;
256:   }
257:   return(0);
258: }
261: /*@
262:    SNESLineSearchReset - Undoes the SNESLineSearchSetUp() and deletes any Vecs or Mats allocated by the line search.
264:    Collective on SNESLineSearch
266:    Input Parameters:
267: .  linesearch - The LineSearch instance.
269:    Notes:
270:     Usually only called by SNESReset()
272:    Level: developer
274: .seealso: SNESGetLineSearch(), SNESLineSearchSetUp()
275: @*/
277: PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
278: {
282:   if (linesearch->ops->reset) (*linesearch->ops->reset)(linesearch);
284:   VecDestroy(&linesearch->vec_sol_new);
285:   VecDestroy(&linesearch->vec_func_new);
287:   VecDestroyVecs(linesearch->nwork, &linesearch->work);
289:   linesearch->nwork       = 0;
290:   linesearch->setupcalled = PETSC_FALSE;
291:   return(0);
292: }
294: /*@C
295:    SNESLineSearchSetFunction - Sets the function evaluation used by the SNES line search
297:    Input Parameters:
298: .  linesearch - the SNESLineSearch context
299: +  func       - function evaluation routine
301:    Level: developer
303:    Notes:
304:     This is used internally by PETSc and not called by users
306: .seealso: SNESGetLineSearch(), SNESSetFunction()
307: @*/
308: PetscErrorCode  SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
309: {
312:   linesearch->ops->snesfunc = func;
313:   return(0);
314: }
316: /*@C
317:    SNESLineSearchSetPreCheck - Sets a user function that is called after the initial search direction has been computed but
318:          before the line search routine has been applied. Allows the user to adjust the result of (usually a linear solve) that
319:          determined the search direction.
321:    Logically Collective on SNESLineSearch
323:    Input Parameters:
324: +  linesearch - the SNESLineSearch context
325: .  func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for the calling sequence
326: -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
328:    Level: intermediate
330: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
331: @*/
332: PetscErrorCode  SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
333: {
336:   if (func) linesearch->ops->precheck = func;
337:   if (ctx) linesearch->precheckctx = ctx;
338:   return(0);
339: }
341: /*@C
342:    SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine.
344:    Input Parameters:
345: .  linesearch - the SNESLineSearch context
347:    Output Parameters:
348: +  func       - [optional] function evaluation routine, see SNESLineSearchPreCheck() for calling sequence
349: -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
351:    Level: intermediate
353: .seealso: SNESGetLineSearch(), SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck()
354: @*/
355: PetscErrorCode  SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
356: {
359:   if (func) *func = linesearch->ops->precheck;
360:   if (ctx) *ctx = linesearch->precheckctx;
361:   return(0);
362: }
364: /*@C
365:    SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step
366:        direction and length. Allows the user a chance to change or override the decision of the line search routine
368:    Logically Collective on SNESLineSearch
370:    Input Parameters:
371: +  linesearch - the SNESLineSearch context
372: .  func - [optional] function evaluation routine, see SNESLineSearchPostCheck()  for the calling sequence
373: -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
375:    Level: intermediate
377: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchGetPostCheck()
378: @*/
379: PetscErrorCode  SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
380: {
383:   if (func) linesearch->ops->postcheck = func;
384:   if (ctx) linesearch->postcheckctx = ctx;
385:   return(0);
386: }
388: /*@C
389:    SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.
391:    Input Parameters:
392: .  linesearch - the SNESLineSearch context
394:    Output Parameters:
395: +  func - [optional] function evaluation routine, see for the calling sequence SNESLineSearchPostCheck()
396: -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
398:    Level: intermediate
400: .seealso: SNESGetLineSearch(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck()
401: @*/
402: PetscErrorCode  SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
403: {
406:   if (func) *func = linesearch->ops->postcheck;
407:   if (ctx) *ctx = linesearch->postcheckctx;
408:   return(0);
409: }
411: /*@
412:    SNESLineSearchPreCheck - Prepares the line search for being applied.
414:    Logically Collective on SNESLineSearch
416:    Input Parameters:
417: +  linesearch - The linesearch instance.
418: .  X - The current solution
419: -  Y - The step direction
421:    Output Parameters:
422: .  changed - Indicator that the precheck routine has changed anything
424:    Level: developer
426: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck()
427: @*/
428: PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
429: {
433:   *changed = PETSC_FALSE;
434:   if (linesearch->ops->precheck) {
435:     (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);
437:   }
438:   return(0);
439: }
441: /*@
442:    SNESLineSearchPostCheck - Prepares the line search for being applied.
444:    Logically Collective on SNESLineSearch
446:    Input Parameters:
447: +  linesearch - The linesearch context
448: .  X - The last solution
449: .  Y - The step direction
450: -  W - The updated solution, W = X + lambda*Y for some lambda
452:    Output Parameters:
453: +  changed_Y - Indicator if the direction Y has been changed.
454: -  changed_W - Indicator if the new candidate solution W has been changed.
456:    Level: developer
458: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPrecheck(), SNESLineSearchGetPrecheck()
459: @*/
460: PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
461: {
465:   *changed_Y = PETSC_FALSE;
466:   *changed_W = PETSC_FALSE;
467:   if (linesearch->ops->postcheck) {
468:     (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);
471:   }
472:   return(0);
473: }
475: /*@C
476:    SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration
478:    Logically Collective on SNESLineSearch
480:    Input Arguments:
481: +  linesearch - linesearch context
482: .  X - base state for this step
483: .  Y - initial correction
484: -  ctx - context for this function
486:    Output Arguments:
487: +  Y - correction, possibly modified
488: -  changed - flag indicating that Y was modified
490:    Options Database Key:
491: +  -snes_linesearch_precheck_picard - activate this routine
492: -  -snes_linesearch_precheck_picard_angle - angle
494:    Level: advanced
496:    Notes:
497:    This function should be passed to SNESLineSearchSetPreCheck()
499:    The justification for this method involves the linear convergence of a Picard iteration
500:    so the Picard linearization should be provided in place of the "Jacobian". This correction
501:    is generally not useful when using a Newton linearization.
503:    Reference:
504:    Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.
506: .seealso: SNESGetLineSearch(), SNESLineSearchSetPreCheck()
507: @*/
508: PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
509: {
511:   PetscReal      angle = *(PetscReal*)linesearch->precheckctx;
512:   Vec            Ylast;
513:   PetscScalar    dot;
514:   PetscInt       iter;
515:   PetscReal      ynorm,ylastnorm,theta,angle_radians;
516:   SNES           snes;
519:   SNESLineSearchGetSNES(linesearch, &snes);
520:   PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);
521:   if (!Ylast) {
522:     VecDuplicate(Y,&Ylast);
523:     PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);
524:     PetscObjectDereference((PetscObject)Ylast);
525:   }
526:   SNESGetIterationNumber(snes,&iter);
527:   if (iter < 2) {
528:     VecCopy(Y,Ylast);
529:     *changed = PETSC_FALSE;
530:     return(0);
531:   }
533:   VecDot(Y,Ylast,&dot);
534:   VecNorm(Y,NORM_2,&ynorm);
535:   VecNorm(Ylast,NORM_2,&ylastnorm);
536:   /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
537:   theta         = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
538:   angle_radians = angle * PETSC_PI / 180.;
539:   if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
540:     /* Modify the step Y */
541:     PetscReal alpha,ydiffnorm;
542:     VecAXPY(Ylast,-1.0,Y);
543:     VecNorm(Ylast,NORM_2,&ydiffnorm);
544:     alpha = (ydiffnorm > .001*ylastnorm) ? ylastnorm / ydiffnorm : 1000.0;
545:     VecCopy(Y,Ylast);
546:     VecScale(Y,alpha);
547:     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);
548:     *changed = PETSC_TRUE;
549:   } else {
550:     PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);
551:     VecCopy(Y,Ylast);
552:     *changed = PETSC_FALSE;
553:   }
554:   return(0);
555: }
557: /*@
558:    SNESLineSearchApply - Computes the line-search update.
560:    Collective on SNESLineSearch
562:    Input Parameters:
563: +  linesearch - The linesearch context
564: .  X - The current solution
565: .  F - The current function
566: .  fnorm - The current norm
567: -  Y - The search direction
569:    Output Parameters:
570: +  X - The new solution
571: .  F - The new function
572: -  fnorm - The new function norm
574:    Options Database Keys:
575: + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell
576: . -snes_linesearch_monitor [:filename] - Print progress of line searches
577: . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping)
578: . -snes_linesearch_norms   - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms())
579: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
580: - -snes_linesearch_max_it - The number of iterations for iterative line searches
582:    Notes:
583:    This is typically called from within a SNESSolve() implementation in order to
584:    help with convergence of the nonlinear method.  Various SNES types use line searches
585:    in different ways, but the overarching theme is that a line search is used to determine
586:    an optimal damping parameter of a step at each iteration of the method.  Each
587:    application of the line search may invoke SNESComputeFunction() several times, and
588:    therefore may be fairly expensive.
590:    Level: Intermediate
592: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(),
593:           SNESLineSearchType, SNESLineSearchSetType()
594: @*/
595: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
596: {
605:   linesearch->result = SNES_LINESEARCH_SUCCEEDED;
607:   linesearch->vec_sol    = X;
608:   linesearch->vec_update = Y;
609:   linesearch->vec_func   = F;
611:   SNESLineSearchSetUp(linesearch);
613:   if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
615:   if (fnorm) linesearch->fnorm = *fnorm;
616:   else {
617:     VecNorm(F, NORM_2, &linesearch->fnorm);
618:   }
620:   PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y);
622:   (*linesearch->ops->apply)(linesearch);
624:   PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y);
626:   if (fnorm) *fnorm = linesearch->fnorm;
627:   return(0);
628: }
630: /*@
631:    SNESLineSearchDestroy - Destroys the line search instance.
633:    Collective on SNESLineSearch
635:    Input Parameters:
636: .  linesearch - The linesearch context
638:    Level: developer
640: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
641: @*/
642: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
643: {
647:   if (!*linesearch) return(0);
649:   if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = NULL; return(0);}
650:   PetscObjectSAWsViewOff((PetscObject)*linesearch);
651:   SNESLineSearchReset(*linesearch);
652:   if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
653:   PetscViewerDestroy(&(*linesearch)->monitor);
654:   SNESLineSearchMonitorCancel((*linesearch));
655:   PetscHeaderDestroy(linesearch);
656:   return(0);
657: }
659: /*@
660:    SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.
662:    Input Parameters:
663: +  linesearch - the linesearch object
664: -  viewer - an ASCII PetscViewer or NULL to turn off monitor
666:    Logically Collective on SNESLineSearch
668:    Options Database:
669: .   -snes_linesearch_monitor [:filename] - enables the monitor
671:    Level: intermediate
673:    Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with
674:      SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the
675:      line search that are not visible to the other monitors.
677: .seealso: SNESGetLineSearch(), SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor()
678: @*/
679: PetscErrorCode  SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
680: {
684:   if (viewer) {PetscObjectReference((PetscObject)viewer);}
685:   PetscViewerDestroy(&linesearch->monitor);
686:   linesearch->monitor = viewer;
687:   return(0);
688: }
690: /*@
691:    SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.
693:    Input Parameter:
694: .  linesearch - linesearch context
696:    Output Parameter:
697: .  monitor - monitor context
699:    Logically Collective on SNES
701:    Options Database Keys:
702: .   -snes_linesearch_monitor - enables the monitor
704:    Level: intermediate
706: .seealso: SNESGetLineSearch(), SNESLineSearchSetDefaultMonitor(), PetscViewer
707: @*/
708: PetscErrorCode  SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
709: {
712:   *monitor = linesearch->monitor;
713:   return(0);
714: }
716: /*@C
717:    SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
719:    Collective on SNESLineSearch
721:    Input Parameters:
722: +  ls - LineSearch object you wish to monitor
723: .  name - the monitor type one is seeking
724: .  help - message indicating what monitoring is done
725: .  manual - manual page for the monitor
726: .  monitor - the monitor function
727: -  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
729:    Level: developer
731: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
732:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
733:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
734:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
735:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
736:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
737:           PetscOptionsFList(), PetscOptionsEList()
738: @*/
739: PetscErrorCode  SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
740: {
741:   PetscErrorCode    ierr;
742:   PetscViewer       viewer;
743:   PetscViewerFormat format;
744:   PetscBool         flg;
747:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject) ls)->options,((PetscObject)ls)->prefix,name,&viewer,&format,&flg);
748:   if (flg) {
749:     PetscViewerAndFormat *vf;
750:     PetscViewerAndFormatCreate(viewer,format,&vf);
751:     PetscObjectDereference((PetscObject)viewer);
752:     if (monitorsetup) {
753:       (*monitorsetup)(ls,vf);
754:     }
755:     SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
756:   }
757:   return(0);
758: }
760: /*@
761:    SNESLineSearchSetFromOptions - Sets options for the line search
763:    Input Parameters:
764: .  linesearch - linesearch context
766:    Options Database Keys:
767: + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
768: . -snes_linesearch_order <order> - 1, 2, 3.  Most types only support certain orders (bt supports 2 or 3)
769: . -snes_linesearch_norms   - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms())
770: . -snes_linesearch_minlambda - The minimum step length
771: . -snes_linesearch_maxstep - The maximum step size
772: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
773: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
774: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
775: . -snes_linesearch_max_it - The number of iterations for iterative line searches
776: . -snes_linesearch_monitor [:filename] - Print progress of line searches
777: . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
778: . -snes_linesearch_damping - The linesearch damping parameter
779: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
780: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
781: - -snes_linesearch_precheck_picard_angle - Angle used in Picard precheck method
783:    Logically Collective on SNESLineSearch
785:    Level: intermediate
787: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(),
788:           SNESLineSearchType, SNESLineSearchSetComputeNorms()
789: @*/
790: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
791: {
792:   PetscErrorCode    ierr;
793:   const char        *deft = SNESLINESEARCHBASIC;
794:   char              type[256];
795:   PetscBool         flg, set;
796:   PetscViewer       viewer;
799:   SNESLineSearchRegisterAll();
801:   PetscObjectOptionsBegin((PetscObject)linesearch);
802:   if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
803:   PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
804:   if (flg) {
805:     SNESLineSearchSetType(linesearch,type);
806:   } else if (!((PetscObject)linesearch)->type_name) {
807:     SNESLineSearchSetType(linesearch,deft);
808:   }
810:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject) linesearch)->options,((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);
811:   if (set) {
812:     SNESLineSearchSetDefaultMonitor(linesearch,viewer);
813:     PetscViewerDestroy(&viewer);
814:   }
815:   SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);
817:   /* tolerances */
818:   PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);
819:   PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);
820:   PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);
821:   PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);
822:   PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);
823:   PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);
825:   /* damping parameters */
826:   PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);
828:   PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL);
830:   /* precheck */
831:   PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);
832:   if (set) {
833:     if (flg) {
834:       linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
836:       PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
837:                               "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);
838:       SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
839:     } else {
840:       SNESLineSearchSetPreCheck(linesearch,NULL,NULL);
841:     }
842:   }
843:   PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);
844:   PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);
846:   if (linesearch->ops->setfromoptions) {
847:     (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);
848:   }
850:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);
851:   PetscOptionsEnd();
852:   return(0);
853: }
855: /*@
856:    SNESLineSearchView - Prints useful information about the line search
858:    Input Parameters:
859: .  linesearch - linesearch context
861:    Logically Collective on SNESLineSearch
863:    Level: intermediate
865: .seealso: SNESLineSearchCreate()
866: @*/
867: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
868: {
870:   PetscBool      iascii;
874:   if (!viewer) {
875:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);
876:   }
880:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
881:   if (iascii) {
882:     PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);
883:     if (linesearch->ops->view) {
884:       PetscViewerASCIIPushTab(viewer);
885:       (*linesearch->ops->view)(linesearch,viewer);
886:       PetscViewerASCIIPopTab(viewer);
887:     }
888:     PetscViewerASCIIPrintf(viewer,"  maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);
889:     PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);
890:     PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D\n", linesearch->max_its);
891:     if (linesearch->ops->precheck) {
892:       if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
893:         PetscViewerASCIIPrintf(viewer,"  using precheck step to speed up Picard convergence\n", linesearch->max_its);
894:       } else {
895:         PetscViewerASCIIPrintf(viewer,"  using user-defined precheck step\n", linesearch->max_its);
896:       }
897:     }
898:     if (linesearch->ops->postcheck) {
899:       PetscViewerASCIIPrintf(viewer,"  using user-defined postcheck step\n", linesearch->max_its);
900:     }
901:   }
902:   return(0);
903: }
905: /*@C
906:    SNESLineSearchGetType - Gets the linesearch type
908:    Logically Collective on SNESLineSearch
910:    Input Parameters:
911: .  linesearch - linesearch context
913:    Output Parameters:
914: -  type - The type of line search, or NULL if not set
916:    Level: intermediate
918: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchSetType()
919: @*/
920: PetscErrorCode SNESLineSearchGetType(SNESLineSearch linesearch, SNESLineSearchType *type)
921: {
925:   *type = ((PetscObject)linesearch)->type_name;
926:   return(0);
927: }
929: /*@C
930:    SNESLineSearchSetType - Sets the linesearch type
932:    Logically Collective on SNESLineSearch
934:    Input Parameters:
935: +  linesearch - linesearch context
936: -  type - The type of line search to be used
938:    Available Types:
939: +  SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
940: .  SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
941: .  SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
942: .  SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
943: .  SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
944: -  SNESLINESEARCHSHELL - User provided SNESLineSearch implementation
946:    Options Database:
947: .  -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
949:    Level: intermediate
951: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchGetType()
952: @*/
953: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
954: {
955:   PetscErrorCode ierr,(*r)(SNESLineSearch);
956:   PetscBool      match;
962:   PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
963:   if (match) return(0);
965:   PetscFunctionListFind(SNESLineSearchList,type,&r);
966:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
967:   /* Destroy the previous private linesearch context */
968:   if (linesearch->ops->destroy) {
969:     (*(linesearch)->ops->destroy)(linesearch);
970:     linesearch->ops->destroy = NULL;
971:   }
972:   /* Reinitialize function pointers in SNESLineSearchOps structure */
973:   linesearch->ops->apply          = NULL;
974:   linesearch->ops->view           = NULL;
975:   linesearch->ops->setfromoptions = NULL;
976:   linesearch->ops->destroy        = NULL;
978:   PetscObjectChangeTypeName((PetscObject)linesearch,type);
979:   (*r)(linesearch);
980:   return(0);
981: }
983: /*@
984:    SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
986:    Input Parameters:
987: +  linesearch - linesearch context
988: -  snes - The snes instance
990:    Level: developer
992:    Notes:
993:    This happens automatically when the line search is obtained/created with
994:    SNESGetLineSearch().  This routine is therefore mainly called within SNES
995:    implementations.
997:    Level: developer
999: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1000: @*/
1001: PetscErrorCode  SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
1002: {
1006:   linesearch->snes = snes;
1007:   return(0);
1008: }
1010: /*@
1011:    SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
1012:    Having an associated SNES is necessary because most line search implementations must be able to
1013:    evaluate the function using SNESComputeFunction() for the associated SNES.  This routine
1014:    is used in the line search implementations when one must get this associated SNES instance.
1016:    Input Parameters:
1017: .  linesearch - linesearch context
1019:    Output Parameters:
1020: .  snes - The snes instance
1022:    Level: developer
1024: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1025: @*/
1026: PetscErrorCode  SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1027: {
1031:   *snes = linesearch->snes;
1032:   return(0);
1033: }
1035: /*@
1036:    SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
1038:    Input Parameters:
1039: .  linesearch - linesearch context
1041:    Output Parameters:
1042: .  lambda - The last steplength computed during SNESLineSearchApply()
1044:    Level: advanced
1046:    Notes:
1047:    This is useful in methods where the solver is ill-scaled and
1048:    requires some adaptive notion of the difference in scale between the
1049:    solution and the function.  For instance, SNESQN may be scaled by the
1050:    line search lambda using the argument -snes_qn_scaling ls.
1052: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1053: @*/
1054: PetscErrorCode  SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1055: {
1059:   *lambda = linesearch->lambda;
1060:   return(0);
1061: }
1063: /*@
1064:    SNESLineSearchSetLambda - Sets the linesearch steplength.
1066:    Input Parameters:
1067: +  linesearch - linesearch context
1068: -  lambda - The last steplength.
1070:    Notes:
1071:    This routine is typically used within implementations of SNESLineSearchApply()
1072:    to set the final steplength.  This routine (and SNESLineSearchGetLambda()) were
1073:    added in order to facilitate Quasi-Newton methods that use the previous steplength
1074:    as an inner scaling parameter.
1076:    Level: advanced
1078: .seealso: SNESLineSearchGetLambda()
1079: @*/
1080: PetscErrorCode  SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1081: {
1084:   linesearch->lambda = lambda;
1085:   return(0);
1086: }
1088: /*@
1089:    SNESLineSearchGetTolerances - Gets the tolerances for the linesearch.  These include
1090:    tolerances for the relative and absolute change in the function norm, the change
1091:    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1092:    and the maximum number of iterations the line search procedure may take.
1094:    Input Parameters:
1095: .  linesearch - linesearch context
1097:    Output Parameters:
1098: +  steptol - The minimum steplength
1099: .  maxstep - The maximum steplength
1100: .  rtol    - The relative tolerance for iterative line searches
1101: .  atol    - The absolute tolerance for iterative line searches
1102: .  ltol    - The change in lambda tolerance for iterative line searches
1103: -  max_it  - The maximum number of iterations of the line search
1105:    Level: intermediate
1107:    Notes:
1108:    Different line searches may implement these parameters slightly differently as
1109:    the type requires.
1111: .seealso: SNESLineSearchSetTolerances()
1112: @*/
1113: PetscErrorCode  SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1114: {
1117:   if (steptol) {
1119:     *steptol = linesearch->steptol;
1120:   }
1121:   if (maxstep) {
1123:     *maxstep = linesearch->maxstep;
1124:   }
1125:   if (rtol) {
1127:     *rtol = linesearch->rtol;
1128:   }
1129:   if (atol) {
1131:     *atol = linesearch->atol;
1132:   }
1133:   if (ltol) {
1135:     *ltol = linesearch->ltol;
1136:   }
1137:   if (max_its) {
1139:     *max_its = linesearch->max_its;
1140:   }
1141:   return(0);
1142: }
1144: /*@
1145:    SNESLineSearchSetTolerances -  Gets the tolerances for the linesearch.  These include
1146:    tolerances for the relative and absolute change in the function norm, the change
1147:    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1148:    and the maximum number of iterations the line search procedure may take.
1150:    Input Parameters:
1151: +  linesearch - linesearch context
1152: .  steptol - The minimum steplength
1153: .  maxstep - The maximum steplength
1154: .  rtol    - The relative tolerance for iterative line searches
1155: .  atol    - The absolute tolerance for iterative line searches
1156: .  ltol    - The change in lambda tolerance for iterative line searches
1157: -  max_it  - The maximum number of iterations of the line search
1159:    Notes:
1160:    The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1161:    place of an argument.
1163:    Level: intermediate
1165: .seealso: SNESLineSearchGetTolerances()
1166: @*/
1167: PetscErrorCode  SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1168: {
1178:   if (steptol!= PETSC_DEFAULT) {
1179:     if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
1180:     linesearch->steptol = steptol;
1181:   }
1183:   if (maxstep!= PETSC_DEFAULT) {
1184:     if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1185:     linesearch->maxstep = maxstep;
1186:   }
1188:   if (rtol != PETSC_DEFAULT) {
1189:     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);
1190:     linesearch->rtol = rtol;
1191:   }
1193:   if (atol != PETSC_DEFAULT) {
1194:     if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1195:     linesearch->atol = atol;
1196:   }
1198:   if (ltol != PETSC_DEFAULT) {
1199:     if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Lambda tolerance %14.12e must be non-negative",(double)ltol);
1200:     linesearch->ltol = ltol;
1201:   }
1203:   if (max_its != PETSC_DEFAULT) {
1204:     if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1205:     linesearch->max_its = max_its;
1206:   }
1207:   return(0);
1208: }
1210: /*@
1211:    SNESLineSearchGetDamping - Gets the line search damping parameter.
1213:    Input Parameters:
1214: .  linesearch - linesearch context
1216:    Output Parameters:
1217: .  damping - The damping parameter
1219:    Level: advanced
1221: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1222: @*/
1224: PetscErrorCode  SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1225: {
1229:   *damping = linesearch->damping;
1230:   return(0);
1231: }
1233: /*@
1234:    SNESLineSearchSetDamping - Sets the line search damping parameter.
1236:    Input Parameters:
1237: +  linesearch - linesearch context
1238: -  damping - The damping parameter
1240:    Options Database:
1241: .   -snes_linesearch_damping
1242:    Level: intermediate
1244:    Notes:
1245:    The basic line search merely takes the update step scaled by the damping parameter.
1246:    The use of the damping parameter in the l2 and cp line searches is much more subtle;
1247:    it is used as a starting point in calculating the secant step. However, the eventual
1248:    step may be of greater length than the damping parameter.  In the bt line search it is
1249:    used as the maximum possible step length, as the bt line search only backtracks.
1251: .seealso: SNESLineSearchGetDamping()
1252: @*/
1253: PetscErrorCode  SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1254: {
1257:   linesearch->damping = damping;
1258:   return(0);
1259: }
1261: /*@
1262:    SNESLineSearchGetOrder - Gets the line search approximation order.
1264:    Input Parameters:
1265: .  linesearch - linesearch context
1267:    Output Parameters:
1268: .  order - The order
1270:    Possible Values for order:
1271: +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1272: .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1273: -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1275:    Level: intermediate
1277: .seealso: SNESLineSearchSetOrder()
1278: @*/
1280: PetscErrorCode  SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1281: {
1285:   *order = linesearch->order;
1286:   return(0);
1287: }
1289: /*@
1290:    SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
1292:    Input Parameters:
1293: +  linesearch - linesearch context
1294: -  order - The damping parameter
1296:    Level: intermediate
1298:    Possible Values for order:
1299: +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1300: .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1301: -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1303:    Notes:
1304:    Variable orders are supported by the following line searches:
1305: +  bt - cubic and quadratic
1306: -  cp - linear and quadratic
1308: .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1309: @*/
1310: PetscErrorCode  SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1311: {
1314:   linesearch->order = order;
1315:   return(0);
1316: }
1318: /*@
1319:    SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1321:    Input Parameters:
1322: .  linesearch - linesearch context
1324:    Output Parameters:
1325: +  xnorm - The norm of the current solution
1326: .  fnorm - The norm of the current function
1327: -  ynorm - The norm of the current update
1329:    Notes:
1330:    This function is mainly called from SNES implementations.
1332:    Level: developer
1334: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1335: @*/
1336: PetscErrorCode  SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1337: {
1340:   if (xnorm) *xnorm = linesearch->xnorm;
1341:   if (fnorm) *fnorm = linesearch->fnorm;
1342:   if (ynorm) *ynorm = linesearch->ynorm;
1343:   return(0);
1344: }
1346: /*@
1347:    SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1349:    Input Parameters:
1350: +  linesearch - linesearch context
1351: .  xnorm - The norm of the current solution
1352: .  fnorm - The norm of the current function
1353: -  ynorm - The norm of the current update
1355:    Level: advanced
1357: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1358: @*/
1359: PetscErrorCode  SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1360: {
1363:   linesearch->xnorm = xnorm;
1364:   linesearch->fnorm = fnorm;
1365:   linesearch->ynorm = ynorm;
1366:   return(0);
1367: }
1369: /*@
1370:    SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1372:    Input Parameters:
1373: .  linesearch - linesearch context
1375:    Options Database Keys:
1376: .   -snes_linesearch_norms - turn norm computation on or off
1378:    Level: intermediate
1380: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1381: @*/
1382: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1383: {
1385:   SNES           snes;
1388:   if (linesearch->norms) {
1389:     if (linesearch->ops->vinorm) {
1390:       SNESLineSearchGetSNES(linesearch, &snes);
1391:       VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1392:       VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1393:       (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1394:     } else {
1395:       VecNormBegin(linesearch->vec_func,   NORM_2, &linesearch->fnorm);
1396:       VecNormBegin(linesearch->vec_sol,    NORM_2, &linesearch->xnorm);
1397:       VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1398:       VecNormEnd(linesearch->vec_func,     NORM_2, &linesearch->fnorm);
1399:       VecNormEnd(linesearch->vec_sol,      NORM_2, &linesearch->xnorm);
1400:       VecNormEnd(linesearch->vec_update,   NORM_2, &linesearch->ynorm);
1401:     }
1402:   }
1403:   return(0);
1404: }
1406: /*@
1407:    SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
1409:    Input Parameters:
1410: +  linesearch  - linesearch context
1411: -  flg  - indicates whether or not to compute norms
1413:    Options Database Keys:
1414: .   -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch
1416:    Notes:
1417:    This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm.
1419:    Level: intermediate
1421: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1422: @*/
1423: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1424: {
1426:   linesearch->norms = flg;
1427:   return(0);
1428: }
1430: /*@
1431:    SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1433:    Input Parameters:
1434: .  linesearch - linesearch context
1436:    Output Parameters:
1437: +  X - Solution vector
1438: .  F - Function vector
1439: .  Y - Search direction vector
1440: .  W - Solution work vector
1441: -  G - Function work vector
1443:    Notes:
1444:    At the beginning of a line search application, X should contain a
1445:    solution and the vector F the function computed at X.  At the end of the
1446:    line search application, X should contain the new solution, and F the
1447:    function evaluated at the new solution.
1449:    These vectors are owned by the SNESLineSearch and should not be destroyed by the caller
1451:    Level: advanced
1453: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1454: @*/
1455: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1456: {
1459:   if (X) {
1461:     *X = linesearch->vec_sol;
1462:   }
1463:   if (F) {
1465:     *F = linesearch->vec_func;
1466:   }
1467:   if (Y) {
1469:     *Y = linesearch->vec_update;
1470:   }
1471:   if (W) {
1473:     *W = linesearch->vec_sol_new;
1474:   }
1475:   if (G) {
1477:     *G = linesearch->vec_func_new;
1478:   }
1479:   return(0);
1480: }
1482: /*@
1483:    SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1485:    Input Parameters:
1486: +  linesearch - linesearch context
1487: .  X - Solution vector
1488: .  F - Function vector
1489: .  Y - Search direction vector
1490: .  W - Solution work vector
1491: -  G - Function work vector
1493:    Level: advanced
1495: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1496: @*/
1497: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1498: {
1501:   if (X) {
1503:     linesearch->vec_sol = X;
1504:   }
1505:   if (F) {
1507:     linesearch->vec_func = F;
1508:   }
1509:   if (Y) {
1511:     linesearch->vec_update = Y;
1512:   }
1513:   if (W) {
1515:     linesearch->vec_sol_new = W;
1516:   }
1517:   if (G) {
1519:     linesearch->vec_func_new = G;
1520:   }
1521:   return(0);
1522: }
1524: /*@C
1525:    SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1526:    SNES options in the database.
1528:    Logically Collective on SNESLineSearch
1530:    Input Parameters:
1531: +  snes - the SNES context
1532: -  prefix - the prefix to prepend to all option names
1534:    Notes:
1535:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1536:    The first character of all runtime options is AUTOMATICALLY the hyphen.
1538:    Level: advanced
1540: .seealso: SNESGetOptionsPrefix()
1541: @*/
1542: PetscErrorCode  SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1543: {
1548:   PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1549:   return(0);
1550: }
1552: /*@C
1553:    SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1554:    SNESLineSearch options in the database.
1556:    Not Collective
1558:    Input Parameter:
1559: .  linesearch - the SNESLineSearch context
1561:    Output Parameter:
1562: .  prefix - pointer to the prefix string used
1564:    Notes:
1565:    On the fortran side, the user should pass in a string 'prefix' of
1566:    sufficient length to hold the prefix.
1568:    Level: advanced
1570: .seealso: SNESAppendOptionsPrefix()
1571: @*/
1572: PetscErrorCode  SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1573: {
1578:   PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1579:   return(0);
1580: }
1582: /*@C
1583:    SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1585:    Input Parameter:
1586: +  linesearch - the SNESLineSearch context
1587: -  nwork - the number of work vectors
1589:    Level: developer
1591: .seealso: SNESSetWorkVecs()
1592: @*/
1593: PetscErrorCode  SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1594: {
1598:   if (linesearch->vec_sol) {
1599:     VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1600:   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1601:   return(0);
1602: }
1604: /*@
1605:    SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1607:    Input Parameters:
1608: .  linesearch - linesearch context
1610:    Output Parameters:
1611: .  result - The success or failure status
1613:    Notes:
1614:    This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1615:    (and set the SNES convergence accordingly).
1617:    Level: intermediate
1619: .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1620: @*/
1621: PetscErrorCode  SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1622: {
1626:   *result = linesearch->result;
1627:   return(0);
1628: }
1630: /*@
1631:    SNESLineSearchSetReason - Sets the success/failure status of the last line search application
1633:    Input Parameters:
1634: +  linesearch - linesearch context
1635: -  result - The success or failure status
1637:    Notes:
1638:    This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1639:    the success or failure of the line search method.
1641:    Level: developer
1643: .seealso: SNESLineSearchGetSResult()
1644: @*/
1645: PetscErrorCode  SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1646: {
1649:   linesearch->result = result;
1650:   return(0);
1651: }
1653: /*@C
1654:    SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
1656:    Input Parameters:
1657: +  snes - nonlinear context obtained from SNESCreate()
1658: .  projectfunc - function for projecting the function to the bounds
1659: -  normfunc - function for computing the norm of an active set
1661:    Logically Collective on SNES
1663:    Calling sequence of projectfunc:
1664: .vb
1665:    projectfunc (SNES snes, Vec X)
1666: .ve
1668:     Input parameters for projectfunc:
1669: +   snes - nonlinear context
1670: -   X - current solution
1672:     Output parameters for projectfunc:
1673: .   X - Projected solution
1675:    Calling sequence of normfunc:
1676: .vb
1677:    projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1678: .ve
1680:     Input parameters for normfunc:
1681: +   snes - nonlinear context
1682: .   X - current solution
1683: -   F - current residual
1685:     Output parameters for normfunc:
1686: .   fnorm - VI-specific norm of the function
1688:     Notes:
1689:     The VI solvers require projection of the solution to the feasible set.  projectfunc should implement this.
1691:     The VI solvers require special evaluation of the function norm such that the norm is only calculated
1692:     on the inactive set.  This should be implemented by normfunc.
1694:     Level: developer
1696: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1697: @*/
1698: PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1699: {
1702:   if (projectfunc) linesearch->ops->viproject = projectfunc;
1703:   if (normfunc) linesearch->ops->vinorm = normfunc;
1704:   return(0);
1705: }
1707: /*@C
1708:    SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
1710:    Input Parameters:
1711: .  linesearch - the line search context, obtain with SNESGetLineSearch()
1713:    Output Parameters:
1714: +  projectfunc - function for projecting the function to the bounds
1715: -  normfunc - function for computing the norm of an active set
1717:    Logically Collective on SNES
1719:     Level: developer
1721: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1722: @*/
1723: PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1724: {
1726:   if (projectfunc) *projectfunc = linesearch->ops->viproject;
1727:   if (normfunc) *normfunc = linesearch->ops->vinorm;
1728:   return(0);
1729: }
1731: /*@C
1732:   SNESLineSearchRegister - See SNESLineSearchRegister()
1734:   Level: advanced
1735: @*/
1736: PetscErrorCode  SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1737: {
1741:   SNESInitializePackage();
1742:   PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1743:   return(0);
1744: }