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