xref: /petsc/src/snes/linesearch/interface/linesearch.c (revision 55e7fe800d976e85ed2b5cd8bfdef564daa37bd9)
1 #include <petsc/private/linesearchimpl.h> /*I "petscsnes.h" I*/
2 
3 PetscBool         SNESLineSearchRegisterAllCalled = PETSC_FALSE;
4 PetscFunctionList SNESLineSearchList              = NULL;
5 
6 PetscClassId  SNESLINESEARCH_CLASSID;
7 PetscLogEvent SNESLINESEARCH_Apply;
8 
9 /*@
10    SNESLineSearchMonitorCancel - Clears all the monitor functions for a SNESLineSearch object.
11 
12    Logically Collective on SNESLineSearch
13 
14    Input Parameters:
15 .  ls - the SNESLineSearch context
16 
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
21 
22    Notes:
23    There is no way to clear one specific monitor from a SNESLineSearch object.
24 
25    This does not clear the monitor set with SNESLineSearchSetDefaultMonitor() use SNESLineSearchSetDefaultMonitor(ls,NULL) to cancel
26    that one.
27 
28    Level: intermediate
29 
30 .keywords: SNESLineSearch, nonlinear, set, monitor
31 
32 .seealso: SNESGetLineSearch(), SNESLineSearchMonitorDefault(), SNESLineSearchMonitorSet()
33 @*/
34 PetscErrorCode  SNESLineSearchMonitorCancel(SNESLineSearch ls)
35 {
36   PetscErrorCode ierr;
37   PetscInt       i;
38 
39   PetscFunctionBegin;
40   PetscValidHeaderSpecific(ls,SNESLINESEARCH_CLASSID,1);
41   for (i=0; i<ls->numbermonitors; i++) {
42     if (ls->monitordestroy[i]) {
43       ierr = (*ls->monitordestroy[i])(&ls->monitorcontext[i]);CHKERRQ(ierr);
44     }
45   }
46   ls->numbermonitors = 0;
47   PetscFunctionReturn(0);
48 }
49 
50 /*@
51    SNESLineSearchMonitor - runs the user provided monitor routines, if they exist
52 
53    Collective on SNES
54 
55    Input Parameters:
56 .  ls - the linesearch object
57 
58    Notes:
59    This routine is called by the SNES implementations.
60    It does not typically need to be called by the user.
61 
62    Level: developer
63 
64 .seealso: SNESGetLineSearch(), SNESLineSearchMonitorSet()
65 @*/
66 PetscErrorCode  SNESLineSearchMonitor(SNESLineSearch ls)
67 {
68   PetscErrorCode ierr;
69   PetscInt       i,n = ls->numbermonitors;
70 
71   PetscFunctionBegin;
72   for (i=0; i<n; i++) {
73     ierr = (*ls->monitorftns[i])(ls,ls->monitorcontext[i]);CHKERRQ(ierr);
74   }
75   PetscFunctionReturn(0);
76 }
77 
78 /*@C
79    SNESLineSearchMonitorSet - Sets an ADDITIONAL function that is to be used at every
80    iteration of the nonlinear solver to display the iteration's
81    progress.
82 
83    Logically Collective on SNESLineSearch
84 
85    Input Parameters:
86 +  ls - the SNESLineSearch context
87 .  f - the monitor function
88 .  mctx - [optional] user-defined context for private data for the
89           monitor routine (use NULL if no context is desired)
90 -  monitordestroy - [optional] routine that frees monitor context
91           (may be NULL)
92 
93    Notes:
94    Several different monitoring routines may be set by calling
95    SNESLineSearchMonitorSet() multiple times; all will be called in the
96    order in which they were set.
97 
98    Fortran Notes:
99     Only a single monitor function can be set for each SNESLineSearch object
100 
101    Level: intermediate
102 
103 .keywords: SNESLineSearch, nonlinear, set, monitor
104 
105 .seealso: SNESGetLineSearch(), SNESLineSearchMonitorDefault(), SNESLineSearchMonitorCancel()
106 @*/
107 PetscErrorCode  SNESLineSearchMonitorSet(SNESLineSearch ls,PetscErrorCode (*f)(SNESLineSearch,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
108 {
109   PetscErrorCode ierr;
110   PetscInt       i;
111   PetscBool      identical;
112 
113   PetscFunctionBegin;
114   PetscValidHeaderSpecific(ls,SNESLINESEARCH_CLASSID,1);
115   for (i=0; i<ls->numbermonitors;i++) {
116     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))ls->monitorftns[i],ls->monitorcontext[i],ls->monitordestroy[i],&identical);CHKERRQ(ierr);
117     if (identical) PetscFunctionReturn(0);
118   }
119   if (ls->numbermonitors >= MAXSNESLSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
120   ls->monitorftns[ls->numbermonitors]          = f;
121   ls->monitordestroy[ls->numbermonitors]   = monitordestroy;
122   ls->monitorcontext[ls->numbermonitors++] = (void*)mctx;
123   PetscFunctionReturn(0);
124 }
125 
126 /*@C
127    SNESLineSearchMonitorSolutionUpdate - Monitors each update a new function value the linesearch tries
128 
129    Collective on SNESLineSearch
130 
131    Input Parameters:
132 +  ls - the SNES linesearch object
133 -  vf - the context for the monitor, in this case it is an ASCII PetscViewer and format
134 
135    Level: intermediate
136 
137 .keywords: SNES, nonlinear, default, monitor, norm
138 
139 .seealso: SNESGetLineSearch(), SNESMonitorSet(), SNESMonitorSolution()
140 @*/
141 PetscErrorCode  SNESLineSearchMonitorSolutionUpdate(SNESLineSearch ls,PetscViewerAndFormat *vf)
142 {
143   PetscErrorCode ierr;
144   PetscViewer    viewer = vf->viewer;
145   Vec            Y,W,G;
146 
147   PetscFunctionBegin;
148   ierr = SNESLineSearchGetVecs(ls,NULL,NULL,&Y,&W,&G);CHKERRQ(ierr);
149   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
150   ierr = PetscViewerASCIIPrintf(viewer,"LineSearch attempted update to solution \n");CHKERRQ(ierr);
151   ierr = VecView(Y,viewer);CHKERRQ(ierr);
152   ierr = PetscViewerASCIIPrintf(viewer,"LineSearch attempted new solution \n");CHKERRQ(ierr);
153   ierr = VecView(W,viewer);CHKERRQ(ierr);
154   ierr = PetscViewerASCIIPrintf(viewer,"LineSearch attempted updated function value\n");CHKERRQ(ierr);
155   ierr = VecView(G,viewer);CHKERRQ(ierr);
156   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
157   PetscFunctionReturn(0);
158 }
159 
160 /*@
161    SNESLineSearchCreate - Creates the line search context.
162 
163    Logically Collective on Comm
164 
165    Input Parameters:
166 .  comm - MPI communicator for the line search (typically from the associated SNES context).
167 
168    Output Parameters:
169 .  outlinesearch - the new linesearch context
170 
171    Level: developer
172 
173    Notes:
174    The preferred calling sequence for users is to use SNESGetLineSearch() to acquire the SNESLineSearch instance
175    already associated with the SNES.  This function is for developer use.
176 
177 .keywords: LineSearch, create, context
178 
179 .seealso: LineSearchDestroy(), SNESGetLineSearch()
180 @*/
181 
182 PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
183 {
184   PetscErrorCode ierr;
185   SNESLineSearch linesearch;
186 
187   PetscFunctionBegin;
188   PetscValidPointer(outlinesearch,2);
189   ierr = SNESInitializePackage();CHKERRQ(ierr);
190   *outlinesearch = NULL;
191 
192   ierr = PetscHeaderCreate(linesearch,SNESLINESEARCH_CLASSID, "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView);CHKERRQ(ierr);
193 
194   linesearch->vec_sol_new  = NULL;
195   linesearch->vec_func_new = NULL;
196   linesearch->vec_sol      = NULL;
197   linesearch->vec_func     = NULL;
198   linesearch->vec_update   = NULL;
199 
200   linesearch->lambda       = 1.0;
201   linesearch->fnorm        = 1.0;
202   linesearch->ynorm        = 1.0;
203   linesearch->xnorm        = 1.0;
204   linesearch->result       = SNES_LINESEARCH_SUCCEEDED;
205   linesearch->norms        = PETSC_TRUE;
206   linesearch->keeplambda   = PETSC_FALSE;
207   linesearch->damping      = 1.0;
208   linesearch->maxstep      = 1e8;
209   linesearch->steptol      = 1e-12;
210   linesearch->rtol         = 1e-8;
211   linesearch->atol         = 1e-15;
212   linesearch->ltol         = 1e-8;
213   linesearch->precheckctx  = NULL;
214   linesearch->postcheckctx = NULL;
215   linesearch->max_its      = 1;
216   linesearch->setupcalled  = PETSC_FALSE;
217   *outlinesearch           = linesearch;
218   PetscFunctionReturn(0);
219 }
220 
221 /*@
222    SNESLineSearchSetUp - Prepares the line search for being applied by allocating
223    any required vectors.
224 
225    Collective on SNESLineSearch
226 
227    Input Parameters:
228 .  linesearch - The LineSearch instance.
229 
230    Notes:
231    For most cases, this needn't be called by users or outside of SNESLineSearchApply().
232    The only current case where this is called outside of this is for the VI
233    solvers, which modify the solution and work vectors before the first call
234    of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be
235    allocated upfront.
236 
237    Level: advanced
238 
239 .keywords: SNESLineSearch, SetUp
240 
241 .seealso: SNESGetLineSearch(), SNESLineSearchReset()
242 @*/
243 
244 PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
245 {
246   PetscErrorCode ierr;
247 
248   PetscFunctionBegin;
249   if (!((PetscObject)linesearch)->type_name) {
250     ierr = SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);CHKERRQ(ierr);
251   }
252   if (!linesearch->setupcalled) {
253     if (!linesearch->vec_sol_new) {
254       ierr = VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);CHKERRQ(ierr);
255     }
256     if (!linesearch->vec_func_new) {
257       ierr = VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);CHKERRQ(ierr);
258     }
259     if (linesearch->ops->setup) {
260       ierr = (*linesearch->ops->setup)(linesearch);CHKERRQ(ierr);
261     }
262     if (!linesearch->ops->snesfunc) {ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunction);CHKERRQ(ierr);}
263     linesearch->lambda      = linesearch->damping;
264     linesearch->setupcalled = PETSC_TRUE;
265   }
266   PetscFunctionReturn(0);
267 }
268 
269 
270 /*@
271    SNESLineSearchReset - Undoes the SNESLineSearchSetUp() and deletes any Vecs or Mats allocated by the line search.
272 
273    Collective on SNESLineSearch
274 
275    Input Parameters:
276 .  linesearch - The LineSearch instance.
277 
278    Notes:
279     Usually only called by SNESReset()
280 
281    Level: developer
282 
283 .keywords: SNESLineSearch, Reset
284 
285 .seealso: SNESGetLineSearch(), SNESLineSearchSetUp()
286 @*/
287 
288 PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
289 {
290   PetscErrorCode ierr;
291 
292   PetscFunctionBegin;
293   if (linesearch->ops->reset) (*linesearch->ops->reset)(linesearch);
294 
295   ierr = VecDestroy(&linesearch->vec_sol_new);CHKERRQ(ierr);
296   ierr = VecDestroy(&linesearch->vec_func_new);CHKERRQ(ierr);
297 
298   ierr = VecDestroyVecs(linesearch->nwork, &linesearch->work);CHKERRQ(ierr);
299 
300   linesearch->nwork       = 0;
301   linesearch->setupcalled = PETSC_FALSE;
302   PetscFunctionReturn(0);
303 }
304 
305 /*@C
306    SNESLineSearchSetFunction - Sets the function evaluation used by the SNES line search
307 
308    Input Parameters:
309 .  linesearch - the SNESLineSearch context
310 +  func       - function evaluation routine
311 
312    Level: developer
313 
314    Notes:
315     This is used internally by PETSc and not called by users
316 
317 .keywords: get, linesearch, pre-check
318 
319 .seealso: SNESGetLineSearch(), SNESSetFunction()
320 @*/
321 PetscErrorCode  SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
322 {
323   PetscFunctionBegin;
324   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
325   linesearch->ops->snesfunc = func;
326   PetscFunctionReturn(0);
327 }
328 
329 /*@C
330    SNESLineSearchSetPreCheck - Sets a user function that is called after the initial search direction has been computed but
331          before the line search routine has been applied. Allows the user to adjust the result of (usually a linear solve) that
332          determined the search direction.
333 
334    Logically Collective on SNESLineSearch
335 
336    Input Parameters:
337 +  linesearch - the SNESLineSearch context
338 .  func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for the calling sequence
339 -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
340 
341    Level: intermediate
342 
343 .keywords: set, linesearch, pre-check
344 
345 .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
346 @*/
347 PetscErrorCode  SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
348 {
349   PetscFunctionBegin;
350   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
351   if (func) linesearch->ops->precheck = func;
352   if (ctx) linesearch->precheckctx = ctx;
353   PetscFunctionReturn(0);
354 }
355 
356 /*@C
357    SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine.
358 
359    Input Parameters:
360 .  linesearch - the SNESLineSearch context
361 
362    Output Parameters:
363 +  func       - [optional] function evaluation routine, see SNESLineSearchPreCheck() for calling sequence
364 -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
365 
366    Level: intermediate
367 
368 .keywords: get, linesearch, pre-check
369 
370 .seealso: SNESGetLineSearch(), SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck()
371 @*/
372 PetscErrorCode  SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
373 {
374   PetscFunctionBegin;
375   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
376   if (func) *func = linesearch->ops->precheck;
377   if (ctx) *ctx = linesearch->precheckctx;
378   PetscFunctionReturn(0);
379 }
380 
381 /*@C
382    SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step
383        direction and length. Allows the user a chance to change or override the decision of the line search routine
384 
385    Logically Collective on SNESLineSearch
386 
387    Input Parameters:
388 +  linesearch - the SNESLineSearch context
389 .  func - [optional] function evaluation routine, see SNESLineSearchPostCheck()  for the calling sequence
390 -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
391 
392    Level: intermediate
393 
394 .keywords: set, linesearch, post-check
395 
396 .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchGetPostCheck()
397 @*/
398 PetscErrorCode  SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
399 {
400   PetscFunctionBegin;
401   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
402   if (func) linesearch->ops->postcheck = func;
403   if (ctx) linesearch->postcheckctx = ctx;
404   PetscFunctionReturn(0);
405 }
406 
407 /*@C
408    SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.
409 
410    Input Parameters:
411 .  linesearch - the SNESLineSearch context
412 
413    Output Parameters:
414 +  func - [optional] function evaluation routine, see for the calling sequence SNESLineSearchPostCheck()
415 -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
416 
417    Level: intermediate
418 
419 .keywords: get, linesearch, post-check
420 
421 .seealso: SNESGetLineSearch(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck()
422 @*/
423 PetscErrorCode  SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
424 {
425   PetscFunctionBegin;
426   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
427   if (func) *func = linesearch->ops->postcheck;
428   if (ctx) *ctx = linesearch->postcheckctx;
429   PetscFunctionReturn(0);
430 }
431 
432 /*@
433    SNESLineSearchPreCheck - Prepares the line search for being applied.
434 
435    Logically Collective on SNESLineSearch
436 
437    Input Parameters:
438 +  linesearch - The linesearch instance.
439 .  X - The current solution
440 -  Y - The step direction
441 
442    Output Parameters:
443 .  changed - Indicator that the precheck routine has changed anything
444 
445    Level: developer
446 
447 .keywords: SNESLineSearch, Create
448 
449 .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck()
450 @*/
451 PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
452 {
453   PetscErrorCode ierr;
454 
455   PetscFunctionBegin;
456   *changed = PETSC_FALSE;
457   if (linesearch->ops->precheck) {
458     ierr = (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);CHKERRQ(ierr);
459     PetscValidLogicalCollectiveBool(linesearch,*changed,4);
460   }
461   PetscFunctionReturn(0);
462 }
463 
464 /*@
465    SNESLineSearchPostCheck - Prepares the line search for being applied.
466 
467    Logically Collective on SNESLineSearch
468 
469    Input Parameters:
470 +  linesearch - The linesearch context
471 .  X - The last solution
472 .  Y - The step direction
473 -  W - The updated solution, W = X + lambda*Y for some lambda
474 
475    Output Parameters:
476 +  changed_Y - Indicator if the direction Y has been changed.
477 -  changed_W - Indicator if the new candidate solution W has been changed.
478 
479    Level: developer
480 
481 .keywords: SNESLineSearch, Create
482 
483 .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPrecheck(), SNESLineSearchGetPrecheck()
484 @*/
485 PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
486 {
487   PetscErrorCode ierr;
488 
489   PetscFunctionBegin;
490   *changed_Y = PETSC_FALSE;
491   *changed_W = PETSC_FALSE;
492   if (linesearch->ops->postcheck) {
493     ierr = (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);CHKERRQ(ierr);
494     PetscValidLogicalCollectiveBool(linesearch,*changed_Y,5);
495     PetscValidLogicalCollectiveBool(linesearch,*changed_W,6);
496   }
497   PetscFunctionReturn(0);
498 }
499 
500 /*@C
501    SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration
502 
503    Logically Collective on SNESLineSearch
504 
505    Input Arguments:
506 +  linesearch - linesearch context
507 .  X - base state for this step
508 .  Y - initial correction
509 -  ctx - context for this function
510 
511    Output Arguments:
512 +  Y - correction, possibly modified
513 -  changed - flag indicating that Y was modified
514 
515    Options Database Key:
516 +  -snes_linesearch_precheck_picard - activate this routine
517 -  -snes_linesearch_precheck_picard_angle - angle
518 
519    Level: advanced
520 
521    Notes:
522    This function should be passed to SNESLineSearchSetPreCheck()
523 
524    The justification for this method involves the linear convergence of a Picard iteration
525    so the Picard linearization should be provided in place of the "Jacobian". This correction
526    is generally not useful when using a Newton linearization.
527 
528    Reference:
529    Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.
530 
531 .seealso: SNESGetLineSearch(), SNESLineSearchSetPreCheck()
532 @*/
533 PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
534 {
535   PetscErrorCode ierr;
536   PetscReal      angle = *(PetscReal*)linesearch->precheckctx;
537   Vec            Ylast;
538   PetscScalar    dot;
539   PetscInt       iter;
540   PetscReal      ynorm,ylastnorm,theta,angle_radians;
541   SNES           snes;
542 
543   PetscFunctionBegin;
544   ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr);
545   ierr = PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);CHKERRQ(ierr);
546   if (!Ylast) {
547     ierr = VecDuplicate(Y,&Ylast);CHKERRQ(ierr);
548     ierr = PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);CHKERRQ(ierr);
549     ierr = PetscObjectDereference((PetscObject)Ylast);CHKERRQ(ierr);
550   }
551   ierr = SNESGetIterationNumber(snes,&iter);CHKERRQ(ierr);
552   if (iter < 2) {
553     ierr     = VecCopy(Y,Ylast);CHKERRQ(ierr);
554     *changed = PETSC_FALSE;
555     PetscFunctionReturn(0);
556   }
557 
558   ierr = VecDot(Y,Ylast,&dot);CHKERRQ(ierr);
559   ierr = VecNorm(Y,NORM_2,&ynorm);CHKERRQ(ierr);
560   ierr = VecNorm(Ylast,NORM_2,&ylastnorm);CHKERRQ(ierr);
561   /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
562   theta         = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
563   angle_radians = angle * PETSC_PI / 180.;
564   if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
565     /* Modify the step Y */
566     PetscReal alpha,ydiffnorm;
567     ierr  = VecAXPY(Ylast,-1.0,Y);CHKERRQ(ierr);
568     ierr  = VecNorm(Ylast,NORM_2,&ydiffnorm);CHKERRQ(ierr);
569     alpha = (ydiffnorm > .001*ylastnorm) ? ylastnorm / ydiffnorm : 1000.0;
570     ierr  = VecCopy(Y,Ylast);CHKERRQ(ierr);
571     ierr  = VecScale(Y,alpha);CHKERRQ(ierr);
572     ierr  = 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);CHKERRQ(ierr);
573     *changed = PETSC_TRUE;
574   } else {
575     ierr     = PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);CHKERRQ(ierr);
576     ierr     = VecCopy(Y,Ylast);CHKERRQ(ierr);
577     *changed = PETSC_FALSE;
578   }
579   PetscFunctionReturn(0);
580 }
581 
582 /*@
583    SNESLineSearchApply - Computes the line-search update.
584 
585    Collective on SNESLineSearch
586 
587    Input Parameters:
588 +  linesearch - The linesearch context
589 .  X - The current solution
590 .  F - The current function
591 .  fnorm - The current norm
592 -  Y - The search direction
593 
594    Output Parameters:
595 +  X - The new solution
596 .  F - The new function
597 -  fnorm - The new function norm
598 
599    Options Database Keys:
600 + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell
601 . -snes_linesearch_monitor [:filename] - Print progress of line searches
602 . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping)
603 . -snes_linesearch_norms   - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms())
604 . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
605 - -snes_linesearch_max_it - The number of iterations for iterative line searches
606 
607    Notes:
608    This is typically called from within a SNESSolve() implementation in order to
609    help with convergence of the nonlinear method.  Various SNES types use line searches
610    in different ways, but the overarching theme is that a line search is used to determine
611    an optimal damping parameter of a step at each iteration of the method.  Each
612    application of the line search may invoke SNESComputeFunction() several times, and
613    therefore may be fairly expensive.
614 
615    Level: Intermediate
616 
617 .keywords: SNESLineSearch, Create
618 
619 .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(),
620           SNESLineSearchType, SNESLineSearchSetType()
621 @*/
622 PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
623 {
624   PetscErrorCode ierr;
625 
626   PetscFunctionBegin;
627   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
628   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
629   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
630   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
631 
632   linesearch->result = SNES_LINESEARCH_SUCCEEDED;
633 
634   linesearch->vec_sol    = X;
635   linesearch->vec_update = Y;
636   linesearch->vec_func   = F;
637 
638   ierr = SNESLineSearchSetUp(linesearch);CHKERRQ(ierr);
639 
640   if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
641 
642   if (fnorm) linesearch->fnorm = *fnorm;
643   else {
644     ierr = VecNorm(F, NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
645   }
646 
647   ierr = PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y);CHKERRQ(ierr);
648 
649   ierr = (*linesearch->ops->apply)(linesearch);CHKERRQ(ierr);
650 
651   ierr = PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y);CHKERRQ(ierr);
652 
653   if (fnorm) *fnorm = linesearch->fnorm;
654   PetscFunctionReturn(0);
655 }
656 
657 /*@
658    SNESLineSearchDestroy - Destroys the line search instance.
659 
660    Collective on SNESLineSearch
661 
662    Input Parameters:
663 .  linesearch - The linesearch context
664 
665    Level: developer
666 
667 .keywords: SNESLineSearch, Destroy
668 
669 .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
670 @*/
671 PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
672 {
673   PetscErrorCode ierr;
674 
675   PetscFunctionBegin;
676   if (!*linesearch) PetscFunctionReturn(0);
677   PetscValidHeaderSpecific((*linesearch),SNESLINESEARCH_CLASSID,1);
678   if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; PetscFunctionReturn(0);}
679   ierr = PetscObjectSAWsViewOff((PetscObject)*linesearch);CHKERRQ(ierr);
680   ierr = SNESLineSearchReset(*linesearch);CHKERRQ(ierr);
681   if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
682   ierr = PetscViewerDestroy(&(*linesearch)->monitor);CHKERRQ(ierr);
683   ierr = SNESLineSearchMonitorCancel((*linesearch));CHKERRQ(ierr);
684   ierr = PetscHeaderDestroy(linesearch);CHKERRQ(ierr);
685   PetscFunctionReturn(0);
686 }
687 
688 /*@
689    SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.
690 
691    Input Parameters:
692 +  linesearch - the linesearch object
693 -  viewer - an ASCII PetscViewer or NULL to turn off monitor
694 
695    Logically Collective on SNESLineSearch
696 
697    Options Database:
698 .   -snes_linesearch_monitor [:filename] - enables the monitor
699 
700    Level: intermediate
701 
702    Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with
703      SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the
704      line search that are not visible to the other monitors.
705 
706 .seealso: SNESGetLineSearch(), SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor()
707 @*/
708 PetscErrorCode  SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
709 {
710   PetscErrorCode ierr;
711 
712   PetscFunctionBegin;
713   if (viewer) {ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);}
714   ierr = PetscViewerDestroy(&linesearch->monitor);CHKERRQ(ierr);
715   linesearch->monitor = viewer;
716   PetscFunctionReturn(0);
717 }
718 
719 /*@
720    SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.
721 
722    Input Parameter:
723 .  linesearch - linesearch context
724 
725    Output Parameter:
726 .  monitor - monitor context
727 
728    Logically Collective on SNES
729 
730    Options Database Keys:
731 .   -snes_linesearch_monitor - enables the monitor
732 
733    Level: intermediate
734 
735 .seealso: SNESGetLineSearch(), SNESLineSearchSetDefaultMonitor(), PetscViewer
736 @*/
737 PetscErrorCode  SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
738 {
739   PetscFunctionBegin;
740   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
741   if (monitor) {
742     PetscValidPointer(monitor, 2);
743     *monitor = linesearch->monitor;
744   }
745   PetscFunctionReturn(0);
746 }
747 
748 /*@C
749    SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
750 
751    Collective on SNESLineSearch
752 
753    Input Parameters:
754 +  ls - LineSearch object you wish to monitor
755 .  name - the monitor type one is seeking
756 .  help - message indicating what monitoring is done
757 .  manual - manual page for the monitor
758 .  monitor - the monitor function
759 -  monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the SNESLineSearch or PetscViewer objects
760 
761    Level: developer
762 
763 .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
764           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
765           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
766           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
767           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
768           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
769           PetscOptionsFList(), PetscOptionsEList()
770 @*/
771 PetscErrorCode  SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
772 {
773   PetscErrorCode    ierr;
774   PetscViewer       viewer;
775   PetscViewerFormat format;
776   PetscBool         flg;
777 
778   PetscFunctionBegin;
779   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject) ls)->options,((PetscObject)ls)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr);
780   if (flg) {
781     PetscViewerAndFormat *vf;
782     ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr);
783     ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr);
784     if (monitorsetup) {
785       ierr = (*monitorsetup)(ls,vf);CHKERRQ(ierr);
786     }
787     ierr = SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr);
788   }
789   PetscFunctionReturn(0);
790 }
791 
792 /*@
793    SNESLineSearchSetFromOptions - Sets options for the line search
794 
795    Input Parameters:
796 .  linesearch - linesearch context
797 
798    Options Database Keys:
799 + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
800 . -snes_linesearch_order <order> - 1, 2, 3.  Most types only support certain orders (bt supports 2 or 3)
801 . -snes_linesearch_norms   - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms())
802 . -snes_linesearch_minlambda - The minimum step length
803 . -snes_linesearch_maxstep - The maximum step size
804 . -snes_linesearch_rtol - Relative tolerance for iterative line searches
805 . -snes_linesearch_atol - Absolute tolerance for iterative line searches
806 . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
807 . -snes_linesearch_max_it - The number of iterations for iterative line searches
808 . -snes_linesearch_monitor [:filename] - Print progress of line searches
809 . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
810 . -snes_linesearch_damping - The linesearch damping parameter
811 . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
812 . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
813 - -snes_linesearch_precheck_picard_angle - Angle used in picard precheck method
814 
815    Logically Collective on SNESLineSearch
816 
817    Level: intermediate
818 
819 .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(),
820           SNESLineSearchType, SNESLineSearchSetComputeNorms()
821 @*/
822 PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
823 {
824   PetscErrorCode    ierr;
825   const char        *deft = SNESLINESEARCHBASIC;
826   char              type[256];
827   PetscBool         flg, set;
828   PetscViewer       viewer;
829 
830   PetscFunctionBegin;
831   ierr = SNESLineSearchRegisterAll();CHKERRQ(ierr);
832 
833   ierr = PetscObjectOptionsBegin((PetscObject)linesearch);CHKERRQ(ierr);
834   if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
835   ierr = PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);CHKERRQ(ierr);
836   if (flg) {
837     ierr = SNESLineSearchSetType(linesearch,type);CHKERRQ(ierr);
838   } else if (!((PetscObject)linesearch)->type_name) {
839     ierr = SNESLineSearchSetType(linesearch,deft);CHKERRQ(ierr);
840   }
841 
842   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject) linesearch)->options,((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);CHKERRQ(ierr);
843   if (set) {
844     ierr = SNESLineSearchSetDefaultMonitor(linesearch,viewer);CHKERRQ(ierr);
845     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
846   }
847   ierr = SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);CHKERRQ(ierr);
848 
849   /* tolerances */
850   ierr = PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);CHKERRQ(ierr);
851   ierr = PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);CHKERRQ(ierr);
852   ierr = PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);CHKERRQ(ierr);
853   ierr = PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);CHKERRQ(ierr);
854   ierr = PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);CHKERRQ(ierr);
855   ierr = PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);CHKERRQ(ierr);
856 
857   /* damping parameters */
858   ierr = PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);CHKERRQ(ierr);
859 
860   ierr = PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL);CHKERRQ(ierr);
861 
862   /* precheck */
863   ierr = PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr);
864   if (set) {
865     if (flg) {
866       linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
867 
868       ierr = PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
869                               "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);CHKERRQ(ierr);
870       ierr = SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);CHKERRQ(ierr);
871     } else {
872       ierr = SNESLineSearchSetPreCheck(linesearch,NULL,NULL);CHKERRQ(ierr);
873     }
874   }
875   ierr = PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);CHKERRQ(ierr);
876   ierr = PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);CHKERRQ(ierr);
877 
878   if (linesearch->ops->setfromoptions) {
879     (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);CHKERRQ(ierr);
880   }
881 
882   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);CHKERRQ(ierr);
883   ierr = PetscOptionsEnd();CHKERRQ(ierr);
884   PetscFunctionReturn(0);
885 }
886 
887 /*@
888    SNESLineSearchView - Prints useful information about the line search
889 
890    Input Parameters:
891 .  linesearch - linesearch context
892 
893    Logically Collective on SNESLineSearch
894 
895    Level: intermediate
896 
897 .seealso: SNESLineSearchCreate()
898 @*/
899 PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
900 {
901   PetscErrorCode ierr;
902   PetscBool      iascii;
903 
904   PetscFunctionBegin;
905   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
906   if (!viewer) {
907     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);CHKERRQ(ierr);
908   }
909   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
910   PetscCheckSameComm(linesearch,1,viewer,2);
911 
912   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
913   if (iascii) {
914     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);CHKERRQ(ierr);
915     if (linesearch->ops->view) {
916       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
917       ierr = (*linesearch->ops->view)(linesearch,viewer);CHKERRQ(ierr);
918       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
919     }
920     ierr = PetscViewerASCIIPrintf(viewer,"  maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);CHKERRQ(ierr);
921     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);CHKERRQ(ierr);
922     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D\n", linesearch->max_its);CHKERRQ(ierr);
923     if (linesearch->ops->precheck) {
924       if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
925         ierr = PetscViewerASCIIPrintf(viewer,"  using precheck step to speed up Picard convergence\n", linesearch->max_its);CHKERRQ(ierr);
926       } else {
927         ierr = PetscViewerASCIIPrintf(viewer,"  using user-defined precheck step\n", linesearch->max_its);CHKERRQ(ierr);
928       }
929     }
930     if (linesearch->ops->postcheck) {
931       ierr = PetscViewerASCIIPrintf(viewer,"  using user-defined postcheck step\n", linesearch->max_its);CHKERRQ(ierr);
932     }
933   }
934   PetscFunctionReturn(0);
935 }
936 
937 /*@C
938    SNESLineSearchSetType - Sets the linesearch type
939 
940    Logically Collective on SNESLineSearch
941 
942    Input Parameters:
943 +  linesearch - linesearch context
944 -  type - The type of line search to be used
945 
946    Available Types:
947 +  SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
948 .  SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
949 .  SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
950 .  SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
951 .  SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
952 -  SNESLINESEARCHSHELL - User provided SNESLineSearch implementation
953 
954    Options Database:
955 .  -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
956 
957    Level: intermediate
958 
959 .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions()
960 @*/
961 PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
962 {
963   PetscErrorCode ierr,(*r)(SNESLineSearch);
964   PetscBool      match;
965 
966   PetscFunctionBegin;
967   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
968   PetscValidCharPointer(type,2);
969 
970   ierr = PetscObjectTypeCompare((PetscObject)linesearch,type,&match);CHKERRQ(ierr);
971   if (match) PetscFunctionReturn(0);
972 
973   ierr = PetscFunctionListFind(SNESLineSearchList,type,&r);CHKERRQ(ierr);
974   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
975   /* Destroy the previous private linesearch context */
976   if (linesearch->ops->destroy) {
977     ierr = (*(linesearch)->ops->destroy)(linesearch);CHKERRQ(ierr);
978 
979     linesearch->ops->destroy = NULL;
980   }
981   /* Reinitialize function pointers in SNESLineSearchOps structure */
982   linesearch->ops->apply          = 0;
983   linesearch->ops->view           = 0;
984   linesearch->ops->setfromoptions = 0;
985   linesearch->ops->destroy        = 0;
986 
987   ierr = PetscObjectChangeTypeName((PetscObject)linesearch,type);CHKERRQ(ierr);
988   ierr = (*r)(linesearch);CHKERRQ(ierr);
989   PetscFunctionReturn(0);
990 }
991 
992 /*@
993    SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
994 
995    Input Parameters:
996 +  linesearch - linesearch context
997 -  snes - The snes instance
998 
999    Level: developer
1000 
1001    Notes:
1002    This happens automatically when the line search is obtained/created with
1003    SNESGetLineSearch().  This routine is therefore mainly called within SNES
1004    implementations.
1005 
1006    Level: developer
1007 
1008 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1009 @*/
1010 PetscErrorCode  SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
1011 {
1012   PetscFunctionBegin;
1013   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1014   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
1015   linesearch->snes = snes;
1016   PetscFunctionReturn(0);
1017 }
1018 
1019 /*@
1020    SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
1021    Having an associated SNES is necessary because most line search implementations must be able to
1022    evaluate the function using SNESComputeFunction() for the associated SNES.  This routine
1023    is used in the line search implementations when one must get this associated SNES instance.
1024 
1025    Input Parameters:
1026 .  linesearch - linesearch context
1027 
1028    Output Parameters:
1029 .  snes - The snes instance
1030 
1031    Level: developer
1032 
1033 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1034 @*/
1035 PetscErrorCode  SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1036 {
1037   PetscFunctionBegin;
1038   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1039   PetscValidPointer(snes, 2);
1040   *snes = linesearch->snes;
1041   PetscFunctionReturn(0);
1042 }
1043 
1044 /*@
1045    SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
1046 
1047    Input Parameters:
1048 .  linesearch - linesearch context
1049 
1050    Output Parameters:
1051 .  lambda - The last steplength computed during SNESLineSearchApply()
1052 
1053    Level: advanced
1054 
1055    Notes:
1056    This is useful in methods where the solver is ill-scaled and
1057    requires some adaptive notion of the difference in scale between the
1058    solution and the function.  For instance, SNESQN may be scaled by the
1059    line search lambda using the argument -snes_qn_scaling ls.
1060 
1061 .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1062 @*/
1063 PetscErrorCode  SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1064 {
1065   PetscFunctionBegin;
1066   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1067   PetscValidPointer(lambda, 2);
1068   *lambda = linesearch->lambda;
1069   PetscFunctionReturn(0);
1070 }
1071 
1072 /*@
1073    SNESLineSearchSetLambda - Sets the linesearch steplength.
1074 
1075    Input Parameters:
1076 +  linesearch - linesearch context
1077 -  lambda - The last steplength.
1078 
1079    Notes:
1080    This routine is typically used within implementations of SNESLineSearchApply()
1081    to set the final steplength.  This routine (and SNESLineSearchGetLambda()) were
1082    added in order to facilitate Quasi-Newton methods that use the previous steplength
1083    as an inner scaling parameter.
1084 
1085    Level: advanced
1086 
1087 .seealso: SNESLineSearchGetLambda()
1088 @*/
1089 PetscErrorCode  SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1090 {
1091   PetscFunctionBegin;
1092   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1093   linesearch->lambda = lambda;
1094   PetscFunctionReturn(0);
1095 }
1096 
1097 /*@
1098    SNESLineSearchGetTolerances - Gets the tolerances for the linesearch.  These include
1099    tolerances for the relative and absolute change in the function norm, the change
1100    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1101    and the maximum number of iterations the line search procedure may take.
1102 
1103    Input Parameters:
1104 .  linesearch - linesearch context
1105 
1106    Output Parameters:
1107 +  steptol - The minimum steplength
1108 .  maxstep - The maximum steplength
1109 .  rtol    - The relative tolerance for iterative line searches
1110 .  atol    - The absolute tolerance for iterative line searches
1111 .  ltol    - The change in lambda tolerance for iterative line searches
1112 -  max_it  - The maximum number of iterations of the line search
1113 
1114    Level: intermediate
1115 
1116    Notes:
1117    Different line searches may implement these parameters slightly differently as
1118    the type requires.
1119 
1120 .seealso: SNESLineSearchSetTolerances()
1121 @*/
1122 PetscErrorCode  SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1123 {
1124   PetscFunctionBegin;
1125   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1126   if (steptol) {
1127     PetscValidPointer(steptol, 2);
1128     *steptol = linesearch->steptol;
1129   }
1130   if (maxstep) {
1131     PetscValidPointer(maxstep, 3);
1132     *maxstep = linesearch->maxstep;
1133   }
1134   if (rtol) {
1135     PetscValidPointer(rtol, 4);
1136     *rtol = linesearch->rtol;
1137   }
1138   if (atol) {
1139     PetscValidPointer(atol, 5);
1140     *atol = linesearch->atol;
1141   }
1142   if (ltol) {
1143     PetscValidPointer(ltol, 6);
1144     *ltol = linesearch->ltol;
1145   }
1146   if (max_its) {
1147     PetscValidPointer(max_its, 7);
1148     *max_its = linesearch->max_its;
1149   }
1150   PetscFunctionReturn(0);
1151 }
1152 
1153 /*@
1154    SNESLineSearchSetTolerances -  Gets the tolerances for the linesearch.  These include
1155    tolerances for the relative and absolute change in the function norm, the change
1156    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1157    and the maximum number of iterations the line search procedure may take.
1158 
1159    Input Parameters:
1160 +  linesearch - linesearch context
1161 .  steptol - The minimum steplength
1162 .  maxstep - The maximum steplength
1163 .  rtol    - The relative tolerance for iterative line searches
1164 .  atol    - The absolute tolerance for iterative line searches
1165 .  ltol    - The change in lambda tolerance for iterative line searches
1166 -  max_it  - The maximum number of iterations of the line search
1167 
1168    Notes:
1169    The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1170    place of an argument.
1171 
1172    Level: intermediate
1173 
1174 .seealso: SNESLineSearchGetTolerances()
1175 @*/
1176 PetscErrorCode  SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1177 {
1178   PetscFunctionBegin;
1179   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1180   PetscValidLogicalCollectiveReal(linesearch,steptol,2);
1181   PetscValidLogicalCollectiveReal(linesearch,maxstep,3);
1182   PetscValidLogicalCollectiveReal(linesearch,rtol,4);
1183   PetscValidLogicalCollectiveReal(linesearch,atol,5);
1184   PetscValidLogicalCollectiveReal(linesearch,ltol,6);
1185   PetscValidLogicalCollectiveInt(linesearch,max_its,7);
1186 
1187   if (steptol!= PETSC_DEFAULT) {
1188     if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
1189     linesearch->steptol = steptol;
1190   }
1191 
1192   if (maxstep!= PETSC_DEFAULT) {
1193     if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1194     linesearch->maxstep = maxstep;
1195   }
1196 
1197   if (rtol != PETSC_DEFAULT) {
1198     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);
1199     linesearch->rtol = rtol;
1200   }
1201 
1202   if (atol != PETSC_DEFAULT) {
1203     if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1204     linesearch->atol = atol;
1205   }
1206 
1207   if (ltol != PETSC_DEFAULT) {
1208     if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %14.12e must be non-negative",(double)ltol);
1209     linesearch->ltol = ltol;
1210   }
1211 
1212   if (max_its != PETSC_DEFAULT) {
1213     if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1214     linesearch->max_its = max_its;
1215   }
1216   PetscFunctionReturn(0);
1217 }
1218 
1219 /*@
1220    SNESLineSearchGetDamping - Gets the line search damping parameter.
1221 
1222    Input Parameters:
1223 .  linesearch - linesearch context
1224 
1225    Output Parameters:
1226 .  damping - The damping parameter
1227 
1228    Level: advanced
1229 
1230 .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1231 @*/
1232 
1233 PetscErrorCode  SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1234 {
1235   PetscFunctionBegin;
1236   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1237   PetscValidPointer(damping, 2);
1238   *damping = linesearch->damping;
1239   PetscFunctionReturn(0);
1240 }
1241 
1242 /*@
1243    SNESLineSearchSetDamping - Sets the line search damping paramter.
1244 
1245    Input Parameters:
1246 +  linesearch - linesearch context
1247 -  damping - The damping parameter
1248 
1249    Options Database:
1250 .   -snes_linesearch_damping
1251    Level: intermediate
1252 
1253    Notes:
1254    The basic line search merely takes the update step scaled by the damping parameter.
1255    The use of the damping parameter in the l2 and cp line searches is much more subtle;
1256    it is used as a starting point in calculating the secant step. However, the eventual
1257    step may be of greater length than the damping parameter.  In the bt line search it is
1258    used as the maximum possible step length, as the bt line search only backtracks.
1259 
1260 .seealso: SNESLineSearchGetDamping()
1261 @*/
1262 PetscErrorCode  SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1263 {
1264   PetscFunctionBegin;
1265   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1266   linesearch->damping = damping;
1267   PetscFunctionReturn(0);
1268 }
1269 
1270 /*@
1271    SNESLineSearchGetOrder - Gets the line search approximation order.
1272 
1273    Input Parameters:
1274 .  linesearch - linesearch context
1275 
1276    Output Parameters:
1277 .  order - The order
1278 
1279    Possible Values for order:
1280 +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1281 .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1282 -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1283 
1284    Level: intermediate
1285 
1286 .seealso: SNESLineSearchSetOrder()
1287 @*/
1288 
1289 PetscErrorCode  SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1290 {
1291   PetscFunctionBegin;
1292   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1293   PetscValidPointer(order, 2);
1294   *order = linesearch->order;
1295   PetscFunctionReturn(0);
1296 }
1297 
1298 /*@
1299    SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
1300 
1301    Input Parameters:
1302 .  linesearch - linesearch context
1303 .  order - The damping parameter
1304 
1305    Level: intermediate
1306 
1307    Possible Values for order:
1308 +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1309 .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1310 -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1311 
1312    Notes:
1313    Variable orders are supported by the following line searches:
1314 +  bt - cubic and quadratic
1315 -  cp - linear and quadratic
1316 
1317 .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1318 @*/
1319 PetscErrorCode  SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1320 {
1321   PetscFunctionBegin;
1322   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1323   linesearch->order = order;
1324   PetscFunctionReturn(0);
1325 }
1326 
1327 /*@
1328    SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1329 
1330    Input Parameters:
1331 .  linesearch - linesearch context
1332 
1333    Output Parameters:
1334 +  xnorm - The norm of the current solution
1335 .  fnorm - The norm of the current function
1336 -  ynorm - The norm of the current update
1337 
1338    Notes:
1339    This function is mainly called from SNES implementations.
1340 
1341    Level: developer
1342 
1343 .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1344 @*/
1345 PetscErrorCode  SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1346 {
1347   PetscFunctionBegin;
1348   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1349   if (xnorm) *xnorm = linesearch->xnorm;
1350   if (fnorm) *fnorm = linesearch->fnorm;
1351   if (ynorm) *ynorm = linesearch->ynorm;
1352   PetscFunctionReturn(0);
1353 }
1354 
1355 /*@
1356    SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1357 
1358    Input Parameters:
1359 +  linesearch - linesearch context
1360 .  xnorm - The norm of the current solution
1361 .  fnorm - The norm of the current function
1362 -  ynorm - The norm of the current update
1363 
1364    Level: advanced
1365 
1366 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1367 @*/
1368 PetscErrorCode  SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1369 {
1370   PetscFunctionBegin;
1371   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1372   linesearch->xnorm = xnorm;
1373   linesearch->fnorm = fnorm;
1374   linesearch->ynorm = ynorm;
1375   PetscFunctionReturn(0);
1376 }
1377 
1378 /*@
1379    SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1380 
1381    Input Parameters:
1382 .  linesearch - linesearch context
1383 
1384    Options Database Keys:
1385 .   -snes_linesearch_norms - turn norm computation on or off
1386 
1387    Level: intermediate
1388 
1389 .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1390 @*/
1391 PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1392 {
1393   PetscErrorCode ierr;
1394   SNES           snes;
1395 
1396   PetscFunctionBegin;
1397   if (linesearch->norms) {
1398     if (linesearch->ops->vinorm) {
1399       ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr);
1400       ierr = VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
1401       ierr = VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
1402       ierr = (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);CHKERRQ(ierr);
1403     } else {
1404       ierr = VecNormBegin(linesearch->vec_func,   NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
1405       ierr = VecNormBegin(linesearch->vec_sol,    NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
1406       ierr = VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
1407       ierr = VecNormEnd(linesearch->vec_func,     NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
1408       ierr = VecNormEnd(linesearch->vec_sol,      NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
1409       ierr = VecNormEnd(linesearch->vec_update,   NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
1410     }
1411   }
1412   PetscFunctionReturn(0);
1413 }
1414 
1415 /*@
1416    SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
1417 
1418    Input Parameters:
1419 +  linesearch  - linesearch context
1420 -  flg  - indicates whether or not to compute norms
1421 
1422    Options Database Keys:
1423 .   -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch
1424 
1425    Notes:
1426    This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm.
1427 
1428    Level: intermediate
1429 
1430 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1431 @*/
1432 PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1433 {
1434   PetscFunctionBegin;
1435   linesearch->norms = flg;
1436   PetscFunctionReturn(0);
1437 }
1438 
1439 /*@
1440    SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1441 
1442    Input Parameters:
1443 .  linesearch - linesearch context
1444 
1445    Output Parameters:
1446 +  X - Solution vector
1447 .  F - Function vector
1448 .  Y - Search direction vector
1449 .  W - Solution work vector
1450 -  G - Function work vector
1451 
1452    Notes:
1453    At the beginning of a line search application, X should contain a
1454    solution and the vector F the function computed at X.  At the end of the
1455    line search application, X should contain the new solution, and F the
1456    function evaluated at the new solution.
1457 
1458    These vectors are owned by the SNESLineSearch and should not be destroyed by the caller
1459 
1460    Level: advanced
1461 
1462 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1463 @*/
1464 PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1465 {
1466   PetscFunctionBegin;
1467   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1468   if (X) {
1469     PetscValidPointer(X, 2);
1470     *X = linesearch->vec_sol;
1471   }
1472   if (F) {
1473     PetscValidPointer(F, 3);
1474     *F = linesearch->vec_func;
1475   }
1476   if (Y) {
1477     PetscValidPointer(Y, 4);
1478     *Y = linesearch->vec_update;
1479   }
1480   if (W) {
1481     PetscValidPointer(W, 5);
1482     *W = linesearch->vec_sol_new;
1483   }
1484   if (G) {
1485     PetscValidPointer(G, 6);
1486     *G = linesearch->vec_func_new;
1487   }
1488   PetscFunctionReturn(0);
1489 }
1490 
1491 /*@
1492    SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1493 
1494    Input Parameters:
1495 +  linesearch - linesearch context
1496 .  X - Solution vector
1497 .  F - Function vector
1498 .  Y - Search direction vector
1499 .  W - Solution work vector
1500 -  G - Function work vector
1501 
1502    Level: advanced
1503 
1504 .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1505 @*/
1506 PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1507 {
1508   PetscFunctionBegin;
1509   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1510   if (X) {
1511     PetscValidHeaderSpecific(X,VEC_CLASSID,2);
1512     linesearch->vec_sol = X;
1513   }
1514   if (F) {
1515     PetscValidHeaderSpecific(F,VEC_CLASSID,3);
1516     linesearch->vec_func = F;
1517   }
1518   if (Y) {
1519     PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
1520     linesearch->vec_update = Y;
1521   }
1522   if (W) {
1523     PetscValidHeaderSpecific(W,VEC_CLASSID,5);
1524     linesearch->vec_sol_new = W;
1525   }
1526   if (G) {
1527     PetscValidHeaderSpecific(G,VEC_CLASSID,6);
1528     linesearch->vec_func_new = G;
1529   }
1530   PetscFunctionReturn(0);
1531 }
1532 
1533 /*@C
1534    SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1535    SNES options in the database.
1536 
1537    Logically Collective on SNESLineSearch
1538 
1539    Input Parameters:
1540 +  snes - the SNES context
1541 -  prefix - the prefix to prepend to all option names
1542 
1543    Notes:
1544    A hyphen (-) must NOT be given at the beginning of the prefix name.
1545    The first character of all runtime options is AUTOMATICALLY the hyphen.
1546 
1547    Level: advanced
1548 
1549 .keywords: SNESLineSearch, append, options, prefix, database
1550 
1551 .seealso: SNESGetOptionsPrefix()
1552 @*/
1553 PetscErrorCode  SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1554 {
1555   PetscErrorCode ierr;
1556 
1557   PetscFunctionBegin;
1558   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1559   ierr = PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr);
1560   PetscFunctionReturn(0);
1561 }
1562 
1563 /*@C
1564    SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1565    SNESLineSearch options in the database.
1566 
1567    Not Collective
1568 
1569    Input Parameter:
1570 .  linesearch - the SNESLineSearch context
1571 
1572    Output Parameter:
1573 .  prefix - pointer to the prefix string used
1574 
1575    Notes:
1576    On the fortran side, the user should pass in a string 'prefix' of
1577    sufficient length to hold the prefix.
1578 
1579    Level: advanced
1580 
1581 .keywords: SNESLineSearch, get, options, prefix, database
1582 
1583 .seealso: SNESAppendOptionsPrefix()
1584 @*/
1585 PetscErrorCode  SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1586 {
1587   PetscErrorCode ierr;
1588 
1589   PetscFunctionBegin;
1590   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1591   ierr = PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr);
1592   PetscFunctionReturn(0);
1593 }
1594 
1595 /*@C
1596    SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1597 
1598    Input Parameter:
1599 +  linesearch - the SNESLineSearch context
1600 -  nwork - the number of work vectors
1601 
1602    Level: developer
1603 
1604 .keywords: SNESLineSearch, work, vector
1605 
1606 .seealso: SNESSetWorkVecs()
1607 @*/
1608 PetscErrorCode  SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1609 {
1610   PetscErrorCode ierr;
1611 
1612   PetscFunctionBegin;
1613   if (linesearch->vec_sol) {
1614     ierr = VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);CHKERRQ(ierr);
1615   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1616   PetscFunctionReturn(0);
1617 }
1618 
1619 /*@
1620    SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1621 
1622    Input Parameters:
1623 .  linesearch - linesearch context
1624 
1625    Output Parameters:
1626 .  result - The success or failure status
1627 
1628    Notes:
1629    This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1630    (and set the SNES convergence accordingly).
1631 
1632    Level: intermediate
1633 
1634 .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1635 @*/
1636 PetscErrorCode  SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1637 {
1638   PetscFunctionBegin;
1639   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1640   PetscValidPointer(result, 2);
1641   *result = linesearch->result;
1642   PetscFunctionReturn(0);
1643 }
1644 
1645 /*@
1646    SNESLineSearchSetReason - Sets the success/failure status of the last line search application
1647 
1648    Input Parameters:
1649 +  linesearch - linesearch context
1650 -  result - The success or failure status
1651 
1652    Notes:
1653    This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1654    the success or failure of the line search method.
1655 
1656    Level: developer
1657 
1658 .seealso: SNESLineSearchGetSResult()
1659 @*/
1660 PetscErrorCode  SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1661 {
1662   PetscFunctionBegin;
1663   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1664   linesearch->result = result;
1665   PetscFunctionReturn(0);
1666 }
1667 
1668 /*@C
1669    SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
1670 
1671    Input Parameters:
1672 +  snes - nonlinear context obtained from SNESCreate()
1673 .  projectfunc - function for projecting the function to the bounds
1674 -  normfunc - function for computing the norm of an active set
1675 
1676    Logically Collective on SNES
1677 
1678    Calling sequence of projectfunc:
1679 .vb
1680    projectfunc (SNES snes, Vec X)
1681 .ve
1682 
1683     Input parameters for projectfunc:
1684 +   snes - nonlinear context
1685 -   X - current solution
1686 
1687     Output parameters for projectfunc:
1688 .   X - Projected solution
1689 
1690    Calling sequence of normfunc:
1691 .vb
1692    projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1693 .ve
1694 
1695     Input parameters for normfunc:
1696 +   snes - nonlinear context
1697 .   X - current solution
1698 -   F - current residual
1699 
1700     Output parameters for normfunc:
1701 .   fnorm - VI-specific norm of the function
1702 
1703     Notes:
1704     The VI solvers require projection of the solution to the feasible set.  projectfunc should implement this.
1705 
1706     The VI solvers require special evaluation of the function norm such that the norm is only calculated
1707     on the inactive set.  This should be implemented by normfunc.
1708 
1709     Level: developer
1710 
1711 .keywords: SNES, line search, VI, nonlinear, set, line search
1712 
1713 .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1714 @*/
1715 PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1716 {
1717   PetscFunctionBegin;
1718   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1719   if (projectfunc) linesearch->ops->viproject = projectfunc;
1720   if (normfunc) linesearch->ops->vinorm = normfunc;
1721   PetscFunctionReturn(0);
1722 }
1723 
1724 /*@C
1725    SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
1726 
1727    Input Parameters:
1728 .  linesearch - the line search context, obtain with SNESGetLineSearch()
1729 
1730    Output Parameters:
1731 +  projectfunc - function for projecting the function to the bounds
1732 -  normfunc - function for computing the norm of an active set
1733 
1734    Logically Collective on SNES
1735 
1736     Level: developer
1737 
1738 .keywords: SNES, line search, VI, nonlinear, get, line search
1739 
1740 .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1741 @*/
1742 PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1743 {
1744   PetscFunctionBegin;
1745   if (projectfunc) *projectfunc = linesearch->ops->viproject;
1746   if (normfunc) *normfunc = linesearch->ops->vinorm;
1747   PetscFunctionReturn(0);
1748 }
1749 
1750 /*@C
1751   SNESLineSearchRegister - See SNESLineSearchRegister()
1752 
1753   Level: advanced
1754 @*/
1755 PetscErrorCode  SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1756 {
1757   PetscErrorCode ierr;
1758 
1759   PetscFunctionBegin;
1760   ierr = SNESInitializePackage();CHKERRQ(ierr);
1761   ierr = PetscFunctionListAdd(&SNESLineSearchList,sname,function);CHKERRQ(ierr);
1762   PetscFunctionReturn(0);
1763 }
1764