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: }
260: /*@
261: SNESLineSearchReset - Undoes the SNESLineSearchSetUp() and deletes any Vecs or Mats allocated by the line search.
263: Collective on SNESLineSearch
265: Input Parameters:
266: . linesearch - The LineSearch instance.
268: Notes:
269: Usually only called by SNESReset()
271: Level: developer
273: .seealso: SNESGetLineSearch(), SNESLineSearchSetUp()
274: @*/
276: PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
277: {
281: if (linesearch->ops->reset) (*linesearch->ops->reset)(linesearch);
283: VecDestroy(&linesearch->vec_sol_new);
284: VecDestroy(&linesearch->vec_func_new);
286: VecDestroyVecs(linesearch->nwork, &linesearch->work);
288: linesearch->nwork = 0;
289: linesearch->setupcalled = PETSC_FALSE;
290: return(0);
291: }
293: /*@C
294: SNESLineSearchSetFunction - Sets the function evaluation used by the SNES line search
296: Input Parameters:
297: . linesearch - the SNESLineSearch context
298: + func - function evaluation routine
300: Level: developer
302: Notes:
303: This is used internally by PETSc and not called by users
305: .seealso: SNESGetLineSearch(), SNESSetFunction()
306: @*/
307: PetscErrorCode SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
308: {
311: linesearch->ops->snesfunc = func;
312: return(0);
313: }
315: /*@C
316: SNESLineSearchSetPreCheck - Sets a user function that is called after the initial search direction has been computed but
317: before the line search routine has been applied. Allows the user to adjust the result of (usually a linear solve) that
318: determined the search direction.
320: Logically Collective on SNESLineSearch
322: Input Parameters:
323: + linesearch - the SNESLineSearch context
324: . func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for the calling sequence
325: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
327: Level: intermediate
329: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
330: @*/
331: PetscErrorCode SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
332: {
335: if (func) linesearch->ops->precheck = func;
336: if (ctx) linesearch->precheckctx = ctx;
337: return(0);
338: }
340: /*@C
341: SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine.
343: Input Parameter:
344: . linesearch - the SNESLineSearch context
346: Output Parameters:
347: + func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for calling sequence
348: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
350: Level: intermediate
352: .seealso: SNESGetLineSearch(), SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck()
353: @*/
354: PetscErrorCode SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
355: {
358: if (func) *func = linesearch->ops->precheck;
359: if (ctx) *ctx = linesearch->precheckctx;
360: return(0);
361: }
363: /*@C
364: SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step
365: direction and length. Allows the user a chance to change or override the decision of the line search routine
367: Logically Collective on SNESLineSearch
369: Input Parameters:
370: + linesearch - the SNESLineSearch context
371: . func - [optional] function evaluation routine, see SNESLineSearchPostCheck() for the calling sequence
372: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
374: Level: intermediate
376: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchGetPostCheck()
377: @*/
378: PetscErrorCode SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
379: {
382: if (func) linesearch->ops->postcheck = func;
383: if (ctx) linesearch->postcheckctx = ctx;
384: return(0);
385: }
387: /*@C
388: SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.
390: Input Parameter:
391: . linesearch - the SNESLineSearch context
393: Output Parameters:
394: + func - [optional] function evaluation routine, see for the calling sequence SNESLineSearchPostCheck()
395: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
397: Level: intermediate
399: .seealso: SNESGetLineSearch(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck()
400: @*/
401: PetscErrorCode SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
402: {
405: if (func) *func = linesearch->ops->postcheck;
406: if (ctx) *ctx = linesearch->postcheckctx;
407: return(0);
408: }
410: /*@
411: SNESLineSearchPreCheck - Prepares the line search for being applied.
413: Logically Collective on SNESLineSearch
415: Input Parameters:
416: + linesearch - The linesearch instance.
417: . X - The current solution
418: - Y - The step direction
420: Output Parameters:
421: . changed - Indicator that the precheck routine has changed anything
423: Level: developer
425: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck()
426: @*/
427: PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
428: {
432: *changed = PETSC_FALSE;
433: if (linesearch->ops->precheck) {
434: (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);
436: }
437: return(0);
438: }
440: /*@
441: SNESLineSearchPostCheck - Prepares the line search for being applied.
443: Logically Collective on SNESLineSearch
445: Input Parameters:
446: + linesearch - The linesearch context
447: . X - The last solution
448: . Y - The step direction
449: - W - The updated solution, W = X + lambda*Y for some lambda
451: Output Parameters:
452: + changed_Y - Indicator if the direction Y has been changed.
453: - changed_W - Indicator if the new candidate solution W has been changed.
455: Level: developer
457: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPrecheck(), SNESLineSearchGetPrecheck()
458: @*/
459: PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
460: {
464: *changed_Y = PETSC_FALSE;
465: *changed_W = PETSC_FALSE;
466: if (linesearch->ops->postcheck) {
467: (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);
470: }
471: return(0);
472: }
474: /*@C
475: SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration
477: Logically Collective on SNESLineSearch
479: Input Parameters:
480: + linesearch - linesearch context
481: . X - base state for this step
482: - ctx - context for this function
484: Input/Output Parameter:
485: . Y - correction, possibly modified
487: Output Parameter:
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: - Y - The search direction
566: Input/Output Parameters:
567: + X - The current solution, on output the new solution
568: . F - The current function, on output the new function
569: - fnorm - The current norm, on output the new function norm
571: Options Database Keys:
572: + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell
573: . -snes_linesearch_monitor [:filename] - Print progress of line searches
574: . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping)
575: . -snes_linesearch_norms - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms())
576: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
577: - -snes_linesearch_max_it - The number of iterations for iterative line searches
579: Notes:
580: This is typically called from within a SNESSolve() implementation in order to
581: help with convergence of the nonlinear method. Various SNES types use line searches
582: in different ways, but the overarching theme is that a line search is used to determine
583: an optimal damping parameter of a step at each iteration of the method. Each
584: application of the line search may invoke SNESComputeFunction() several times, and
585: therefore may be fairly expensive.
587: Level: Intermediate
589: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(),
590: SNESLineSearchType, SNESLineSearchSetType()
591: @*/
592: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
593: {
602: linesearch->result = SNES_LINESEARCH_SUCCEEDED;
604: linesearch->vec_sol = X;
605: linesearch->vec_update = Y;
606: linesearch->vec_func = F;
608: SNESLineSearchSetUp(linesearch);
610: if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
612: if (fnorm) linesearch->fnorm = *fnorm;
613: else {
614: VecNorm(F, NORM_2, &linesearch->fnorm);
615: }
617: PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y);
619: (*linesearch->ops->apply)(linesearch);
621: PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y);
623: if (fnorm) *fnorm = linesearch->fnorm;
624: return(0);
625: }
627: /*@
628: SNESLineSearchDestroy - Destroys the line search instance.
630: Collective on SNESLineSearch
632: Input Parameters:
633: . linesearch - The linesearch context
635: Level: developer
637: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
638: @*/
639: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
640: {
644: if (!*linesearch) return(0);
646: if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = NULL; return(0);}
647: PetscObjectSAWsViewOff((PetscObject)*linesearch);
648: SNESLineSearchReset(*linesearch);
649: if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
650: PetscViewerDestroy(&(*linesearch)->monitor);
651: SNESLineSearchMonitorCancel((*linesearch));
652: PetscHeaderDestroy(linesearch);
653: return(0);
654: }
656: /*@
657: SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.
659: Input Parameters:
660: + linesearch - the linesearch object
661: - viewer - an ASCII PetscViewer or NULL to turn off monitor
663: Logically Collective on SNESLineSearch
665: Options Database:
666: . -snes_linesearch_monitor [:filename] - enables the monitor
668: Level: intermediate
670: Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with
671: SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the
672: line search that are not visible to the other monitors.
674: .seealso: SNESGetLineSearch(), SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor()
675: @*/
676: PetscErrorCode SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
677: {
681: if (viewer) {PetscObjectReference((PetscObject)viewer);}
682: PetscViewerDestroy(&linesearch->monitor);
683: linesearch->monitor = viewer;
684: return(0);
685: }
687: /*@
688: SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.
690: Input Parameter:
691: . linesearch - linesearch context
693: Output Parameter:
694: . monitor - monitor context
696: Logically Collective on SNES
698: Options Database Keys:
699: . -snes_linesearch_monitor - enables the monitor
701: Level: intermediate
703: .seealso: SNESGetLineSearch(), SNESLineSearchSetDefaultMonitor(), PetscViewer
704: @*/
705: PetscErrorCode SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
706: {
709: *monitor = linesearch->monitor;
710: return(0);
711: }
713: /*@C
714: SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
716: Collective on SNESLineSearch
718: Input Parameters:
719: + ls - LineSearch object you wish to monitor
720: . name - the monitor type one is seeking
721: . help - message indicating what monitoring is done
722: . manual - manual page for the monitor
723: . monitor - the monitor function
724: - 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
726: Level: developer
728: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
729: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
730: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
731: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
732: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
733: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
734: PetscOptionsFList(), PetscOptionsEList()
735: @*/
736: PetscErrorCode SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
737: {
738: PetscErrorCode ierr;
739: PetscViewer viewer;
740: PetscViewerFormat format;
741: PetscBool flg;
744: PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject) ls)->options,((PetscObject)ls)->prefix,name,&viewer,&format,&flg);
745: if (flg) {
746: PetscViewerAndFormat *vf;
747: PetscViewerAndFormatCreate(viewer,format,&vf);
748: PetscObjectDereference((PetscObject)viewer);
749: if (monitorsetup) {
750: (*monitorsetup)(ls,vf);
751: }
752: SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
753: }
754: return(0);
755: }
757: /*@
758: SNESLineSearchSetFromOptions - Sets options for the line search
760: Input Parameter:
761: . linesearch - linesearch context
763: Options Database Keys:
764: + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
765: . -snes_linesearch_order <order> - 1, 2, 3. Most types only support certain orders (bt supports 2 or 3)
766: . -snes_linesearch_norms - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms())
767: . -snes_linesearch_minlambda - The minimum step length
768: . -snes_linesearch_maxstep - The maximum step size
769: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
770: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
771: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
772: . -snes_linesearch_max_it - The number of iterations for iterative line searches
773: . -snes_linesearch_monitor [:filename] - Print progress of line searches
774: . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
775: . -snes_linesearch_damping - The linesearch damping parameter
776: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
777: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
778: - -snes_linesearch_precheck_picard_angle - Angle used in Picard precheck method
780: Logically Collective on SNESLineSearch
782: Level: intermediate
784: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(),
785: SNESLineSearchType, SNESLineSearchSetComputeNorms()
786: @*/
787: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
788: {
789: PetscErrorCode ierr;
790: const char *deft = SNESLINESEARCHBASIC;
791: char type[256];
792: PetscBool flg, set;
793: PetscViewer viewer;
796: SNESLineSearchRegisterAll();
798: PetscObjectOptionsBegin((PetscObject)linesearch);
799: if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
800: PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
801: if (flg) {
802: SNESLineSearchSetType(linesearch,type);
803: } else if (!((PetscObject)linesearch)->type_name) {
804: SNESLineSearchSetType(linesearch,deft);
805: }
807: PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject) linesearch)->options,((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);
808: if (set) {
809: SNESLineSearchSetDefaultMonitor(linesearch,viewer);
810: PetscViewerDestroy(&viewer);
811: }
812: SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);
814: /* tolerances */
815: PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);
816: PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);
817: PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);
818: PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);
819: PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);
820: PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);
822: /* damping parameters */
823: PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);
825: PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL);
827: /* precheck */
828: PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);
829: if (set) {
830: if (flg) {
831: linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
833: PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
834: "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);
835: SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
836: } else {
837: SNESLineSearchSetPreCheck(linesearch,NULL,NULL);
838: }
839: }
840: PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);
841: PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);
843: if (linesearch->ops->setfromoptions) {
844: (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);
845: }
847: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);
848: PetscOptionsEnd();
849: return(0);
850: }
852: /*@
853: SNESLineSearchView - Prints useful information about the line search
855: Input Parameters:
856: . linesearch - linesearch context
858: Logically Collective on SNESLineSearch
860: Level: intermediate
862: .seealso: SNESLineSearchCreate()
863: @*/
864: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
865: {
867: PetscBool iascii;
871: if (!viewer) {
872: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);
873: }
877: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
878: if (iascii) {
879: PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);
880: if (linesearch->ops->view) {
881: PetscViewerASCIIPushTab(viewer);
882: (*linesearch->ops->view)(linesearch,viewer);
883: PetscViewerASCIIPopTab(viewer);
884: }
885: PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);
886: PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);
887: PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", linesearch->max_its);
888: if (linesearch->ops->precheck) {
889: if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
890: PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n", linesearch->max_its);
891: } else {
892: PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n", linesearch->max_its);
893: }
894: }
895: if (linesearch->ops->postcheck) {
896: PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n", linesearch->max_its);
897: }
898: }
899: return(0);
900: }
902: /*@C
903: SNESLineSearchGetType - Gets the linesearch type
905: Logically Collective on SNESLineSearch
907: Input Parameters:
908: . linesearch - linesearch context
910: Output Parameters:
911: - type - The type of line search, or NULL if not set
913: Level: intermediate
915: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchSetType()
916: @*/
917: PetscErrorCode SNESLineSearchGetType(SNESLineSearch linesearch, SNESLineSearchType *type)
918: {
922: *type = ((PetscObject)linesearch)->type_name;
923: return(0);
924: }
926: /*@C
927: SNESLineSearchSetType - Sets the linesearch type
929: Logically Collective on SNESLineSearch
931: Input Parameters:
932: + linesearch - linesearch context
933: - type - The type of line search to be used
935: Available Types:
936: + SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
937: . SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
938: . SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
939: . SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
940: . SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
941: - SNESLINESEARCHSHELL - User provided SNESLineSearch implementation
943: Options Database:
944: . -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
946: Level: intermediate
948: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchGetType()
949: @*/
950: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
951: {
952: PetscErrorCode ierr,(*r)(SNESLineSearch);
953: PetscBool match;
959: PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
960: if (match) return(0);
962: PetscFunctionListFind(SNESLineSearchList,type,&r);
963: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
964: /* Destroy the previous private linesearch context */
965: if (linesearch->ops->destroy) {
966: (*(linesearch)->ops->destroy)(linesearch);
967: linesearch->ops->destroy = NULL;
968: }
969: /* Reinitialize function pointers in SNESLineSearchOps structure */
970: linesearch->ops->apply = NULL;
971: linesearch->ops->view = NULL;
972: linesearch->ops->setfromoptions = NULL;
973: linesearch->ops->destroy = NULL;
975: PetscObjectChangeTypeName((PetscObject)linesearch,type);
976: (*r)(linesearch);
977: return(0);
978: }
980: /*@
981: SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
983: Input Parameters:
984: + linesearch - linesearch context
985: - snes - The snes instance
987: Level: developer
989: Notes:
990: This happens automatically when the line search is obtained/created with
991: SNESGetLineSearch(). This routine is therefore mainly called within SNES
992: implementations.
994: Level: developer
996: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
997: @*/
998: PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
999: {
1003: linesearch->snes = snes;
1004: return(0);
1005: }
1007: /*@
1008: SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
1009: Having an associated SNES is necessary because most line search implementations must be able to
1010: evaluate the function using SNESComputeFunction() for the associated SNES. This routine
1011: is used in the line search implementations when one must get this associated SNES instance.
1013: Input Parameters:
1014: . linesearch - linesearch context
1016: Output Parameters:
1017: . snes - The snes instance
1019: Level: developer
1021: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1022: @*/
1023: PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1024: {
1028: *snes = linesearch->snes;
1029: return(0);
1030: }
1032: /*@
1033: SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
1035: Input Parameters:
1036: . linesearch - linesearch context
1038: Output Parameters:
1039: . lambda - The last steplength computed during SNESLineSearchApply()
1041: Level: advanced
1043: Notes:
1044: This is useful in methods where the solver is ill-scaled and
1045: requires some adaptive notion of the difference in scale between the
1046: solution and the function. For instance, SNESQN may be scaled by the
1047: line search lambda using the argument -snes_qn_scaling ls.
1049: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1050: @*/
1051: PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1052: {
1056: *lambda = linesearch->lambda;
1057: return(0);
1058: }
1060: /*@
1061: SNESLineSearchSetLambda - Sets the linesearch steplength.
1063: Input Parameters:
1064: + linesearch - linesearch context
1065: - lambda - The last steplength.
1067: Notes:
1068: This routine is typically used within implementations of SNESLineSearchApply()
1069: to set the final steplength. This routine (and SNESLineSearchGetLambda()) were
1070: added in order to facilitate Quasi-Newton methods that use the previous steplength
1071: as an inner scaling parameter.
1073: Level: advanced
1075: .seealso: SNESLineSearchGetLambda()
1076: @*/
1077: PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1078: {
1081: linesearch->lambda = lambda;
1082: return(0);
1083: }
1085: /*@
1086: SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include
1087: tolerances for the relative and absolute change in the function norm, the change
1088: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1089: and the maximum number of iterations the line search procedure may take.
1091: Input Parameter:
1092: . linesearch - linesearch context
1094: Output Parameters:
1095: + steptol - The minimum steplength
1096: . maxstep - The maximum steplength
1097: . rtol - The relative tolerance for iterative line searches
1098: . atol - The absolute tolerance for iterative line searches
1099: . ltol - The change in lambda tolerance for iterative line searches
1100: - max_it - The maximum number of iterations of the line search
1102: Level: intermediate
1104: Notes:
1105: Different line searches may implement these parameters slightly differently as
1106: the type requires.
1108: .seealso: SNESLineSearchSetTolerances()
1109: @*/
1110: PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1111: {
1114: if (steptol) {
1116: *steptol = linesearch->steptol;
1117: }
1118: if (maxstep) {
1120: *maxstep = linesearch->maxstep;
1121: }
1122: if (rtol) {
1124: *rtol = linesearch->rtol;
1125: }
1126: if (atol) {
1128: *atol = linesearch->atol;
1129: }
1130: if (ltol) {
1132: *ltol = linesearch->ltol;
1133: }
1134: if (max_its) {
1136: *max_its = linesearch->max_its;
1137: }
1138: return(0);
1139: }
1141: /*@
1142: SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include
1143: tolerances for the relative and absolute change in the function norm, the change
1144: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1145: and the maximum number of iterations the line search procedure may take.
1147: Input Parameters:
1148: + linesearch - linesearch context
1149: . steptol - The minimum steplength
1150: . maxstep - The maximum steplength
1151: . rtol - The relative tolerance for iterative line searches
1152: . atol - The absolute tolerance for iterative line searches
1153: . ltol - The change in lambda tolerance for iterative line searches
1154: - max_it - The maximum number of iterations of the line search
1156: Notes:
1157: The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1158: place of an argument.
1160: Level: intermediate
1162: .seealso: SNESLineSearchGetTolerances()
1163: @*/
1164: PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1165: {
1175: if (steptol!= PETSC_DEFAULT) {
1176: if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
1177: linesearch->steptol = steptol;
1178: }
1180: if (maxstep!= PETSC_DEFAULT) {
1181: if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1182: linesearch->maxstep = maxstep;
1183: }
1185: if (rtol != PETSC_DEFAULT) {
1186: 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);
1187: linesearch->rtol = rtol;
1188: }
1190: if (atol != PETSC_DEFAULT) {
1191: if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1192: linesearch->atol = atol;
1193: }
1195: if (ltol != PETSC_DEFAULT) {
1196: if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Lambda tolerance %14.12e must be non-negative",(double)ltol);
1197: linesearch->ltol = ltol;
1198: }
1200: if (max_its != PETSC_DEFAULT) {
1201: if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1202: linesearch->max_its = max_its;
1203: }
1204: return(0);
1205: }
1207: /*@
1208: SNESLineSearchGetDamping - Gets the line search damping parameter.
1210: Input Parameters:
1211: . linesearch - linesearch context
1213: Output Parameters:
1214: . damping - The damping parameter
1216: Level: advanced
1218: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1219: @*/
1221: PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1222: {
1226: *damping = linesearch->damping;
1227: return(0);
1228: }
1230: /*@
1231: SNESLineSearchSetDamping - Sets the line search damping parameter.
1233: Input Parameters:
1234: + linesearch - linesearch context
1235: - damping - The damping parameter
1237: Options Database:
1238: . -snes_linesearch_damping
1239: Level: intermediate
1241: Notes:
1242: The basic line search merely takes the update step scaled by the damping parameter.
1243: The use of the damping parameter in the l2 and cp line searches is much more subtle;
1244: it is used as a starting point in calculating the secant step. However, the eventual
1245: step may be of greater length than the damping parameter. In the bt line search it is
1246: used as the maximum possible step length, as the bt line search only backtracks.
1248: .seealso: SNESLineSearchGetDamping()
1249: @*/
1250: PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1251: {
1254: linesearch->damping = damping;
1255: return(0);
1256: }
1258: /*@
1259: SNESLineSearchGetOrder - Gets the line search approximation order.
1261: Input Parameters:
1262: . linesearch - linesearch context
1264: Output Parameters:
1265: . order - The order
1267: Possible Values for order:
1268: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1269: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1270: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1272: Level: intermediate
1274: .seealso: SNESLineSearchSetOrder()
1275: @*/
1277: PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1278: {
1282: *order = linesearch->order;
1283: return(0);
1284: }
1286: /*@
1287: SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
1289: Input Parameters:
1290: + linesearch - linesearch context
1291: - order - The damping parameter
1293: Level: intermediate
1295: Possible Values for order:
1296: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1297: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1298: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1300: Notes:
1301: Variable orders are supported by the following line searches:
1302: + bt - cubic and quadratic
1303: - cp - linear and quadratic
1305: .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1306: @*/
1307: PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1308: {
1311: linesearch->order = order;
1312: return(0);
1313: }
1315: /*@
1316: SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1318: Input Parameter:
1319: . linesearch - linesearch context
1321: Output Parameters:
1322: + xnorm - The norm of the current solution
1323: . fnorm - The norm of the current function
1324: - ynorm - The norm of the current update
1326: Notes:
1327: This function is mainly called from SNES implementations.
1329: Level: developer
1331: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1332: @*/
1333: PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1334: {
1337: if (xnorm) *xnorm = linesearch->xnorm;
1338: if (fnorm) *fnorm = linesearch->fnorm;
1339: if (ynorm) *ynorm = linesearch->ynorm;
1340: return(0);
1341: }
1343: /*@
1344: SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1346: Input Parameters:
1347: + linesearch - linesearch context
1348: . xnorm - The norm of the current solution
1349: . fnorm - The norm of the current function
1350: - ynorm - The norm of the current update
1352: Level: advanced
1354: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1355: @*/
1356: PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1357: {
1360: linesearch->xnorm = xnorm;
1361: linesearch->fnorm = fnorm;
1362: linesearch->ynorm = ynorm;
1363: return(0);
1364: }
1366: /*@
1367: SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1369: Input Parameters:
1370: . linesearch - linesearch context
1372: Options Database Keys:
1373: . -snes_linesearch_norms - turn norm computation on or off
1375: Level: intermediate
1377: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1378: @*/
1379: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1380: {
1382: SNES snes;
1385: if (linesearch->norms) {
1386: if (linesearch->ops->vinorm) {
1387: SNESLineSearchGetSNES(linesearch, &snes);
1388: VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1389: VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1390: (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1391: } else {
1392: VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1393: VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1394: VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1395: VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1396: VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1397: VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1398: }
1399: }
1400: return(0);
1401: }
1403: /*@
1404: SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
1406: Input Parameters:
1407: + linesearch - linesearch context
1408: - flg - indicates whether or not to compute norms
1410: Options Database Keys:
1411: . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch
1413: Notes:
1414: This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm.
1416: Level: intermediate
1418: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1419: @*/
1420: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1421: {
1423: linesearch->norms = flg;
1424: return(0);
1425: }
1427: /*@
1428: SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1430: Input Parameter:
1431: . linesearch - linesearch context
1433: Output Parameters:
1434: + X - Solution vector
1435: . F - Function vector
1436: . Y - Search direction vector
1437: . W - Solution work vector
1438: - G - Function work vector
1440: Notes:
1441: At the beginning of a line search application, X should contain a
1442: solution and the vector F the function computed at X. At the end of the
1443: line search application, X should contain the new solution, and F the
1444: function evaluated at the new solution.
1446: These vectors are owned by the SNESLineSearch and should not be destroyed by the caller
1448: Level: advanced
1450: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1451: @*/
1452: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1453: {
1456: if (X) {
1458: *X = linesearch->vec_sol;
1459: }
1460: if (F) {
1462: *F = linesearch->vec_func;
1463: }
1464: if (Y) {
1466: *Y = linesearch->vec_update;
1467: }
1468: if (W) {
1470: *W = linesearch->vec_sol_new;
1471: }
1472: if (G) {
1474: *G = linesearch->vec_func_new;
1475: }
1476: return(0);
1477: }
1479: /*@
1480: SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1482: Input Parameters:
1483: + linesearch - linesearch context
1484: . X - Solution vector
1485: . F - Function vector
1486: . Y - Search direction vector
1487: . W - Solution work vector
1488: - G - Function work vector
1490: Level: advanced
1492: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1493: @*/
1494: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1495: {
1498: if (X) {
1500: linesearch->vec_sol = X;
1501: }
1502: if (F) {
1504: linesearch->vec_func = F;
1505: }
1506: if (Y) {
1508: linesearch->vec_update = Y;
1509: }
1510: if (W) {
1512: linesearch->vec_sol_new = W;
1513: }
1514: if (G) {
1516: linesearch->vec_func_new = G;
1517: }
1518: return(0);
1519: }
1521: /*@C
1522: SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1523: SNES options in the database.
1525: Logically Collective on SNESLineSearch
1527: Input Parameters:
1528: + snes - the SNES context
1529: - prefix - the prefix to prepend to all option names
1531: Notes:
1532: A hyphen (-) must NOT be given at the beginning of the prefix name.
1533: The first character of all runtime options is AUTOMATICALLY the hyphen.
1535: Level: advanced
1537: .seealso: SNESGetOptionsPrefix()
1538: @*/
1539: PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1540: {
1545: PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1546: return(0);
1547: }
1549: /*@C
1550: SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1551: SNESLineSearch options in the database.
1553: Not Collective
1555: Input Parameter:
1556: . linesearch - the SNESLineSearch context
1558: Output Parameter:
1559: . prefix - pointer to the prefix string used
1561: Notes:
1562: On the fortran side, the user should pass in a string 'prefix' of
1563: sufficient length to hold the prefix.
1565: Level: advanced
1567: .seealso: SNESAppendOptionsPrefix()
1568: @*/
1569: PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1570: {
1575: PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1576: return(0);
1577: }
1579: /*@C
1580: SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1582: Input Parameters:
1583: + linesearch - the SNESLineSearch context
1584: - nwork - the number of work vectors
1586: Level: developer
1588: .seealso: SNESSetWorkVecs()
1589: @*/
1590: PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1591: {
1595: if (linesearch->vec_sol) {
1596: VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1597: } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1598: return(0);
1599: }
1601: /*@
1602: SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1604: Input Parameters:
1605: . linesearch - linesearch context
1607: Output Parameters:
1608: . result - The success or failure status
1610: Notes:
1611: This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1612: (and set the SNES convergence accordingly).
1614: Level: intermediate
1616: .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1617: @*/
1618: PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1619: {
1623: *result = linesearch->result;
1624: return(0);
1625: }
1627: /*@
1628: SNESLineSearchSetReason - Sets the success/failure status of the last line search application
1630: Input Parameters:
1631: + linesearch - linesearch context
1632: - result - The success or failure status
1634: Notes:
1635: This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1636: the success or failure of the line search method.
1638: Level: developer
1640: .seealso: SNESLineSearchGetSResult()
1641: @*/
1642: PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1643: {
1646: linesearch->result = result;
1647: return(0);
1648: }
1650: /*@C
1651: SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
1653: Input Parameters:
1654: + snes - nonlinear context obtained from SNESCreate()
1655: . projectfunc - function for projecting the function to the bounds
1656: - normfunc - function for computing the norm of an active set
1658: Logically Collective on SNES
1660: Calling sequence of projectfunc:
1661: .vb
1662: projectfunc (SNES snes, Vec X)
1663: .ve
1665: Input parameters for projectfunc:
1666: + snes - nonlinear context
1667: - X - current solution
1669: Output parameters for projectfunc:
1670: . X - Projected solution
1672: Calling sequence of normfunc:
1673: .vb
1674: projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1675: .ve
1677: Input parameters for normfunc:
1678: + snes - nonlinear context
1679: . X - current solution
1680: - F - current residual
1682: Output parameters for normfunc:
1683: . fnorm - VI-specific norm of the function
1685: Notes:
1686: The VI solvers require projection of the solution to the feasible set. projectfunc should implement this.
1688: The VI solvers require special evaluation of the function norm such that the norm is only calculated
1689: on the inactive set. This should be implemented by normfunc.
1691: Level: developer
1693: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1694: @*/
1695: PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1696: {
1699: if (projectfunc) linesearch->ops->viproject = projectfunc;
1700: if (normfunc) linesearch->ops->vinorm = normfunc;
1701: return(0);
1702: }
1704: /*@C
1705: SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
1707: Input Parameter:
1708: . linesearch - the line search context, obtain with SNESGetLineSearch()
1710: Output Parameters:
1711: + projectfunc - function for projecting the function to the bounds
1712: - normfunc - function for computing the norm of an active set
1714: Logically Collective on SNES
1716: Level: developer
1718: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1719: @*/
1720: PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1721: {
1723: if (projectfunc) *projectfunc = linesearch->ops->viproject;
1724: if (normfunc) *normfunc = linesearch->ops->vinorm;
1725: return(0);
1726: }
1728: /*@C
1729: SNESLineSearchRegister - See SNESLineSearchRegister()
1731: Level: advanced
1732: @*/
1733: PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1734: {
1738: SNESInitializePackage();
1739: PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1740: return(0);
1741: }