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