xref: /petsc/src/snes/linesearch/interface/linesearch.c (revision 49a6f2e5440bbcbd382a01c535bb68c01842b385)
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     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);CHKERRQ(ierr);
911     if (linesearch->ops->view) {
912       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
913       ierr = (*linesearch->ops->view)(linesearch,viewer);CHKERRQ(ierr);
914       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
915     }
916     ierr = PetscViewerASCIIPrintf(viewer,"  maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);CHKERRQ(ierr);
917     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);CHKERRQ(ierr);
918     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D\n", linesearch->max_its);CHKERRQ(ierr);
919     if (linesearch->ops->precheck) {
920       if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
921         ierr = PetscViewerASCIIPrintf(viewer,"  using precheck step to speed up Picard convergence\n", linesearch->max_its);CHKERRQ(ierr);
922       } else {
923         ierr = PetscViewerASCIIPrintf(viewer,"  using user-defined precheck step\n", linesearch->max_its);CHKERRQ(ierr);
924       }
925     }
926     if (linesearch->ops->postcheck) {
927       ierr = PetscViewerASCIIPrintf(viewer,"  using user-defined postcheck step\n", linesearch->max_its);CHKERRQ(ierr);
928     }
929   }
930   PetscFunctionReturn(0);
931 }
932 
933 /*@C
934    SNESLineSearchSetType - Sets the linesearch type
935 
936    Logically Collective on SNESLineSearch
937 
938    Input Parameters:
939 +  linesearch - linesearch context
940 -  type - The type of line search to be used
941 
942    Available Types:
943 +  SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
944 .  SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
945 .  SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
946 .  SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
947 .  SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
948 -  SNESLINESEARCHSHELL - User provided SNESLineSearch implementation
949 
950    Options Database:
951 .  -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
952 
953    Level: intermediate
954 
955 .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions()
956 @*/
957 PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
958 {
959   PetscErrorCode ierr,(*r)(SNESLineSearch);
960   PetscBool      match;
961 
962   PetscFunctionBegin;
963   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
964   PetscValidCharPointer(type,2);
965 
966   ierr = PetscObjectTypeCompare((PetscObject)linesearch,type,&match);CHKERRQ(ierr);
967   if (match) PetscFunctionReturn(0);
968 
969   ierr = PetscFunctionListFind(SNESLineSearchList,type,&r);CHKERRQ(ierr);
970   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
971   /* Destroy the previous private linesearch context */
972   if (linesearch->ops->destroy) {
973     ierr = (*(linesearch)->ops->destroy)(linesearch);CHKERRQ(ierr);
974 
975     linesearch->ops->destroy = NULL;
976   }
977   /* Reinitialize function pointers in SNESLineSearchOps structure */
978   linesearch->ops->apply          = 0;
979   linesearch->ops->view           = 0;
980   linesearch->ops->setfromoptions = 0;
981   linesearch->ops->destroy        = 0;
982 
983   ierr = PetscObjectChangeTypeName((PetscObject)linesearch,type);CHKERRQ(ierr);
984   ierr = (*r)(linesearch);CHKERRQ(ierr);
985   PetscFunctionReturn(0);
986 }
987 
988 /*@
989    SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
990 
991    Input Parameters:
992 +  linesearch - linesearch context
993 -  snes - The snes instance
994 
995    Level: developer
996 
997    Notes:
998    This happens automatically when the line search is obtained/created with
999    SNESGetLineSearch().  This routine is therefore mainly called within SNES
1000    implementations.
1001 
1002    Level: developer
1003 
1004 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1005 @*/
1006 PetscErrorCode  SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
1007 {
1008   PetscFunctionBegin;
1009   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1010   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
1011   linesearch->snes = snes;
1012   PetscFunctionReturn(0);
1013 }
1014 
1015 /*@
1016    SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
1017    Having an associated SNES is necessary because most line search implementations must be able to
1018    evaluate the function using SNESComputeFunction() for the associated SNES.  This routine
1019    is used in the line search implementations when one must get this associated SNES instance.
1020 
1021    Input Parameters:
1022 .  linesearch - linesearch context
1023 
1024    Output Parameters:
1025 .  snes - The snes instance
1026 
1027    Level: developer
1028 
1029 .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1030 @*/
1031 PetscErrorCode  SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1032 {
1033   PetscFunctionBegin;
1034   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1035   PetscValidPointer(snes, 2);
1036   *snes = linesearch->snes;
1037   PetscFunctionReturn(0);
1038 }
1039 
1040 /*@
1041    SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
1042 
1043    Input Parameters:
1044 .  linesearch - linesearch context
1045 
1046    Output Parameters:
1047 .  lambda - The last steplength computed during SNESLineSearchApply()
1048 
1049    Level: advanced
1050 
1051    Notes:
1052    This is useful in methods where the solver is ill-scaled and
1053    requires some adaptive notion of the difference in scale between the
1054    solution and the function.  For instance, SNESQN may be scaled by the
1055    line search lambda using the argument -snes_qn_scaling ls.
1056 
1057 .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1058 @*/
1059 PetscErrorCode  SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1060 {
1061   PetscFunctionBegin;
1062   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1063   PetscValidPointer(lambda, 2);
1064   *lambda = linesearch->lambda;
1065   PetscFunctionReturn(0);
1066 }
1067 
1068 /*@
1069    SNESLineSearchSetLambda - Sets the linesearch steplength.
1070 
1071    Input Parameters:
1072 +  linesearch - linesearch context
1073 -  lambda - The last steplength.
1074 
1075    Notes:
1076    This routine is typically used within implementations of SNESLineSearchApply()
1077    to set the final steplength.  This routine (and SNESLineSearchGetLambda()) were
1078    added in order to facilitate Quasi-Newton methods that use the previous steplength
1079    as an inner scaling parameter.
1080 
1081    Level: advanced
1082 
1083 .seealso: SNESLineSearchGetLambda()
1084 @*/
1085 PetscErrorCode  SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1086 {
1087   PetscFunctionBegin;
1088   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1089   linesearch->lambda = lambda;
1090   PetscFunctionReturn(0);
1091 }
1092 
1093 /*@
1094    SNESLineSearchGetTolerances - Gets the tolerances for the linesearch.  These include
1095    tolerances for the relative and absolute change in the function norm, the change
1096    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1097    and the maximum number of iterations the line search procedure may take.
1098 
1099    Input Parameters:
1100 .  linesearch - linesearch context
1101 
1102    Output Parameters:
1103 +  steptol - The minimum steplength
1104 .  maxstep - The maximum steplength
1105 .  rtol    - The relative tolerance for iterative line searches
1106 .  atol    - The absolute tolerance for iterative line searches
1107 .  ltol    - The change in lambda tolerance for iterative line searches
1108 -  max_it  - The maximum number of iterations of the line search
1109 
1110    Level: intermediate
1111 
1112    Notes:
1113    Different line searches may implement these parameters slightly differently as
1114    the type requires.
1115 
1116 .seealso: SNESLineSearchSetTolerances()
1117 @*/
1118 PetscErrorCode  SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1119 {
1120   PetscFunctionBegin;
1121   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1122   if (steptol) {
1123     PetscValidPointer(steptol, 2);
1124     *steptol = linesearch->steptol;
1125   }
1126   if (maxstep) {
1127     PetscValidPointer(maxstep, 3);
1128     *maxstep = linesearch->maxstep;
1129   }
1130   if (rtol) {
1131     PetscValidPointer(rtol, 4);
1132     *rtol = linesearch->rtol;
1133   }
1134   if (atol) {
1135     PetscValidPointer(atol, 5);
1136     *atol = linesearch->atol;
1137   }
1138   if (ltol) {
1139     PetscValidPointer(ltol, 6);
1140     *ltol = linesearch->ltol;
1141   }
1142   if (max_its) {
1143     PetscValidPointer(max_its, 7);
1144     *max_its = linesearch->max_its;
1145   }
1146   PetscFunctionReturn(0);
1147 }
1148 
1149 /*@
1150    SNESLineSearchSetTolerances -  Gets the tolerances for the linesearch.  These include
1151    tolerances for the relative and absolute change in the function norm, the change
1152    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1153    and the maximum number of iterations the line search procedure may take.
1154 
1155    Input Parameters:
1156 +  linesearch - linesearch context
1157 .  steptol - The minimum steplength
1158 .  maxstep - The maximum steplength
1159 .  rtol    - The relative tolerance for iterative line searches
1160 .  atol    - The absolute tolerance for iterative line searches
1161 .  ltol    - The change in lambda tolerance for iterative line searches
1162 -  max_it  - The maximum number of iterations of the line search
1163 
1164    Notes:
1165    The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1166    place of an argument.
1167 
1168    Level: intermediate
1169 
1170 .seealso: SNESLineSearchGetTolerances()
1171 @*/
1172 PetscErrorCode  SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1173 {
1174   PetscFunctionBegin;
1175   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1176   PetscValidLogicalCollectiveReal(linesearch,steptol,2);
1177   PetscValidLogicalCollectiveReal(linesearch,maxstep,3);
1178   PetscValidLogicalCollectiveReal(linesearch,rtol,4);
1179   PetscValidLogicalCollectiveReal(linesearch,atol,5);
1180   PetscValidLogicalCollectiveReal(linesearch,ltol,6);
1181   PetscValidLogicalCollectiveInt(linesearch,max_its,7);
1182 
1183   if (steptol!= PETSC_DEFAULT) {
1184     if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
1185     linesearch->steptol = steptol;
1186   }
1187 
1188   if (maxstep!= PETSC_DEFAULT) {
1189     if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1190     linesearch->maxstep = maxstep;
1191   }
1192 
1193   if (rtol != PETSC_DEFAULT) {
1194     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);
1195     linesearch->rtol = rtol;
1196   }
1197 
1198   if (atol != PETSC_DEFAULT) {
1199     if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1200     linesearch->atol = atol;
1201   }
1202 
1203   if (ltol != PETSC_DEFAULT) {
1204     if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %14.12e must be non-negative",(double)ltol);
1205     linesearch->ltol = ltol;
1206   }
1207 
1208   if (max_its != PETSC_DEFAULT) {
1209     if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1210     linesearch->max_its = max_its;
1211   }
1212   PetscFunctionReturn(0);
1213 }
1214 
1215 /*@
1216    SNESLineSearchGetDamping - Gets the line search damping parameter.
1217 
1218    Input Parameters:
1219 .  linesearch - linesearch context
1220 
1221    Output Parameters:
1222 .  damping - The damping parameter
1223 
1224    Level: advanced
1225 
1226 .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1227 @*/
1228 
1229 PetscErrorCode  SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1230 {
1231   PetscFunctionBegin;
1232   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1233   PetscValidPointer(damping, 2);
1234   *damping = linesearch->damping;
1235   PetscFunctionReturn(0);
1236 }
1237 
1238 /*@
1239    SNESLineSearchSetDamping - Sets the line search damping paramter.
1240 
1241    Input Parameters:
1242 +  linesearch - linesearch context
1243 -  damping - The damping parameter
1244 
1245    Options Database:
1246 .   -snes_linesearch_damping
1247    Level: intermediate
1248 
1249    Notes:
1250    The basic line search merely takes the update step scaled by the damping parameter.
1251    The use of the damping parameter in the l2 and cp line searches is much more subtle;
1252    it is used as a starting point in calculating the secant step. However, the eventual
1253    step may be of greater length than the damping parameter.  In the bt line search it is
1254    used as the maximum possible step length, as the bt line search only backtracks.
1255 
1256 .seealso: SNESLineSearchGetDamping()
1257 @*/
1258 PetscErrorCode  SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1259 {
1260   PetscFunctionBegin;
1261   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1262   linesearch->damping = damping;
1263   PetscFunctionReturn(0);
1264 }
1265 
1266 /*@
1267    SNESLineSearchGetOrder - Gets the line search approximation order.
1268 
1269    Input Parameters:
1270 .  linesearch - linesearch context
1271 
1272    Output Parameters:
1273 .  order - The order
1274 
1275    Possible Values for order:
1276 +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1277 .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1278 -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1279 
1280    Level: intermediate
1281 
1282 .seealso: SNESLineSearchSetOrder()
1283 @*/
1284 
1285 PetscErrorCode  SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1286 {
1287   PetscFunctionBegin;
1288   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1289   PetscValidPointer(order, 2);
1290   *order = linesearch->order;
1291   PetscFunctionReturn(0);
1292 }
1293 
1294 /*@
1295    SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
1296 
1297    Input Parameters:
1298 .  linesearch - linesearch context
1299 .  order - The damping parameter
1300 
1301    Level: intermediate
1302 
1303    Possible Values for order:
1304 +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1305 .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1306 -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1307 
1308    Notes:
1309    Variable orders are supported by the following line searches:
1310 +  bt - cubic and quadratic
1311 -  cp - linear and quadratic
1312 
1313 .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1314 @*/
1315 PetscErrorCode  SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1316 {
1317   PetscFunctionBegin;
1318   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1319   linesearch->order = order;
1320   PetscFunctionReturn(0);
1321 }
1322 
1323 /*@
1324    SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1325 
1326    Input Parameters:
1327 .  linesearch - linesearch context
1328 
1329    Output Parameters:
1330 +  xnorm - The norm of the current solution
1331 .  fnorm - The norm of the current function
1332 -  ynorm - The norm of the current update
1333 
1334    Notes:
1335    This function is mainly called from SNES implementations.
1336 
1337    Level: developer
1338 
1339 .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1340 @*/
1341 PetscErrorCode  SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1342 {
1343   PetscFunctionBegin;
1344   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1345   if (xnorm) *xnorm = linesearch->xnorm;
1346   if (fnorm) *fnorm = linesearch->fnorm;
1347   if (ynorm) *ynorm = linesearch->ynorm;
1348   PetscFunctionReturn(0);
1349 }
1350 
1351 /*@
1352    SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1353 
1354    Input Parameters:
1355 +  linesearch - linesearch context
1356 .  xnorm - The norm of the current solution
1357 .  fnorm - The norm of the current function
1358 -  ynorm - The norm of the current update
1359 
1360    Level: advanced
1361 
1362 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1363 @*/
1364 PetscErrorCode  SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1365 {
1366   PetscFunctionBegin;
1367   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1368   linesearch->xnorm = xnorm;
1369   linesearch->fnorm = fnorm;
1370   linesearch->ynorm = ynorm;
1371   PetscFunctionReturn(0);
1372 }
1373 
1374 /*@
1375    SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1376 
1377    Input Parameters:
1378 .  linesearch - linesearch context
1379 
1380    Options Database Keys:
1381 .   -snes_linesearch_norms - turn norm computation on or off
1382 
1383    Level: intermediate
1384 
1385 .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1386 @*/
1387 PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1388 {
1389   PetscErrorCode ierr;
1390   SNES           snes;
1391 
1392   PetscFunctionBegin;
1393   if (linesearch->norms) {
1394     if (linesearch->ops->vinorm) {
1395       ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr);
1396       ierr = VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
1397       ierr = VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
1398       ierr = (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);CHKERRQ(ierr);
1399     } else {
1400       ierr = VecNormBegin(linesearch->vec_func,   NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
1401       ierr = VecNormBegin(linesearch->vec_sol,    NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
1402       ierr = VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
1403       ierr = VecNormEnd(linesearch->vec_func,     NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
1404       ierr = VecNormEnd(linesearch->vec_sol,      NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
1405       ierr = VecNormEnd(linesearch->vec_update,   NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
1406     }
1407   }
1408   PetscFunctionReturn(0);
1409 }
1410 
1411 /*@
1412    SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
1413 
1414    Input Parameters:
1415 +  linesearch  - linesearch context
1416 -  flg  - indicates whether or not to compute norms
1417 
1418    Options Database Keys:
1419 .   -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch
1420 
1421    Notes:
1422    This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm.
1423 
1424    Level: intermediate
1425 
1426 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1427 @*/
1428 PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1429 {
1430   PetscFunctionBegin;
1431   linesearch->norms = flg;
1432   PetscFunctionReturn(0);
1433 }
1434 
1435 /*@
1436    SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1437 
1438    Input Parameters:
1439 .  linesearch - linesearch context
1440 
1441    Output Parameters:
1442 +  X - Solution vector
1443 .  F - Function vector
1444 .  Y - Search direction vector
1445 .  W - Solution work vector
1446 -  G - Function work vector
1447 
1448    Notes:
1449    At the beginning of a line search application, X should contain a
1450    solution and the vector F the function computed at X.  At the end of the
1451    line search application, X should contain the new solution, and F the
1452    function evaluated at the new solution.
1453 
1454    These vectors are owned by the SNESLineSearch and should not be destroyed by the caller
1455 
1456    Level: advanced
1457 
1458 .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1459 @*/
1460 PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1461 {
1462   PetscFunctionBegin;
1463   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1464   if (X) {
1465     PetscValidPointer(X, 2);
1466     *X = linesearch->vec_sol;
1467   }
1468   if (F) {
1469     PetscValidPointer(F, 3);
1470     *F = linesearch->vec_func;
1471   }
1472   if (Y) {
1473     PetscValidPointer(Y, 4);
1474     *Y = linesearch->vec_update;
1475   }
1476   if (W) {
1477     PetscValidPointer(W, 5);
1478     *W = linesearch->vec_sol_new;
1479   }
1480   if (G) {
1481     PetscValidPointer(G, 6);
1482     *G = linesearch->vec_func_new;
1483   }
1484   PetscFunctionReturn(0);
1485 }
1486 
1487 /*@
1488    SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1489 
1490    Input Parameters:
1491 +  linesearch - linesearch context
1492 .  X - Solution vector
1493 .  F - Function vector
1494 .  Y - Search direction vector
1495 .  W - Solution work vector
1496 -  G - Function work vector
1497 
1498    Level: advanced
1499 
1500 .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1501 @*/
1502 PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1503 {
1504   PetscFunctionBegin;
1505   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1506   if (X) {
1507     PetscValidHeaderSpecific(X,VEC_CLASSID,2);
1508     linesearch->vec_sol = X;
1509   }
1510   if (F) {
1511     PetscValidHeaderSpecific(F,VEC_CLASSID,3);
1512     linesearch->vec_func = F;
1513   }
1514   if (Y) {
1515     PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
1516     linesearch->vec_update = Y;
1517   }
1518   if (W) {
1519     PetscValidHeaderSpecific(W,VEC_CLASSID,5);
1520     linesearch->vec_sol_new = W;
1521   }
1522   if (G) {
1523     PetscValidHeaderSpecific(G,VEC_CLASSID,6);
1524     linesearch->vec_func_new = G;
1525   }
1526   PetscFunctionReturn(0);
1527 }
1528 
1529 /*@C
1530    SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1531    SNES options in the database.
1532 
1533    Logically Collective on SNESLineSearch
1534 
1535    Input Parameters:
1536 +  snes - the SNES context
1537 -  prefix - the prefix to prepend to all option names
1538 
1539    Notes:
1540    A hyphen (-) must NOT be given at the beginning of the prefix name.
1541    The first character of all runtime options is AUTOMATICALLY the hyphen.
1542 
1543    Level: advanced
1544 
1545 .keywords: SNESLineSearch, append, options, prefix, database
1546 
1547 .seealso: SNESGetOptionsPrefix()
1548 @*/
1549 PetscErrorCode  SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1550 {
1551   PetscErrorCode ierr;
1552 
1553   PetscFunctionBegin;
1554   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1555   ierr = PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr);
1556   PetscFunctionReturn(0);
1557 }
1558 
1559 /*@C
1560    SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1561    SNESLineSearch options in the database.
1562 
1563    Not Collective
1564 
1565    Input Parameter:
1566 .  linesearch - the SNESLineSearch context
1567 
1568    Output Parameter:
1569 .  prefix - pointer to the prefix string used
1570 
1571    Notes:
1572    On the fortran side, the user should pass in a string 'prefix' of
1573    sufficient length to hold the prefix.
1574 
1575    Level: advanced
1576 
1577 .keywords: SNESLineSearch, get, options, prefix, database
1578 
1579 .seealso: SNESAppendOptionsPrefix()
1580 @*/
1581 PetscErrorCode  SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1582 {
1583   PetscErrorCode ierr;
1584 
1585   PetscFunctionBegin;
1586   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1587   ierr = PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr);
1588   PetscFunctionReturn(0);
1589 }
1590 
1591 /*@C
1592    SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1593 
1594    Input Parameter:
1595 +  linesearch - the SNESLineSearch context
1596 -  nwork - the number of work vectors
1597 
1598    Level: developer
1599 
1600    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations
1601 
1602 .keywords: SNESLineSearch, work, vector
1603 
1604 .seealso: SNESSetWorkVecs()
1605 @*/
1606 PetscErrorCode  SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1607 {
1608   PetscErrorCode ierr;
1609 
1610   PetscFunctionBegin;
1611   if (linesearch->vec_sol) {
1612     ierr = VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);CHKERRQ(ierr);
1613   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1614   PetscFunctionReturn(0);
1615 }
1616 
1617 /*@
1618    SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1619 
1620    Input Parameters:
1621 .  linesearch - linesearch context
1622 
1623    Output Parameters:
1624 .  result - The success or failure status
1625 
1626    Notes:
1627    This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1628    (and set the SNES convergence accordingly).
1629 
1630    Level: intermediate
1631 
1632 .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1633 @*/
1634 PetscErrorCode  SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1635 {
1636   PetscFunctionBegin;
1637   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1638   PetscValidPointer(result, 2);
1639   *result = linesearch->result;
1640   PetscFunctionReturn(0);
1641 }
1642 
1643 /*@
1644    SNESLineSearchSetReason - Sets the success/failure status of the last line search application
1645 
1646    Input Parameters:
1647 +  linesearch - linesearch context
1648 -  result - The success or failure status
1649 
1650    Notes:
1651    This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1652    the success or failure of the line search method.
1653 
1654    Level: developer
1655 
1656 .seealso: SNESLineSearchGetSResult()
1657 @*/
1658 PetscErrorCode  SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1659 {
1660   PetscFunctionBegin;
1661   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1662   linesearch->result = result;
1663   PetscFunctionReturn(0);
1664 }
1665 
1666 /*@C
1667    SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
1668 
1669    Input Parameters:
1670 +  snes - nonlinear context obtained from SNESCreate()
1671 .  projectfunc - function for projecting the function to the bounds
1672 -  normfunc - function for computing the norm of an active set
1673 
1674    Logically Collective on SNES
1675 
1676    Calling sequence of projectfunc:
1677 .vb
1678    projectfunc (SNES snes, Vec X)
1679 .ve
1680 
1681     Input parameters for projectfunc:
1682 +   snes - nonlinear context
1683 -   X - current solution
1684 
1685     Output parameters for projectfunc:
1686 .   X - Projected solution
1687 
1688    Calling sequence of normfunc:
1689 .vb
1690    projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1691 .ve
1692 
1693     Input parameters for normfunc:
1694 +   snes - nonlinear context
1695 .   X - current solution
1696 -   F - current residual
1697 
1698     Output parameters for normfunc:
1699 .   fnorm - VI-specific norm of the function
1700 
1701     Notes:
1702     The VI solvers require projection of the solution to the feasible set.  projectfunc should implement this.
1703 
1704     The VI solvers require special evaluation of the function norm such that the norm is only calculated
1705     on the inactive set.  This should be implemented by normfunc.
1706 
1707     Level: developer
1708 
1709 .keywords: SNES, line search, VI, nonlinear, set, line search
1710 
1711 .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1712 @*/
1713 extern PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1714 {
1715   PetscFunctionBegin;
1716   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1717   if (projectfunc) linesearch->ops->viproject = projectfunc;
1718   if (normfunc) linesearch->ops->vinorm = normfunc;
1719   PetscFunctionReturn(0);
1720 }
1721 
1722 /*@C
1723    SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
1724 
1725    Input Parameters:
1726 .  linesearch - the line search context, obtain with SNESGetLineSearch()
1727 
1728    Output Parameters:
1729 +  projectfunc - function for projecting the function to the bounds
1730 -  normfunc - function for computing the norm of an active set
1731 
1732    Logically Collective on SNES
1733 
1734     Level: developer
1735 
1736 .keywords: SNES, line search, VI, nonlinear, get, line search
1737 
1738 .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1739 @*/
1740 extern PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1741 {
1742   PetscFunctionBegin;
1743   if (projectfunc) *projectfunc = linesearch->ops->viproject;
1744   if (normfunc) *normfunc = linesearch->ops->vinorm;
1745   PetscFunctionReturn(0);
1746 }
1747 
1748 /*@C
1749   SNESLineSearchRegister - See SNESLineSearchRegister()
1750 
1751   Level: advanced
1752 @*/
1753 PetscErrorCode  SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1754 {
1755   PetscErrorCode ierr;
1756 
1757   PetscFunctionBegin;
1758   ierr = PetscFunctionListAdd(&SNESLineSearchList,sname,function);CHKERRQ(ierr);
1759   PetscFunctionReturn(0);
1760 }
1761