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