Actual source code: linesearch.c
petsc-3.7.1 2016-05-15
1: #include <petsc/private/linesearchimpl.h> /*I "petscsnes.h" I*/
3: PetscBool SNESLineSearchRegisterAllCalled = PETSC_FALSE;
4: PetscFunctionList SNESLineSearchList = NULL;
6: PetscClassId SNESLINESEARCH_CLASSID;
7: PetscLogEvent SNESLineSearch_Apply;
11: /*@
12: SNESLineSearchMonitorCancel - Clears all the monitor functions for a SNESLineSearch object.
14: Logically Collective on SNESLineSearch
16: Input Parameters:
17: . ls - the SNESLineSearch context
19: Options Database Key:
20: . -snes_linesearch_monitor_cancel - cancels all monitors that have been hardwired
21: into a code by calls to SNESLineSearchMonitorSet(), but does not cancel those
22: set via the options database
24: Notes:
25: There is no way to clear one specific monitor from a SNESLineSearch object.
27: This does not clear the monitor set with SNESLineSearchSetDefaultMonitor() use SNESLineSearchSetDefaultMonitor(ls,NULL) to cancel
28: that one.
30: Level: intermediate
32: .keywords: SNESLineSearch, nonlinear, set, monitor
34: .seealso: SNESLineSearchMonitorDefault(), SNESLineSearchMonitorSet()
35: @*/
36: PetscErrorCode SNESLineSearchMonitorCancel(SNESLineSearch ls)
37: {
39: PetscInt i;
43: for (i=0; i<ls->numbermonitors; i++) {
44: if (ls->monitordestroy[i]) {
45: (*ls->monitordestroy[i])(&ls->monitorcontext[i]);
46: }
47: }
48: ls->numbermonitors = 0;
49: return(0);
50: }
54: /*@
55: SNESLineSearchMonitor - runs the user provided monitor routines, if they exist
57: Collective on SNES
59: Input Parameters:
60: . ls - the linesearch object
62: Notes:
63: This routine is called by the SNES implementations.
64: It does not typically need to be called by the user.
66: Level: developer
68: .seealso: SNESLineSearchMonitorSet()
69: @*/
70: PetscErrorCode SNESLineSearchMonitor(SNESLineSearch ls)
71: {
73: PetscInt i,n = ls->numbermonitors;
76: for (i=0; i<n; i++) {
77: (*ls->monitorftns[i])(ls,ls->monitorcontext[i]);
78: }
79: return(0);
80: }
84: /*@C
85: SNESLineSearchMonitorSet - Sets an ADDITIONAL function that is to be used at every
86: iteration of the nonlinear solver to display the iteration's
87: progress.
89: Logically Collective on SNESLineSearch
91: Input Parameters:
92: + ls - the SNESLineSearch context
93: . f - the monitor function
94: . mctx - [optional] user-defined context for private data for the
95: monitor routine (use NULL if no context is desired)
96: - monitordestroy - [optional] routine that frees monitor context
97: (may be NULL)
99: Notes:
100: Several different monitoring routines may be set by calling
101: SNESLineSearchMonitorSet() multiple times; all will be called in the
102: order in which they were set.
104: Fortran notes: Only a single monitor function can be set for each SNESLineSearch object
106: Level: intermediate
108: .keywords: SNESLineSearch, nonlinear, set, monitor
110: .seealso: SNESLineSearchMonitorDefault(), SNESLineSearchMonitorCancel()
111: @*/
112: PetscErrorCode SNESLineSearchMonitorSet(SNESLineSearch ls,PetscErrorCode (*f)(SNESLineSearch,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
113: {
116: if (ls->numbermonitors >= MAXSNESLSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
117: ls->monitorftns[ls->numbermonitors] = f;
118: ls->monitordestroy[ls->numbermonitors] = monitordestroy;
119: ls->monitorcontext[ls->numbermonitors++] = (void*)mctx;
120: return(0);
121: }
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: }
161: /*@
162: SNESLineSearchCreate - Creates the line search context.
164: Logically Collective on Comm
166: Input Parameters:
167: . comm - MPI communicator for the line search (typically from the associated SNES context).
169: Output Parameters:
170: . outlinesearch - the new linesearch context
172: Level: developer
174: Notes:
175: The preferred calling sequence for users is to use SNESGetLineSearch() to acquire the SNESLineSearch instance
176: already associated with the SNES. This function is for developer use.
178: .keywords: LineSearch, create, context
180: .seealso: LineSearchDestroy(), SNESGetLineSearch()
181: @*/
183: PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
184: {
186: SNESLineSearch linesearch;
190: SNESInitializePackage();
191: *outlinesearch = NULL;
193: PetscHeaderCreate(linesearch,SNESLINESEARCH_CLASSID, "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView);
195: linesearch->vec_sol_new = NULL;
196: linesearch->vec_func_new = NULL;
197: linesearch->vec_sol = NULL;
198: linesearch->vec_func = NULL;
199: linesearch->vec_update = NULL;
201: linesearch->lambda = 1.0;
202: linesearch->fnorm = 1.0;
203: linesearch->ynorm = 1.0;
204: linesearch->xnorm = 1.0;
205: linesearch->result = SNES_LINESEARCH_SUCCEEDED;
206: linesearch->norms = PETSC_TRUE;
207: linesearch->keeplambda = PETSC_FALSE;
208: linesearch->damping = 1.0;
209: linesearch->maxstep = 1e8;
210: linesearch->steptol = 1e-12;
211: linesearch->rtol = 1e-8;
212: linesearch->atol = 1e-15;
213: linesearch->ltol = 1e-8;
214: linesearch->precheckctx = NULL;
215: linesearch->postcheckctx = NULL;
216: linesearch->max_its = 1;
217: linesearch->setupcalled = PETSC_FALSE;
218: *outlinesearch = linesearch;
219: return(0);
220: }
224: /*@
225: SNESLineSearchSetUp - Prepares the line search for being applied by allocating
226: any required vectors.
228: Collective on SNESLineSearch
230: Input Parameters:
231: . linesearch - The LineSearch instance.
233: Notes:
234: For most cases, this needn't be called by users or outside of SNESLineSearchApply().
235: The only current case where this is called outside of this is for the VI
236: solvers, which modify the solution and work vectors before the first call
237: of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be
238: allocated upfront.
240: Level: advanced
242: .keywords: SNESLineSearch, SetUp
244: .seealso: SNESLineSearchReset()
245: @*/
247: PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
248: {
252: if (!((PetscObject)linesearch)->type_name) {
253: SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);
254: }
255: if (!linesearch->setupcalled) {
256: if (!linesearch->vec_sol_new) {
257: VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);
258: }
259: if (!linesearch->vec_func_new) {
260: VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);
261: }
262: if (linesearch->ops->setup) {
263: (*linesearch->ops->setup)(linesearch);
264: }
265: if (!linesearch->ops->snesfunc) {SNESLineSearchSetFunction(linesearch,SNESComputeFunction);}
266: linesearch->lambda = linesearch->damping;
267: linesearch->setupcalled = PETSC_TRUE;
268: }
269: return(0);
270: }
275: /*@
276: SNESLineSearchReset - Undoes the SNESLineSearchSetUp() and deletes any Vecs or Mats allocated by the line search.
278: Collective on SNESLineSearch
280: Input Parameters:
281: . linesearch - The LineSearch instance.
283: Notes: Usually only called by SNESReset()
285: Level: developer
287: .keywords: SNESLineSearch, Reset
289: .seealso: SNESLineSearchSetUp()
290: @*/
292: PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
293: {
297: if (linesearch->ops->reset) (*linesearch->ops->reset)(linesearch);
299: VecDestroy(&linesearch->vec_sol_new);
300: VecDestroy(&linesearch->vec_func_new);
302: VecDestroyVecs(linesearch->nwork, &linesearch->work);
304: linesearch->nwork = 0;
305: linesearch->setupcalled = PETSC_FALSE;
306: return(0);
307: }
311: /*@C
312: SNESLineSearchSetFunction - Sets the function evaluation used by the SNES line search
314: Input Parameters:
315: . linesearch - the SNESLineSearch context
316: + func - function evaluation routine
318: Level: developer
320: Notes: This is used internally by PETSc and not called by users
322: .keywords: get, linesearch, pre-check
324: .seealso: SNESSetFunction()
325: @*/
326: PetscErrorCode SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
327: {
330: linesearch->ops->snesfunc = func;
331: return(0);
332: }
335: /*MC
336: SNESLineSearchPreCheckFunction - form of function passed to check the search direction before line search is called
338: Synopsis:
339: #include <petscsnes.h>
340: SNESLineSearchPreCheckFunction(SNESLineSearch snes,Vec x,Vec y, PetscBool *changed);
342: Input Parameters:
343: + x - solution vector
344: . y - search direction vector
345: - changed - flag to indicate the precheck changed x or y.
347: Note: This is NOTE a PETSc function, rather it documents the calling sequence of functions passed to SNESLineSearchSetPreCheck()
348: and SNESLineSearchGetPreCheck()
350: Level: advanced
352: .seealso: SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck()
353: M*/
357: /*@C
358: SNESLineSearchSetPreCheck - Sets a user function that is called after the initial search direction has been computed but
359: before the line search routine has been applied. Allows the user to adjust the result of (usually a linear solve) that
360: determined the search direction.
362: Logically Collective on SNESLineSearch
364: Input Parameters:
365: + linesearch - the SNESLineSearch context
366: . func - [optional] function evaluation routine, see SNESLineSearchPreCheckFunction for the calling sequence
367: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
369: Level: intermediate
371: .keywords: set, linesearch, pre-check
373: .seealso: SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
374: @*/
375: PetscErrorCode SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
376: {
379: if (func) linesearch->ops->precheck = func;
380: if (ctx) linesearch->precheckctx = ctx;
381: return(0);
382: }
386: /*@C
387: SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine.
389: Input Parameters:
390: . linesearch - the SNESLineSearch context
392: Output Parameters:
393: + func - [optional] function evaluation routine, see SNESLineSearchPreCheckFunction for calling sequence
394: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
396: Level: intermediate
398: .keywords: get, linesearch, pre-check
400: .seealso: SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck()
401: @*/
402: PetscErrorCode SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
403: {
406: if (func) *func = linesearch->ops->precheck;
407: if (ctx) *ctx = linesearch->precheckctx;
408: return(0);
409: }
411: /*MC
412: SNESLineSearchPostCheckFunction - form of function that is called after line search is complete
414: Synopsis:
415: #include <petscsnes.h>
416: SNESLineSearchPostheckFunction(SNESLineSearch linesearch,Vec x,Vec y, Vec w, *changed_y, PetscBool *changed_w);
418: Input Parameters:
419: + x - old solution vector
420: . y - search direction vector
421: . w - new solution vector
422: . changed_y - indicates that the line search changed y
423: - changed_w - indicates that the line search changed w
425: Note: This is NOTE a PETSc function, rather it documents the calling sequence of functions passed to SNESLineSearchSetPostCheck()
426: and SNESLineSearchGetPostCheck()
428: Level: advanced
430: .seealso: SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchGetPostCheck()
431: M*/
435: /*@C
436: SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step
437: direction and length. Allows the user a chance to change or override the decision of the line search routine
439: Logically Collective on SNESLineSearch
441: Input Parameters:
442: + linesearch - the SNESLineSearch context
443: . func - [optional] function evaluation routine, see SNESLineSearchPostCheckFunction for the calling sequence
444: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
446: Level: intermediate
448: .keywords: set, linesearch, post-check
450: .seealso: SNESLineSearchSetPreCheck()
451: @*/
452: PetscErrorCode SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
453: {
456: if (func) linesearch->ops->postcheck = func;
457: if (ctx) linesearch->postcheckctx = ctx;
458: return(0);
459: }
463: /*@C
464: SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.
466: Input Parameters:
467: . linesearch - the SNESLineSearch context
469: Output Parameters:
470: + func - [optional] function evaluation routine, see for the calling sequence SNESLineSearchPostCheckFunction
471: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
473: Level: intermediate
475: .keywords: get, linesearch, post-check
477: .seealso: SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck()
478: @*/
479: PetscErrorCode SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
480: {
483: if (func) *func = linesearch->ops->postcheck;
484: if (ctx) *ctx = linesearch->postcheckctx;
485: return(0);
486: }
490: /*@
491: SNESLineSearchPreCheck - Prepares the line search for being applied.
493: Logically Collective on SNESLineSearch
495: Input Parameters:
496: + linesearch - The linesearch instance.
497: . X - The current solution
498: - Y - The step direction
500: Output Parameters:
501: . changed - Indicator that the precheck routine has changed anything
503: Level: developer
505: .keywords: SNESLineSearch, Create
507: .seealso: SNESLineSearchPostCheck()
508: @*/
509: PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
510: {
514: *changed = PETSC_FALSE;
515: if (linesearch->ops->precheck) {
516: (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);
518: }
519: return(0);
520: }
524: /*@
525: SNESLineSearchPostCheck - Prepares the line search for being applied.
527: Logically Collective on SNESLineSearch
529: Input Parameters:
530: + linesearch - The linesearch context
531: . X - The last solution
532: . Y - The step direction
533: - W - The updated solution, W = X + lambda*Y for some lambda
535: Output Parameters:
536: + changed_Y - Indicator if the direction Y has been changed.
537: - changed_W - Indicator if the new candidate solution W has been changed.
539: Level: developer
541: .keywords: SNESLineSearch, Create
543: .seealso: SNESLineSearchPreCheck()
544: @*/
545: PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
546: {
550: *changed_Y = PETSC_FALSE;
551: *changed_W = PETSC_FALSE;
552: if (linesearch->ops->postcheck) {
553: (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);
556: }
557: return(0);
558: }
562: /*@C
563: SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration
565: Logically Collective on SNESLineSearch
567: Input Arguments:
568: + linesearch - linesearch context
569: . X - base state for this step
570: . Y - initial correction
571: - ctx - context for this function
573: Output Arguments:
574: + Y - correction, possibly modified
575: - changed - flag indicating that Y was modified
577: Options Database Key:
578: + -snes_linesearch_precheck_picard - activate this routine
579: - -snes_linesearch_precheck_picard_angle - angle
581: Level: advanced
583: Notes:
584: This function should be passed to SNESLineSearchSetPreCheck()
586: The justification for this method involves the linear convergence of a Picard iteration
587: so the Picard linearization should be provided in place of the "Jacobian". This correction
588: is generally not useful when using a Newton linearization.
590: Reference:
591: Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.
593: .seealso: SNESLineSearchSetPreCheck()
594: @*/
595: PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
596: {
598: PetscReal angle = *(PetscReal*)linesearch->precheckctx;
599: Vec Ylast;
600: PetscScalar dot;
601: PetscInt iter;
602: PetscReal ynorm,ylastnorm,theta,angle_radians;
603: SNES snes;
606: SNESLineSearchGetSNES(linesearch, &snes);
607: PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);
608: if (!Ylast) {
609: VecDuplicate(Y,&Ylast);
610: PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);
611: PetscObjectDereference((PetscObject)Ylast);
612: }
613: SNESGetIterationNumber(snes,&iter);
614: if (iter < 2) {
615: VecCopy(Y,Ylast);
616: *changed = PETSC_FALSE;
617: return(0);
618: }
620: VecDot(Y,Ylast,&dot);
621: VecNorm(Y,NORM_2,&ynorm);
622: VecNorm(Ylast,NORM_2,&ylastnorm);
623: /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
624: theta = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
625: angle_radians = angle * PETSC_PI / 180.;
626: if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
627: /* Modify the step Y */
628: PetscReal alpha,ydiffnorm;
629: VecAXPY(Ylast,-1.0,Y);
630: VecNorm(Ylast,NORM_2,&ydiffnorm);
631: alpha = ylastnorm / ydiffnorm;
632: VecCopy(Y,Ylast);
633: VecScale(Y,alpha);
634: 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);
635: } else {
636: PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);
637: VecCopy(Y,Ylast);
638: *changed = PETSC_FALSE;
639: }
640: return(0);
641: }
645: /*@
646: SNESLineSearchApply - Computes the line-search update.
648: Collective on SNESLineSearch
650: Input Parameters:
651: + linesearch - The linesearch context
652: . X - The current solution
653: . F - The current function
654: . fnorm - The current norm
655: - Y - The search direction
657: Output Parameters:
658: + X - The new solution
659: . F - The new function
660: - fnorm - The new function norm
662: Options Database Keys:
663: + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell
664: . -snes_linesearch_monitor [:filename] - Print progress of line searches
665: . -snes_linesearch_damping - The linesearch damping parameter
666: . -snes_linesearch_norms - Turn on/off the linesearch norms
667: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
668: - -snes_linesearch_max_it - The number of iterations for iterative line searches
670: Notes:
671: This is typically called from within a SNESSolve() implementation in order to
672: help with convergence of the nonlinear method. Various SNES types use line searches
673: in different ways, but the overarching theme is that a line search is used to determine
674: an optimal damping parameter of a step at each iteration of the method. Each
675: application of the line search may invoke SNESComputeFunction several times, and
676: therefore may be fairly expensive.
678: Level: Intermediate
680: .keywords: SNESLineSearch, Create
682: .seealso: SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction()
683: @*/
684: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
685: {
694: linesearch->result = SNES_LINESEARCH_SUCCEEDED;
696: linesearch->vec_sol = X;
697: linesearch->vec_update = Y;
698: linesearch->vec_func = F;
700: SNESLineSearchSetUp(linesearch);
702: if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
704: if (fnorm) linesearch->fnorm = *fnorm;
705: else {
706: VecNorm(F, NORM_2, &linesearch->fnorm);
707: }
709: PetscLogEventBegin(SNESLineSearch_Apply,linesearch,X,F,Y);
711: (*linesearch->ops->apply)(linesearch);
713: PetscLogEventEnd(SNESLineSearch_Apply,linesearch,X,F,Y);
715: if (fnorm) *fnorm = linesearch->fnorm;
716: return(0);
717: }
721: /*@
722: SNESLineSearchDestroy - Destroys the line search instance.
724: Collective on SNESLineSearch
726: Input Parameters:
727: . linesearch - The linesearch context
729: Level: Intermediate
731: .keywords: SNESLineSearch, Destroy
733: .seealso: SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
734: @*/
735: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
736: {
740: if (!*linesearch) return(0);
742: if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; return(0);}
743: PetscObjectSAWsViewOff((PetscObject)*linesearch);
744: SNESLineSearchReset(*linesearch);
745: if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
746: PetscViewerDestroy(&(*linesearch)->monitor);
747: SNESLineSearchMonitorCancel((*linesearch));
748: PetscHeaderDestroy(linesearch);
749: return(0);
750: }
754: /*@
755: SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.
757: Input Parameters:
758: + linesearch - the linesearch object
759: - viewer - an ASCII PetscViewer or NULL to turn off monitor
761: Logically Collective on SNESLineSearch
763: Options Database:
764: . -snes_linesearch_monitor [:filename] - enables the monitor
766: Level: intermediate
768: Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with
769: SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the
770: line search that are not visible to the other monitors.
772: .seealso: SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor()
773: @*/
774: PetscErrorCode SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
775: {
779: if (viewer) {PetscObjectReference((PetscObject)viewer);}
780: PetscViewerDestroy(&linesearch->monitor);
781: linesearch->monitor = viewer;
782: return(0);
783: }
787: /*@
788: SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.
790: Input Parameter:
791: . linesearch - linesearch context
793: Output Parameter:
794: . monitor - monitor context
796: Logically Collective on SNES
798: Options Database Keys:
799: . -snes_linesearch_monitor - enables the monitor
801: Level: intermediate
803: .seealso: SNESLineSearchSetDefaultMonitor(), PetscViewer
804: @*/
805: PetscErrorCode SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
806: {
809: if (monitor) {
811: *monitor = linesearch->monitor;
812: }
813: return(0);
814: }
818: /*@C
819: SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
821: Collective on SNESLineSearch
823: Input Parameters:
824: + ls - LineSearch object you wish to monitor
825: . name - the monitor type one is seeking
826: . help - message indicating what monitoring is done
827: . manual - manual page for the monitor
828: . monitor - the monitor function
829: - 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
831: Level: developer
833: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
834: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
835: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
836: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
837: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
838: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
839: PetscOptionsFList(), PetscOptionsEList()
840: @*/
841: PetscErrorCode SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
842: {
843: PetscErrorCode ierr;
844: PetscViewer viewer;
845: PetscViewerFormat format;
846: PetscBool flg;
849: PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject)ls)->prefix,name,&viewer,&format,&flg);
850: if (flg) {
851: PetscViewerAndFormat *vf;
852: PetscViewerAndFormatCreate(viewer,format,&vf);
853: PetscObjectDereference((PetscObject)viewer);
854: if (monitorsetup) {
855: (*monitorsetup)(ls,vf);
856: }
857: SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
858: }
859: return(0);
860: }
864: /*@
865: SNESLineSearchSetFromOptions - Sets options for the line search
867: Input Parameters:
868: . linesearch - linesearch context
870: Options Database Keys:
871: + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
872: . -snes_linesearch_order <order> - 1, 2, 3. Most types only support certain orders (bt supports 2 or 3)
873: . -snes_linesearch_norms - Turn on/off the linesearch norms for the basic linesearch type
874: . -snes_linesearch_minlambda - The minimum step length
875: . -snes_linesearch_maxstep - The maximum step size
876: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
877: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
878: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
879: . -snes_linesearch_max_it - The number of iterations for iterative line searches
880: . -snes_linesearch_monitor [:filename] - Print progress of line searches
881: . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
882: . -snes_linesearch_damping - The linesearch damping parameter
883: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
884: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
885: - -snes_linesearch_precheck_picard_angle - Angle used in picard precheck method
887: Logically Collective on SNESLineSearch
889: Level: intermediate
891: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard()
892: @*/
893: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
894: {
895: PetscErrorCode ierr;
896: const char *deft = SNESLINESEARCHBASIC;
897: char type[256];
898: PetscBool flg, set;
899: PetscViewer viewer;
902: SNESLineSearchRegisterAll();
904: PetscObjectOptionsBegin((PetscObject)linesearch);
905: if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
906: PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
907: if (flg) {
908: SNESLineSearchSetType(linesearch,type);
909: } else if (!((PetscObject)linesearch)->type_name) {
910: SNESLineSearchSetType(linesearch,deft);
911: }
913: PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);
914: if (set) {
915: SNESLineSearchSetDefaultMonitor(linesearch,viewer);
916: PetscViewerDestroy(&viewer);
917: }
918: SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);
919:
920: /* tolerances */
921: PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);
922: PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);
923: PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);
924: PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);
925: PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);
926: PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);
928: /* damping parameters */
929: PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);
931: PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL);
933: /* precheck */
934: PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);
935: if (set) {
936: if (flg) {
937: linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
939: PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
940: "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);
941: SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
942: } else {
943: SNESLineSearchSetPreCheck(linesearch,NULL,NULL);
944: }
945: }
946: PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);
947: PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);
949: if (linesearch->ops->setfromoptions) {
950: (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);
951: }
953: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);
954: PetscOptionsEnd();
955: return(0);
956: }
960: /*@
961: SNESLineSearchView - Prints useful information about the line search
963: Input Parameters:
964: . linesearch - linesearch context
966: Logically Collective on SNESLineSearch
968: Level: intermediate
970: .seealso: SNESLineSearchCreate()
971: @*/
972: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
973: {
975: PetscBool iascii;
979: if (!viewer) {
980: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);
981: }
985: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
986: if (iascii) {
987: PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);
988: if (linesearch->ops->view) {
989: PetscViewerASCIIPushTab(viewer);
990: (*linesearch->ops->view)(linesearch,viewer);
991: PetscViewerASCIIPopTab(viewer);
992: }
993: PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);
994: PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);
995: PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", linesearch->max_its);
996: if (linesearch->ops->precheck) {
997: if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
998: PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n", linesearch->max_its);
999: } else {
1000: PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n", linesearch->max_its);
1001: }
1002: }
1003: if (linesearch->ops->postcheck) {
1004: PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n", linesearch->max_its);
1005: }
1006: }
1007: return(0);
1008: }
1012: /*@C
1013: SNESLineSearchSetType - Sets the linesearch type
1015: Logically Collective on SNESLineSearch
1017: Input Parameters:
1018: + linesearch - linesearch context
1019: - type - The type of line search to be used
1021: Available Types:
1022: + basic - Simple damping line search.
1023: . bt - Backtracking line search over the L2 norm of the function
1024: . l2 - Secant line search over the L2 norm of the function
1025: . cp - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
1026: . nleqerr - Affine-covariant error-oriented linesearch
1027: - shell - User provided SNESLineSearch implementation
1029: Level: intermediate
1031: .seealso: SNESLineSearchCreate()
1032: @*/
1033: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
1034: {
1035: PetscErrorCode ierr,(*r)(SNESLineSearch);
1036: PetscBool match;
1042: PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
1043: if (match) return(0);
1045: PetscFunctionListFind(SNESLineSearchList,type,&r);
1046: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
1047: /* Destroy the previous private linesearch context */
1048: if (linesearch->ops->destroy) {
1049: (*(linesearch)->ops->destroy)(linesearch);
1051: linesearch->ops->destroy = NULL;
1052: }
1053: /* Reinitialize function pointers in SNESLineSearchOps structure */
1054: linesearch->ops->apply = 0;
1055: linesearch->ops->view = 0;
1056: linesearch->ops->setfromoptions = 0;
1057: linesearch->ops->destroy = 0;
1059: PetscObjectChangeTypeName((PetscObject)linesearch,type);
1060: (*r)(linesearch);
1061: return(0);
1062: }
1066: /*@
1067: SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
1069: Input Parameters:
1070: + linesearch - linesearch context
1071: - snes - The snes instance
1073: Level: developer
1075: Notes:
1076: This happens automatically when the line search is obtained/created with
1077: SNESGetLineSearch(). This routine is therefore mainly called within SNES
1078: implementations.
1080: Level: developer
1082: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1083: @*/
1084: PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
1085: {
1089: linesearch->snes = snes;
1090: return(0);
1091: }
1095: /*@
1096: SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
1097: Having an associated SNES is necessary because most line search implementations must be able to
1098: evaluate the function using SNESComputeFunction() for the associated SNES. This routine
1099: is used in the line search implementations when one must get this associated SNES instance.
1101: Input Parameters:
1102: . linesearch - linesearch context
1104: Output Parameters:
1105: . snes - The snes instance
1107: Level: developer
1109: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1110: @*/
1111: PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1112: {
1116: *snes = linesearch->snes;
1117: return(0);
1118: }
1122: /*@
1123: SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
1125: Input Parameters:
1126: . linesearch - linesearch context
1128: Output Parameters:
1129: . lambda - The last steplength computed during SNESLineSearchApply()
1131: Level: advanced
1133: Notes:
1134: This is useful in methods where the solver is ill-scaled and
1135: requires some adaptive notion of the difference in scale between the
1136: solution and the function. For instance, SNESQN may be scaled by the
1137: line search lambda using the argument -snes_qn_scaling ls.
1139: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1140: @*/
1141: PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1142: {
1146: *lambda = linesearch->lambda;
1147: return(0);
1148: }
1152: /*@
1153: SNESLineSearchSetLambda - Sets the linesearch steplength.
1155: Input Parameters:
1156: + linesearch - linesearch context
1157: - lambda - The last steplength.
1159: Notes:
1160: This routine is typically used within implementations of SNESLineSearchApply()
1161: to set the final steplength. This routine (and SNESLineSearchGetLambda()) were
1162: added in order to facilitate Quasi-Newton methods that use the previous steplength
1163: as an inner scaling parameter.
1165: Level: advanced
1167: .seealso: SNESLineSearchGetLambda()
1168: @*/
1169: PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1170: {
1173: linesearch->lambda = lambda;
1174: return(0);
1175: }
1177: #undef __FUNCT__
1179: /*@
1180: SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include
1181: tolerances for the relative and absolute change in the function norm, the change
1182: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1183: and the maximum number of iterations the line search procedure may take.
1185: Input Parameters:
1186: . linesearch - linesearch context
1188: Output Parameters:
1189: + steptol - The minimum steplength
1190: . maxstep - The maximum steplength
1191: . rtol - The relative tolerance for iterative line searches
1192: . atol - The absolute tolerance for iterative line searches
1193: . ltol - The change in lambda tolerance for iterative line searches
1194: - max_it - The maximum number of iterations of the line search
1196: Level: intermediate
1198: Notes:
1199: Different line searches may implement these parameters slightly differently as
1200: the type requires.
1202: .seealso: SNESLineSearchSetTolerances()
1203: @*/
1204: PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1205: {
1208: if (steptol) {
1210: *steptol = linesearch->steptol;
1211: }
1212: if (maxstep) {
1214: *maxstep = linesearch->maxstep;
1215: }
1216: if (rtol) {
1218: *rtol = linesearch->rtol;
1219: }
1220: if (atol) {
1222: *atol = linesearch->atol;
1223: }
1224: if (ltol) {
1226: *ltol = linesearch->ltol;
1227: }
1228: if (max_its) {
1230: *max_its = linesearch->max_its;
1231: }
1232: return(0);
1233: }
1235: #undef __FUNCT__
1237: /*@
1238: SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include
1239: tolerances for the relative and absolute change in the function norm, the change
1240: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1241: and the maximum number of iterations the line search procedure may take.
1243: Input Parameters:
1244: + linesearch - linesearch context
1245: . steptol - The minimum steplength
1246: . maxstep - The maximum steplength
1247: . rtol - The relative tolerance for iterative line searches
1248: . atol - The absolute tolerance for iterative line searches
1249: . ltol - The change in lambda tolerance for iterative line searches
1250: - max_it - The maximum number of iterations of the line search
1252: Notes:
1253: The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1254: place of an argument.
1256: Level: intermediate
1258: .seealso: SNESLineSearchGetTolerances()
1259: @*/
1260: PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1261: {
1271: if (steptol!= PETSC_DEFAULT) {
1272: if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
1273: linesearch->steptol = steptol;
1274: }
1276: if (maxstep!= PETSC_DEFAULT) {
1277: if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1278: linesearch->maxstep = maxstep;
1279: }
1281: if (rtol != PETSC_DEFAULT) {
1282: 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);
1283: linesearch->rtol = rtol;
1284: }
1286: if (atol != PETSC_DEFAULT) {
1287: if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1288: linesearch->atol = atol;
1289: }
1291: if (ltol != PETSC_DEFAULT) {
1292: if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %14.12e must be non-negative",(double)ltol);
1293: linesearch->ltol = ltol;
1294: }
1296: if (max_its != PETSC_DEFAULT) {
1297: if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1298: linesearch->max_its = max_its;
1299: }
1300: return(0);
1301: }
1305: /*@
1306: SNESLineSearchGetDamping - Gets the line search damping parameter.
1308: Input Parameters:
1309: . linesearch - linesearch context
1311: Output Parameters:
1312: . damping - The damping parameter
1314: Level: advanced
1316: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1317: @*/
1319: PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1320: {
1324: *damping = linesearch->damping;
1325: return(0);
1326: }
1330: /*@
1331: SNESLineSearchSetDamping - Sets the line search damping paramter.
1333: Input Parameters:
1334: + linesearch - linesearch context
1335: - damping - The damping parameter
1337: Options Database:
1338: . -snes_linesearch_damping
1339: Level: intermediate
1341: Notes:
1342: The basic line search merely takes the update step scaled by the damping parameter.
1343: The use of the damping parameter in the l2 and cp line searches is much more subtle;
1344: it is used as a starting point in calculating the secant step. However, the eventual
1345: step may be of greater length than the damping parameter. In the bt line search it is
1346: used as the maximum possible step length, as the bt line search only backtracks.
1348: .seealso: SNESLineSearchGetDamping()
1349: @*/
1350: PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1351: {
1354: linesearch->damping = damping;
1355: return(0);
1356: }
1360: /*@
1361: SNESLineSearchGetOrder - Gets the line search approximation order.
1363: Input Parameters:
1364: . linesearch - linesearch context
1366: Output Parameters:
1367: . order - The order
1369: Possible Values for order:
1370: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1371: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1372: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1374: Level: intermediate
1376: .seealso: SNESLineSearchSetOrder()
1377: @*/
1379: PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1380: {
1384: *order = linesearch->order;
1385: return(0);
1386: }
1390: /*@
1391: SNESLineSearchSetOrder - Sets the line search damping paramter.
1393: Input Parameters:
1394: . linesearch - linesearch context
1395: . order - The damping parameter
1397: Level: intermediate
1399: Possible Values for order:
1400: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1401: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1402: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1404: Notes:
1405: Variable orders are supported by the following line searches:
1406: + bt - cubic and quadratic
1407: - cp - linear and quadratic
1409: .seealso: SNESLineSearchGetOrder()
1410: @*/
1411: PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1412: {
1415: linesearch->order = order;
1416: return(0);
1417: }
1421: /*@
1422: SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1424: Input Parameters:
1425: . linesearch - linesearch context
1427: Output Parameters:
1428: + xnorm - The norm of the current solution
1429: . fnorm - The norm of the current function
1430: - ynorm - The norm of the current update
1432: Notes:
1433: This function is mainly called from SNES implementations.
1435: Level: developer
1437: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1438: @*/
1439: PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1440: {
1443: if (xnorm) *xnorm = linesearch->xnorm;
1444: if (fnorm) *fnorm = linesearch->fnorm;
1445: if (ynorm) *ynorm = linesearch->ynorm;
1446: return(0);
1447: }
1451: /*@
1452: SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1454: Input Parameters:
1455: + linesearch - linesearch context
1456: . xnorm - The norm of the current solution
1457: . fnorm - The norm of the current function
1458: - ynorm - The norm of the current update
1460: Level: advanced
1462: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1463: @*/
1464: PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1465: {
1468: linesearch->xnorm = xnorm;
1469: linesearch->fnorm = fnorm;
1470: linesearch->ynorm = ynorm;
1471: return(0);
1472: }
1476: /*@
1477: SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1479: Input Parameters:
1480: . linesearch - linesearch context
1482: Options Database Keys:
1483: . -snes_linesearch_norms - turn norm computation on or off
1485: Level: intermediate
1487: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1488: @*/
1489: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1490: {
1492: SNES snes;
1495: if (linesearch->norms) {
1496: if (linesearch->ops->vinorm) {
1497: SNESLineSearchGetSNES(linesearch, &snes);
1498: VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1499: VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1500: (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1501: } else {
1502: VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1503: VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1504: VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1505: VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1506: VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1507: VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1508: }
1509: }
1510: return(0);
1511: }
1515: /*@
1516: SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
1518: Input Parameters:
1519: + linesearch - linesearch context
1520: - flg - indicates whether or not to compute norms
1522: Options Database Keys:
1523: . -snes_linesearch_norms - turn norm computation on or off
1525: Notes:
1526: This is most relevant to the SNESLINESEARCHBASIC line search type.
1528: Level: intermediate
1530: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1531: @*/
1532: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1533: {
1535: linesearch->norms = flg;
1536: return(0);
1537: }
1541: /*@
1542: SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1544: Input Parameters:
1545: . linesearch - linesearch context
1547: Output Parameters:
1548: + X - Solution vector
1549: . F - Function vector
1550: . Y - Search direction vector
1551: . W - Solution work vector
1552: - G - Function work vector
1554: Notes:
1555: At the beginning of a line search application, X should contain a
1556: solution and the vector F the function computed at X. At the end of the
1557: line search application, X should contain the new solution, and F the
1558: function evaluated at the new solution.
1560: These vectors are owned by the SNESLineSearch and should not be destroyed by the caller
1562: Level: advanced
1564: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1565: @*/
1566: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1567: {
1570: if (X) {
1572: *X = linesearch->vec_sol;
1573: }
1574: if (F) {
1576: *F = linesearch->vec_func;
1577: }
1578: if (Y) {
1580: *Y = linesearch->vec_update;
1581: }
1582: if (W) {
1584: *W = linesearch->vec_sol_new;
1585: }
1586: if (G) {
1588: *G = linesearch->vec_func_new;
1589: }
1590: return(0);
1591: }
1595: /*@
1596: SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1598: Input Parameters:
1599: + linesearch - linesearch context
1600: . X - Solution vector
1601: . F - Function vector
1602: . Y - Search direction vector
1603: . W - Solution work vector
1604: - G - Function work vector
1606: Level: advanced
1608: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1609: @*/
1610: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1611: {
1614: if (X) {
1616: linesearch->vec_sol = X;
1617: }
1618: if (F) {
1620: linesearch->vec_func = F;
1621: }
1622: if (Y) {
1624: linesearch->vec_update = Y;
1625: }
1626: if (W) {
1628: linesearch->vec_sol_new = W;
1629: }
1630: if (G) {
1632: linesearch->vec_func_new = G;
1633: }
1634: return(0);
1635: }
1639: /*@C
1640: SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1641: SNES options in the database.
1643: Logically Collective on SNESLineSearch
1645: Input Parameters:
1646: + snes - the SNES context
1647: - prefix - the prefix to prepend to all option names
1649: Notes:
1650: A hyphen (-) must NOT be given at the beginning of the prefix name.
1651: The first character of all runtime options is AUTOMATICALLY the hyphen.
1653: Level: advanced
1655: .keywords: SNESLineSearch, append, options, prefix, database
1657: .seealso: SNESGetOptionsPrefix()
1658: @*/
1659: PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1660: {
1665: PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1666: return(0);
1667: }
1671: /*@C
1672: SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1673: SNESLineSearch options in the database.
1675: Not Collective
1677: Input Parameter:
1678: . linesearch - the SNESLineSearch context
1680: Output Parameter:
1681: . prefix - pointer to the prefix string used
1683: Notes:
1684: On the fortran side, the user should pass in a string 'prefix' of
1685: sufficient length to hold the prefix.
1687: Level: advanced
1689: .keywords: SNESLineSearch, get, options, prefix, database
1691: .seealso: SNESAppendOptionsPrefix()
1692: @*/
1693: PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1694: {
1699: PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1700: return(0);
1701: }
1705: /*@C
1706: SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1708: Input Parameter:
1709: + linesearch - the SNESLineSearch context
1710: - nwork - the number of work vectors
1712: Level: developer
1714: Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations
1716: .keywords: SNESLineSearch, work, vector
1718: .seealso: SNESSetWorkVecs()
1719: @*/
1720: PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1721: {
1725: if (linesearch->vec_sol) {
1726: VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1727: } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1728: return(0);
1729: }
1733: /*@
1734: SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1736: Input Parameters:
1737: . linesearch - linesearch context
1739: Output Parameters:
1740: . result - The success or failure status
1742: Notes:
1743: This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1744: (and set the SNES convergence accordingly).
1746: Level: intermediate
1748: .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1749: @*/
1750: PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1751: {
1755: *result = linesearch->result;
1756: return(0);
1757: }
1761: /*@
1762: SNESLineSearchSetReason - Sets the success/failure status of the last line search application
1764: Input Parameters:
1765: + linesearch - linesearch context
1766: - result - The success or failure status
1768: Notes:
1769: This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1770: the success or failure of the line search method.
1772: Level: developer
1774: .seealso: SNESLineSearchGetSResult()
1775: @*/
1776: PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1777: {
1780: linesearch->result = result;
1781: return(0);
1782: }
1786: /*@C
1787: SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
1789: Input Parameters:
1790: + snes - nonlinear context obtained from SNESCreate()
1791: . projectfunc - function for projecting the function to the bounds
1792: - normfunc - function for computing the norm of an active set
1794: Logically Collective on SNES
1796: Calling sequence of projectfunc:
1797: .vb
1798: projectfunc (SNES snes, Vec X)
1799: .ve
1801: Input parameters for projectfunc:
1802: + snes - nonlinear context
1803: - X - current solution
1805: Output parameters for projectfunc:
1806: . X - Projected solution
1808: Calling sequence of normfunc:
1809: .vb
1810: projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1811: .ve
1813: Input parameters for normfunc:
1814: + snes - nonlinear context
1815: . X - current solution
1816: - F - current residual
1818: Output parameters for normfunc:
1819: . fnorm - VI-specific norm of the function
1821: Notes:
1822: The VI solvers require projection of the solution to the feasible set. projectfunc should implement this.
1824: The VI solvers require special evaluation of the function norm such that the norm is only calculated
1825: on the inactive set. This should be implemented by normfunc.
1827: Level: developer
1829: .keywords: SNES, line search, VI, nonlinear, set, line search
1831: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1832: @*/
1833: extern PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1834: {
1837: if (projectfunc) linesearch->ops->viproject = projectfunc;
1838: if (normfunc) linesearch->ops->vinorm = normfunc;
1839: return(0);
1840: }
1844: /*@C
1845: SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
1847: Input Parameters:
1848: . linesearch - the line search context, obtain with SNESGetLineSearch()
1850: Output Parameters:
1851: + projectfunc - function for projecting the function to the bounds
1852: - normfunc - function for computing the norm of an active set
1854: Logically Collective on SNES
1856: Level: developer
1858: .keywords: SNES, line search, VI, nonlinear, get, line search
1860: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1861: @*/
1862: extern PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1863: {
1865: if (projectfunc) *projectfunc = linesearch->ops->viproject;
1866: if (normfunc) *normfunc = linesearch->ops->vinorm;
1867: return(0);
1868: }
1872: /*@C
1873: SNESLineSearchRegister - See SNESLineSearchRegister()
1875: Level: advanced
1876: @*/
1877: PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1878: {
1882: PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1883: return(0);
1884: }