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