Actual source code: linesearch.c
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: .seealso: SNESGetLineSearch(), SNESLineSearchMonitorDefault(), SNESLineSearchMonitorSet()
31: @*/
32: PetscErrorCode SNESLineSearchMonitorCancel(SNESLineSearch ls)
33: {
35: PetscInt i;
39: for (i=0; i<ls->numbermonitors; i++) {
40: if (ls->monitordestroy[i]) {
41: (*ls->monitordestroy[i])(&ls->monitorcontext[i]);
42: }
43: }
44: ls->numbermonitors = 0;
45: return(0);
46: }
48: /*@
49: SNESLineSearchMonitor - runs the user provided monitor routines, if they exist
51: Collective on SNES
53: Input Parameters:
54: . ls - the linesearch object
56: Notes:
57: This routine is called by the SNES implementations.
58: It does not typically need to be called by the user.
60: Level: developer
62: .seealso: SNESGetLineSearch(), SNESLineSearchMonitorSet()
63: @*/
64: PetscErrorCode SNESLineSearchMonitor(SNESLineSearch ls)
65: {
67: PetscInt i,n = ls->numbermonitors;
70: for (i=0; i<n; i++) {
71: (*ls->monitorftns[i])(ls,ls->monitorcontext[i]);
72: }
73: return(0);
74: }
76: /*@C
77: SNESLineSearchMonitorSet - Sets an ADDITIONAL function that is to be used at every
78: iteration of the nonlinear solver to display the iteration's
79: progress.
81: Logically Collective on SNESLineSearch
83: Input Parameters:
84: + ls - the SNESLineSearch context
85: . f - the monitor function
86: . mctx - [optional] user-defined context for private data for the
87: monitor routine (use NULL if no context is desired)
88: - monitordestroy - [optional] routine that frees monitor context
89: (may be NULL)
91: Notes:
92: Several different monitoring routines may be set by calling
93: SNESLineSearchMonitorSet() multiple times; all will be called in the
94: order in which they were set.
96: Fortran Notes:
97: Only a single monitor function can be set for each SNESLineSearch object
99: Level: intermediate
101: .seealso: SNESGetLineSearch(), SNESLineSearchMonitorDefault(), SNESLineSearchMonitorCancel()
102: @*/
103: PetscErrorCode SNESLineSearchMonitorSet(SNESLineSearch ls,PetscErrorCode (*f)(SNESLineSearch,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
104: {
106: PetscInt i;
107: PetscBool identical;
111: for (i=0; i<ls->numbermonitors;i++) {
112: PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))ls->monitorftns[i],ls->monitorcontext[i],ls->monitordestroy[i],&identical);
113: if (identical) return(0);
114: }
115: if (ls->numbermonitors >= MAXSNESLSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
116: ls->monitorftns[ls->numbermonitors] = f;
117: ls->monitordestroy[ls->numbermonitors] = monitordestroy;
118: ls->monitorcontext[ls->numbermonitors++] = (void*)mctx;
119: return(0);
120: }
122: /*@C
123: SNESLineSearchMonitorSolutionUpdate - Monitors each update a new function value the linesearch tries
125: Collective on SNESLineSearch
127: Input Parameters:
128: + ls - the SNES linesearch object
129: - vf - the context for the monitor, in this case it is an ASCII PetscViewer and format
131: Level: intermediate
133: .seealso: SNESGetLineSearch(), SNESMonitorSet(), SNESMonitorSolution()
134: @*/
135: PetscErrorCode SNESLineSearchMonitorSolutionUpdate(SNESLineSearch ls,PetscViewerAndFormat *vf)
136: {
138: PetscViewer viewer = vf->viewer;
139: Vec Y,W,G;
142: SNESLineSearchGetVecs(ls,NULL,NULL,&Y,&W,&G);
143: PetscViewerPushFormat(viewer,vf->format);
144: PetscViewerASCIIPrintf(viewer,"LineSearch attempted update to solution \n");
145: VecView(Y,viewer);
146: PetscViewerASCIIPrintf(viewer,"LineSearch attempted new solution \n");
147: VecView(W,viewer);
148: PetscViewerASCIIPrintf(viewer,"LineSearch attempted updated function value\n");
149: VecView(G,viewer);
150: PetscViewerPopFormat(viewer);
151: return(0);
152: }
154: /*@
155: SNESLineSearchCreate - Creates the line search context.
157: Logically Collective on Comm
159: Input Parameters:
160: . comm - MPI communicator for the line search (typically from the associated SNES context).
162: Output Parameters:
163: . outlinesearch - the new linesearch context
165: Level: developer
167: Notes:
168: The preferred calling sequence for users is to use SNESGetLineSearch() to acquire the SNESLineSearch instance
169: already associated with the SNES. This function is for developer use.
171: .seealso: LineSearchDestroy(), SNESGetLineSearch()
172: @*/
174: PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
175: {
177: SNESLineSearch linesearch;
181: SNESInitializePackage();
182: *outlinesearch = NULL;
184: PetscHeaderCreate(linesearch,SNESLINESEARCH_CLASSID, "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView);
186: linesearch->vec_sol_new = NULL;
187: linesearch->vec_func_new = NULL;
188: linesearch->vec_sol = NULL;
189: linesearch->vec_func = NULL;
190: linesearch->vec_update = NULL;
192: linesearch->lambda = 1.0;
193: linesearch->fnorm = 1.0;
194: linesearch->ynorm = 1.0;
195: linesearch->xnorm = 1.0;
196: linesearch->result = SNES_LINESEARCH_SUCCEEDED;
197: linesearch->norms = PETSC_TRUE;
198: linesearch->keeplambda = PETSC_FALSE;
199: linesearch->damping = 1.0;
200: linesearch->maxstep = 1e8;
201: linesearch->steptol = 1e-12;
202: linesearch->rtol = 1e-8;
203: linesearch->atol = 1e-15;
204: linesearch->ltol = 1e-8;
205: linesearch->precheckctx = NULL;
206: linesearch->postcheckctx = NULL;
207: linesearch->max_its = 1;
208: linesearch->setupcalled = PETSC_FALSE;
209: linesearch->monitor = NULL;
210: *outlinesearch = linesearch;
211: return(0);
212: }
214: /*@
215: SNESLineSearchSetUp - Prepares the line search for being applied by allocating
216: any required vectors.
218: Collective on SNESLineSearch
220: Input Parameters:
221: . linesearch - The LineSearch instance.
223: Notes:
224: For most cases, this needn't be called by users or outside of SNESLineSearchApply().
225: The only current case where this is called outside of this is for the VI
226: solvers, which modify the solution and work vectors before the first call
227: of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be
228: allocated upfront.
230: Level: advanced
232: .seealso: SNESGetLineSearch(), SNESLineSearchReset()
233: @*/
235: PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
236: {
240: if (!((PetscObject)linesearch)->type_name) {
241: SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);
242: }
243: if (!linesearch->setupcalled) {
244: if (!linesearch->vec_sol_new) {
245: VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);
246: }
247: if (!linesearch->vec_func_new) {
248: VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);
249: }
250: if (linesearch->ops->setup) {
251: (*linesearch->ops->setup)(linesearch);
252: }
253: if (!linesearch->ops->snesfunc) {SNESLineSearchSetFunction(linesearch,SNESComputeFunction);}
254: linesearch->lambda = linesearch->damping;
255: linesearch->setupcalled = PETSC_TRUE;
256: }
257: return(0);
258: }
261: /*@
262: SNESLineSearchReset - Undoes the SNESLineSearchSetUp() and deletes any Vecs or Mats allocated by the line search.
264: Collective on SNESLineSearch
266: Input Parameters:
267: . linesearch - The LineSearch instance.
269: Notes:
270: Usually only called by SNESReset()
272: Level: developer
274: .seealso: SNESGetLineSearch(), SNESLineSearchSetUp()
275: @*/
277: PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
278: {
282: if (linesearch->ops->reset) (*linesearch->ops->reset)(linesearch);
284: VecDestroy(&linesearch->vec_sol_new);
285: VecDestroy(&linesearch->vec_func_new);
287: VecDestroyVecs(linesearch->nwork, &linesearch->work);
289: linesearch->nwork = 0;
290: linesearch->setupcalled = PETSC_FALSE;
291: return(0);
292: }
294: /*@C
295: SNESLineSearchSetFunction - Sets the function evaluation used by the SNES line search
297: Input Parameters:
298: . linesearch - the SNESLineSearch context
299: + func - function evaluation routine
301: Level: developer
303: Notes:
304: This is used internally by PETSc and not called by users
306: .seealso: SNESGetLineSearch(), SNESSetFunction()
307: @*/
308: PetscErrorCode SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
309: {
312: linesearch->ops->snesfunc = func;
313: return(0);
314: }
316: /*@C
317: SNESLineSearchSetPreCheck - Sets a user function that is called after the initial search direction has been computed but
318: before the line search routine has been applied. Allows the user to adjust the result of (usually a linear solve) that
319: determined the search direction.
321: Logically Collective on SNESLineSearch
323: Input Parameters:
324: + linesearch - the SNESLineSearch context
325: . func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for the calling sequence
326: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
328: Level: intermediate
330: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
331: @*/
332: PetscErrorCode SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
333: {
336: if (func) linesearch->ops->precheck = func;
337: if (ctx) linesearch->precheckctx = ctx;
338: return(0);
339: }
341: /*@C
342: SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine.
344: Input Parameters:
345: . linesearch - the SNESLineSearch context
347: Output Parameters:
348: + func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for calling sequence
349: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
351: Level: intermediate
353: .seealso: SNESGetLineSearch(), SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck()
354: @*/
355: PetscErrorCode SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
356: {
359: if (func) *func = linesearch->ops->precheck;
360: if (ctx) *ctx = linesearch->precheckctx;
361: return(0);
362: }
364: /*@C
365: SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step
366: direction and length. Allows the user a chance to change or override the decision of the line search routine
368: Logically Collective on SNESLineSearch
370: Input Parameters:
371: + linesearch - the SNESLineSearch context
372: . func - [optional] function evaluation routine, see SNESLineSearchPostCheck() for the calling sequence
373: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
375: Level: intermediate
377: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchGetPostCheck()
378: @*/
379: PetscErrorCode SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
380: {
383: if (func) linesearch->ops->postcheck = func;
384: if (ctx) linesearch->postcheckctx = ctx;
385: return(0);
386: }
388: /*@C
389: SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.
391: Input Parameters:
392: . linesearch - the SNESLineSearch context
394: Output Parameters:
395: + func - [optional] function evaluation routine, see for the calling sequence SNESLineSearchPostCheck()
396: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
398: Level: intermediate
400: .seealso: SNESGetLineSearch(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck()
401: @*/
402: PetscErrorCode SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
403: {
406: if (func) *func = linesearch->ops->postcheck;
407: if (ctx) *ctx = linesearch->postcheckctx;
408: return(0);
409: }
411: /*@
412: SNESLineSearchPreCheck - Prepares the line search for being applied.
414: Logically Collective on SNESLineSearch
416: Input Parameters:
417: + linesearch - The linesearch instance.
418: . X - The current solution
419: - Y - The step direction
421: Output Parameters:
422: . changed - Indicator that the precheck routine has changed anything
424: Level: developer
426: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck()
427: @*/
428: PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
429: {
433: *changed = PETSC_FALSE;
434: if (linesearch->ops->precheck) {
435: (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);
437: }
438: return(0);
439: }
441: /*@
442: SNESLineSearchPostCheck - Prepares the line search for being applied.
444: Logically Collective on SNESLineSearch
446: Input Parameters:
447: + linesearch - The linesearch context
448: . X - The last solution
449: . Y - The step direction
450: - W - The updated solution, W = X + lambda*Y for some lambda
452: Output Parameters:
453: + changed_Y - Indicator if the direction Y has been changed.
454: - changed_W - Indicator if the new candidate solution W has been changed.
456: Level: developer
458: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPrecheck(), SNESLineSearchGetPrecheck()
459: @*/
460: PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
461: {
465: *changed_Y = PETSC_FALSE;
466: *changed_W = PETSC_FALSE;
467: if (linesearch->ops->postcheck) {
468: (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);
471: }
472: return(0);
473: }
475: /*@C
476: SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration
478: Logically Collective on SNESLineSearch
480: Input Arguments:
481: + linesearch - linesearch context
482: . X - base state for this step
483: . Y - initial correction
484: - ctx - context for this function
486: Output Arguments:
487: + Y - correction, possibly modified
488: - changed - flag indicating that Y was modified
490: Options Database Key:
491: + -snes_linesearch_precheck_picard - activate this routine
492: - -snes_linesearch_precheck_picard_angle - angle
494: Level: advanced
496: Notes:
497: This function should be passed to SNESLineSearchSetPreCheck()
499: The justification for this method involves the linear convergence of a Picard iteration
500: so the Picard linearization should be provided in place of the "Jacobian". This correction
501: is generally not useful when using a Newton linearization.
503: Reference:
504: Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.
506: .seealso: SNESGetLineSearch(), SNESLineSearchSetPreCheck()
507: @*/
508: PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
509: {
511: PetscReal angle = *(PetscReal*)linesearch->precheckctx;
512: Vec Ylast;
513: PetscScalar dot;
514: PetscInt iter;
515: PetscReal ynorm,ylastnorm,theta,angle_radians;
516: SNES snes;
519: SNESLineSearchGetSNES(linesearch, &snes);
520: PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);
521: if (!Ylast) {
522: VecDuplicate(Y,&Ylast);
523: PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);
524: PetscObjectDereference((PetscObject)Ylast);
525: }
526: SNESGetIterationNumber(snes,&iter);
527: if (iter < 2) {
528: VecCopy(Y,Ylast);
529: *changed = PETSC_FALSE;
530: return(0);
531: }
533: VecDot(Y,Ylast,&dot);
534: VecNorm(Y,NORM_2,&ynorm);
535: VecNorm(Ylast,NORM_2,&ylastnorm);
536: /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
537: theta = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
538: angle_radians = angle * PETSC_PI / 180.;
539: if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
540: /* Modify the step Y */
541: PetscReal alpha,ydiffnorm;
542: VecAXPY(Ylast,-1.0,Y);
543: VecNorm(Ylast,NORM_2,&ydiffnorm);
544: alpha = (ydiffnorm > .001*ylastnorm) ? ylastnorm / ydiffnorm : 1000.0;
545: VecCopy(Y,Ylast);
546: VecScale(Y,alpha);
547: 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);
548: *changed = PETSC_TRUE;
549: } else {
550: PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);
551: VecCopy(Y,Ylast);
552: *changed = PETSC_FALSE;
553: }
554: return(0);
555: }
557: /*@
558: SNESLineSearchApply - Computes the line-search update.
560: Collective on SNESLineSearch
562: Input Parameters:
563: + linesearch - The linesearch context
564: . X - The current solution
565: . F - The current function
566: . fnorm - The current norm
567: - Y - The search direction
569: Output Parameters:
570: + X - The new solution
571: . F - The new function
572: - fnorm - The new function norm
574: Options Database Keys:
575: + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell
576: . -snes_linesearch_monitor [:filename] - Print progress of line searches
577: . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping)
578: . -snes_linesearch_norms - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms())
579: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
580: - -snes_linesearch_max_it - The number of iterations for iterative line searches
582: Notes:
583: This is typically called from within a SNESSolve() implementation in order to
584: help with convergence of the nonlinear method. Various SNES types use line searches
585: in different ways, but the overarching theme is that a line search is used to determine
586: an optimal damping parameter of a step at each iteration of the method. Each
587: application of the line search may invoke SNESComputeFunction() several times, and
588: therefore may be fairly expensive.
590: Level: Intermediate
592: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(),
593: SNESLineSearchType, SNESLineSearchSetType()
594: @*/
595: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
596: {
605: linesearch->result = SNES_LINESEARCH_SUCCEEDED;
607: linesearch->vec_sol = X;
608: linesearch->vec_update = Y;
609: linesearch->vec_func = F;
611: SNESLineSearchSetUp(linesearch);
613: if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
615: if (fnorm) linesearch->fnorm = *fnorm;
616: else {
617: VecNorm(F, NORM_2, &linesearch->fnorm);
618: }
620: PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y);
622: (*linesearch->ops->apply)(linesearch);
624: PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y);
626: if (fnorm) *fnorm = linesearch->fnorm;
627: return(0);
628: }
630: /*@
631: SNESLineSearchDestroy - Destroys the line search instance.
633: Collective on SNESLineSearch
635: Input Parameters:
636: . linesearch - The linesearch context
638: Level: developer
640: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
641: @*/
642: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
643: {
647: if (!*linesearch) return(0);
649: if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = NULL; return(0);}
650: PetscObjectSAWsViewOff((PetscObject)*linesearch);
651: SNESLineSearchReset(*linesearch);
652: if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
653: PetscViewerDestroy(&(*linesearch)->monitor);
654: SNESLineSearchMonitorCancel((*linesearch));
655: PetscHeaderDestroy(linesearch);
656: return(0);
657: }
659: /*@
660: SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.
662: Input Parameters:
663: + linesearch - the linesearch object
664: - viewer - an ASCII PetscViewer or NULL to turn off monitor
666: Logically Collective on SNESLineSearch
668: Options Database:
669: . -snes_linesearch_monitor [:filename] - enables the monitor
671: Level: intermediate
673: Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with
674: SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the
675: line search that are not visible to the other monitors.
677: .seealso: SNESGetLineSearch(), SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor()
678: @*/
679: PetscErrorCode SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
680: {
684: if (viewer) {PetscObjectReference((PetscObject)viewer);}
685: PetscViewerDestroy(&linesearch->monitor);
686: linesearch->monitor = viewer;
687: return(0);
688: }
690: /*@
691: SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.
693: Input Parameter:
694: . linesearch - linesearch context
696: Output Parameter:
697: . monitor - monitor context
699: Logically Collective on SNES
701: Options Database Keys:
702: . -snes_linesearch_monitor - enables the monitor
704: Level: intermediate
706: .seealso: SNESGetLineSearch(), SNESLineSearchSetDefaultMonitor(), PetscViewer
707: @*/
708: PetscErrorCode SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
709: {
712: *monitor = linesearch->monitor;
713: return(0);
714: }
716: /*@C
717: SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
719: Collective on SNESLineSearch
721: Input Parameters:
722: + ls - LineSearch object you wish to monitor
723: . name - the monitor type one is seeking
724: . help - message indicating what monitoring is done
725: . manual - manual page for the monitor
726: . monitor - the monitor function
727: - 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
729: Level: developer
731: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
732: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
733: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
734: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
735: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
736: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
737: PetscOptionsFList(), PetscOptionsEList()
738: @*/
739: PetscErrorCode SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
740: {
741: PetscErrorCode ierr;
742: PetscViewer viewer;
743: PetscViewerFormat format;
744: PetscBool flg;
747: PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject) ls)->options,((PetscObject)ls)->prefix,name,&viewer,&format,&flg);
748: if (flg) {
749: PetscViewerAndFormat *vf;
750: PetscViewerAndFormatCreate(viewer,format,&vf);
751: PetscObjectDereference((PetscObject)viewer);
752: if (monitorsetup) {
753: (*monitorsetup)(ls,vf);
754: }
755: SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
756: }
757: return(0);
758: }
760: /*@
761: SNESLineSearchSetFromOptions - Sets options for the line search
763: Input Parameters:
764: . linesearch - linesearch context
766: Options Database Keys:
767: + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
768: . -snes_linesearch_order <order> - 1, 2, 3. Most types only support certain orders (bt supports 2 or 3)
769: . -snes_linesearch_norms - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms())
770: . -snes_linesearch_minlambda - The minimum step length
771: . -snes_linesearch_maxstep - The maximum step size
772: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
773: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
774: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
775: . -snes_linesearch_max_it - The number of iterations for iterative line searches
776: . -snes_linesearch_monitor [:filename] - Print progress of line searches
777: . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
778: . -snes_linesearch_damping - The linesearch damping parameter
779: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
780: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
781: - -snes_linesearch_precheck_picard_angle - Angle used in Picard precheck method
783: Logically Collective on SNESLineSearch
785: Level: intermediate
787: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(),
788: SNESLineSearchType, SNESLineSearchSetComputeNorms()
789: @*/
790: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
791: {
792: PetscErrorCode ierr;
793: const char *deft = SNESLINESEARCHBASIC;
794: char type[256];
795: PetscBool flg, set;
796: PetscViewer viewer;
799: SNESLineSearchRegisterAll();
801: PetscObjectOptionsBegin((PetscObject)linesearch);
802: if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
803: PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
804: if (flg) {
805: SNESLineSearchSetType(linesearch,type);
806: } else if (!((PetscObject)linesearch)->type_name) {
807: SNESLineSearchSetType(linesearch,deft);
808: }
810: PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject) linesearch)->options,((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);
811: if (set) {
812: SNESLineSearchSetDefaultMonitor(linesearch,viewer);
813: PetscViewerDestroy(&viewer);
814: }
815: SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);
817: /* tolerances */
818: PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);
819: PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);
820: PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);
821: PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);
822: PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);
823: PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);
825: /* damping parameters */
826: PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);
828: PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL);
830: /* precheck */
831: PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);
832: if (set) {
833: if (flg) {
834: linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
836: PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
837: "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);
838: SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
839: } else {
840: SNESLineSearchSetPreCheck(linesearch,NULL,NULL);
841: }
842: }
843: PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);
844: PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);
846: if (linesearch->ops->setfromoptions) {
847: (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);
848: }
850: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);
851: PetscOptionsEnd();
852: return(0);
853: }
855: /*@
856: SNESLineSearchView - Prints useful information about the line search
858: Input Parameters:
859: . linesearch - linesearch context
861: Logically Collective on SNESLineSearch
863: Level: intermediate
865: .seealso: SNESLineSearchCreate()
866: @*/
867: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
868: {
870: PetscBool iascii;
874: if (!viewer) {
875: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);
876: }
880: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
881: if (iascii) {
882: PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);
883: if (linesearch->ops->view) {
884: PetscViewerASCIIPushTab(viewer);
885: (*linesearch->ops->view)(linesearch,viewer);
886: PetscViewerASCIIPopTab(viewer);
887: }
888: PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);
889: PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);
890: PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", linesearch->max_its);
891: if (linesearch->ops->precheck) {
892: if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
893: PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n", linesearch->max_its);
894: } else {
895: PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n", linesearch->max_its);
896: }
897: }
898: if (linesearch->ops->postcheck) {
899: PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n", linesearch->max_its);
900: }
901: }
902: return(0);
903: }
905: /*@C
906: SNESLineSearchGetType - Gets the linesearch type
908: Logically Collective on SNESLineSearch
910: Input Parameters:
911: . linesearch - linesearch context
913: Output Parameters:
914: - type - The type of line search, or NULL if not set
916: Level: intermediate
918: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchSetType()
919: @*/
920: PetscErrorCode SNESLineSearchGetType(SNESLineSearch linesearch, SNESLineSearchType *type)
921: {
925: *type = ((PetscObject)linesearch)->type_name;
926: return(0);
927: }
929: /*@C
930: SNESLineSearchSetType - Sets the linesearch type
932: Logically Collective on SNESLineSearch
934: Input Parameters:
935: + linesearch - linesearch context
936: - type - The type of line search to be used
938: Available Types:
939: + SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
940: . SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
941: . SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
942: . SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
943: . SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
944: - SNESLINESEARCHSHELL - User provided SNESLineSearch implementation
946: Options Database:
947: . -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
949: Level: intermediate
951: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchGetType()
952: @*/
953: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
954: {
955: PetscErrorCode ierr,(*r)(SNESLineSearch);
956: PetscBool match;
962: PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
963: if (match) return(0);
965: PetscFunctionListFind(SNESLineSearchList,type,&r);
966: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
967: /* Destroy the previous private linesearch context */
968: if (linesearch->ops->destroy) {
969: (*(linesearch)->ops->destroy)(linesearch);
970: linesearch->ops->destroy = NULL;
971: }
972: /* Reinitialize function pointers in SNESLineSearchOps structure */
973: linesearch->ops->apply = NULL;
974: linesearch->ops->view = NULL;
975: linesearch->ops->setfromoptions = NULL;
976: linesearch->ops->destroy = NULL;
978: PetscObjectChangeTypeName((PetscObject)linesearch,type);
979: (*r)(linesearch);
980: return(0);
981: }
983: /*@
984: SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
986: Input Parameters:
987: + linesearch - linesearch context
988: - snes - The snes instance
990: Level: developer
992: Notes:
993: This happens automatically when the line search is obtained/created with
994: SNESGetLineSearch(). This routine is therefore mainly called within SNES
995: implementations.
997: Level: developer
999: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1000: @*/
1001: PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
1002: {
1006: linesearch->snes = snes;
1007: return(0);
1008: }
1010: /*@
1011: SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
1012: Having an associated SNES is necessary because most line search implementations must be able to
1013: evaluate the function using SNESComputeFunction() for the associated SNES. This routine
1014: is used in the line search implementations when one must get this associated SNES instance.
1016: Input Parameters:
1017: . linesearch - linesearch context
1019: Output Parameters:
1020: . snes - The snes instance
1022: Level: developer
1024: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1025: @*/
1026: PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1027: {
1031: *snes = linesearch->snes;
1032: return(0);
1033: }
1035: /*@
1036: SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
1038: Input Parameters:
1039: . linesearch - linesearch context
1041: Output Parameters:
1042: . lambda - The last steplength computed during SNESLineSearchApply()
1044: Level: advanced
1046: Notes:
1047: This is useful in methods where the solver is ill-scaled and
1048: requires some adaptive notion of the difference in scale between the
1049: solution and the function. For instance, SNESQN may be scaled by the
1050: line search lambda using the argument -snes_qn_scaling ls.
1052: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1053: @*/
1054: PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1055: {
1059: *lambda = linesearch->lambda;
1060: return(0);
1061: }
1063: /*@
1064: SNESLineSearchSetLambda - Sets the linesearch steplength.
1066: Input Parameters:
1067: + linesearch - linesearch context
1068: - lambda - The last steplength.
1070: Notes:
1071: This routine is typically used within implementations of SNESLineSearchApply()
1072: to set the final steplength. This routine (and SNESLineSearchGetLambda()) were
1073: added in order to facilitate Quasi-Newton methods that use the previous steplength
1074: as an inner scaling parameter.
1076: Level: advanced
1078: .seealso: SNESLineSearchGetLambda()
1079: @*/
1080: PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1081: {
1084: linesearch->lambda = lambda;
1085: return(0);
1086: }
1088: /*@
1089: SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include
1090: tolerances for the relative and absolute change in the function norm, the change
1091: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1092: and the maximum number of iterations the line search procedure may take.
1094: Input Parameters:
1095: . linesearch - linesearch context
1097: Output Parameters:
1098: + steptol - The minimum steplength
1099: . maxstep - The maximum steplength
1100: . rtol - The relative tolerance for iterative line searches
1101: . atol - The absolute tolerance for iterative line searches
1102: . ltol - The change in lambda tolerance for iterative line searches
1103: - max_it - The maximum number of iterations of the line search
1105: Level: intermediate
1107: Notes:
1108: Different line searches may implement these parameters slightly differently as
1109: the type requires.
1111: .seealso: SNESLineSearchSetTolerances()
1112: @*/
1113: PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1114: {
1117: if (steptol) {
1119: *steptol = linesearch->steptol;
1120: }
1121: if (maxstep) {
1123: *maxstep = linesearch->maxstep;
1124: }
1125: if (rtol) {
1127: *rtol = linesearch->rtol;
1128: }
1129: if (atol) {
1131: *atol = linesearch->atol;
1132: }
1133: if (ltol) {
1135: *ltol = linesearch->ltol;
1136: }
1137: if (max_its) {
1139: *max_its = linesearch->max_its;
1140: }
1141: return(0);
1142: }
1144: /*@
1145: SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include
1146: tolerances for the relative and absolute change in the function norm, the change
1147: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1148: and the maximum number of iterations the line search procedure may take.
1150: Input Parameters:
1151: + linesearch - linesearch context
1152: . steptol - The minimum steplength
1153: . maxstep - The maximum steplength
1154: . rtol - The relative tolerance for iterative line searches
1155: . atol - The absolute tolerance for iterative line searches
1156: . ltol - The change in lambda tolerance for iterative line searches
1157: - max_it - The maximum number of iterations of the line search
1159: Notes:
1160: The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1161: place of an argument.
1163: Level: intermediate
1165: .seealso: SNESLineSearchGetTolerances()
1166: @*/
1167: PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1168: {
1178: if (steptol!= PETSC_DEFAULT) {
1179: if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
1180: linesearch->steptol = steptol;
1181: }
1183: if (maxstep!= PETSC_DEFAULT) {
1184: if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1185: linesearch->maxstep = maxstep;
1186: }
1188: if (rtol != PETSC_DEFAULT) {
1189: 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);
1190: linesearch->rtol = rtol;
1191: }
1193: if (atol != PETSC_DEFAULT) {
1194: if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1195: linesearch->atol = atol;
1196: }
1198: if (ltol != PETSC_DEFAULT) {
1199: if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Lambda tolerance %14.12e must be non-negative",(double)ltol);
1200: linesearch->ltol = ltol;
1201: }
1203: if (max_its != PETSC_DEFAULT) {
1204: if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1205: linesearch->max_its = max_its;
1206: }
1207: return(0);
1208: }
1210: /*@
1211: SNESLineSearchGetDamping - Gets the line search damping parameter.
1213: Input Parameters:
1214: . linesearch - linesearch context
1216: Output Parameters:
1217: . damping - The damping parameter
1219: Level: advanced
1221: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1222: @*/
1224: PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1225: {
1229: *damping = linesearch->damping;
1230: return(0);
1231: }
1233: /*@
1234: SNESLineSearchSetDamping - Sets the line search damping parameter.
1236: Input Parameters:
1237: + linesearch - linesearch context
1238: - damping - The damping parameter
1240: Options Database:
1241: . -snes_linesearch_damping
1242: Level: intermediate
1244: Notes:
1245: The basic line search merely takes the update step scaled by the damping parameter.
1246: The use of the damping parameter in the l2 and cp line searches is much more subtle;
1247: it is used as a starting point in calculating the secant step. However, the eventual
1248: step may be of greater length than the damping parameter. In the bt line search it is
1249: used as the maximum possible step length, as the bt line search only backtracks.
1251: .seealso: SNESLineSearchGetDamping()
1252: @*/
1253: PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1254: {
1257: linesearch->damping = damping;
1258: return(0);
1259: }
1261: /*@
1262: SNESLineSearchGetOrder - Gets the line search approximation order.
1264: Input Parameters:
1265: . linesearch - linesearch context
1267: Output Parameters:
1268: . order - The order
1270: Possible Values for order:
1271: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1272: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1273: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1275: Level: intermediate
1277: .seealso: SNESLineSearchSetOrder()
1278: @*/
1280: PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1281: {
1285: *order = linesearch->order;
1286: return(0);
1287: }
1289: /*@
1290: SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
1292: Input Parameters:
1293: + linesearch - linesearch context
1294: - order - The damping parameter
1296: Level: intermediate
1298: Possible Values for order:
1299: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1300: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1301: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1303: Notes:
1304: Variable orders are supported by the following line searches:
1305: + bt - cubic and quadratic
1306: - cp - linear and quadratic
1308: .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1309: @*/
1310: PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1311: {
1314: linesearch->order = order;
1315: return(0);
1316: }
1318: /*@
1319: SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1321: Input Parameters:
1322: . linesearch - linesearch context
1324: Output Parameters:
1325: + xnorm - The norm of the current solution
1326: . fnorm - The norm of the current function
1327: - ynorm - The norm of the current update
1329: Notes:
1330: This function is mainly called from SNES implementations.
1332: Level: developer
1334: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1335: @*/
1336: PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1337: {
1340: if (xnorm) *xnorm = linesearch->xnorm;
1341: if (fnorm) *fnorm = linesearch->fnorm;
1342: if (ynorm) *ynorm = linesearch->ynorm;
1343: return(0);
1344: }
1346: /*@
1347: SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1349: Input Parameters:
1350: + linesearch - linesearch context
1351: . xnorm - The norm of the current solution
1352: . fnorm - The norm of the current function
1353: - ynorm - The norm of the current update
1355: Level: advanced
1357: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1358: @*/
1359: PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1360: {
1363: linesearch->xnorm = xnorm;
1364: linesearch->fnorm = fnorm;
1365: linesearch->ynorm = ynorm;
1366: return(0);
1367: }
1369: /*@
1370: SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1372: Input Parameters:
1373: . linesearch - linesearch context
1375: Options Database Keys:
1376: . -snes_linesearch_norms - turn norm computation on or off
1378: Level: intermediate
1380: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1381: @*/
1382: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1383: {
1385: SNES snes;
1388: if (linesearch->norms) {
1389: if (linesearch->ops->vinorm) {
1390: SNESLineSearchGetSNES(linesearch, &snes);
1391: VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1392: VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1393: (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1394: } else {
1395: VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1396: VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1397: VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1398: VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1399: VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1400: VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1401: }
1402: }
1403: return(0);
1404: }
1406: /*@
1407: SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
1409: Input Parameters:
1410: + linesearch - linesearch context
1411: - flg - indicates whether or not to compute norms
1413: Options Database Keys:
1414: . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch
1416: Notes:
1417: This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm.
1419: Level: intermediate
1421: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1422: @*/
1423: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1424: {
1426: linesearch->norms = flg;
1427: return(0);
1428: }
1430: /*@
1431: SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1433: Input Parameters:
1434: . linesearch - linesearch context
1436: Output Parameters:
1437: + X - Solution vector
1438: . F - Function vector
1439: . Y - Search direction vector
1440: . W - Solution work vector
1441: - G - Function work vector
1443: Notes:
1444: At the beginning of a line search application, X should contain a
1445: solution and the vector F the function computed at X. At the end of the
1446: line search application, X should contain the new solution, and F the
1447: function evaluated at the new solution.
1449: These vectors are owned by the SNESLineSearch and should not be destroyed by the caller
1451: Level: advanced
1453: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1454: @*/
1455: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1456: {
1459: if (X) {
1461: *X = linesearch->vec_sol;
1462: }
1463: if (F) {
1465: *F = linesearch->vec_func;
1466: }
1467: if (Y) {
1469: *Y = linesearch->vec_update;
1470: }
1471: if (W) {
1473: *W = linesearch->vec_sol_new;
1474: }
1475: if (G) {
1477: *G = linesearch->vec_func_new;
1478: }
1479: return(0);
1480: }
1482: /*@
1483: SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1485: Input Parameters:
1486: + linesearch - linesearch context
1487: . X - Solution vector
1488: . F - Function vector
1489: . Y - Search direction vector
1490: . W - Solution work vector
1491: - G - Function work vector
1493: Level: advanced
1495: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1496: @*/
1497: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1498: {
1501: if (X) {
1503: linesearch->vec_sol = X;
1504: }
1505: if (F) {
1507: linesearch->vec_func = F;
1508: }
1509: if (Y) {
1511: linesearch->vec_update = Y;
1512: }
1513: if (W) {
1515: linesearch->vec_sol_new = W;
1516: }
1517: if (G) {
1519: linesearch->vec_func_new = G;
1520: }
1521: return(0);
1522: }
1524: /*@C
1525: SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1526: SNES options in the database.
1528: Logically Collective on SNESLineSearch
1530: Input Parameters:
1531: + snes - the SNES context
1532: - prefix - the prefix to prepend to all option names
1534: Notes:
1535: A hyphen (-) must NOT be given at the beginning of the prefix name.
1536: The first character of all runtime options is AUTOMATICALLY the hyphen.
1538: Level: advanced
1540: .seealso: SNESGetOptionsPrefix()
1541: @*/
1542: PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1543: {
1548: PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1549: return(0);
1550: }
1552: /*@C
1553: SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1554: SNESLineSearch options in the database.
1556: Not Collective
1558: Input Parameter:
1559: . linesearch - the SNESLineSearch context
1561: Output Parameter:
1562: . prefix - pointer to the prefix string used
1564: Notes:
1565: On the fortran side, the user should pass in a string 'prefix' of
1566: sufficient length to hold the prefix.
1568: Level: advanced
1570: .seealso: SNESAppendOptionsPrefix()
1571: @*/
1572: PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1573: {
1578: PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1579: return(0);
1580: }
1582: /*@C
1583: SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1585: Input Parameter:
1586: + linesearch - the SNESLineSearch context
1587: - nwork - the number of work vectors
1589: Level: developer
1591: .seealso: SNESSetWorkVecs()
1592: @*/
1593: PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1594: {
1598: if (linesearch->vec_sol) {
1599: VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1600: } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1601: return(0);
1602: }
1604: /*@
1605: SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1607: Input Parameters:
1608: . linesearch - linesearch context
1610: Output Parameters:
1611: . result - The success or failure status
1613: Notes:
1614: This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1615: (and set the SNES convergence accordingly).
1617: Level: intermediate
1619: .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1620: @*/
1621: PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1622: {
1626: *result = linesearch->result;
1627: return(0);
1628: }
1630: /*@
1631: SNESLineSearchSetReason - Sets the success/failure status of the last line search application
1633: Input Parameters:
1634: + linesearch - linesearch context
1635: - result - The success or failure status
1637: Notes:
1638: This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1639: the success or failure of the line search method.
1641: Level: developer
1643: .seealso: SNESLineSearchGetSResult()
1644: @*/
1645: PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1646: {
1649: linesearch->result = result;
1650: return(0);
1651: }
1653: /*@C
1654: SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
1656: Input Parameters:
1657: + snes - nonlinear context obtained from SNESCreate()
1658: . projectfunc - function for projecting the function to the bounds
1659: - normfunc - function for computing the norm of an active set
1661: Logically Collective on SNES
1663: Calling sequence of projectfunc:
1664: .vb
1665: projectfunc (SNES snes, Vec X)
1666: .ve
1668: Input parameters for projectfunc:
1669: + snes - nonlinear context
1670: - X - current solution
1672: Output parameters for projectfunc:
1673: . X - Projected solution
1675: Calling sequence of normfunc:
1676: .vb
1677: projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1678: .ve
1680: Input parameters for normfunc:
1681: + snes - nonlinear context
1682: . X - current solution
1683: - F - current residual
1685: Output parameters for normfunc:
1686: . fnorm - VI-specific norm of the function
1688: Notes:
1689: The VI solvers require projection of the solution to the feasible set. projectfunc should implement this.
1691: The VI solvers require special evaluation of the function norm such that the norm is only calculated
1692: on the inactive set. This should be implemented by normfunc.
1694: Level: developer
1696: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1697: @*/
1698: PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1699: {
1702: if (projectfunc) linesearch->ops->viproject = projectfunc;
1703: if (normfunc) linesearch->ops->vinorm = normfunc;
1704: return(0);
1705: }
1707: /*@C
1708: SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
1710: Input Parameters:
1711: . linesearch - the line search context, obtain with SNESGetLineSearch()
1713: Output Parameters:
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: Level: developer
1721: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1722: @*/
1723: PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1724: {
1726: if (projectfunc) *projectfunc = linesearch->ops->viproject;
1727: if (normfunc) *normfunc = linesearch->ops->vinorm;
1728: return(0);
1729: }
1731: /*@C
1732: SNESLineSearchRegister - See SNESLineSearchRegister()
1734: Level: advanced
1735: @*/
1736: PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1737: {
1741: SNESInitializePackage();
1742: PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1743: return(0);
1744: }