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