Actual source code: linesearch.c
petsc-3.8.4 2018-03-24
1: #include <petsc/private/linesearchimpl.h>
3: PetscBool SNESLineSearchRegisterAllCalled = PETSC_FALSE;
4: PetscFunctionList SNESLineSearchList = NULL;
6: PetscClassId SNESLINESEARCH_CLASSID;
7: PetscLogEvent SNESLINESEARCH_Apply;
9: /*@
10: SNESLineSearchMonitorCancel - Clears all the monitor functions for a SNESLineSearch object.
12: Logically Collective on SNESLineSearch
14: Input Parameters:
15: . ls - the SNESLineSearch context
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
22: Notes:
23: There is no way to clear one specific monitor from a SNESLineSearch object.
25: This does not clear the monitor set with SNESLineSearchSetDefaultMonitor() use SNESLineSearchSetDefaultMonitor(ls,NULL) to cancel
26: that one.
28: Level: intermediate
30: .keywords: SNESLineSearch, nonlinear, set, monitor
32: .seealso: SNESLineSearchMonitorDefault(), SNESLineSearchMonitorSet()
33: @*/
34: PetscErrorCode SNESLineSearchMonitorCancel(SNESLineSearch ls)
35: {
37: PetscInt i;
41: for (i=0; i<ls->numbermonitors; i++) {
42: if (ls->monitordestroy[i]) {
43: (*ls->monitordestroy[i])(&ls->monitorcontext[i]);
44: }
45: }
46: ls->numbermonitors = 0;
47: return(0);
48: }
50: /*@
51: SNESLineSearchMonitor - runs the user provided monitor routines, if they exist
53: Collective on SNES
55: Input Parameters:
56: . ls - the linesearch object
58: Notes:
59: This routine is called by the SNES implementations.
60: It does not typically need to be called by the user.
62: Level: developer
64: .seealso: SNESLineSearchMonitorSet()
65: @*/
66: PetscErrorCode SNESLineSearchMonitor(SNESLineSearch ls)
67: {
69: PetscInt i,n = ls->numbermonitors;
72: for (i=0; i<n; i++) {
73: (*ls->monitorftns[i])(ls,ls->monitorcontext[i]);
74: }
75: return(0);
76: }
78: /*@C
79: SNESLineSearchMonitorSet - Sets an ADDITIONAL function that is to be used at every
80: iteration of the nonlinear solver to display the iteration's
81: progress.
83: Logically Collective on SNESLineSearch
85: Input Parameters:
86: + ls - the SNESLineSearch context
87: . f - the monitor function
88: . mctx - [optional] user-defined context for private data for the
89: monitor routine (use NULL if no context is desired)
90: - monitordestroy - [optional] routine that frees monitor context
91: (may be NULL)
93: Notes:
94: Several different monitoring routines may be set by calling
95: SNESLineSearchMonitorSet() multiple times; all will be called in the
96: order in which they were set.
98: Fortran notes: Only a single monitor function can be set for each SNESLineSearch object
100: Level: intermediate
102: .keywords: SNESLineSearch, nonlinear, set, monitor
104: .seealso: SNESLineSearchMonitorDefault(), SNESLineSearchMonitorCancel()
105: @*/
106: PetscErrorCode SNESLineSearchMonitorSet(SNESLineSearch ls,PetscErrorCode (*f)(SNESLineSearch,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
107: {
109: PetscInt i;
110: PetscBool identical;
111:
114: for (i=0; i<ls->numbermonitors;i++) {
115: PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))ls->monitorftns[i],ls->monitorcontext[i],ls->monitordestroy[i],&identical);
116: if (identical) return(0);
117: }
118: if (ls->numbermonitors >= MAXSNESLSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
119: ls->monitorftns[ls->numbermonitors] = f;
120: ls->monitordestroy[ls->numbermonitors] = monitordestroy;
121: ls->monitorcontext[ls->numbermonitors++] = (void*)mctx;
122: return(0);
123: }
125: /*@C
126: SNESLineSearchMonitorSolutionUpdate - Monitors each update a new function value the linesearch tries
128: Collective on SNESLineSearch
130: Input Parameters:
131: + ls - the SNES linesearch object
132: - vf - the context for the monitor, in this case it is an ASCII PetscViewer and format
134: Level: intermediate
136: .keywords: SNES, nonlinear, default, monitor, norm
138: .seealso: SNESMonitorSet(), SNESMonitorSolution()
139: @*/
140: PetscErrorCode SNESLineSearchMonitorSolutionUpdate(SNESLineSearch ls,PetscViewerAndFormat *vf)
141: {
143: PetscViewer viewer = vf->viewer;
144: Vec Y,W,G;
147: SNESLineSearchGetVecs(ls,NULL,NULL,&Y,&W,&G);
148: PetscViewerPushFormat(viewer,vf->format);
149: PetscViewerASCIIPrintf(viewer,"LineSearch attempted update to solution \n");
150: VecView(Y,viewer);
151: PetscViewerASCIIPrintf(viewer,"LineSearch attempted new solution \n");
152: VecView(W,viewer);
153: PetscViewerASCIIPrintf(viewer,"LineSearch attempted updated function value\n");
154: VecView(G,viewer);
155: PetscViewerPopFormat(viewer);
156: return(0);
157: }
159: /*@
160: SNESLineSearchCreate - Creates the line search context.
162: Logically Collective on Comm
164: Input Parameters:
165: . comm - MPI communicator for the line search (typically from the associated SNES context).
167: Output Parameters:
168: . outlinesearch - the new linesearch context
170: Level: developer
172: Notes:
173: The preferred calling sequence for users is to use SNESGetLineSearch() to acquire the SNESLineSearch instance
174: already associated with the SNES. This function is for developer use.
176: .keywords: LineSearch, create, context
178: .seealso: LineSearchDestroy(), SNESGetLineSearch()
179: @*/
181: PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
182: {
184: SNESLineSearch linesearch;
188: SNESInitializePackage();
189: *outlinesearch = NULL;
191: PetscHeaderCreate(linesearch,SNESLINESEARCH_CLASSID, "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView);
193: linesearch->vec_sol_new = NULL;
194: linesearch->vec_func_new = NULL;
195: linesearch->vec_sol = NULL;
196: linesearch->vec_func = NULL;
197: linesearch->vec_update = NULL;
199: linesearch->lambda = 1.0;
200: linesearch->fnorm = 1.0;
201: linesearch->ynorm = 1.0;
202: linesearch->xnorm = 1.0;
203: linesearch->result = SNES_LINESEARCH_SUCCEEDED;
204: linesearch->norms = PETSC_TRUE;
205: linesearch->keeplambda = PETSC_FALSE;
206: linesearch->damping = 1.0;
207: linesearch->maxstep = 1e8;
208: linesearch->steptol = 1e-12;
209: linesearch->rtol = 1e-8;
210: linesearch->atol = 1e-15;
211: linesearch->ltol = 1e-8;
212: linesearch->precheckctx = NULL;
213: linesearch->postcheckctx = NULL;
214: linesearch->max_its = 1;
215: linesearch->setupcalled = PETSC_FALSE;
216: *outlinesearch = linesearch;
217: return(0);
218: }
220: /*@
221: SNESLineSearchSetUp - Prepares the line search for being applied by allocating
222: any required vectors.
224: Collective on SNESLineSearch
226: Input Parameters:
227: . linesearch - The LineSearch instance.
229: Notes:
230: For most cases, this needn't be called by users or outside of SNESLineSearchApply().
231: The only current case where this is called outside of this is for the VI
232: solvers, which modify the solution and work vectors before the first call
233: of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be
234: allocated upfront.
236: Level: advanced
238: .keywords: SNESLineSearch, SetUp
240: .seealso: SNESLineSearchReset()
241: @*/
243: PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
244: {
248: if (!((PetscObject)linesearch)->type_name) {
249: SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);
250: }
251: if (!linesearch->setupcalled) {
252: if (!linesearch->vec_sol_new) {
253: VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);
254: }
255: if (!linesearch->vec_func_new) {
256: VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);
257: }
258: if (linesearch->ops->setup) {
259: (*linesearch->ops->setup)(linesearch);
260: }
261: if (!linesearch->ops->snesfunc) {SNESLineSearchSetFunction(linesearch,SNESComputeFunction);}
262: linesearch->lambda = linesearch->damping;
263: linesearch->setupcalled = PETSC_TRUE;
264: }
265: return(0);
266: }
269: /*@
270: SNESLineSearchReset - Undoes the SNESLineSearchSetUp() and deletes any Vecs or Mats allocated by the line search.
272: Collective on SNESLineSearch
274: Input Parameters:
275: . linesearch - The LineSearch instance.
277: Notes: Usually only called by SNESReset()
279: Level: developer
281: .keywords: SNESLineSearch, Reset
283: .seealso: SNESLineSearchSetUp()
284: @*/
286: PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
287: {
291: if (linesearch->ops->reset) (*linesearch->ops->reset)(linesearch);
293: VecDestroy(&linesearch->vec_sol_new);
294: VecDestroy(&linesearch->vec_func_new);
296: VecDestroyVecs(linesearch->nwork, &linesearch->work);
298: linesearch->nwork = 0;
299: linesearch->setupcalled = PETSC_FALSE;
300: return(0);
301: }
303: /*@C
304: SNESLineSearchSetFunction - Sets the function evaluation used by the SNES line search
306: Input Parameters:
307: . linesearch - the SNESLineSearch context
308: + func - function evaluation routine
310: Level: developer
312: Notes: This is used internally by PETSc and not called by users
314: .keywords: get, linesearch, pre-check
316: .seealso: SNESSetFunction()
317: @*/
318: PetscErrorCode SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
319: {
322: linesearch->ops->snesfunc = func;
323: return(0);
324: }
327: /*MC
328: SNESLineSearchPreCheckFunction - form of function passed to check the search direction before line search is called
330: Synopsis:
331: #include <petscsnes.h>
332: SNESLineSearchPreCheckFunction(SNESLineSearch snes,Vec x,Vec y, PetscBool *changed);
334: Input Parameters:
335: + x - solution vector
336: . y - search direction vector
337: - changed - flag to indicate the precheck changed x or y.
339: Note: This is NOTE a PETSc function, rather it documents the calling sequence of functions passed to SNESLineSearchSetPreCheck()
340: and SNESLineSearchGetPreCheck()
342: Level: advanced
344: .seealso: SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck()
345: M*/
347: /*@C
348: SNESLineSearchSetPreCheck - Sets a user function that is called after the initial search direction has been computed but
349: before the line search routine has been applied. Allows the user to adjust the result of (usually a linear solve) that
350: determined the search direction.
352: Logically Collective on SNESLineSearch
354: Input Parameters:
355: + linesearch - the SNESLineSearch context
356: . func - [optional] function evaluation routine, see SNESLineSearchPreCheckFunction for the calling sequence
357: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
359: Level: intermediate
361: .keywords: set, linesearch, pre-check
363: .seealso: SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
364: @*/
365: PetscErrorCode SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
366: {
369: if (func) linesearch->ops->precheck = func;
370: if (ctx) linesearch->precheckctx = ctx;
371: return(0);
372: }
374: /*@C
375: SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine.
377: Input Parameters:
378: . linesearch - the SNESLineSearch context
380: Output Parameters:
381: + func - [optional] function evaluation routine, see SNESLineSearchPreCheckFunction for calling sequence
382: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
384: Level: intermediate
386: .keywords: get, linesearch, pre-check
388: .seealso: SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck()
389: @*/
390: PetscErrorCode SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
391: {
394: if (func) *func = linesearch->ops->precheck;
395: if (ctx) *ctx = linesearch->precheckctx;
396: return(0);
397: }
399: /*MC
400: SNESLineSearchPostCheckFunction - form of function that is called after line search is complete
402: Synopsis:
403: #include <petscsnes.h>
404: SNESLineSearchPostheckFunction(SNESLineSearch linesearch,Vec x,Vec y, Vec w, *changed_y, PetscBool *changed_w);
406: Input Parameters:
407: + x - old solution vector
408: . y - search direction vector
409: . w - new solution vector
410: . changed_y - indicates that the line search changed y
411: - changed_w - indicates that the line search changed w
413: Note: This is NOTE a PETSc function, rather it documents the calling sequence of functions passed to SNESLineSearchSetPostCheck()
414: and SNESLineSearchGetPostCheck()
416: Level: advanced
418: .seealso: SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchGetPostCheck()
419: M*/
421: /*@C
422: SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step
423: direction and length. Allows the user a chance to change or override the decision of the line search routine
425: Logically Collective on SNESLineSearch
427: Input Parameters:
428: + linesearch - the SNESLineSearch context
429: . func - [optional] function evaluation routine, see SNESLineSearchPostCheckFunction for the calling sequence
430: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
432: Level: intermediate
434: .keywords: set, linesearch, post-check
436: .seealso: SNESLineSearchSetPreCheck()
437: @*/
438: PetscErrorCode SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
439: {
442: if (func) linesearch->ops->postcheck = func;
443: if (ctx) linesearch->postcheckctx = ctx;
444: return(0);
445: }
447: /*@C
448: SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.
450: Input Parameters:
451: . linesearch - the SNESLineSearch context
453: Output Parameters:
454: + func - [optional] function evaluation routine, see for the calling sequence SNESLineSearchPostCheckFunction
455: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
457: Level: intermediate
459: .keywords: get, linesearch, post-check
461: .seealso: SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck()
462: @*/
463: PetscErrorCode SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
464: {
467: if (func) *func = linesearch->ops->postcheck;
468: if (ctx) *ctx = linesearch->postcheckctx;
469: return(0);
470: }
472: /*@
473: SNESLineSearchPreCheck - Prepares the line search for being applied.
475: Logically Collective on SNESLineSearch
477: Input Parameters:
478: + linesearch - The linesearch instance.
479: . X - The current solution
480: - Y - The step direction
482: Output Parameters:
483: . changed - Indicator that the precheck routine has changed anything
485: Level: developer
487: .keywords: SNESLineSearch, Create
489: .seealso: SNESLineSearchPostCheck()
490: @*/
491: PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
492: {
496: *changed = PETSC_FALSE;
497: if (linesearch->ops->precheck) {
498: (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);
500: }
501: return(0);
502: }
504: /*@
505: SNESLineSearchPostCheck - Prepares the line search for being applied.
507: Logically Collective on SNESLineSearch
509: Input Parameters:
510: + linesearch - The linesearch context
511: . X - The last solution
512: . Y - The step direction
513: - W - The updated solution, W = X + lambda*Y for some lambda
515: Output Parameters:
516: + changed_Y - Indicator if the direction Y has been changed.
517: - changed_W - Indicator if the new candidate solution W has been changed.
519: Level: developer
521: .keywords: SNESLineSearch, Create
523: .seealso: SNESLineSearchPreCheck()
524: @*/
525: PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
526: {
530: *changed_Y = PETSC_FALSE;
531: *changed_W = PETSC_FALSE;
532: if (linesearch->ops->postcheck) {
533: (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);
536: }
537: return(0);
538: }
540: /*@C
541: SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration
543: Logically Collective on SNESLineSearch
545: Input Arguments:
546: + linesearch - linesearch context
547: . X - base state for this step
548: . Y - initial correction
549: - ctx - context for this function
551: Output Arguments:
552: + Y - correction, possibly modified
553: - changed - flag indicating that Y was modified
555: Options Database Key:
556: + -snes_linesearch_precheck_picard - activate this routine
557: - -snes_linesearch_precheck_picard_angle - angle
559: Level: advanced
561: Notes:
562: This function should be passed to SNESLineSearchSetPreCheck()
564: The justification for this method involves the linear convergence of a Picard iteration
565: so the Picard linearization should be provided in place of the "Jacobian". This correction
566: is generally not useful when using a Newton linearization.
568: Reference:
569: Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.
571: .seealso: SNESLineSearchSetPreCheck()
572: @*/
573: PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
574: {
576: PetscReal angle = *(PetscReal*)linesearch->precheckctx;
577: Vec Ylast;
578: PetscScalar dot;
579: PetscInt iter;
580: PetscReal ynorm,ylastnorm,theta,angle_radians;
581: SNES snes;
584: SNESLineSearchGetSNES(linesearch, &snes);
585: PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);
586: if (!Ylast) {
587: VecDuplicate(Y,&Ylast);
588: PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);
589: PetscObjectDereference((PetscObject)Ylast);
590: }
591: SNESGetIterationNumber(snes,&iter);
592: if (iter < 2) {
593: VecCopy(Y,Ylast);
594: *changed = PETSC_FALSE;
595: return(0);
596: }
598: VecDot(Y,Ylast,&dot);
599: VecNorm(Y,NORM_2,&ynorm);
600: VecNorm(Ylast,NORM_2,&ylastnorm);
601: /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
602: theta = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
603: angle_radians = angle * PETSC_PI / 180.;
604: if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
605: /* Modify the step Y */
606: PetscReal alpha,ydiffnorm;
607: VecAXPY(Ylast,-1.0,Y);
608: VecNorm(Ylast,NORM_2,&ydiffnorm);
609: alpha = ylastnorm / ydiffnorm;
610: VecCopy(Y,Ylast);
611: VecScale(Y,alpha);
612: 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);
613: } else {
614: PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);
615: VecCopy(Y,Ylast);
616: *changed = PETSC_FALSE;
617: }
618: return(0);
619: }
621: /*@
622: SNESLineSearchApply - Computes the line-search update.
624: Collective on SNESLineSearch
626: Input Parameters:
627: + linesearch - The linesearch context
628: . X - The current solution
629: . F - The current function
630: . fnorm - The current norm
631: - Y - The search direction
633: Output Parameters:
634: + X - The new solution
635: . F - The new function
636: - fnorm - The new function norm
638: Options Database Keys:
639: + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell
640: . -snes_linesearch_monitor [:filename] - Print progress of line searches
641: . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping)
642: . -snes_linesearch_norms - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms())
643: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
644: - -snes_linesearch_max_it - The number of iterations for iterative line searches
646: Notes:
647: This is typically called from within a SNESSolve() implementation in order to
648: help with convergence of the nonlinear method. Various SNES types use line searches
649: in different ways, but the overarching theme is that a line search is used to determine
650: an optimal damping parameter of a step at each iteration of the method. Each
651: application of the line search may invoke SNESComputeFunction several times, and
652: therefore may be fairly expensive.
654: Level: Intermediate
656: .keywords: SNESLineSearch, Create
658: .seealso: SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(),
659: SNESLineSearchType, SNESLineSearchSetType()
660: @*/
661: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
662: {
671: linesearch->result = SNES_LINESEARCH_SUCCEEDED;
673: linesearch->vec_sol = X;
674: linesearch->vec_update = Y;
675: linesearch->vec_func = F;
677: SNESLineSearchSetUp(linesearch);
679: if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
681: if (fnorm) linesearch->fnorm = *fnorm;
682: else {
683: VecNorm(F, NORM_2, &linesearch->fnorm);
684: }
686: PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y);
688: (*linesearch->ops->apply)(linesearch);
690: PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y);
692: if (fnorm) *fnorm = linesearch->fnorm;
693: return(0);
694: }
696: /*@
697: SNESLineSearchDestroy - Destroys the line search instance.
699: Collective on SNESLineSearch
701: Input Parameters:
702: . linesearch - The linesearch context
704: Level: Intermediate
706: .keywords: SNESLineSearch, Destroy
708: .seealso: SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
709: @*/
710: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
711: {
715: if (!*linesearch) return(0);
717: if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; return(0);}
718: PetscObjectSAWsViewOff((PetscObject)*linesearch);
719: SNESLineSearchReset(*linesearch);
720: if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
721: PetscViewerDestroy(&(*linesearch)->monitor);
722: SNESLineSearchMonitorCancel((*linesearch));
723: PetscHeaderDestroy(linesearch);
724: return(0);
725: }
727: /*@
728: SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.
730: Input Parameters:
731: + linesearch - the linesearch object
732: - viewer - an ASCII PetscViewer or NULL to turn off monitor
734: Logically Collective on SNESLineSearch
736: Options Database:
737: . -snes_linesearch_monitor [:filename] - enables the monitor
739: Level: intermediate
741: Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with
742: SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the
743: line search that are not visible to the other monitors.
745: .seealso: SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor()
746: @*/
747: PetscErrorCode SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
748: {
752: if (viewer) {PetscObjectReference((PetscObject)viewer);}
753: PetscViewerDestroy(&linesearch->monitor);
754: linesearch->monitor = viewer;
755: return(0);
756: }
758: /*@
759: SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.
761: Input Parameter:
762: . linesearch - linesearch context
764: Output Parameter:
765: . monitor - monitor context
767: Logically Collective on SNES
769: Options Database Keys:
770: . -snes_linesearch_monitor - enables the monitor
772: Level: intermediate
774: .seealso: SNESLineSearchSetDefaultMonitor(), PetscViewer
775: @*/
776: PetscErrorCode SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
777: {
780: if (monitor) {
782: *monitor = linesearch->monitor;
783: }
784: return(0);
785: }
787: /*@C
788: SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
790: Collective on SNESLineSearch
792: Input Parameters:
793: + ls - LineSearch object you wish to monitor
794: . name - the monitor type one is seeking
795: . help - message indicating what monitoring is done
796: . manual - manual page for the monitor
797: . monitor - the monitor function
798: - 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
800: Level: developer
802: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
803: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
804: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
805: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
806: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
807: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
808: PetscOptionsFList(), PetscOptionsEList()
809: @*/
810: PetscErrorCode SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
811: {
812: PetscErrorCode ierr;
813: PetscViewer viewer;
814: PetscViewerFormat format;
815: PetscBool flg;
818: PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject)ls)->prefix,name,&viewer,&format,&flg);
819: if (flg) {
820: PetscViewerAndFormat *vf;
821: PetscViewerAndFormatCreate(viewer,format,&vf);
822: PetscObjectDereference((PetscObject)viewer);
823: if (monitorsetup) {
824: (*monitorsetup)(ls,vf);
825: }
826: SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
827: }
828: return(0);
829: }
831: /*@
832: SNESLineSearchSetFromOptions - Sets options for the line search
834: Input Parameters:
835: . linesearch - linesearch context
837: Options Database Keys:
838: + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
839: . -snes_linesearch_order <order> - 1, 2, 3. Most types only support certain orders (bt supports 2 or 3)
840: . -snes_linesearch_norms - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms())
841: . -snes_linesearch_minlambda - The minimum step length
842: . -snes_linesearch_maxstep - The maximum step size
843: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
844: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
845: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
846: . -snes_linesearch_max_it - The number of iterations for iterative line searches
847: . -snes_linesearch_monitor [:filename] - Print progress of line searches
848: . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
849: . -snes_linesearch_damping - The linesearch damping parameter
850: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
851: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
852: - -snes_linesearch_precheck_picard_angle - Angle used in picard precheck method
854: Logically Collective on SNESLineSearch
856: Level: intermediate
858: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(),
859: SNESLineSearchType, SNESLineSearchSetComputeNorms()
860: @*/
861: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
862: {
863: PetscErrorCode ierr;
864: const char *deft = SNESLINESEARCHBASIC;
865: char type[256];
866: PetscBool flg, set;
867: PetscViewer viewer;
870: SNESLineSearchRegisterAll();
872: PetscObjectOptionsBegin((PetscObject)linesearch);
873: if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
874: PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
875: if (flg) {
876: SNESLineSearchSetType(linesearch,type);
877: } else if (!((PetscObject)linesearch)->type_name) {
878: SNESLineSearchSetType(linesearch,deft);
879: }
881: PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);
882: if (set) {
883: SNESLineSearchSetDefaultMonitor(linesearch,viewer);
884: PetscViewerDestroy(&viewer);
885: }
886: SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);
887:
888: /* tolerances */
889: PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);
890: PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);
891: PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);
892: PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);
893: PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);
894: PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);
896: /* damping parameters */
897: PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);
899: PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL);
901: /* precheck */
902: PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);
903: if (set) {
904: if (flg) {
905: linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
907: PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
908: "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);
909: SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
910: } else {
911: SNESLineSearchSetPreCheck(linesearch,NULL,NULL);
912: }
913: }
914: PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);
915: PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);
917: if (linesearch->ops->setfromoptions) {
918: (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);
919: }
921: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);
922: PetscOptionsEnd();
923: return(0);
924: }
926: /*@
927: SNESLineSearchView - Prints useful information about the line search
929: Input Parameters:
930: . linesearch - linesearch context
932: Logically Collective on SNESLineSearch
934: Level: intermediate
936: .seealso: SNESLineSearchCreate()
937: @*/
938: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
939: {
941: PetscBool iascii;
945: if (!viewer) {
946: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);
947: }
951: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
952: if (iascii) {
953: PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);
954: if (linesearch->ops->view) {
955: PetscViewerASCIIPushTab(viewer);
956: (*linesearch->ops->view)(linesearch,viewer);
957: PetscViewerASCIIPopTab(viewer);
958: }
959: PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);
960: PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);
961: PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", linesearch->max_its);
962: if (linesearch->ops->precheck) {
963: if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
964: PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n", linesearch->max_its);
965: } else {
966: PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n", linesearch->max_its);
967: }
968: }
969: if (linesearch->ops->postcheck) {
970: PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n", linesearch->max_its);
971: }
972: }
973: return(0);
974: }
976: /*@C
977: SNESLineSearchSetType - Sets the linesearch type
979: Logically Collective on SNESLineSearch
981: Input Parameters:
982: + linesearch - linesearch context
983: - type - The type of line search to be used
985: Available Types:
986: + SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
987: . SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
988: . SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
989: . SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
990: . SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
991: - SNESLINESEARCHSHELL - User provided SNESLineSearch implementation
993: Options Database:
994: . -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
996: Level: intermediate
998: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions()
999: @*/
1000: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
1001: {
1002: PetscErrorCode ierr,(*r)(SNESLineSearch);
1003: PetscBool match;
1009: PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
1010: if (match) return(0);
1012: PetscFunctionListFind(SNESLineSearchList,type,&r);
1013: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
1014: /* Destroy the previous private linesearch context */
1015: if (linesearch->ops->destroy) {
1016: (*(linesearch)->ops->destroy)(linesearch);
1018: linesearch->ops->destroy = NULL;
1019: }
1020: /* Reinitialize function pointers in SNESLineSearchOps structure */
1021: linesearch->ops->apply = 0;
1022: linesearch->ops->view = 0;
1023: linesearch->ops->setfromoptions = 0;
1024: linesearch->ops->destroy = 0;
1026: PetscObjectChangeTypeName((PetscObject)linesearch,type);
1027: (*r)(linesearch);
1028: return(0);
1029: }
1031: /*@
1032: SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
1034: Input Parameters:
1035: + linesearch - linesearch context
1036: - snes - The snes instance
1038: Level: developer
1040: Notes:
1041: This happens automatically when the line search is obtained/created with
1042: SNESGetLineSearch(). This routine is therefore mainly called within SNES
1043: implementations.
1045: Level: developer
1047: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1048: @*/
1049: PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
1050: {
1054: linesearch->snes = snes;
1055: return(0);
1056: }
1058: /*@
1059: SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
1060: Having an associated SNES is necessary because most line search implementations must be able to
1061: evaluate the function using SNESComputeFunction() for the associated SNES. This routine
1062: is used in the line search implementations when one must get this associated SNES instance.
1064: Input Parameters:
1065: . linesearch - linesearch context
1067: Output Parameters:
1068: . snes - The snes instance
1070: Level: developer
1072: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1073: @*/
1074: PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1075: {
1079: *snes = linesearch->snes;
1080: return(0);
1081: }
1083: /*@
1084: SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
1086: Input Parameters:
1087: . linesearch - linesearch context
1089: Output Parameters:
1090: . lambda - The last steplength computed during SNESLineSearchApply()
1092: Level: advanced
1094: Notes:
1095: This is useful in methods where the solver is ill-scaled and
1096: requires some adaptive notion of the difference in scale between the
1097: solution and the function. For instance, SNESQN may be scaled by the
1098: line search lambda using the argument -snes_qn_scaling ls.
1100: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1101: @*/
1102: PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1103: {
1107: *lambda = linesearch->lambda;
1108: return(0);
1109: }
1111: /*@
1112: SNESLineSearchSetLambda - Sets the linesearch steplength.
1114: Input Parameters:
1115: + linesearch - linesearch context
1116: - lambda - The last steplength.
1118: Notes:
1119: This routine is typically used within implementations of SNESLineSearchApply()
1120: to set the final steplength. This routine (and SNESLineSearchGetLambda()) were
1121: added in order to facilitate Quasi-Newton methods that use the previous steplength
1122: as an inner scaling parameter.
1124: Level: advanced
1126: .seealso: SNESLineSearchGetLambda()
1127: @*/
1128: PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1129: {
1132: linesearch->lambda = lambda;
1133: return(0);
1134: }
1136: /*@
1137: SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include
1138: tolerances for the relative and absolute change in the function norm, the change
1139: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1140: and the maximum number of iterations the line search procedure may take.
1142: Input Parameters:
1143: . linesearch - linesearch context
1145: Output Parameters:
1146: + steptol - The minimum steplength
1147: . maxstep - The maximum steplength
1148: . rtol - The relative tolerance for iterative line searches
1149: . atol - The absolute tolerance for iterative line searches
1150: . ltol - The change in lambda tolerance for iterative line searches
1151: - max_it - The maximum number of iterations of the line search
1153: Level: intermediate
1155: Notes:
1156: Different line searches may implement these parameters slightly differently as
1157: the type requires.
1159: .seealso: SNESLineSearchSetTolerances()
1160: @*/
1161: PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1162: {
1165: if (steptol) {
1167: *steptol = linesearch->steptol;
1168: }
1169: if (maxstep) {
1171: *maxstep = linesearch->maxstep;
1172: }
1173: if (rtol) {
1175: *rtol = linesearch->rtol;
1176: }
1177: if (atol) {
1179: *atol = linesearch->atol;
1180: }
1181: if (ltol) {
1183: *ltol = linesearch->ltol;
1184: }
1185: if (max_its) {
1187: *max_its = linesearch->max_its;
1188: }
1189: return(0);
1190: }
1192: /*@
1193: SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include
1194: tolerances for the relative and absolute change in the function norm, the change
1195: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1196: and the maximum number of iterations the line search procedure may take.
1198: Input Parameters:
1199: + linesearch - linesearch context
1200: . steptol - The minimum steplength
1201: . maxstep - The maximum steplength
1202: . rtol - The relative tolerance for iterative line searches
1203: . atol - The absolute tolerance for iterative line searches
1204: . ltol - The change in lambda tolerance for iterative line searches
1205: - max_it - The maximum number of iterations of the line search
1207: Notes:
1208: The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1209: place of an argument.
1211: Level: intermediate
1213: .seealso: SNESLineSearchGetTolerances()
1214: @*/
1215: PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1216: {
1226: if (steptol!= PETSC_DEFAULT) {
1227: if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
1228: linesearch->steptol = steptol;
1229: }
1231: if (maxstep!= PETSC_DEFAULT) {
1232: if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1233: linesearch->maxstep = maxstep;
1234: }
1236: if (rtol != PETSC_DEFAULT) {
1237: 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);
1238: linesearch->rtol = rtol;
1239: }
1241: if (atol != PETSC_DEFAULT) {
1242: if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1243: linesearch->atol = atol;
1244: }
1246: if (ltol != PETSC_DEFAULT) {
1247: if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %14.12e must be non-negative",(double)ltol);
1248: linesearch->ltol = ltol;
1249: }
1251: if (max_its != PETSC_DEFAULT) {
1252: if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1253: linesearch->max_its = max_its;
1254: }
1255: return(0);
1256: }
1258: /*@
1259: SNESLineSearchGetDamping - Gets the line search damping parameter.
1261: Input Parameters:
1262: . linesearch - linesearch context
1264: Output Parameters:
1265: . damping - The damping parameter
1267: Level: advanced
1269: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1270: @*/
1272: PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1273: {
1277: *damping = linesearch->damping;
1278: return(0);
1279: }
1281: /*@
1282: SNESLineSearchSetDamping - Sets the line search damping paramter.
1284: Input Parameters:
1285: + linesearch - linesearch context
1286: - damping - The damping parameter
1288: Options Database:
1289: . -snes_linesearch_damping
1290: Level: intermediate
1292: Notes:
1293: The basic line search merely takes the update step scaled by the damping parameter.
1294: The use of the damping parameter in the l2 and cp line searches is much more subtle;
1295: it is used as a starting point in calculating the secant step. However, the eventual
1296: step may be of greater length than the damping parameter. In the bt line search it is
1297: used as the maximum possible step length, as the bt line search only backtracks.
1299: .seealso: SNESLineSearchGetDamping()
1300: @*/
1301: PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1302: {
1305: linesearch->damping = damping;
1306: return(0);
1307: }
1309: /*@
1310: SNESLineSearchGetOrder - Gets the line search approximation order.
1312: Input Parameters:
1313: . linesearch - linesearch context
1315: Output Parameters:
1316: . order - The order
1318: Possible Values for order:
1319: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1320: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1321: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1323: Level: intermediate
1325: .seealso: SNESLineSearchSetOrder()
1326: @*/
1328: PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1329: {
1333: *order = linesearch->order;
1334: return(0);
1335: }
1337: /*@
1338: SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
1340: Input Parameters:
1341: . linesearch - linesearch context
1342: . order - The damping parameter
1344: Level: intermediate
1346: Possible Values for order:
1347: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1348: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1349: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1351: Notes:
1352: Variable orders are supported by the following line searches:
1353: + bt - cubic and quadratic
1354: - cp - linear and quadratic
1356: .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1357: @*/
1358: PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1359: {
1362: linesearch->order = order;
1363: return(0);
1364: }
1366: /*@
1367: SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1369: Input Parameters:
1370: . linesearch - linesearch context
1372: Output Parameters:
1373: + xnorm - The norm of the current solution
1374: . fnorm - The norm of the current function
1375: - ynorm - The norm of the current update
1377: Notes:
1378: This function is mainly called from SNES implementations.
1380: Level: developer
1382: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1383: @*/
1384: PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1385: {
1388: if (xnorm) *xnorm = linesearch->xnorm;
1389: if (fnorm) *fnorm = linesearch->fnorm;
1390: if (ynorm) *ynorm = linesearch->ynorm;
1391: return(0);
1392: }
1394: /*@
1395: SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1397: Input Parameters:
1398: + linesearch - linesearch context
1399: . xnorm - The norm of the current solution
1400: . fnorm - The norm of the current function
1401: - ynorm - The norm of the current update
1403: Level: advanced
1405: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1406: @*/
1407: PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1408: {
1411: linesearch->xnorm = xnorm;
1412: linesearch->fnorm = fnorm;
1413: linesearch->ynorm = ynorm;
1414: return(0);
1415: }
1417: /*@
1418: SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1420: Input Parameters:
1421: . linesearch - linesearch context
1423: Options Database Keys:
1424: . -snes_linesearch_norms - turn norm computation on or off
1426: Level: intermediate
1428: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1429: @*/
1430: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1431: {
1433: SNES snes;
1436: if (linesearch->norms) {
1437: if (linesearch->ops->vinorm) {
1438: SNESLineSearchGetSNES(linesearch, &snes);
1439: VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1440: VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1441: (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1442: } else {
1443: VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1444: VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1445: VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1446: VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1447: VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1448: VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1449: }
1450: }
1451: return(0);
1452: }
1454: /*@
1455: SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
1457: Input Parameters:
1458: + linesearch - linesearch context
1459: - flg - indicates whether or not to compute norms
1461: Options Database Keys:
1462: . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch
1464: Notes:
1465: This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm.
1467: Level: intermediate
1469: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1470: @*/
1471: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1472: {
1474: linesearch->norms = flg;
1475: return(0);
1476: }
1478: /*@
1479: SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1481: Input Parameters:
1482: . linesearch - linesearch context
1484: Output Parameters:
1485: + X - Solution vector
1486: . F - Function vector
1487: . Y - Search direction vector
1488: . W - Solution work vector
1489: - G - Function work vector
1491: Notes:
1492: At the beginning of a line search application, X should contain a
1493: solution and the vector F the function computed at X. At the end of the
1494: line search application, X should contain the new solution, and F the
1495: function evaluated at the new solution.
1497: These vectors are owned by the SNESLineSearch and should not be destroyed by the caller
1499: Level: advanced
1501: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1502: @*/
1503: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1504: {
1507: if (X) {
1509: *X = linesearch->vec_sol;
1510: }
1511: if (F) {
1513: *F = linesearch->vec_func;
1514: }
1515: if (Y) {
1517: *Y = linesearch->vec_update;
1518: }
1519: if (W) {
1521: *W = linesearch->vec_sol_new;
1522: }
1523: if (G) {
1525: *G = linesearch->vec_func_new;
1526: }
1527: return(0);
1528: }
1530: /*@
1531: SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1533: Input Parameters:
1534: + linesearch - linesearch context
1535: . X - Solution vector
1536: . F - Function vector
1537: . Y - Search direction vector
1538: . W - Solution work vector
1539: - G - Function work vector
1541: Level: advanced
1543: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1544: @*/
1545: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1546: {
1549: if (X) {
1551: linesearch->vec_sol = X;
1552: }
1553: if (F) {
1555: linesearch->vec_func = F;
1556: }
1557: if (Y) {
1559: linesearch->vec_update = Y;
1560: }
1561: if (W) {
1563: linesearch->vec_sol_new = W;
1564: }
1565: if (G) {
1567: linesearch->vec_func_new = G;
1568: }
1569: return(0);
1570: }
1572: /*@C
1573: SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1574: SNES options in the database.
1576: Logically Collective on SNESLineSearch
1578: Input Parameters:
1579: + snes - the SNES context
1580: - prefix - the prefix to prepend to all option names
1582: Notes:
1583: A hyphen (-) must NOT be given at the beginning of the prefix name.
1584: The first character of all runtime options is AUTOMATICALLY the hyphen.
1586: Level: advanced
1588: .keywords: SNESLineSearch, append, options, prefix, database
1590: .seealso: SNESGetOptionsPrefix()
1591: @*/
1592: PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1593: {
1598: PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1599: return(0);
1600: }
1602: /*@C
1603: SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1604: SNESLineSearch options in the database.
1606: Not Collective
1608: Input Parameter:
1609: . linesearch - the SNESLineSearch context
1611: Output Parameter:
1612: . prefix - pointer to the prefix string used
1614: Notes:
1615: On the fortran side, the user should pass in a string 'prefix' of
1616: sufficient length to hold the prefix.
1618: Level: advanced
1620: .keywords: SNESLineSearch, get, options, prefix, database
1622: .seealso: SNESAppendOptionsPrefix()
1623: @*/
1624: PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1625: {
1630: PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1631: return(0);
1632: }
1634: /*@C
1635: SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1637: Input Parameter:
1638: + linesearch - the SNESLineSearch context
1639: - nwork - the number of work vectors
1641: Level: developer
1643: Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations
1645: .keywords: SNESLineSearch, work, vector
1647: .seealso: SNESSetWorkVecs()
1648: @*/
1649: PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1650: {
1654: if (linesearch->vec_sol) {
1655: VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1656: } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1657: return(0);
1658: }
1660: /*@
1661: SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1663: Input Parameters:
1664: . linesearch - linesearch context
1666: Output Parameters:
1667: . result - The success or failure status
1669: Notes:
1670: This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1671: (and set the SNES convergence accordingly).
1673: Level: intermediate
1675: .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1676: @*/
1677: PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1678: {
1682: *result = linesearch->result;
1683: return(0);
1684: }
1686: /*@
1687: SNESLineSearchSetReason - Sets the success/failure status of the last line search application
1689: Input Parameters:
1690: + linesearch - linesearch context
1691: - result - The success or failure status
1693: Notes:
1694: This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1695: the success or failure of the line search method.
1697: Level: developer
1699: .seealso: SNESLineSearchGetSResult()
1700: @*/
1701: PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1702: {
1705: linesearch->result = result;
1706: return(0);
1707: }
1709: /*@C
1710: SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
1712: Input Parameters:
1713: + snes - nonlinear context obtained from SNESCreate()
1714: . projectfunc - function for projecting the function to the bounds
1715: - normfunc - function for computing the norm of an active set
1717: Logically Collective on SNES
1719: Calling sequence of projectfunc:
1720: .vb
1721: projectfunc (SNES snes, Vec X)
1722: .ve
1724: Input parameters for projectfunc:
1725: + snes - nonlinear context
1726: - X - current solution
1728: Output parameters for projectfunc:
1729: . X - Projected solution
1731: Calling sequence of normfunc:
1732: .vb
1733: projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1734: .ve
1736: Input parameters for normfunc:
1737: + snes - nonlinear context
1738: . X - current solution
1739: - F - current residual
1741: Output parameters for normfunc:
1742: . fnorm - VI-specific norm of the function
1744: Notes:
1745: The VI solvers require projection of the solution to the feasible set. projectfunc should implement this.
1747: The VI solvers require special evaluation of the function norm such that the norm is only calculated
1748: on the inactive set. This should be implemented by normfunc.
1750: Level: developer
1752: .keywords: SNES, line search, VI, nonlinear, set, line search
1754: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1755: @*/
1756: extern PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1757: {
1760: if (projectfunc) linesearch->ops->viproject = projectfunc;
1761: if (normfunc) linesearch->ops->vinorm = normfunc;
1762: return(0);
1763: }
1765: /*@C
1766: SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
1768: Input Parameters:
1769: . linesearch - the line search context, obtain with SNESGetLineSearch()
1771: Output Parameters:
1772: + projectfunc - function for projecting the function to the bounds
1773: - normfunc - function for computing the norm of an active set
1775: Logically Collective on SNES
1777: Level: developer
1779: .keywords: SNES, line search, VI, nonlinear, get, line search
1781: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1782: @*/
1783: extern PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1784: {
1786: if (projectfunc) *projectfunc = linesearch->ops->viproject;
1787: if (normfunc) *normfunc = linesearch->ops->vinorm;
1788: return(0);
1789: }
1791: /*@C
1792: SNESLineSearchRegister - See SNESLineSearchRegister()
1794: Level: advanced
1795: @*/
1796: PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1797: {
1801: PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1802: return(0);
1803: }