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