Actual source code: linesearch.c

petsc-3.3-p7 2013-05-11
  1: #include <petsc-private/linesearchimpl.h> /*I "petscsnes.h" I*/

  3: PetscBool  SNESLineSearchRegisterAllCalled = PETSC_FALSE;
  4: PetscFList SNESLineSearchList              = PETSC_NULL;

  6: PetscClassId   SNESLINESEARCH_CLASSID;
  7: PetscLogEvent  SNESLineSearch_Apply;

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

 14:    Logically Collective on Comm

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

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

 22:    Level: beginner

 24: .keywords: LineSearch, create, context

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

 29: PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch) {
 30:   PetscErrorCode      ierr;
 31:   SNESLineSearch     linesearch;
 34:   *outlinesearch = PETSC_NULL;
 35:   PetscHeaderCreate(linesearch,_p_LineSearch,struct _LineSearchOps,SNESLINESEARCH_CLASSID, 0,
 36:                            "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView);

 38:   linesearch->ops->precheckstep = PETSC_NULL;
 39:   linesearch->ops->postcheckstep = PETSC_NULL;

 41:   linesearch->vec_sol_new   = PETSC_NULL;
 42:   linesearch->vec_func_new  = PETSC_NULL;
 43:   linesearch->vec_sol       = PETSC_NULL;
 44:   linesearch->vec_func      = PETSC_NULL;
 45:   linesearch->vec_update    = PETSC_NULL;

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

 70: /*@
 71:    SNESLineSearchSetUp - Prepares the line search for being applied by allocating
 72:    any required vectors.

 74:    Collective on SNESLineSearch

 76:    Input Parameters:
 77: .  linesearch - The LineSearch instance.

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


 87:    Level: advanced

 89: .keywords: SNESLineSearch, SetUp

 91: .seealso: SNESLineSearchReset()
 92: @*/

 94: PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch) {
 97:   if (!((PetscObject)linesearch)->type_name) {
 98:     SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);
 99:   }
100:   if (!linesearch->setupcalled) {
101:     if (!linesearch->vec_sol_new) {
102:       VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);
103:     }
104:     if (!linesearch->vec_func_new) {
105:       VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);
106:     }
107:     if (linesearch->ops->setup) {
108:       (*linesearch->ops->setup)(linesearch);
109:     }
110:     linesearch->lambda = linesearch->damping;
111:     linesearch->setupcalled = PETSC_TRUE;
112:   }
113:   return(0);
114: }


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

122:    Collective on SNESLineSearch

124:    Input Parameters:
125: .  linesearch - The LineSearch instance.

127:    Level: intermediate

129: .keywords: SNESLineSearch, Reset

131: .seealso: SNESLineSearchSetUp()
132: @*/

134: PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch) {
137:   if (linesearch->ops->reset) {
138:     (*linesearch->ops->reset)(linesearch);
139:   }
140:   VecDestroy(&linesearch->vec_sol_new);
141:   VecDestroy(&linesearch->vec_func_new);

143:   VecDestroyVecs(linesearch->nwork, &linesearch->work);
144:   linesearch->nwork = 0;
145:   linesearch->setupcalled = PETSC_FALSE;
146:   return(0);
147: }


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

155:    Logically Collective on SNESLineSearch

157:    Input Parameters:
158: +  linesearch - the SNESLineSearch context
159: .  func       - [optional] function evaluation routine
160: -  ctx        - [optional] user-defined context for private data for the
161:                 function evaluation routine (may be PETSC_NULL)

163:    Calling sequence of func:
164: $    func (SNESLineSearch snes,Vec x,Vec y, PetscBool *changed);

166: +  x - solution vector
167: .  y - search direction vector
168: -  changed - flag to indicate the precheck changed x or y.

170:    Level: intermediate

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

174: .seealso: SNESLineSearchSetPostCheck()
175: @*/
176: PetscErrorCode  SNESLineSearchSetPreCheck(SNESLineSearch linesearch, SNESLineSearchPreCheckFunc func,void *ctx)
177: {
180:   if (func) linesearch->ops->precheckstep = func;
181:   if (ctx) linesearch->precheckctx = ctx;
182:   return(0);
183: }


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

191:    Input Parameters:
192: .  linesearch - the SNESLineSearch context

194:    Output Parameters:
195: +  func       - [optional] function evaluation routine
196: -  ctx        - [optional] user-defined context for private data for the
197:                 function evaluation routine (may be PETSC_NULL)

199:    Level: intermediate

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

203: .seealso: SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck()
204: @*/
205: PetscErrorCode  SNESLineSearchGetPreCheck(SNESLineSearch linesearch, SNESLineSearchPreCheckFunc *func,void **ctx)
206: {
209:   if (func) *func = linesearch->ops->precheckstep;
210:   if (ctx) *ctx = linesearch->precheckctx;
211:   return(0);
212: }


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

220:    Logically Collective on SNESLineSearch

222:    Input Parameters:
223: +  linesearch - the SNESLineSearch context
224: .  func       - [optional] function evaluation routine
225: -  ctx        - [optional] user-defined context for private data for the
226:                 function evaluation routine (may be PETSC_NULL)

228:    Calling sequence of func:
229: $    func (SNESLineSearch linesearch,Vec x,Vec y,  Vec w, *changed_y, PetscBool *changed_w);

231: +  x - old solution vector
232: .  y - search direction vector
233: .  w - new solution vector
234: .  changed_y - indicates that the line search changed y
235: .  changed_w - indicates that the line search changed w

237:    Level: intermediate

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

241: .seealso: SNESLineSearchSetPreCheck()
242: @*/
243: PetscErrorCode  SNESLineSearchSetPostCheck(SNESLineSearch linesearch, SNESLineSearchPostCheckFunc func,void *ctx)
244: {
247:   if (func) linesearch->ops->postcheckstep = func;
248:   if (ctx) linesearch->postcheckctx = ctx;
249:   return(0);
250: }


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

258:    Input Parameters:
259: .  linesearch - the SNESLineSearch context

261:    Output Parameters:
262: +  func       - [optional] function evaluation routine
263: -  ctx        - [optional] user-defined context for private data for the
264:                 function evaluation routine (may be PETSC_NULL)

266:    Level: intermediate

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

270: .seealso: SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck()
271: @*/
272: PetscErrorCode  SNESLineSearchGetPostCheck(SNESLineSearch linesearch, SNESLineSearchPostCheckFunc *func,void **ctx)
273: {
276:   if (func) *func = linesearch->ops->postcheckstep;
277:   if (ctx) *ctx = linesearch->postcheckctx;
278:   return(0);
279: }


284: /*@
285:    SNESLineSearchPreCheck - Prepares the line search for being applied.

287:    Logically Collective on SNESLineSearch

289:    Input Parameters:
290: +  linesearch - The linesearch instance.
291: .  X - The current solution
292: -  Y - The step direction

294:    Output Parameters:
295: .  changed - Indicator that the precheck routine has changed anything

297:    Level: Beginner

299: .keywords: SNESLineSearch, Create

301: .seealso: SNESLineSearchPostCheck()
302: @*/
303: PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
304: {
307:   *changed = PETSC_FALSE;
308:   if (linesearch->ops->precheckstep) {
309:     (*linesearch->ops->precheckstep)(linesearch, X, Y, changed, linesearch->precheckctx);
310:   }
311:   return(0);
312: }

316: /*@
317:    SNESLineSearchPostCheck - Prepares the line search for being applied.

319:    Logically Collective on SNESLineSearch

321:    Input Parameters:
322: +  linesearch - The linesearch context
323: .  X - The last solution
324: .  Y - The step direction
325: -  W - The updated solution, W = X + lambda*Y for some lambda

327:    Output Parameters:
328: +  changed_Y - Indicator if the direction Y has been changed.
329: -  changed_W - Indicator if the new candidate solution W has been changed.

331:    Level: Intermediate

333: .keywords: SNESLineSearch, Create

335: .seealso: SNESLineSearchPreCheck()
336: @*/
337: PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
338: {
341:   *changed_Y = PETSC_FALSE;
342:   *changed_W = PETSC_FALSE;
343:   if (linesearch->ops->postcheckstep) {
344:     (*linesearch->ops->postcheckstep)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);
345:   }
346:   return(0);
347: }


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

355:    Logically Collective on SNESLineSearch

357:    Input Arguments:
358: +  linesearch - linesearch context
359: .  X - base state for this step
360: .  Y - initial correction

362:    Output Arguments:
363: +  Y - correction, possibly modified
364: -  changed - flag indicating that Y was modified

366:    Options Database Key:
367: +  -snes_linesearch_precheck_picard - activate this routine
368: -  -snes_linesearch_precheck_picard_angle - angle

370:    Level: advanced

372:    Notes:
373:    This function should be passed to SNESLineSearchSetPreCheck()

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

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

382: .seealso: SNESLineSearchSetPreCheck()
383: @*/
384: PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
385: {
387:   PetscReal      angle = *(PetscReal*)linesearch->precheckctx;
388:   Vec            Ylast;
389:   PetscScalar    dot;
390: 
391:   PetscInt       iter;
392:   PetscReal      ynorm,ylastnorm,theta,angle_radians;
393:   SNES           snes;

396:   SNESLineSearchGetSNES(linesearch, &snes);
397:   PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);
398:   if (!Ylast) {
399:     VecDuplicate(Y,&Ylast);
400:     PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);
401:     PetscObjectDereference((PetscObject)Ylast);
402:   }
403:   SNESGetIterationNumber(snes,&iter);
404:   if (iter < 2) {
405:     VecCopy(Y,Ylast);
406:     *changed = PETSC_FALSE;
407:     return(0);
408:   }

410:   VecDot(Y,Ylast,&dot);
411:   VecNorm(Y,NORM_2,&ynorm);
412:   VecNorm(Ylast,NORM_2,&ylastnorm);
413:   /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
414:   theta = acos((double)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
415:   angle_radians = angle * PETSC_PI / 180.;
416:   if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
417:     /* Modify the step Y */
418:     PetscReal alpha,ydiffnorm;
419:     VecAXPY(Ylast,-1.0,Y);
420:     VecNorm(Ylast,NORM_2,&ydiffnorm);
421:     alpha = ylastnorm / ydiffnorm;
422:     VecCopy(Y,Ylast);
423:     VecScale(Y,alpha);
424:     PetscInfo3(snes,"Angle %G degrees less than threshold %G, corrected step by alpha=%G\n",theta*180./PETSC_PI,angle,alpha);
425:   } else {
426:     PetscInfo2(snes,"Angle %G degrees exceeds threshold %G, no correction applied\n",theta*180./PETSC_PI,angle);
427:     VecCopy(Y,Ylast);
428:     *changed = PETSC_FALSE;
429:   }
430:   return(0);
431: }

435: /*@
436:    SNESLineSearchApply - Computes the line-search update.

438:    Collective on SNESLineSearch

440:    Input Parameters:
441: +  linesearch - The linesearch context
442: .  X - The current solution
443: .  F - The current function
444: .  fnorm - The current norm
445: -  Y - The search direction

447:    Output Parameters:
448: +  X - The new solution
449: .  F - The new function
450: -  fnorm - The new function norm

452:    Options Database Keys:
453: + -snes_linesearch_type - basic, bt, l2, cp, shell
454: . -snes_linesearch_monitor - Print progress of line searches
455: . -snes_linesearch_damping - The linesearch damping parameter
456: . -snes_linesearch_norms   - Turn on/off the linesearch norms
457: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
458: - -snes_linesearch_max_it - The number of iterations for iterative line searches

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

468:    Level: Intermediate

470: .keywords: SNESLineSearch, Create

472: .seealso: SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction()
473: @*/
474: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y) {

478:   /* check the pointers */

484:   linesearch->success = PETSC_TRUE;

486:   linesearch->vec_sol = X;
487:   linesearch->vec_update = Y;
488:   linesearch->vec_func = F;

490:   SNESLineSearchSetUp(linesearch);

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

495:   if (fnorm) {
496:     linesearch->fnorm = *fnorm;
497:   } else {
498:     VecNorm(F, NORM_2, &linesearch->fnorm);
499:   }

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

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

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

507:   if (fnorm)
508:     *fnorm = linesearch->fnorm;
509:   return(0);
510: }

514: /*@
515:    SNESLineSearchDestroy - Destroys the line search instance.

517:    Collective on SNESLineSearch

519:    Input Parameters:
520: .  linesearch - The linesearch context

522:    Level: Intermediate

524: .keywords: SNESLineSearch, Destroy

526: .seealso: SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
527: @*/
528: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch) {
531:   if (!*linesearch) return(0);
533:   if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; return(0);}
534:   PetscObjectDepublish((*linesearch));
535:   SNESLineSearchReset(*linesearch);
536:   if ((*linesearch)->ops->destroy) {
537:     (*linesearch)->ops->destroy(*linesearch);
538:   }
539:   PetscViewerDestroy(&(*linesearch)->monitor);
540:   PetscHeaderDestroy(linesearch);
541:   return(0);
542: }

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

549:    Input Parameters:
550: +  snes - nonlinear context obtained from SNESCreate()
551: -  flg - PETSC_TRUE to monitor the line search

553:    Logically Collective on SNES

555:    Options Database:
556: .   -snes_linesearch_monitor - enables the monitor

558:    Level: intermediate


561: .seealso: SNESLineSearchGetMonitor(), PetscViewer
562: @*/
563: PetscErrorCode  SNESLineSearchSetMonitor(SNESLineSearch linesearch, PetscBool flg)
564: {

568:   if (flg && !linesearch->monitor) {
569:     PetscViewerASCIIOpen(((PetscObject)linesearch)->comm,"stdout",&linesearch->monitor);
570:   } else if (!flg && linesearch->monitor) {
571:     PetscViewerDestroy(&linesearch->monitor);
572:   }
573:   return(0);
574: }

578: /*@
579:    SNESLineSearchGetMonitor - Gets the PetscViewer instance for the line search monitor.

581:    Input Parameters:
582: .  linesearch - linesearch context

584:    Input Parameters:
585: .  monitor - monitor context

587:    Logically Collective on SNES


590:    Options Database Keys:
591: .   -snes_linesearch_monitor - enables the monitor

593:    Level: intermediate


596: .seealso: SNESLineSearchSetMonitor(), PetscViewer
597: @*/
598: PetscErrorCode  SNESLineSearchGetMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
599: {

603:   if (monitor) {
605:     *monitor = linesearch->monitor;
606:   }
607:   return(0);
608: }

612: /*@
613:    SNESLineSearchSetFromOptions - Sets options for the line search

615:    Input Parameters:
616: .  linesearch - linesearch context

618:    Options Database Keys:
619: + -snes_linesearch_type <type> - basic, bt, l2, cp, shell
620: . -snes_linesearch_order <order> - 1, 2, 3.  Most types only support certain orders (bt supports 2 or 3)
621: . -snes_linesearch_norms   - Turn on/off the linesearch norms for the basic linesearch type
622: . -snes_linesearch_minlambda - The minimum step length
623: . -snes_linesearch_maxstep - The maximum step size
624: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
625: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
626: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
627: . -snes_linesearch_max_it - The number of iterations for iterative line searches
628: . -snes_linesearch_monitor - Print progress of line searches
629: . -snes_linesearch_damping - The linesearch damping parameter
630: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
631: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
632: - -snes_linesearch_precheck_picard_angle - Angle used in picard precheck method

634:    Logically Collective on SNESLineSearch

636:    Level: intermediate


639: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard()
640: @*/
641: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch) {
643:   const char     *deft = SNESLINESEARCHBASIC;
644:   char           type[256];
645:   PetscBool      flg, set;
647:   if (!SNESLineSearchRegisterAllCalled) {SNESLineSearchRegisterAll(PETSC_NULL);}

649:   PetscObjectOptionsBegin((PetscObject)linesearch);
650:   if (((PetscObject)linesearch)->type_name) {
651:     deft = ((PetscObject)linesearch)->type_name;
652:   }
653:   PetscOptionsList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
654:   if (flg) {
655:     SNESLineSearchSetType(linesearch,type);
656:   } else if (!((PetscObject)linesearch)->type_name) {
657:     SNESLineSearchSetType(linesearch,deft);
658:   }

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

664:   /* tolerances */
665:   PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,0);
666:   PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,0);
667:   PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,0);
668:   PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,0);
669:   PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,0);
670:   PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,0);

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

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

677:   /* precheck */
678:   PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);
679:   if (set) {
680:     if (flg) {
681:       linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
682:       PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
683:                               "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,PETSC_NULL);
684:       SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
685:     } else {
686:       SNESLineSearchSetPreCheck(linesearch,PETSC_NULL,PETSC_NULL);
687:     }
688:   }
689:   PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,0);
690:   PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,0);

692:   if (linesearch->ops->setfromoptions) {
693:     (*linesearch->ops->setfromoptions)(linesearch);
694:   }

696:   PetscObjectProcessOptionsHandlers((PetscObject)linesearch);
697:   PetscOptionsEnd();
698:   return(0);
699: }

703: /*@
704:    SNESLineSearchView - Prints useful information about the line search not
705:    related to an individual call.

707:    Input Parameters:
708: .  linesearch - linesearch context

710:    Logically Collective on SNESLineSearch

712:    Level: intermediate

714: .seealso: SNESLineSearchCreate()
715: @*/
716: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer) {
718:   PetscBool      iascii;
721:   if (!viewer) {
722:     PetscViewerASCIIGetStdout(((PetscObject)linesearch)->comm,&viewer);
723:   }

727:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
728:   if (iascii) {
729:     PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer,"SNESLineSearch Object");
730:     if (linesearch->ops->view) {
731:       PetscViewerASCIIPushTab(viewer);
732:       (*linesearch->ops->view)(linesearch,viewer);
733:       PetscViewerASCIIPopTab(viewer);
734:     }
735:     PetscViewerASCIIPrintf(viewer,"  maxstep=%e, minlambda=%e\n", linesearch->maxstep,linesearch->steptol);
736:     PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%e, absolute=%e, lambda=%e\n", linesearch->rtol,linesearch->atol,linesearch->ltol);
737:     PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D\n", linesearch->max_its);
738:     if (linesearch->ops->precheckstep) {
739:       if (linesearch->ops->precheckstep == SNESLineSearchPreCheckPicard) {
740:         PetscViewerASCIIPrintf(viewer,"  using precheck step to speed up Picard convergence\n", linesearch->max_its);
741:       } else {
742:         PetscViewerASCIIPrintf(viewer,"  using user-defined precheck step\n", linesearch->max_its);
743:       }
744:     }
745:     if (linesearch->ops->postcheckstep) {
746:       PetscViewerASCIIPrintf(viewer,"  using user-defined postcheck step\n", linesearch->max_its);
747:     }
748:   }
749:   return(0);
750: }

754: /*@C
755:    SNESLineSearchSetType - Sets the linesearch type

757:    Input Parameters:
758: +  linesearch - linesearch context
759: -  type - The type of line search to be used

761:    Available Types:
762: +  basic - Simple damping line search.
763: .  bt - Backtracking line search over the L2 norm of the function
764: .  l2 - Secant line search over the L2 norm of the function
765: .  cp - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
766: -  shell - User provided SNESLineSearch implementation

768:    Logically Collective on SNESLineSearch

770:    Level: intermediate


773: .seealso: SNESLineSearchCreate()
774: @*/
775: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, const SNESLineSearchType type)
776: {

778:   PetscErrorCode ierr,(*r)(SNESLineSearch);
779:   PetscBool      match;


785:   PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
786:   if (match) return(0);

788:    PetscFListFind(SNESLineSearchList,((PetscObject)linesearch)->comm,type,PETSC_TRUE,(void (**)(void)) &r);
789:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
790:   /* Destroy the previous private linesearch context */
791:   if (linesearch->ops->destroy) {
792:     (*(linesearch)->ops->destroy)(linesearch);
793:     linesearch->ops->destroy = PETSC_NULL;
794:   }
795:   /* Reinitialize function pointers in SNESLineSearchOps structure */
796:   linesearch->ops->apply          = 0;
797:   linesearch->ops->view           = 0;
798:   linesearch->ops->setfromoptions = 0;
799:   linesearch->ops->destroy        = 0;

801:   PetscObjectChangeTypeName((PetscObject)linesearch,type);
802:   (*r)(linesearch);
803: #if defined(PETSC_HAVE_AMS)
804:   if (PetscAMSPublishAll) {
805:     PetscObjectAMSPublish((PetscObject)linesearch);
806:   }
807: #endif
808:   return(0);
809: }

813: /*@
814:    SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.

816:    Input Parameters:
817: +  linesearch - linesearch context
818: -  snes - The snes instance

820:    Level: developer

822:    Notes:
823:    This happens automatically when the line search is gotten/created with
824:    SNESGetSNESLineSearch().  This routine is therefore mainly called within SNES
825:    implementations.

827:    Level: developer

829: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
830: @*/
831: PetscErrorCode  SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes){
835:   linesearch->snes = snes;
836:   return(0);
837: }

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

847:    Input Parameters:
848: .  linesearch - linesearch context

850:    Output Parameters:
851: .  snes - The snes instance

853:    Level: developer

855: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
856: @*/
857: PetscErrorCode  SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes){
861:   *snes = linesearch->snes;
862:   return(0);
863: }

867: /*@
868:    SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.

870:    Input Parameters:
871: .  linesearch - linesearch context

873:    Output Parameters:
874: .  lambda - The last steplength computed during SNESLineSearchApply()

876:    Level: advanced

878:    Notes:
879:    This is useful in methods where the solver is ill-scaled and
880:    requires some adaptive notion of the difference in scale between the
881:    solution and the function.  For instance, SNESQN may be scaled by the
882:    line search lambda using the argument -snes_qn_scaling ls.


885: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
886: @*/
887: PetscErrorCode  SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
888: {
892:   *lambda = linesearch->lambda;
893:   return(0);
894: }

898: /*@
899:    SNESLineSearchSetLambda - Sets the linesearch steplength.

901:    Input Parameters:
902: +  linesearch - linesearch context
903: -  lambda - The last steplength.

905:    Notes:
906:    This routine is typically used within implementations of SNESLineSearchApply
907:    to set the final steplength.  This routine (and SNESLineSearchGetLambda()) were
908:    added in order to facilitate Quasi-Newton methods that use the previous steplength
909:    as an inner scaling parameter.

911:    Level: advanced

913: .seealso: SNESLineSearchGetLambda()
914: @*/
915: PetscErrorCode  SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
916: {
919:   linesearch->lambda = lambda;
920:   return(0);
921: }

923: #undef  __FUNCT__
925: /*@
926:    SNESLineSearchGetTolerances - Gets the tolerances for the linesearch.  These include
927:    tolerances for the relative and absolute change in the function norm, the change
928:    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
929:    and the maximum number of iterations the line search procedure may take.

931:    Input Parameters:
932: .  linesearch - linesearch context

934:    Output Parameters:
935: +  steptol - The minimum steplength
936: .  maxstep - The maximum steplength
937: .  rtol    - The relative tolerance for iterative line searches
938: .  atol    - The absolute tolerance for iterative line searches
939: .  ltol    - The change in lambda tolerance for iterative line searches
940: -  max_it  - The maximum number of iterations of the line search

942:    Level: intermediate

944:    Notes:
945:    Different line searches may implement these parameters slightly differently as
946:    the type requires.

948: .seealso: SNESLineSearchSetTolerances()
949: @*/
950: PetscErrorCode  SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
951: {
954:   if (steptol) {
956:     *steptol = linesearch->steptol;
957:   }
958:   if (maxstep) {
960:     *maxstep = linesearch->maxstep;
961:   }
962:   if (rtol) {
964:     *rtol = linesearch->rtol;
965:   }
966:   if (atol) {
968:     *atol = linesearch->atol;
969:   }
970:   if (ltol) {
972:     *ltol = linesearch->ltol;
973:   }
974:   if (max_its) {
976:     *max_its = linesearch->max_its;
977:   }
978:   return(0);
979: }

981: #undef  __FUNCT__
983: /*@
984:    SNESLineSearchSetTolerances -  Gets the tolerances for the linesearch.  These include
985:    tolerances for the relative and absolute change in the function norm, the change
986:    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
987:    and the maximum number of iterations the line search procedure may take.

989:    Input Parameters:
990: +  linesearch - linesearch context
991: .  steptol - The minimum steplength
992: .  maxstep - The maximum steplength
993: .  rtol    - The relative tolerance for iterative line searches
994: .  atol    - The absolute tolerance for iterative line searches
995: .  ltol    - The change in lambda tolerance for iterative line searches
996: -  max_it  - The maximum number of iterations of the line search

998:    Notes:
999:    The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1000:    place of an argument.

1002:    Level: intermediate

1004: .seealso: SNESLineSearchGetTolerances()
1005: @*/
1006: PetscErrorCode  SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1007: {

1017:   if ( steptol!= PETSC_DEFAULT) {
1018:     if ( steptol < 0.0) SETERRQ1(((PetscObject)linesearch)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %G must be non-negative",steptol);
1019:     linesearch->steptol = steptol;
1020:   }

1022:   if ( maxstep!= PETSC_DEFAULT) {
1023:     if ( maxstep < 0.0) SETERRQ1(((PetscObject)linesearch)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %G must be non-negative",maxstep);
1024:     linesearch->maxstep = maxstep;
1025:   }

1027:   if (rtol != PETSC_DEFAULT) {
1028:     if (rtol < 0.0 || 1.0 <= rtol) SETERRQ1(((PetscObject)linesearch)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %G must be non-negative and less than 1.0",rtol);
1029:     linesearch->rtol = rtol;
1030:   }

1032:   if (atol != PETSC_DEFAULT) {
1033:     if (atol < 0.0) SETERRQ1(((PetscObject)linesearch)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",atol);
1034:     linesearch->atol = atol;
1035:   }

1037:   if (ltol != PETSC_DEFAULT) {
1038:     if (ltol < 0.0) SETERRQ1(((PetscObject)linesearch)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %G must be non-negative",ltol);
1039:   linesearch->ltol = ltol;
1040:   }

1042:   if (max_its != PETSC_DEFAULT) {
1043:     if (max_its < 0) SETERRQ1(((PetscObject)linesearch)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1044:     linesearch->max_its = max_its;
1045:   }

1047:   return(0);
1048: }


1053: /*@
1054:    SNESLineSearchGetDamping - Gets the line search damping parameter.

1056:    Input Parameters:
1057: .  linesearch - linesearch context

1059:    Output Parameters:
1060: .  damping - The damping parameter

1062:    Level: advanced

1064: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1065: @*/

1067: PetscErrorCode  SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1068: {
1072:   *damping = linesearch->damping;
1073:   return(0);
1074: }

1078: /*@
1079:    SNESLineSearchSetDamping - Sets the line search damping paramter.

1081:    Input Parameters:
1082: .  linesearch - linesearch context
1083: .  damping - The damping parameter

1085:    Level: intermediate

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

1094: .seealso: SNESLineSearchGetDamping()
1095: @*/
1096: PetscErrorCode  SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1097: {
1100:   linesearch->damping = damping;
1101:   return(0);
1102: }

1106: /*@
1107:    SNESLineSearchGetOrder - Gets the line search approximation order.

1109:    Input Parameters:
1110: .  linesearch - linesearch context

1112:    Output Parameters:
1113: .  order - The order

1115:    Possible Values for order:
1116: +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1117: .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1118: -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order

1120:    Level: intermediate

1122: .seealso: SNESLineSearchSetOrder()
1123: @*/

1125: PetscErrorCode  SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1126: {
1130:   *order = linesearch->order;
1131:   return(0);
1132: }

1136: /*@
1137:    SNESLineSearchSetOrder - Sets the line search damping paramter.

1139:    Input Parameters:
1140: .  linesearch - linesearch context
1141: .  order - The damping parameter

1143:    Level: intermediate

1145:    Possible Values for order:
1146: +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1147: .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1148: -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order

1150:    Notes:
1151:    Variable orders are supported by the following line searches:
1152: +  bt - cubic and quadratic
1153: -  cp - linear and quadratic

1155: .seealso: SNESLineSearchGetOrder()
1156: @*/
1157: PetscErrorCode  SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1158: {
1161:   linesearch->order = order;
1162:   return(0);
1163: }

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

1170:    Input Parameters:
1171: .  linesearch - linesearch context

1173:    Output Parameters:
1174: +  xnorm - The norm of the current solution
1175: .  fnorm - The norm of the current function
1176: -  ynorm - The norm of the current update

1178:    Notes:
1179:    This function is mainly called from SNES implementations.

1181:    Level: developer

1183: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1184: @*/
1185: PetscErrorCode  SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1186: {
1189:   if (xnorm) {
1190:     *xnorm = linesearch->xnorm;
1191:   }
1192:   if (fnorm) {
1193:     *fnorm = linesearch->fnorm;
1194:   }
1195:   if (ynorm) {
1196:     *ynorm = linesearch->ynorm;
1197:   }
1198:   return(0);
1199: }

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

1206:    Input Parameters:
1207: +  linesearch - linesearch context
1208: .  xnorm - The norm of the current solution
1209: .  fnorm - The norm of the current function
1210: -  ynorm - The norm of the current update

1212:    Level: advanced

1214: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1215: @*/
1216: PetscErrorCode  SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1217: {
1220:   linesearch->xnorm = xnorm;
1221:   linesearch->fnorm = fnorm;
1222:   linesearch->ynorm = ynorm;
1223:   return(0);
1224: }

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

1231:    Input Parameters:
1232: .  linesearch - linesearch context

1234:    Options Database Keys:
1235: .   -snes_linesearch_norms - turn norm computation on or off

1237:    Level: intermediate

1239: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1240: @*/
1241: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1242: {
1244:   SNES snes;
1246:   if (linesearch->norms) {
1247:     if (linesearch->ops->vinorm) {
1248:       SNESLineSearchGetSNES(linesearch, &snes);
1249:       VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1250:       VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1251:       (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1252:     } else {
1253:       VecNormBegin(linesearch->vec_func,   NORM_2, &linesearch->fnorm);
1254:       VecNormBegin(linesearch->vec_sol,    NORM_2, &linesearch->xnorm);
1255:       VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1256:       VecNormEnd(linesearch->vec_func,     NORM_2, &linesearch->fnorm);
1257:       VecNormEnd(linesearch->vec_sol,      NORM_2, &linesearch->xnorm);
1258:       VecNormEnd(linesearch->vec_update,   NORM_2, &linesearch->ynorm);
1259:     }
1260:   }
1261:   return(0);
1262: }


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

1270:    Input Parameters:
1271: +  linesearch  - linesearch context
1272: -  flg  - indicates whether or not to compute norms

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

1277:    Notes:
1278:    This is most relevant to the SNESLINESEARCHBASIC line search type.

1280:    Level: intermediate

1282: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1283: @*/
1284: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1285: {
1287:   linesearch->norms = flg;
1288:   return(0);
1289: }

1293: /*@
1294:    SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context

1296:    Input Parameters:
1297: .  linesearch - linesearch context

1299:    Output Parameters:
1300: +  X - The old solution
1301: .  F - The old function
1302: .  Y - The search direction
1303: .  W - The new solution
1304: -  G - The new function

1306:    Level: advanced

1308: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1309: @*/
1310: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G) {
1313:   if (X) {
1315:     *X = linesearch->vec_sol;
1316:   }
1317:   if (F) {
1319:     *F = linesearch->vec_func;
1320:   }
1321:   if (Y) {
1323:     *Y = linesearch->vec_update;
1324:   }
1325:   if (W) {
1327:     *W = linesearch->vec_sol_new;
1328:   }
1329:   if (G) {
1331:     *G = linesearch->vec_func_new;
1332:   }

1334:   return(0);
1335: }

1339: /*@
1340:    SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context

1342:    Input Parameters:
1343: +  linesearch - linesearch context
1344: .  X - The old solution
1345: .  F - The old function
1346: .  Y - The search direction
1347: .  W - The new solution
1348: -  G - The new function

1350:    Level: advanced

1352: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1353: @*/
1354: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G) {
1357:   if (X) {
1359:     linesearch->vec_sol = X;
1360:   }
1361:   if (F) {
1363:     linesearch->vec_func = F;
1364:   }
1365:   if (Y) {
1367:     linesearch->vec_update = Y;
1368:   }
1369:   if (W) {
1371:     linesearch->vec_sol_new = W;
1372:   }
1373:   if (G) {
1375:     linesearch->vec_func_new = G;
1376:   }

1378:   return(0);
1379: }

1383: /*@C
1384:    SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1385:    SNES options in the database.

1387:    Logically Collective on SNESLineSearch

1389:    Input Parameters:
1390: +  snes - the SNES context
1391: -  prefix - the prefix to prepend to all option names

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

1397:    Level: advanced

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

1401: .seealso: SNESGetOptionsPrefix()
1402: @*/
1403: PetscErrorCode  SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1404: {

1409:   PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1410:   return(0);
1411: }

1415: /*@C
1416:    SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1417:    SNESLineSearch options in the database.

1419:    Not Collective

1421:    Input Parameter:
1422: .  linesearch - the SNESLineSearch context

1424:    Output Parameter:
1425: .  prefix - pointer to the prefix string used

1427:    Notes:
1428:    On the fortran side, the user should pass in a string 'prefix' of
1429:    sufficient length to hold the prefix.

1431:    Level: advanced

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

1435: .seealso: SNESAppendOptionsPrefix()
1436: @*/
1437: PetscErrorCode  SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1438: {

1443:   PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1444:   return(0);
1445: }

1449: /*@
1450:    SNESLineSearchGetWork - Gets work vectors for the line search.

1452:    Input Parameter:
1453: +  linesearch - the SNESLineSearch context
1454: -  nwork - the number of work vectors

1456:    Level: developer

1458:    Notes:
1459:    This is typically called at the beginning of a SNESLineSearch or SNESLineSearchShell implementation.

1461: .keywords: SNESLineSearch, work, vector

1463: .seealso: SNESDefaultGetWork()
1464: @*/
1465: PetscErrorCode  SNESLineSearchGetWork(SNESLineSearch linesearch, PetscInt nwork)
1466: {
1469:   if (linesearch->vec_sol) {
1470:     VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1471:   } else {
1472:     SETERRQ(((PetscObject)linesearch)->comm, PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1473:   }
1474:   return(0);
1475: }


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

1483:    Input Parameters:
1484: .  linesearch - linesearch context

1486:    Output Parameters:
1487: .  success - The success or failure status

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

1493:    Level: intermediate

1495: .seealso: SNESLineSearchSetSuccess()
1496: @*/
1497: PetscErrorCode  SNESLineSearchGetSuccess(SNESLineSearch linesearch, PetscBool *success)
1498: {
1502:   if (success) {
1503:     *success = linesearch->success;
1504:   }
1505:   return(0);
1506: }

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

1513:    Input Parameters:
1514: +  linesearch - linesearch context
1515: -  success - The success or failure status

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

1521:    Level: developer

1523: .seealso: SNESLineSearchGetSuccess()
1524: @*/
1525: PetscErrorCode  SNESLineSearchSetSuccess(SNESLineSearch linesearch, PetscBool success)
1526: {
1529:   linesearch->success = success;
1530:   return(0);
1531: }

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

1538:    Input Parameters:
1539: +  snes - nonlinear context obtained from SNESCreate()
1540: .  projectfunc - function for projecting the function to the bounds
1541: -  normfunc - function for computing the norm of an active set

1543:    Logically Collective on SNES

1545:    Calling sequence of projectfunc:
1546: .vb
1547:    projectfunc (SNES snes, Vec X)
1548: .ve

1550:     Input parameters for projectfunc:
1551: +   snes - nonlinear context
1552: -   X - current solution

1554:     Output parameters for projectfunc:
1555: .   X - Projected solution

1557:    Calling sequence of normfunc:
1558: .vb
1559:    projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1560: .ve

1562:     Input parameters for normfunc:
1563: +   snes - nonlinear context
1564: .   X - current solution
1565: -   F - current residual

1567:     Output parameters for normfunc:
1568: .   fnorm - VI-specific norm of the function

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

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

1576:     Level: developer

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

1580: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1581: @*/
1582: extern PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1583: {
1586:   if (projectfunc) linesearch->ops->viproject = projectfunc;
1587:   if (normfunc) linesearch->ops->vinorm = normfunc;
1588:   return(0);
1589: }

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

1596:    Input Parameters:
1597: .  snes - nonlinear context obtained from SNESCreate()

1599:    Output Parameters:
1600: +  projectfunc - function for projecting the function to the bounds
1601: -  normfunc - function for computing the norm of an active set

1603:    Logically Collective on SNES

1605:     Level: developer

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

1609: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1610: @*/
1611: extern PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1612: {
1614:   if (projectfunc) *projectfunc = linesearch->ops->viproject;
1615:   if (normfunc) *normfunc = linesearch->ops->vinorm;
1616:   return(0);
1617: }

1621: /*@C
1622:   SNESLineSearchRegister - See SNESLineSearchRegisterDynamic()

1624:   Level: advanced
1625: @*/
1626: PetscErrorCode  SNESLineSearchRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNESLineSearch))
1627: {
1628:   char           fullname[PETSC_MAX_PATH_LEN];

1632:   PetscFListConcat(path,name,fullname);
1633:   PetscFListAdd(&SNESLineSearchList,sname,fullname,(void (*)(void))function);
1634:   return(0);
1635: }