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