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