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