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