xref: /petsc/src/snes/linesearch/interface/linesearch.c (revision 487a658c8b32ba712a1dc8280daad2fd70c1dcd9)
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 = ylastnorm / ydiffnorm;
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   } else {
574     ierr     = PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);CHKERRQ(ierr);
575     ierr     = VecCopy(Y,Ylast);CHKERRQ(ierr);
576     *changed = PETSC_FALSE;
577   }
578   PetscFunctionReturn(0);
579 }
580 
581 /*@
582    SNESLineSearchApply - Computes the line-search update.
583 
584    Collective on SNESLineSearch
585 
586    Input Parameters:
587 +  linesearch - The linesearch context
588 .  X - The current solution
589 .  F - The current function
590 .  fnorm - The current norm
591 -  Y - The search direction
592 
593    Output Parameters:
594 +  X - The new solution
595 .  F - The new function
596 -  fnorm - The new function norm
597 
598    Options Database Keys:
599 + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell
600 . -snes_linesearch_monitor [:filename] - Print progress of line searches
601 . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping)
602 . -snes_linesearch_norms   - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms())
603 . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
604 - -snes_linesearch_max_it - The number of iterations for iterative line searches
605 
606    Notes:
607    This is typically called from within a SNESSolve() implementation in order to
608    help with convergence of the nonlinear method.  Various SNES types use line searches
609    in different ways, but the overarching theme is that a line search is used to determine
610    an optimal damping parameter of a step at each iteration of the method.  Each
611    application of the line search may invoke SNESComputeFunction() several times, and
612    therefore may be fairly expensive.
613 
614    Level: Intermediate
615 
616 .keywords: SNESLineSearch, Create
617 
618 .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(),
619           SNESLineSearchType, SNESLineSearchSetType()
620 @*/
621 PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
622 {
623   PetscErrorCode ierr;
624 
625   PetscFunctionBegin;
626   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
627   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
628   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
629   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
630 
631   linesearch->result = SNES_LINESEARCH_SUCCEEDED;
632 
633   linesearch->vec_sol    = X;
634   linesearch->vec_update = Y;
635   linesearch->vec_func   = F;
636 
637   ierr = SNESLineSearchSetUp(linesearch);CHKERRQ(ierr);
638 
639   if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
640 
641   if (fnorm) linesearch->fnorm = *fnorm;
642   else {
643     ierr = VecNorm(F, NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
644   }
645 
646   ierr = PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y);CHKERRQ(ierr);
647 
648   ierr = (*linesearch->ops->apply)(linesearch);CHKERRQ(ierr);
649 
650   ierr = PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y);CHKERRQ(ierr);
651 
652   if (fnorm) *fnorm = linesearch->fnorm;
653   PetscFunctionReturn(0);
654 }
655 
656 /*@
657    SNESLineSearchDestroy - Destroys the line search instance.
658 
659    Collective on SNESLineSearch
660 
661    Input Parameters:
662 .  linesearch - The linesearch context
663 
664    Level: developer
665 
666 .keywords: SNESLineSearch, Destroy
667 
668 .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
669 @*/
670 PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
671 {
672   PetscErrorCode ierr;
673 
674   PetscFunctionBegin;
675   if (!*linesearch) PetscFunctionReturn(0);
676   PetscValidHeaderSpecific((*linesearch),SNESLINESEARCH_CLASSID,1);
677   if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; PetscFunctionReturn(0);}
678   ierr = PetscObjectSAWsViewOff((PetscObject)*linesearch);CHKERRQ(ierr);
679   ierr = SNESLineSearchReset(*linesearch);CHKERRQ(ierr);
680   if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
681   ierr = PetscViewerDestroy(&(*linesearch)->monitor);CHKERRQ(ierr);
682   ierr = SNESLineSearchMonitorCancel((*linesearch));CHKERRQ(ierr);
683   ierr = PetscHeaderDestroy(linesearch);CHKERRQ(ierr);
684   PetscFunctionReturn(0);
685 }
686 
687 /*@
688    SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.
689 
690    Input Parameters:
691 +  linesearch - the linesearch object
692 -  viewer - an ASCII PetscViewer or NULL to turn off monitor
693 
694    Logically Collective on SNESLineSearch
695 
696    Options Database:
697 .   -snes_linesearch_monitor [:filename] - enables the monitor
698 
699    Level: intermediate
700 
701    Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with
702      SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the
703      line search that are not visible to the other monitors.
704 
705 .seealso: SNESGetLineSearch(), SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor()
706 @*/
707 PetscErrorCode  SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
708 {
709   PetscErrorCode ierr;
710 
711   PetscFunctionBegin;
712   if (viewer) {ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);}
713   ierr = PetscViewerDestroy(&linesearch->monitor);CHKERRQ(ierr);
714   linesearch->monitor = viewer;
715   PetscFunctionReturn(0);
716 }
717 
718 /*@
719    SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.
720 
721    Input Parameter:
722 .  linesearch - linesearch context
723 
724    Output Parameter:
725 .  monitor - monitor context
726 
727    Logically Collective on SNES
728 
729    Options Database Keys:
730 .   -snes_linesearch_monitor - enables the monitor
731 
732    Level: intermediate
733 
734 .seealso: SNESGetLineSearch(), SNESLineSearchSetDefaultMonitor(), PetscViewer
735 @*/
736 PetscErrorCode  SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
737 {
738   PetscFunctionBegin;
739   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
740   if (monitor) {
741     PetscValidPointer(monitor, 2);
742     *monitor = linesearch->monitor;
743   }
744   PetscFunctionReturn(0);
745 }
746 
747 /*@C
748    SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
749 
750    Collective on SNESLineSearch
751 
752    Input Parameters:
753 +  ls - LineSearch object you wish to monitor
754 .  name - the monitor type one is seeking
755 .  help - message indicating what monitoring is done
756 .  manual - manual page for the monitor
757 .  monitor - the monitor function
758 -  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
759 
760    Level: developer
761 
762 .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
763           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
764           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
765           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
766           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
767           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
768           PetscOptionsFList(), PetscOptionsEList()
769 @*/
770 PetscErrorCode  SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
771 {
772   PetscErrorCode    ierr;
773   PetscViewer       viewer;
774   PetscViewerFormat format;
775   PetscBool         flg;
776 
777   PetscFunctionBegin;
778   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject)ls)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr);
779   if (flg) {
780     PetscViewerAndFormat *vf;
781     ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr);
782     ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr);
783     if (monitorsetup) {
784       ierr = (*monitorsetup)(ls,vf);CHKERRQ(ierr);
785     }
786     ierr = SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr);
787   }
788   PetscFunctionReturn(0);
789 }
790 
791 /*@
792    SNESLineSearchSetFromOptions - Sets options for the line search
793 
794    Input Parameters:
795 .  linesearch - linesearch context
796 
797    Options Database Keys:
798 + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
799 . -snes_linesearch_order <order> - 1, 2, 3.  Most types only support certain orders (bt supports 2 or 3)
800 . -snes_linesearch_norms   - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms())
801 . -snes_linesearch_minlambda - The minimum step length
802 . -snes_linesearch_maxstep - The maximum step size
803 . -snes_linesearch_rtol - Relative tolerance for iterative line searches
804 . -snes_linesearch_atol - Absolute tolerance for iterative line searches
805 . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
806 . -snes_linesearch_max_it - The number of iterations for iterative line searches
807 . -snes_linesearch_monitor [:filename] - Print progress of line searches
808 . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
809 . -snes_linesearch_damping - The linesearch damping parameter
810 . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
811 . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
812 - -snes_linesearch_precheck_picard_angle - Angle used in picard precheck method
813 
814    Logically Collective on SNESLineSearch
815 
816    Level: intermediate
817 
818 .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(),
819           SNESLineSearchType, SNESLineSearchSetComputeNorms()
820 @*/
821 PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
822 {
823   PetscErrorCode    ierr;
824   const char        *deft = SNESLINESEARCHBASIC;
825   char              type[256];
826   PetscBool         flg, set;
827   PetscViewer       viewer;
828 
829   PetscFunctionBegin;
830   ierr = SNESLineSearchRegisterAll();CHKERRQ(ierr);
831 
832   ierr = PetscObjectOptionsBegin((PetscObject)linesearch);CHKERRQ(ierr);
833   if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
834   ierr = PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);CHKERRQ(ierr);
835   if (flg) {
836     ierr = SNESLineSearchSetType(linesearch,type);CHKERRQ(ierr);
837   } else if (!((PetscObject)linesearch)->type_name) {
838     ierr = SNESLineSearchSetType(linesearch,deft);CHKERRQ(ierr);
839   }
840 
841   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);CHKERRQ(ierr);
842   if (set) {
843     ierr = SNESLineSearchSetDefaultMonitor(linesearch,viewer);CHKERRQ(ierr);
844     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
845   }
846   ierr = SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);CHKERRQ(ierr);
847 
848   /* tolerances */
849   ierr = PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);CHKERRQ(ierr);
850   ierr = PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);CHKERRQ(ierr);
851   ierr = PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);CHKERRQ(ierr);
852   ierr = PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);CHKERRQ(ierr);
853   ierr = PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);CHKERRQ(ierr);
854   ierr = PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);CHKERRQ(ierr);
855 
856   /* damping parameters */
857   ierr = PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);CHKERRQ(ierr);
858 
859   ierr = PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL);CHKERRQ(ierr);
860 
861   /* precheck */
862   ierr = PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr);
863   if (set) {
864     if (flg) {
865       linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
866 
867       ierr = PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
868                               "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);CHKERRQ(ierr);
869       ierr = SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);CHKERRQ(ierr);
870     } else {
871       ierr = SNESLineSearchSetPreCheck(linesearch,NULL,NULL);CHKERRQ(ierr);
872     }
873   }
874   ierr = PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);CHKERRQ(ierr);
875   ierr = PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);CHKERRQ(ierr);
876 
877   if (linesearch->ops->setfromoptions) {
878     (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);CHKERRQ(ierr);
879   }
880 
881   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);CHKERRQ(ierr);
882   ierr = PetscOptionsEnd();CHKERRQ(ierr);
883   PetscFunctionReturn(0);
884 }
885 
886 /*@
887    SNESLineSearchView - Prints useful information about the line search
888 
889    Input Parameters:
890 .  linesearch - linesearch context
891 
892    Logically Collective on SNESLineSearch
893 
894    Level: intermediate
895 
896 .seealso: SNESLineSearchCreate()
897 @*/
898 PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
899 {
900   PetscErrorCode ierr;
901   PetscBool      iascii;
902 
903   PetscFunctionBegin;
904   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
905   if (!viewer) {
906     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);CHKERRQ(ierr);
907   }
908   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
909   PetscCheckSameComm(linesearch,1,viewer,2);
910 
911   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
912   if (iascii) {
913     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);CHKERRQ(ierr);
914     if (linesearch->ops->view) {
915       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
916       ierr = (*linesearch->ops->view)(linesearch,viewer);CHKERRQ(ierr);
917       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
918     }
919     ierr = PetscViewerASCIIPrintf(viewer,"  maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);CHKERRQ(ierr);
920     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);CHKERRQ(ierr);
921     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D\n", linesearch->max_its);CHKERRQ(ierr);
922     if (linesearch->ops->precheck) {
923       if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
924         ierr = PetscViewerASCIIPrintf(viewer,"  using precheck step to speed up Picard convergence\n", linesearch->max_its);CHKERRQ(ierr);
925       } else {
926         ierr = PetscViewerASCIIPrintf(viewer,"  using user-defined precheck step\n", linesearch->max_its);CHKERRQ(ierr);
927       }
928     }
929     if (linesearch->ops->postcheck) {
930       ierr = PetscViewerASCIIPrintf(viewer,"  using user-defined postcheck step\n", linesearch->max_its);CHKERRQ(ierr);
931     }
932   }
933   PetscFunctionReturn(0);
934 }
935 
936 /*@C
937    SNESLineSearchSetType - Sets the linesearch type
938 
939    Logically Collective on SNESLineSearch
940 
941    Input Parameters:
942 +  linesearch - linesearch context
943 -  type - The type of line search to be used
944 
945    Available Types:
946 +  SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
947 .  SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
948 .  SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
949 .  SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
950 .  SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
951 -  SNESLINESEARCHSHELL - User provided SNESLineSearch implementation
952 
953    Options Database:
954 .  -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
955 
956    Level: intermediate
957 
958 .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions()
959 @*/
960 PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
961 {
962   PetscErrorCode ierr,(*r)(SNESLineSearch);
963   PetscBool      match;
964 
965   PetscFunctionBegin;
966   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
967   PetscValidCharPointer(type,2);
968 
969   ierr = PetscObjectTypeCompare((PetscObject)linesearch,type,&match);CHKERRQ(ierr);
970   if (match) PetscFunctionReturn(0);
971 
972   ierr = PetscFunctionListFind(SNESLineSearchList,type,&r);CHKERRQ(ierr);
973   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
974   /* Destroy the previous private linesearch context */
975   if (linesearch->ops->destroy) {
976     ierr = (*(linesearch)->ops->destroy)(linesearch);CHKERRQ(ierr);
977 
978     linesearch->ops->destroy = NULL;
979   }
980   /* Reinitialize function pointers in SNESLineSearchOps structure */
981   linesearch->ops->apply          = 0;
982   linesearch->ops->view           = 0;
983   linesearch->ops->setfromoptions = 0;
984   linesearch->ops->destroy        = 0;
985 
986   ierr = PetscObjectChangeTypeName((PetscObject)linesearch,type);CHKERRQ(ierr);
987   ierr = (*r)(linesearch);CHKERRQ(ierr);
988   PetscFunctionReturn(0);
989 }
990 
991 /*@
992    SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
993 
994    Input Parameters:
995 +  linesearch - linesearch context
996 -  snes - The snes instance
997 
998    Level: developer
999 
1000    Notes:
1001    This happens automatically when the line search is obtained/created with
1002    SNESGetLineSearch().  This routine is therefore mainly called within SNES
1003    implementations.
1004 
1005    Level: developer
1006 
1007 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1008 @*/
1009 PetscErrorCode  SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
1010 {
1011   PetscFunctionBegin;
1012   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1013   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
1014   linesearch->snes = snes;
1015   PetscFunctionReturn(0);
1016 }
1017 
1018 /*@
1019    SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
1020    Having an associated SNES is necessary because most line search implementations must be able to
1021    evaluate the function using SNESComputeFunction() for the associated SNES.  This routine
1022    is used in the line search implementations when one must get this associated SNES instance.
1023 
1024    Input Parameters:
1025 .  linesearch - linesearch context
1026 
1027    Output Parameters:
1028 .  snes - The snes instance
1029 
1030    Level: developer
1031 
1032 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1033 @*/
1034 PetscErrorCode  SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1035 {
1036   PetscFunctionBegin;
1037   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1038   PetscValidPointer(snes, 2);
1039   *snes = linesearch->snes;
1040   PetscFunctionReturn(0);
1041 }
1042 
1043 /*@
1044    SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
1045 
1046    Input Parameters:
1047 .  linesearch - linesearch context
1048 
1049    Output Parameters:
1050 .  lambda - The last steplength computed during SNESLineSearchApply()
1051 
1052    Level: advanced
1053 
1054    Notes:
1055    This is useful in methods where the solver is ill-scaled and
1056    requires some adaptive notion of the difference in scale between the
1057    solution and the function.  For instance, SNESQN may be scaled by the
1058    line search lambda using the argument -snes_qn_scaling ls.
1059 
1060 .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1061 @*/
1062 PetscErrorCode  SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1063 {
1064   PetscFunctionBegin;
1065   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1066   PetscValidPointer(lambda, 2);
1067   *lambda = linesearch->lambda;
1068   PetscFunctionReturn(0);
1069 }
1070 
1071 /*@
1072    SNESLineSearchSetLambda - Sets the linesearch steplength.
1073 
1074    Input Parameters:
1075 +  linesearch - linesearch context
1076 -  lambda - The last steplength.
1077 
1078    Notes:
1079    This routine is typically used within implementations of SNESLineSearchApply()
1080    to set the final steplength.  This routine (and SNESLineSearchGetLambda()) were
1081    added in order to facilitate Quasi-Newton methods that use the previous steplength
1082    as an inner scaling parameter.
1083 
1084    Level: advanced
1085 
1086 .seealso: SNESLineSearchGetLambda()
1087 @*/
1088 PetscErrorCode  SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1089 {
1090   PetscFunctionBegin;
1091   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1092   linesearch->lambda = lambda;
1093   PetscFunctionReturn(0);
1094 }
1095 
1096 /*@
1097    SNESLineSearchGetTolerances - Gets the tolerances for the linesearch.  These include
1098    tolerances for the relative and absolute change in the function norm, the change
1099    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1100    and the maximum number of iterations the line search procedure may take.
1101 
1102    Input Parameters:
1103 .  linesearch - linesearch context
1104 
1105    Output Parameters:
1106 +  steptol - The minimum steplength
1107 .  maxstep - The maximum steplength
1108 .  rtol    - The relative tolerance for iterative line searches
1109 .  atol    - The absolute tolerance for iterative line searches
1110 .  ltol    - The change in lambda tolerance for iterative line searches
1111 -  max_it  - The maximum number of iterations of the line search
1112 
1113    Level: intermediate
1114 
1115    Notes:
1116    Different line searches may implement these parameters slightly differently as
1117    the type requires.
1118 
1119 .seealso: SNESLineSearchSetTolerances()
1120 @*/
1121 PetscErrorCode  SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1122 {
1123   PetscFunctionBegin;
1124   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1125   if (steptol) {
1126     PetscValidPointer(steptol, 2);
1127     *steptol = linesearch->steptol;
1128   }
1129   if (maxstep) {
1130     PetscValidPointer(maxstep, 3);
1131     *maxstep = linesearch->maxstep;
1132   }
1133   if (rtol) {
1134     PetscValidPointer(rtol, 4);
1135     *rtol = linesearch->rtol;
1136   }
1137   if (atol) {
1138     PetscValidPointer(atol, 5);
1139     *atol = linesearch->atol;
1140   }
1141   if (ltol) {
1142     PetscValidPointer(ltol, 6);
1143     *ltol = linesearch->ltol;
1144   }
1145   if (max_its) {
1146     PetscValidPointer(max_its, 7);
1147     *max_its = linesearch->max_its;
1148   }
1149   PetscFunctionReturn(0);
1150 }
1151 
1152 /*@
1153    SNESLineSearchSetTolerances -  Gets the tolerances for the linesearch.  These include
1154    tolerances for the relative and absolute change in the function norm, the change
1155    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1156    and the maximum number of iterations the line search procedure may take.
1157 
1158    Input Parameters:
1159 +  linesearch - linesearch context
1160 .  steptol - The minimum steplength
1161 .  maxstep - The maximum steplength
1162 .  rtol    - The relative tolerance for iterative line searches
1163 .  atol    - The absolute tolerance for iterative line searches
1164 .  ltol    - The change in lambda tolerance for iterative line searches
1165 -  max_it  - The maximum number of iterations of the line search
1166 
1167    Notes:
1168    The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1169    place of an argument.
1170 
1171    Level: intermediate
1172 
1173 .seealso: SNESLineSearchGetTolerances()
1174 @*/
1175 PetscErrorCode  SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1176 {
1177   PetscFunctionBegin;
1178   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1179   PetscValidLogicalCollectiveReal(linesearch,steptol,2);
1180   PetscValidLogicalCollectiveReal(linesearch,maxstep,3);
1181   PetscValidLogicalCollectiveReal(linesearch,rtol,4);
1182   PetscValidLogicalCollectiveReal(linesearch,atol,5);
1183   PetscValidLogicalCollectiveReal(linesearch,ltol,6);
1184   PetscValidLogicalCollectiveInt(linesearch,max_its,7);
1185 
1186   if (steptol!= PETSC_DEFAULT) {
1187     if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
1188     linesearch->steptol = steptol;
1189   }
1190 
1191   if (maxstep!= PETSC_DEFAULT) {
1192     if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1193     linesearch->maxstep = maxstep;
1194   }
1195 
1196   if (rtol != PETSC_DEFAULT) {
1197     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);
1198     linesearch->rtol = rtol;
1199   }
1200 
1201   if (atol != PETSC_DEFAULT) {
1202     if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1203     linesearch->atol = atol;
1204   }
1205 
1206   if (ltol != PETSC_DEFAULT) {
1207     if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %14.12e must be non-negative",(double)ltol);
1208     linesearch->ltol = ltol;
1209   }
1210 
1211   if (max_its != PETSC_DEFAULT) {
1212     if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1213     linesearch->max_its = max_its;
1214   }
1215   PetscFunctionReturn(0);
1216 }
1217 
1218 /*@
1219    SNESLineSearchGetDamping - Gets the line search damping parameter.
1220 
1221    Input Parameters:
1222 .  linesearch - linesearch context
1223 
1224    Output Parameters:
1225 .  damping - The damping parameter
1226 
1227    Level: advanced
1228 
1229 .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1230 @*/
1231 
1232 PetscErrorCode  SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1233 {
1234   PetscFunctionBegin;
1235   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1236   PetscValidPointer(damping, 2);
1237   *damping = linesearch->damping;
1238   PetscFunctionReturn(0);
1239 }
1240 
1241 /*@
1242    SNESLineSearchSetDamping - Sets the line search damping paramter.
1243 
1244    Input Parameters:
1245 +  linesearch - linesearch context
1246 -  damping - The damping parameter
1247 
1248    Options Database:
1249 .   -snes_linesearch_damping
1250    Level: intermediate
1251 
1252    Notes:
1253    The basic line search merely takes the update step scaled by the damping parameter.
1254    The use of the damping parameter in the l2 and cp line searches is much more subtle;
1255    it is used as a starting point in calculating the secant step. However, the eventual
1256    step may be of greater length than the damping parameter.  In the bt line search it is
1257    used as the maximum possible step length, as the bt line search only backtracks.
1258 
1259 .seealso: SNESLineSearchGetDamping()
1260 @*/
1261 PetscErrorCode  SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1262 {
1263   PetscFunctionBegin;
1264   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1265   linesearch->damping = damping;
1266   PetscFunctionReturn(0);
1267 }
1268 
1269 /*@
1270    SNESLineSearchGetOrder - Gets the line search approximation order.
1271 
1272    Input Parameters:
1273 .  linesearch - linesearch context
1274 
1275    Output Parameters:
1276 .  order - The order
1277 
1278    Possible Values for order:
1279 +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1280 .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1281 -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1282 
1283    Level: intermediate
1284 
1285 .seealso: SNESLineSearchSetOrder()
1286 @*/
1287 
1288 PetscErrorCode  SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1289 {
1290   PetscFunctionBegin;
1291   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1292   PetscValidPointer(order, 2);
1293   *order = linesearch->order;
1294   PetscFunctionReturn(0);
1295 }
1296 
1297 /*@
1298    SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
1299 
1300    Input Parameters:
1301 .  linesearch - linesearch context
1302 .  order - The damping parameter
1303 
1304    Level: intermediate
1305 
1306    Possible Values for order:
1307 +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1308 .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1309 -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1310 
1311    Notes:
1312    Variable orders are supported by the following line searches:
1313 +  bt - cubic and quadratic
1314 -  cp - linear and quadratic
1315 
1316 .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1317 @*/
1318 PetscErrorCode  SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1319 {
1320   PetscFunctionBegin;
1321   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1322   linesearch->order = order;
1323   PetscFunctionReturn(0);
1324 }
1325 
1326 /*@
1327    SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1328 
1329    Input Parameters:
1330 .  linesearch - linesearch context
1331 
1332    Output Parameters:
1333 +  xnorm - The norm of the current solution
1334 .  fnorm - The norm of the current function
1335 -  ynorm - The norm of the current update
1336 
1337    Notes:
1338    This function is mainly called from SNES implementations.
1339 
1340    Level: developer
1341 
1342 .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1343 @*/
1344 PetscErrorCode  SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1345 {
1346   PetscFunctionBegin;
1347   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1348   if (xnorm) *xnorm = linesearch->xnorm;
1349   if (fnorm) *fnorm = linesearch->fnorm;
1350   if (ynorm) *ynorm = linesearch->ynorm;
1351   PetscFunctionReturn(0);
1352 }
1353 
1354 /*@
1355    SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1356 
1357    Input Parameters:
1358 +  linesearch - linesearch context
1359 .  xnorm - The norm of the current solution
1360 .  fnorm - The norm of the current function
1361 -  ynorm - The norm of the current update
1362 
1363    Level: advanced
1364 
1365 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1366 @*/
1367 PetscErrorCode  SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1368 {
1369   PetscFunctionBegin;
1370   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1371   linesearch->xnorm = xnorm;
1372   linesearch->fnorm = fnorm;
1373   linesearch->ynorm = ynorm;
1374   PetscFunctionReturn(0);
1375 }
1376 
1377 /*@
1378    SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1379 
1380    Input Parameters:
1381 .  linesearch - linesearch context
1382 
1383    Options Database Keys:
1384 .   -snes_linesearch_norms - turn norm computation on or off
1385 
1386    Level: intermediate
1387 
1388 .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1389 @*/
1390 PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1391 {
1392   PetscErrorCode ierr;
1393   SNES           snes;
1394 
1395   PetscFunctionBegin;
1396   if (linesearch->norms) {
1397     if (linesearch->ops->vinorm) {
1398       ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr);
1399       ierr = VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
1400       ierr = VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
1401       ierr = (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);CHKERRQ(ierr);
1402     } else {
1403       ierr = VecNormBegin(linesearch->vec_func,   NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
1404       ierr = VecNormBegin(linesearch->vec_sol,    NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
1405       ierr = VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
1406       ierr = VecNormEnd(linesearch->vec_func,     NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
1407       ierr = VecNormEnd(linesearch->vec_sol,      NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
1408       ierr = VecNormEnd(linesearch->vec_update,   NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
1409     }
1410   }
1411   PetscFunctionReturn(0);
1412 }
1413 
1414 /*@
1415    SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
1416 
1417    Input Parameters:
1418 +  linesearch  - linesearch context
1419 -  flg  - indicates whether or not to compute norms
1420 
1421    Options Database Keys:
1422 .   -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch
1423 
1424    Notes:
1425    This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm.
1426 
1427    Level: intermediate
1428 
1429 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1430 @*/
1431 PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1432 {
1433   PetscFunctionBegin;
1434   linesearch->norms = flg;
1435   PetscFunctionReturn(0);
1436 }
1437 
1438 /*@
1439    SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1440 
1441    Input Parameters:
1442 .  linesearch - linesearch context
1443 
1444    Output Parameters:
1445 +  X - Solution vector
1446 .  F - Function vector
1447 .  Y - Search direction vector
1448 .  W - Solution work vector
1449 -  G - Function work vector
1450 
1451    Notes:
1452    At the beginning of a line search application, X should contain a
1453    solution and the vector F the function computed at X.  At the end of the
1454    line search application, X should contain the new solution, and F the
1455    function evaluated at the new solution.
1456 
1457    These vectors are owned by the SNESLineSearch and should not be destroyed by the caller
1458 
1459    Level: advanced
1460 
1461 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1462 @*/
1463 PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1464 {
1465   PetscFunctionBegin;
1466   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1467   if (X) {
1468     PetscValidPointer(X, 2);
1469     *X = linesearch->vec_sol;
1470   }
1471   if (F) {
1472     PetscValidPointer(F, 3);
1473     *F = linesearch->vec_func;
1474   }
1475   if (Y) {
1476     PetscValidPointer(Y, 4);
1477     *Y = linesearch->vec_update;
1478   }
1479   if (W) {
1480     PetscValidPointer(W, 5);
1481     *W = linesearch->vec_sol_new;
1482   }
1483   if (G) {
1484     PetscValidPointer(G, 6);
1485     *G = linesearch->vec_func_new;
1486   }
1487   PetscFunctionReturn(0);
1488 }
1489 
1490 /*@
1491    SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1492 
1493    Input Parameters:
1494 +  linesearch - linesearch context
1495 .  X - Solution vector
1496 .  F - Function vector
1497 .  Y - Search direction vector
1498 .  W - Solution work vector
1499 -  G - Function work vector
1500 
1501    Level: advanced
1502 
1503 .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1504 @*/
1505 PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1506 {
1507   PetscFunctionBegin;
1508   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1509   if (X) {
1510     PetscValidHeaderSpecific(X,VEC_CLASSID,2);
1511     linesearch->vec_sol = X;
1512   }
1513   if (F) {
1514     PetscValidHeaderSpecific(F,VEC_CLASSID,3);
1515     linesearch->vec_func = F;
1516   }
1517   if (Y) {
1518     PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
1519     linesearch->vec_update = Y;
1520   }
1521   if (W) {
1522     PetscValidHeaderSpecific(W,VEC_CLASSID,5);
1523     linesearch->vec_sol_new = W;
1524   }
1525   if (G) {
1526     PetscValidHeaderSpecific(G,VEC_CLASSID,6);
1527     linesearch->vec_func_new = G;
1528   }
1529   PetscFunctionReturn(0);
1530 }
1531 
1532 /*@C
1533    SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1534    SNES options in the database.
1535 
1536    Logically Collective on SNESLineSearch
1537 
1538    Input Parameters:
1539 +  snes - the SNES context
1540 -  prefix - the prefix to prepend to all option names
1541 
1542    Notes:
1543    A hyphen (-) must NOT be given at the beginning of the prefix name.
1544    The first character of all runtime options is AUTOMATICALLY the hyphen.
1545 
1546    Level: advanced
1547 
1548 .keywords: SNESLineSearch, append, options, prefix, database
1549 
1550 .seealso: SNESGetOptionsPrefix()
1551 @*/
1552 PetscErrorCode  SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1553 {
1554   PetscErrorCode ierr;
1555 
1556   PetscFunctionBegin;
1557   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1558   ierr = PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr);
1559   PetscFunctionReturn(0);
1560 }
1561 
1562 /*@C
1563    SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1564    SNESLineSearch options in the database.
1565 
1566    Not Collective
1567 
1568    Input Parameter:
1569 .  linesearch - the SNESLineSearch context
1570 
1571    Output Parameter:
1572 .  prefix - pointer to the prefix string used
1573 
1574    Notes:
1575    On the fortran side, the user should pass in a string 'prefix' of
1576    sufficient length to hold the prefix.
1577 
1578    Level: advanced
1579 
1580 .keywords: SNESLineSearch, get, options, prefix, database
1581 
1582 .seealso: SNESAppendOptionsPrefix()
1583 @*/
1584 PetscErrorCode  SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1585 {
1586   PetscErrorCode ierr;
1587 
1588   PetscFunctionBegin;
1589   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1590   ierr = PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr);
1591   PetscFunctionReturn(0);
1592 }
1593 
1594 /*@C
1595    SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1596 
1597    Input Parameter:
1598 +  linesearch - the SNESLineSearch context
1599 -  nwork - the number of work vectors
1600 
1601    Level: developer
1602 
1603 .keywords: SNESLineSearch, work, vector
1604 
1605 .seealso: SNESSetWorkVecs()
1606 @*/
1607 PetscErrorCode  SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1608 {
1609   PetscErrorCode ierr;
1610 
1611   PetscFunctionBegin;
1612   if (linesearch->vec_sol) {
1613     ierr = VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);CHKERRQ(ierr);
1614   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1615   PetscFunctionReturn(0);
1616 }
1617 
1618 /*@
1619    SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1620 
1621    Input Parameters:
1622 .  linesearch - linesearch context
1623 
1624    Output Parameters:
1625 .  result - The success or failure status
1626 
1627    Notes:
1628    This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1629    (and set the SNES convergence accordingly).
1630 
1631    Level: intermediate
1632 
1633 .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1634 @*/
1635 PetscErrorCode  SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1636 {
1637   PetscFunctionBegin;
1638   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1639   PetscValidPointer(result, 2);
1640   *result = linesearch->result;
1641   PetscFunctionReturn(0);
1642 }
1643 
1644 /*@
1645    SNESLineSearchSetReason - Sets the success/failure status of the last line search application
1646 
1647    Input Parameters:
1648 +  linesearch - linesearch context
1649 -  result - The success or failure status
1650 
1651    Notes:
1652    This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1653    the success or failure of the line search method.
1654 
1655    Level: developer
1656 
1657 .seealso: SNESLineSearchGetSResult()
1658 @*/
1659 PetscErrorCode  SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1660 {
1661   PetscFunctionBegin;
1662   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1663   linesearch->result = result;
1664   PetscFunctionReturn(0);
1665 }
1666 
1667 /*@C
1668    SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
1669 
1670    Input Parameters:
1671 +  snes - nonlinear context obtained from SNESCreate()
1672 .  projectfunc - function for projecting the function to the bounds
1673 -  normfunc - function for computing the norm of an active set
1674 
1675    Logically Collective on SNES
1676 
1677    Calling sequence of projectfunc:
1678 .vb
1679    projectfunc (SNES snes, Vec X)
1680 .ve
1681 
1682     Input parameters for projectfunc:
1683 +   snes - nonlinear context
1684 -   X - current solution
1685 
1686     Output parameters for projectfunc:
1687 .   X - Projected solution
1688 
1689    Calling sequence of normfunc:
1690 .vb
1691    projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1692 .ve
1693 
1694     Input parameters for normfunc:
1695 +   snes - nonlinear context
1696 .   X - current solution
1697 -   F - current residual
1698 
1699     Output parameters for normfunc:
1700 .   fnorm - VI-specific norm of the function
1701 
1702     Notes:
1703     The VI solvers require projection of the solution to the feasible set.  projectfunc should implement this.
1704 
1705     The VI solvers require special evaluation of the function norm such that the norm is only calculated
1706     on the inactive set.  This should be implemented by normfunc.
1707 
1708     Level: developer
1709 
1710 .keywords: SNES, line search, VI, nonlinear, set, line search
1711 
1712 .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1713 @*/
1714 PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1715 {
1716   PetscFunctionBegin;
1717   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1718   if (projectfunc) linesearch->ops->viproject = projectfunc;
1719   if (normfunc) linesearch->ops->vinorm = normfunc;
1720   PetscFunctionReturn(0);
1721 }
1722 
1723 /*@C
1724    SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
1725 
1726    Input Parameters:
1727 .  linesearch - the line search context, obtain with SNESGetLineSearch()
1728 
1729    Output Parameters:
1730 +  projectfunc - function for projecting the function to the bounds
1731 -  normfunc - function for computing the norm of an active set
1732 
1733    Logically Collective on SNES
1734 
1735     Level: developer
1736 
1737 .keywords: SNES, line search, VI, nonlinear, get, line search
1738 
1739 .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1740 @*/
1741 PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1742 {
1743   PetscFunctionBegin;
1744   if (projectfunc) *projectfunc = linesearch->ops->viproject;
1745   if (normfunc) *normfunc = linesearch->ops->vinorm;
1746   PetscFunctionReturn(0);
1747 }
1748 
1749 /*@C
1750   SNESLineSearchRegister - See SNESLineSearchRegister()
1751 
1752   Level: advanced
1753 @*/
1754 PetscErrorCode  SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1755 {
1756   PetscErrorCode ierr;
1757 
1758   PetscFunctionBegin;
1759   ierr = PetscFunctionListAdd(&SNESLineSearchList,sname,function);CHKERRQ(ierr);
1760   PetscFunctionReturn(0);
1761 }
1762