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