Actual source code: linesearch.c

petsc-3.13.6 2020-09-29
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: .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:   *outlinesearch           = linesearch;
210:   return(0);
211: }

213: /*@
214:    SNESLineSearchSetUp - Prepares the line search for being applied by allocating
215:    any required vectors.

217:    Collective on SNESLineSearch

219:    Input Parameters:
220: .  linesearch - The LineSearch instance.

222:    Notes:
223:    For most cases, this needn't be called by users or outside of SNESLineSearchApply().
224:    The only current case where this is called outside of this is for the VI
225:    solvers, which modify the solution and work vectors before the first call
226:    of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be
227:    allocated upfront.

229:    Level: advanced

231: .seealso: SNESGetLineSearch(), SNESLineSearchReset()
232: @*/

234: PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
235: {

239:   if (!((PetscObject)linesearch)->type_name) {
240:     SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);
241:   }
242:   if (!linesearch->setupcalled) {
243:     if (!linesearch->vec_sol_new) {
244:       VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);
245:     }
246:     if (!linesearch->vec_func_new) {
247:       VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);
248:     }
249:     if (linesearch->ops->setup) {
250:       (*linesearch->ops->setup)(linesearch);
251:     }
252:     if (!linesearch->ops->snesfunc) {SNESLineSearchSetFunction(linesearch,SNESComputeFunction);}
253:     linesearch->lambda      = linesearch->damping;
254:     linesearch->setupcalled = PETSC_TRUE;
255:   }
256:   return(0);
257: }


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

263:    Collective on SNESLineSearch

265:    Input Parameters:
266: .  linesearch - The LineSearch instance.

268:    Notes:
269:     Usually only called by SNESReset()

271:    Level: developer

273: .seealso: SNESGetLineSearch(), SNESLineSearchSetUp()
274: @*/

276: PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
277: {

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

283:   VecDestroy(&linesearch->vec_sol_new);
284:   VecDestroy(&linesearch->vec_func_new);

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

288:   linesearch->nwork       = 0;
289:   linesearch->setupcalled = PETSC_FALSE;
290:   return(0);
291: }

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

296:    Input Parameters:
297: .  linesearch - the SNESLineSearch context
298: +  func       - function evaluation routine

300:    Level: developer

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

305: .seealso: SNESGetLineSearch(), SNESSetFunction()
306: @*/
307: PetscErrorCode  SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
308: {
311:   linesearch->ops->snesfunc = func;
312:   return(0);
313: }

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

320:    Logically Collective on SNESLineSearch

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

327:    Level: intermediate

329: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
330: @*/
331: PetscErrorCode  SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
332: {
335:   if (func) linesearch->ops->precheck = func;
336:   if (ctx) linesearch->precheckctx = ctx;
337:   return(0);
338: }

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

343:    Input Parameters:
344: .  linesearch - the SNESLineSearch context

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

350:    Level: intermediate

352: .seealso: SNESGetLineSearch(), SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck()
353: @*/
354: PetscErrorCode  SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
355: {
358:   if (func) *func = linesearch->ops->precheck;
359:   if (ctx) *ctx = linesearch->precheckctx;
360:   return(0);
361: }

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

367:    Logically Collective on SNESLineSearch

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

374:    Level: intermediate

376: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchGetPostCheck()
377: @*/
378: PetscErrorCode  SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
379: {
382:   if (func) linesearch->ops->postcheck = func;
383:   if (ctx) linesearch->postcheckctx = ctx;
384:   return(0);
385: }

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

390:    Input Parameters:
391: .  linesearch - the SNESLineSearch context

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

397:    Level: intermediate

399: .seealso: SNESGetLineSearch(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck()
400: @*/
401: PetscErrorCode  SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
402: {
405:   if (func) *func = linesearch->ops->postcheck;
406:   if (ctx) *ctx = linesearch->postcheckctx;
407:   return(0);
408: }

410: /*@
411:    SNESLineSearchPreCheck - Prepares the line search for being applied.

413:    Logically Collective on SNESLineSearch

415:    Input Parameters:
416: +  linesearch - The linesearch instance.
417: .  X - The current solution
418: -  Y - The step direction

420:    Output Parameters:
421: .  changed - Indicator that the precheck routine has changed anything

423:    Level: developer

425: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck()
426: @*/
427: PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
428: {

432:   *changed = PETSC_FALSE;
433:   if (linesearch->ops->precheck) {
434:     (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);
436:   }
437:   return(0);
438: }

440: /*@
441:    SNESLineSearchPostCheck - Prepares the line search for being applied.

443:    Logically Collective on SNESLineSearch

445:    Input Parameters:
446: +  linesearch - The linesearch context
447: .  X - The last solution
448: .  Y - The step direction
449: -  W - The updated solution, W = X + lambda*Y for some lambda

451:    Output Parameters:
452: +  changed_Y - Indicator if the direction Y has been changed.
453: -  changed_W - Indicator if the new candidate solution W has been changed.

455:    Level: developer

457: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPrecheck(), SNESLineSearchGetPrecheck()
458: @*/
459: PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
460: {

464:   *changed_Y = PETSC_FALSE;
465:   *changed_W = PETSC_FALSE;
466:   if (linesearch->ops->postcheck) {
467:     (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);
470:   }
471:   return(0);
472: }

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

477:    Logically Collective on SNESLineSearch

479:    Input Arguments:
480: +  linesearch - linesearch context
481: .  X - base state for this step
482: .  Y - initial correction
483: -  ctx - context for this function

485:    Output Arguments:
486: +  Y - correction, possibly modified
487: -  changed - flag indicating that Y was modified

489:    Options Database Key:
490: +  -snes_linesearch_precheck_picard - activate this routine
491: -  -snes_linesearch_precheck_picard_angle - angle

493:    Level: advanced

495:    Notes:
496:    This function should be passed to SNESLineSearchSetPreCheck()

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

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

505: .seealso: SNESGetLineSearch(), SNESLineSearchSetPreCheck()
506: @*/
507: PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
508: {
510:   PetscReal      angle = *(PetscReal*)linesearch->precheckctx;
511:   Vec            Ylast;
512:   PetscScalar    dot;
513:   PetscInt       iter;
514:   PetscReal      ynorm,ylastnorm,theta,angle_radians;
515:   SNES           snes;

518:   SNESLineSearchGetSNES(linesearch, &snes);
519:   PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);
520:   if (!Ylast) {
521:     VecDuplicate(Y,&Ylast);
522:     PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);
523:     PetscObjectDereference((PetscObject)Ylast);
524:   }
525:   SNESGetIterationNumber(snes,&iter);
526:   if (iter < 2) {
527:     VecCopy(Y,Ylast);
528:     *changed = PETSC_FALSE;
529:     return(0);
530:   }

532:   VecDot(Y,Ylast,&dot);
533:   VecNorm(Y,NORM_2,&ynorm);
534:   VecNorm(Ylast,NORM_2,&ylastnorm);
535:   /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
536:   theta         = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
537:   angle_radians = angle * PETSC_PI / 180.;
538:   if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
539:     /* Modify the step Y */
540:     PetscReal alpha,ydiffnorm;
541:     VecAXPY(Ylast,-1.0,Y);
542:     VecNorm(Ylast,NORM_2,&ydiffnorm);
543:     alpha = (ydiffnorm > .001*ylastnorm) ? ylastnorm / ydiffnorm : 1000.0;
544:     VecCopy(Y,Ylast);
545:     VecScale(Y,alpha);
546:     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);
547:     *changed = PETSC_TRUE;
548:   } else {
549:     PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);
550:     VecCopy(Y,Ylast);
551:     *changed = PETSC_FALSE;
552:   }
553:   return(0);
554: }

556: /*@
557:    SNESLineSearchApply - Computes the line-search update.

559:    Collective on SNESLineSearch

561:    Input Parameters:
562: +  linesearch - The linesearch context
563: .  X - The current solution
564: .  F - The current function
565: .  fnorm - The current norm
566: -  Y - The search direction

568:    Output Parameters:
569: +  X - The new solution
570: .  F - The new function
571: -  fnorm - The new function norm

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

581:    Notes:
582:    This is typically called from within a SNESSolve() implementation in order to
583:    help with convergence of the nonlinear method.  Various SNES types use line searches
584:    in different ways, but the overarching theme is that a line search is used to determine
585:    an optimal damping parameter of a step at each iteration of the method.  Each
586:    Section 1.5 Writing Application Codes with PETSc of the line search may invoke SNESComputeFunction() several times, and
587:    therefore may be fairly expensive.

589:    Level: Intermediate

591: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(),
592:           SNESLineSearchType, SNESLineSearchSetType()
593: @*/
594: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
595: {


604:   linesearch->result = SNES_LINESEARCH_SUCCEEDED;

606:   linesearch->vec_sol    = X;
607:   linesearch->vec_update = Y;
608:   linesearch->vec_func   = F;

610:   SNESLineSearchSetUp(linesearch);

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

614:   if (fnorm) linesearch->fnorm = *fnorm;
615:   else {
616:     VecNorm(F, NORM_2, &linesearch->fnorm);
617:   }

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

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

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

625:   if (fnorm) *fnorm = linesearch->fnorm;
626:   return(0);
627: }

629: /*@
630:    SNESLineSearchDestroy - Destroys the line search instance.

632:    Collective on SNESLineSearch

634:    Input Parameters:
635: .  linesearch - The linesearch context

637:    Level: developer

639: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
640: @*/
641: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
642: {

646:   if (!*linesearch) return(0);
648:   if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; return(0);}
649:   PetscObjectSAWsViewOff((PetscObject)*linesearch);
650:   SNESLineSearchReset(*linesearch);
651:   if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
652:   PetscViewerDestroy(&(*linesearch)->monitor);
653:   SNESLineSearchMonitorCancel((*linesearch));
654:   PetscHeaderDestroy(linesearch);
655:   return(0);
656: }

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

661:    Input Parameters:
662: +  linesearch - the linesearch object
663: -  viewer - an ASCII PetscViewer or NULL to turn off monitor

665:    Logically Collective on SNESLineSearch

667:    Options Database:
668: .   -snes_linesearch_monitor [:filename] - enables the monitor

670:    Level: intermediate

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

676: .seealso: SNESGetLineSearch(), SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor()
677: @*/
678: PetscErrorCode  SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
679: {

683:   if (viewer) {PetscObjectReference((PetscObject)viewer);}
684:   PetscViewerDestroy(&linesearch->monitor);
685:   linesearch->monitor = viewer;
686:   return(0);
687: }

689: /*@
690:    SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.

692:    Input Parameter:
693: .  linesearch - linesearch context

695:    Output Parameter:
696: .  monitor - monitor context

698:    Logically Collective on SNES

700:    Options Database Keys:
701: .   -snes_linesearch_monitor - enables the monitor

703:    Level: intermediate

705: .seealso: SNESGetLineSearch(), SNESLineSearchSetDefaultMonitor(), PetscViewer
706: @*/
707: PetscErrorCode  SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
708: {
711:   if (monitor) {
713:     *monitor = linesearch->monitor;
714:   }
715:   return(0);
716: }

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

721:    Collective on SNESLineSearch

723:    Input Parameters:
724: +  ls - LineSearch object you wish to monitor
725: .  name - the monitor type one is seeking
726: .  help - message indicating what monitoring is done
727: .  manual - manual page for the monitor
728: .  monitor - the monitor function
729: -  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

731:    Level: developer

733: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
734:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
735:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
736:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
737:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
738:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
739:           PetscOptionsFList(), PetscOptionsEList()
740: @*/
741: PetscErrorCode  SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
742: {
743:   PetscErrorCode    ierr;
744:   PetscViewer       viewer;
745:   PetscViewerFormat format;
746:   PetscBool         flg;

749:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject) ls)->options,((PetscObject)ls)->prefix,name,&viewer,&format,&flg);
750:   if (flg) {
751:     PetscViewerAndFormat *vf;
752:     PetscViewerAndFormatCreate(viewer,format,&vf);
753:     PetscObjectDereference((PetscObject)viewer);
754:     if (monitorsetup) {
755:       (*monitorsetup)(ls,vf);
756:     }
757:     SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
758:   }
759:   return(0);
760: }

762: /*@
763:    SNESLineSearchSetFromOptions - Sets options for the line search

765:    Input Parameters:
766: .  linesearch - linesearch context

768:    Options Database Keys:
769: + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
770: . -snes_linesearch_order <order> - 1, 2, 3.  Most types only support certain orders (bt supports 2 or 3)
771: . -snes_linesearch_norms   - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms())
772: . -snes_linesearch_minlambda - The minimum step length
773: . -snes_linesearch_maxstep - The maximum step size
774: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
775: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
776: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
777: . -snes_linesearch_max_it - The number of iterations for iterative line searches
778: . -snes_linesearch_monitor [:filename] - Print progress of line searches
779: . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
780: . -snes_linesearch_damping - The linesearch damping parameter
781: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
782: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
783: - -snes_linesearch_precheck_picard_angle - Angle used in Picard precheck method

785:    Logically Collective on SNESLineSearch

787:    Level: intermediate

789: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(),
790:           SNESLineSearchType, SNESLineSearchSetComputeNorms()
791: @*/
792: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
793: {
794:   PetscErrorCode    ierr;
795:   const char        *deft = SNESLINESEARCHBASIC;
796:   char              type[256];
797:   PetscBool         flg, set;
798:   PetscViewer       viewer;

801:   SNESLineSearchRegisterAll();

803:   PetscObjectOptionsBegin((PetscObject)linesearch);
804:   if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
805:   PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
806:   if (flg) {
807:     SNESLineSearchSetType(linesearch,type);
808:   } else if (!((PetscObject)linesearch)->type_name) {
809:     SNESLineSearchSetType(linesearch,deft);
810:   }

812:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject) linesearch)->options,((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);
813:   if (set) {
814:     SNESLineSearchSetDefaultMonitor(linesearch,viewer);
815:     PetscViewerDestroy(&viewer);
816:   }
817:   SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);

819:   /* tolerances */
820:   PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);
821:   PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);
822:   PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);
823:   PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);
824:   PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);
825:   PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);

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

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

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

838:       PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
839:                               "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);
840:       SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
841:     } else {
842:       SNESLineSearchSetPreCheck(linesearch,NULL,NULL);
843:     }
844:   }
845:   PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);
846:   PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);

848:   if (linesearch->ops->setfromoptions) {
849:     (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);
850:   }

852:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);
853:   PetscOptionsEnd();
854:   return(0);
855: }

857: /*@
858:    SNESLineSearchView - Prints useful information about the line search

860:    Input Parameters:
861: .  linesearch - linesearch context

863:    Logically Collective on SNESLineSearch

865:    Level: intermediate

867: .seealso: SNESLineSearchCreate()
868: @*/
869: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
870: {
872:   PetscBool      iascii;

876:   if (!viewer) {
877:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);
878:   }

882:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
883:   if (iascii) {
884:     PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);
885:     if (linesearch->ops->view) {
886:       PetscViewerASCIIPushTab(viewer);
887:       (*linesearch->ops->view)(linesearch,viewer);
888:       PetscViewerASCIIPopTab(viewer);
889:     }
890:     PetscViewerASCIIPrintf(viewer,"  maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);
891:     PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);
892:     PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D\n", linesearch->max_its);
893:     if (linesearch->ops->precheck) {
894:       if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
895:         PetscViewerASCIIPrintf(viewer,"  using precheck step to speed up Picard convergence\n", linesearch->max_its);
896:       } else {
897:         PetscViewerASCIIPrintf(viewer,"  using user-defined precheck step\n", linesearch->max_its);
898:       }
899:     }
900:     if (linesearch->ops->postcheck) {
901:       PetscViewerASCIIPrintf(viewer,"  using user-defined postcheck step\n", linesearch->max_its);
902:     }
903:   }
904:   return(0);
905: }

907: /*@C
908:    SNESLineSearchGetType - Gets the linesearch type

910:    Logically Collective on SNESLineSearch

912:    Input Parameters:
913: .  linesearch - linesearch context

915:    Output Parameters:
916: -  type - The type of line search, or NULL if not set

918:    Level: intermediate

920: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchSetType()
921: @*/
922: PetscErrorCode SNESLineSearchGetType(SNESLineSearch linesearch, SNESLineSearchType *type)
923: {
927:   *type = ((PetscObject)linesearch)->type_name;
928:   return(0);
929: }

931: /*@C
932:    SNESLineSearchSetType - Sets the linesearch type

934:    Logically Collective on SNESLineSearch

936:    Input Parameters:
937: +  linesearch - linesearch context
938: -  type - The type of line search to be used

940:    Available Types:
941: +  SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
942: .  SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
943: .  SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
944: .  SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
945: .  SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
946: -  SNESLINESEARCHSHELL - User provided SNESLineSearch implementation

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

951:    Level: intermediate

953: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchGetType()
954: @*/
955: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
956: {
957:   PetscErrorCode ierr,(*r)(SNESLineSearch);
958:   PetscBool      match;


964:   PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
965:   if (match) return(0);

967:   PetscFunctionListFind(SNESLineSearchList,type,&r);
968:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
969:   /* Destroy the previous private linesearch context */
970:   if (linesearch->ops->destroy) {
971:     (*(linesearch)->ops->destroy)(linesearch);

973:     linesearch->ops->destroy = NULL;
974:   }
975:   /* Reinitialize function pointers in SNESLineSearchOps structure */
976:   linesearch->ops->apply          = 0;
977:   linesearch->ops->view           = 0;
978:   linesearch->ops->setfromoptions = 0;
979:   linesearch->ops->destroy        = 0;

981:   PetscObjectChangeTypeName((PetscObject)linesearch,type);
982:   (*r)(linesearch);
983:   return(0);
984: }

986: /*@
987:    SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.

989:    Input Parameters:
990: +  linesearch - linesearch context
991: -  snes - The snes instance

993:    Level: developer

995:    Notes:
996:    This happens automatically when the line search is obtained/created with
997:    SNESGetLineSearch().  This routine is therefore mainly called within SNES
998:    implementations.

1000:    Level: developer

1002: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1003: @*/
1004: PetscErrorCode  SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
1005: {
1009:   linesearch->snes = snes;
1010:   return(0);
1011: }

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

1019:    Input Parameters:
1020: .  linesearch - linesearch context

1022:    Output Parameters:
1023: .  snes - The snes instance

1025:    Level: developer

1027: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1028: @*/
1029: PetscErrorCode  SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1030: {
1034:   *snes = linesearch->snes;
1035:   return(0);
1036: }

1038: /*@
1039:    SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.

1041:    Input Parameters:
1042: .  linesearch - linesearch context

1044:    Output Parameters:
1045: .  lambda - The last steplength computed during SNESLineSearchApply()

1047:    Level: advanced

1049:    Notes:
1050:    This is useful in methods where the solver is ill-scaled and
1051:    requires some adaptive notion of the difference in scale between the
1052:    solution and the function.  For instance, SNESQN may be scaled by the
1053:    line search lambda using the argument -snes_qn_scaling ls.

1055: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1056: @*/
1057: PetscErrorCode  SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1058: {
1062:   *lambda = linesearch->lambda;
1063:   return(0);
1064: }

1066: /*@
1067:    SNESLineSearchSetLambda - Sets the linesearch steplength.

1069:    Input Parameters:
1070: +  linesearch - linesearch context
1071: -  lambda - The last steplength.

1073:    Notes:
1074:    This routine is typically used within implementations of SNESLineSearchApply()
1075:    to set the final steplength.  This routine (and SNESLineSearchGetLambda()) were
1076:    added in order to facilitate Quasi-Newton methods that use the previous steplength
1077:    as an inner scaling parameter.

1079:    Level: advanced

1081: .seealso: SNESLineSearchGetLambda()
1082: @*/
1083: PetscErrorCode  SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1084: {
1087:   linesearch->lambda = lambda;
1088:   return(0);
1089: }

1091: /*@
1092:    SNESLineSearchGetTolerances - Gets the tolerances for the linesearch.  These include
1093:    tolerances for the relative and absolute change in the function norm, the change
1094:    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1095:    and the maximum number of iterations the line search procedure may take.

1097:    Input Parameters:
1098: .  linesearch - linesearch context

1100:    Output Parameters:
1101: +  steptol - The minimum steplength
1102: .  maxstep - The maximum steplength
1103: .  rtol    - The relative tolerance for iterative line searches
1104: .  atol    - The absolute tolerance for iterative line searches
1105: .  ltol    - The change in lambda tolerance for iterative line searches
1106: -  max_it  - The maximum number of iterations of the line search

1108:    Level: intermediate

1110:    Notes:
1111:    Different line searches may implement these parameters slightly differently as
1112:    the type requires.

1114: .seealso: SNESLineSearchSetTolerances()
1115: @*/
1116: PetscErrorCode  SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1117: {
1120:   if (steptol) {
1122:     *steptol = linesearch->steptol;
1123:   }
1124:   if (maxstep) {
1126:     *maxstep = linesearch->maxstep;
1127:   }
1128:   if (rtol) {
1130:     *rtol = linesearch->rtol;
1131:   }
1132:   if (atol) {
1134:     *atol = linesearch->atol;
1135:   }
1136:   if (ltol) {
1138:     *ltol = linesearch->ltol;
1139:   }
1140:   if (max_its) {
1142:     *max_its = linesearch->max_its;
1143:   }
1144:   return(0);
1145: }

1147: /*@
1148:    SNESLineSearchSetTolerances -  Gets the tolerances for the linesearch.  These include
1149:    tolerances for the relative and absolute change in the function norm, the change
1150:    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1151:    and the maximum number of iterations the line search procedure may take.

1153:    Input Parameters:
1154: +  linesearch - linesearch context
1155: .  steptol - The minimum steplength
1156: .  maxstep - The maximum steplength
1157: .  rtol    - The relative tolerance for iterative line searches
1158: .  atol    - The absolute tolerance for iterative line searches
1159: .  ltol    - The change in lambda tolerance for iterative line searches
1160: -  max_it  - The maximum number of iterations of the line search

1162:    Notes:
1163:    The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1164:    place of an argument.

1166:    Level: intermediate

1168: .seealso: SNESLineSearchGetTolerances()
1169: @*/
1170: PetscErrorCode  SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1171: {

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

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

1191:   if (rtol != PETSC_DEFAULT) {
1192:     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);
1193:     linesearch->rtol = rtol;
1194:   }

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

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

1206:   if (max_its != PETSC_DEFAULT) {
1207:     if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1208:     linesearch->max_its = max_its;
1209:   }
1210:   return(0);
1211: }

1213: /*@
1214:    SNESLineSearchGetDamping - Gets the line search damping parameter.

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

1219:    Output Parameters:
1220: .  damping - The damping parameter

1222:    Level: advanced

1224: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1225: @*/

1227: PetscErrorCode  SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1228: {
1232:   *damping = linesearch->damping;
1233:   return(0);
1234: }

1236: /*@
1237:    SNESLineSearchSetDamping - Sets the line search damping parameter.

1239:    Input Parameters:
1240: +  linesearch - linesearch context
1241: -  damping - The damping parameter

1243:    Options Database:
1244: .   -snes_linesearch_damping
1245:    Level: intermediate

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

1254: .seealso: SNESLineSearchGetDamping()
1255: @*/
1256: PetscErrorCode  SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1257: {
1260:   linesearch->damping = damping;
1261:   return(0);
1262: }

1264: /*@
1265:    SNESLineSearchGetOrder - Gets the line search approximation order.

1267:    Input Parameters:
1268: .  linesearch - linesearch context

1270:    Output Parameters:
1271: .  order - The order

1273:    Possible Values for order:
1274: +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1275: .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1276: -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order

1278:    Level: intermediate

1280: .seealso: SNESLineSearchSetOrder()
1281: @*/

1283: PetscErrorCode  SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1284: {
1288:   *order = linesearch->order;
1289:   return(0);
1290: }

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

1295:    Input Parameters:
1296: +  linesearch - linesearch context
1297: -  order - The damping parameter

1299:    Level: intermediate

1301:    Possible Values for order:
1302: +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1303: .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1304: -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order

1306:    Notes:
1307:    Variable orders are supported by the following line searches:
1308: +  bt - cubic and quadratic
1309: -  cp - linear and quadratic

1311: .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1312: @*/
1313: PetscErrorCode  SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1314: {
1317:   linesearch->order = order;
1318:   return(0);
1319: }

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

1324:    Input Parameters:
1325: .  linesearch - linesearch context

1327:    Output Parameters:
1328: +  xnorm - The norm of the current solution
1329: .  fnorm - The norm of the current function
1330: -  ynorm - The norm of the current update

1332:    Notes:
1333:    This function is mainly called from SNES implementations.

1335:    Level: developer

1337: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1338: @*/
1339: PetscErrorCode  SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1340: {
1343:   if (xnorm) *xnorm = linesearch->xnorm;
1344:   if (fnorm) *fnorm = linesearch->fnorm;
1345:   if (ynorm) *ynorm = linesearch->ynorm;
1346:   return(0);
1347: }

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

1352:    Input Parameters:
1353: +  linesearch - linesearch context
1354: .  xnorm - The norm of the current solution
1355: .  fnorm - The norm of the current function
1356: -  ynorm - The norm of the current update

1358:    Level: advanced

1360: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1361: @*/
1362: PetscErrorCode  SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1363: {
1366:   linesearch->xnorm = xnorm;
1367:   linesearch->fnorm = fnorm;
1368:   linesearch->ynorm = ynorm;
1369:   return(0);
1370: }

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

1375:    Input Parameters:
1376: .  linesearch - linesearch context

1378:    Options Database Keys:
1379: .   -snes_linesearch_norms - turn norm computation on or off

1381:    Level: intermediate

1383: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1384: @*/
1385: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1386: {
1388:   SNES           snes;

1391:   if (linesearch->norms) {
1392:     if (linesearch->ops->vinorm) {
1393:       SNESLineSearchGetSNES(linesearch, &snes);
1394:       VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1395:       VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1396:       (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1397:     } else {
1398:       VecNormBegin(linesearch->vec_func,   NORM_2, &linesearch->fnorm);
1399:       VecNormBegin(linesearch->vec_sol,    NORM_2, &linesearch->xnorm);
1400:       VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1401:       VecNormEnd(linesearch->vec_func,     NORM_2, &linesearch->fnorm);
1402:       VecNormEnd(linesearch->vec_sol,      NORM_2, &linesearch->xnorm);
1403:       VecNormEnd(linesearch->vec_update,   NORM_2, &linesearch->ynorm);
1404:     }
1405:   }
1406:   return(0);
1407: }

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

1412:    Input Parameters:
1413: +  linesearch  - linesearch context
1414: -  flg  - indicates whether or not to compute norms

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

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

1422:    Level: intermediate

1424: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1425: @*/
1426: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1427: {
1429:   linesearch->norms = flg;
1430:   return(0);
1431: }

1433: /*@
1434:    SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context

1436:    Input Parameters:
1437: .  linesearch - linesearch context

1439:    Output Parameters:
1440: +  X - Solution vector
1441: .  F - Function vector
1442: .  Y - Search direction vector
1443: .  W - Solution work vector
1444: -  G - Function work vector

1446:    Notes:
1447:    At the beginning of a line search Section 1.5 Writing Application Codes with PETSc, X should contain a
1448:    solution and the vector F the function computed at X.  At the end of the
1449:    line search Section 1.5 Writing Application Codes with PETSc, X should contain the new solution, and F the
1450:    function evaluated at the new solution.

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

1454:    Level: advanced

1456: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1457: @*/
1458: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1459: {
1462:   if (X) {
1464:     *X = linesearch->vec_sol;
1465:   }
1466:   if (F) {
1468:     *F = linesearch->vec_func;
1469:   }
1470:   if (Y) {
1472:     *Y = linesearch->vec_update;
1473:   }
1474:   if (W) {
1476:     *W = linesearch->vec_sol_new;
1477:   }
1478:   if (G) {
1480:     *G = linesearch->vec_func_new;
1481:   }
1482:   return(0);
1483: }

1485: /*@
1486:    SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context

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

1496:    Level: advanced

1498: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1499: @*/
1500: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1501: {
1504:   if (X) {
1506:     linesearch->vec_sol = X;
1507:   }
1508:   if (F) {
1510:     linesearch->vec_func = F;
1511:   }
1512:   if (Y) {
1514:     linesearch->vec_update = Y;
1515:   }
1516:   if (W) {
1518:     linesearch->vec_sol_new = W;
1519:   }
1520:   if (G) {
1522:     linesearch->vec_func_new = G;
1523:   }
1524:   return(0);
1525: }

1527: /*@C
1528:    SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1529:    SNES options in the database.

1531:    Logically Collective on SNESLineSearch

1533:    Input Parameters:
1534: +  snes - the SNES context
1535: -  prefix - the prefix to prepend to all option names

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

1541:    Level: advanced

1543: .seealso: SNESGetOptionsPrefix()
1544: @*/
1545: PetscErrorCode  SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1546: {

1551:   PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1552:   return(0);
1553: }

1555: /*@C
1556:    SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1557:    SNESLineSearch options in the database.

1559:    Not Collective

1561:    Input Parameter:
1562: .  linesearch - the SNESLineSearch context

1564:    Output Parameter:
1565: .  prefix - pointer to the prefix string used

1567:    Notes:
1568:    On the fortran side, the user should pass in a string 'prefix' of
1569:    sufficient length to hold the prefix.

1571:    Level: advanced

1573: .seealso: SNESAppendOptionsPrefix()
1574: @*/
1575: PetscErrorCode  SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1576: {

1581:   PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1582:   return(0);
1583: }

1585: /*@C
1586:    SNESLineSearchSetWorkVecs - Gets work vectors for the line search.

1588:    Input Parameter:
1589: +  linesearch - the SNESLineSearch context
1590: -  nwork - the number of work vectors

1592:    Level: developer

1594: .seealso: SNESSetWorkVecs()
1595: @*/
1596: PetscErrorCode  SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1597: {

1601:   if (linesearch->vec_sol) {
1602:     VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1603:   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1604:   return(0);
1605: }

1607: /*@
1608:    SNESLineSearchGetReason - Gets the success/failure status of the last line search Section 1.5 Writing Application Codes with PETSc

1610:    Input Parameters:
1611: .  linesearch - linesearch context

1613:    Output Parameters:
1614: .  result - The success or failure status

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

1620:    Level: intermediate

1622: .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1623: @*/
1624: PetscErrorCode  SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1625: {
1629:   *result = linesearch->result;
1630:   return(0);
1631: }

1633: /*@
1634:    SNESLineSearchSetReason - Sets the success/failure status of the last line search Section 1.5 Writing Application Codes with PETSc

1636:    Input Parameters:
1637: +  linesearch - linesearch context
1638: -  result - The success or failure status

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

1644:    Level: developer

1646: .seealso: SNESLineSearchGetSResult()
1647: @*/
1648: PetscErrorCode  SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1649: {
1652:   linesearch->result = result;
1653:   return(0);
1654: }

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

1659:    Input Parameters:
1660: +  snes - nonlinear context obtained from SNESCreate()
1661: .  projectfunc - function for projecting the function to the bounds
1662: -  normfunc - function for computing the norm of an active set

1664:    Logically Collective on SNES

1666:    Calling sequence of projectfunc:
1667: .vb
1668:    projectfunc (SNES snes, Vec X)
1669: .ve

1671:     Input parameters for projectfunc:
1672: +   snes - nonlinear context
1673: -   X - current solution

1675:     Output parameters for projectfunc:
1676: .   X - Projected solution

1678:    Calling sequence of normfunc:
1679: .vb
1680:    projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1681: .ve

1683:     Input parameters for normfunc:
1684: +   snes - nonlinear context
1685: .   X - current solution
1686: -   F - current residual

1688:     Output parameters for normfunc:
1689: .   fnorm - VI-specific norm of the function

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

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

1697:     Level: developer

1699: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1700: @*/
1701: PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1702: {
1705:   if (projectfunc) linesearch->ops->viproject = projectfunc;
1706:   if (normfunc) linesearch->ops->vinorm = normfunc;
1707:   return(0);
1708: }

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

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

1716:    Output Parameters:
1717: +  projectfunc - function for projecting the function to the bounds
1718: -  normfunc - function for computing the norm of an active set

1720:    Logically Collective on SNES

1722:     Level: developer

1724: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1725: @*/
1726: PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1727: {
1729:   if (projectfunc) *projectfunc = linesearch->ops->viproject;
1730:   if (normfunc) *normfunc = linesearch->ops->vinorm;
1731:   return(0);
1732: }

1734: /*@C
1735:   SNESLineSearchRegister - See SNESLineSearchRegister()

1737:   Level: advanced
1738: @*/
1739: PetscErrorCode  SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1740: {

1744:   SNESInitializePackage();
1745:   PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1746:   return(0);
1747: }