Actual source code: linesearch.c
petsc-3.12.5 2020-03-29
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: *outlinesearch = linesearch;
210: return(0);
211: }
213: /*@
214: SNESLineSearchSetUp - Prepares the line search for being applied by allocating
215: any required vectors.
217: Collective on SNESLineSearch
219: Input Parameters:
220: . linesearch - The LineSearch instance.
222: Notes:
223: For most cases, this needn't be called by users or outside of SNESLineSearchApply().
224: The only current case where this is called outside of this is for the VI
225: solvers, which modify the solution and work vectors before the first call
226: of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be
227: allocated upfront.
229: Level: advanced
231: .seealso: SNESGetLineSearch(), SNESLineSearchReset()
232: @*/
234: PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
235: {
239: if (!((PetscObject)linesearch)->type_name) {
240: SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);
241: }
242: if (!linesearch->setupcalled) {
243: if (!linesearch->vec_sol_new) {
244: VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);
245: }
246: if (!linesearch->vec_func_new) {
247: VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);
248: }
249: if (linesearch->ops->setup) {
250: (*linesearch->ops->setup)(linesearch);
251: }
252: if (!linesearch->ops->snesfunc) {SNESLineSearchSetFunction(linesearch,SNESComputeFunction);}
253: linesearch->lambda = linesearch->damping;
254: linesearch->setupcalled = PETSC_TRUE;
255: }
256: return(0);
257: }
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 Parameters:
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 Parameters:
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 Arguments:
480: + linesearch - linesearch context
481: . X - base state for this step
482: . Y - initial correction
483: - ctx - context for this function
485: Output Arguments:
486: + Y - correction, possibly modified
487: - changed - flag indicating that Y was modified
489: Options Database Key:
490: + -snes_linesearch_precheck_picard - activate this routine
491: - -snes_linesearch_precheck_picard_angle - angle
493: Level: advanced
495: Notes:
496: This function should be passed to SNESLineSearchSetPreCheck()
498: The justification for this method involves the linear convergence of a Picard iteration
499: so the Picard linearization should be provided in place of the "Jacobian". This correction
500: is generally not useful when using a Newton linearization.
502: Reference:
503: Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.
505: .seealso: SNESGetLineSearch(), SNESLineSearchSetPreCheck()
506: @*/
507: PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
508: {
510: PetscReal angle = *(PetscReal*)linesearch->precheckctx;
511: Vec Ylast;
512: PetscScalar dot;
513: PetscInt iter;
514: PetscReal ynorm,ylastnorm,theta,angle_radians;
515: SNES snes;
518: SNESLineSearchGetSNES(linesearch, &snes);
519: PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);
520: if (!Ylast) {
521: VecDuplicate(Y,&Ylast);
522: PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);
523: PetscObjectDereference((PetscObject)Ylast);
524: }
525: SNESGetIterationNumber(snes,&iter);
526: if (iter < 2) {
527: VecCopy(Y,Ylast);
528: *changed = PETSC_FALSE;
529: return(0);
530: }
532: VecDot(Y,Ylast,&dot);
533: VecNorm(Y,NORM_2,&ynorm);
534: VecNorm(Ylast,NORM_2,&ylastnorm);
535: /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
536: theta = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
537: angle_radians = angle * PETSC_PI / 180.;
538: if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
539: /* Modify the step Y */
540: PetscReal alpha,ydiffnorm;
541: VecAXPY(Ylast,-1.0,Y);
542: VecNorm(Ylast,NORM_2,&ydiffnorm);
543: alpha = (ydiffnorm > .001*ylastnorm) ? ylastnorm / ydiffnorm : 1000.0;
544: VecCopy(Y,Ylast);
545: VecScale(Y,alpha);
546: 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);
547: *changed = PETSC_TRUE;
548: } else {
549: PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);
550: VecCopy(Y,Ylast);
551: *changed = PETSC_FALSE;
552: }
553: return(0);
554: }
556: /*@
557: SNESLineSearchApply - Computes the line-search update.
559: Collective on SNESLineSearch
561: Input Parameters:
562: + linesearch - The linesearch context
563: . X - The current solution
564: . F - The current function
565: . fnorm - The current norm
566: - Y - The search direction
568: Output Parameters:
569: + X - The new solution
570: . F - The new function
571: - fnorm - The new function norm
573: Options Database Keys:
574: + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell
575: . -snes_linesearch_monitor [:filename] - Print progress of line searches
576: . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping)
577: . -snes_linesearch_norms - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms())
578: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
579: - -snes_linesearch_max_it - The number of iterations for iterative line searches
581: Notes:
582: This is typically called from within a SNESSolve() implementation in order to
583: help with convergence of the nonlinear method. Various SNES types use line searches
584: in different ways, but the overarching theme is that a line search is used to determine
585: an optimal damping parameter of a step at each iteration of the method. Each
586: application of the line search may invoke SNESComputeFunction() several times, and
587: therefore may be fairly expensive.
589: Level: Intermediate
591: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(),
592: SNESLineSearchType, SNESLineSearchSetType()
593: @*/
594: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
595: {
604: linesearch->result = SNES_LINESEARCH_SUCCEEDED;
606: linesearch->vec_sol = X;
607: linesearch->vec_update = Y;
608: linesearch->vec_func = F;
610: SNESLineSearchSetUp(linesearch);
612: if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
614: if (fnorm) linesearch->fnorm = *fnorm;
615: else {
616: VecNorm(F, NORM_2, &linesearch->fnorm);
617: }
619: PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y);
621: (*linesearch->ops->apply)(linesearch);
623: PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y);
625: if (fnorm) *fnorm = linesearch->fnorm;
626: return(0);
627: }
629: /*@
630: SNESLineSearchDestroy - Destroys the line search instance.
632: Collective on SNESLineSearch
634: Input Parameters:
635: . linesearch - The linesearch context
637: Level: developer
639: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
640: @*/
641: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
642: {
646: if (!*linesearch) return(0);
648: if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; return(0);}
649: PetscObjectSAWsViewOff((PetscObject)*linesearch);
650: SNESLineSearchReset(*linesearch);
651: if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
652: PetscViewerDestroy(&(*linesearch)->monitor);
653: SNESLineSearchMonitorCancel((*linesearch));
654: PetscHeaderDestroy(linesearch);
655: return(0);
656: }
658: /*@
659: SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.
661: Input Parameters:
662: + linesearch - the linesearch object
663: - viewer - an ASCII PetscViewer or NULL to turn off monitor
665: Logically Collective on SNESLineSearch
667: Options Database:
668: . -snes_linesearch_monitor [:filename] - enables the monitor
670: Level: intermediate
672: Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with
673: SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the
674: line search that are not visible to the other monitors.
676: .seealso: SNESGetLineSearch(), SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor()
677: @*/
678: PetscErrorCode SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
679: {
683: if (viewer) {PetscObjectReference((PetscObject)viewer);}
684: PetscViewerDestroy(&linesearch->monitor);
685: linesearch->monitor = viewer;
686: return(0);
687: }
689: /*@
690: SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.
692: Input Parameter:
693: . linesearch - linesearch context
695: Output Parameter:
696: . monitor - monitor context
698: Logically Collective on SNES
700: Options Database Keys:
701: . -snes_linesearch_monitor - enables the monitor
703: Level: intermediate
705: .seealso: SNESGetLineSearch(), SNESLineSearchSetDefaultMonitor(), PetscViewer
706: @*/
707: PetscErrorCode SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
708: {
711: if (monitor) {
713: *monitor = linesearch->monitor;
714: }
715: return(0);
716: }
718: /*@C
719: SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
721: Collective on SNESLineSearch
723: Input Parameters:
724: + ls - LineSearch object you wish to monitor
725: . name - the monitor type one is seeking
726: . help - message indicating what monitoring is done
727: . manual - manual page for the monitor
728: . monitor - the monitor function
729: - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the SNESLineSearch or PetscViewer objects
731: Level: developer
733: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
734: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
735: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
736: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
737: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
738: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
739: PetscOptionsFList(), PetscOptionsEList()
740: @*/
741: PetscErrorCode SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
742: {
743: PetscErrorCode ierr;
744: PetscViewer viewer;
745: PetscViewerFormat format;
746: PetscBool flg;
749: PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject) ls)->options,((PetscObject)ls)->prefix,name,&viewer,&format,&flg);
750: if (flg) {
751: PetscViewerAndFormat *vf;
752: PetscViewerAndFormatCreate(viewer,format,&vf);
753: PetscObjectDereference((PetscObject)viewer);
754: if (monitorsetup) {
755: (*monitorsetup)(ls,vf);
756: }
757: SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
758: }
759: return(0);
760: }
762: /*@
763: SNESLineSearchSetFromOptions - Sets options for the line search
765: Input Parameters:
766: . linesearch - linesearch context
768: Options Database Keys:
769: + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
770: . -snes_linesearch_order <order> - 1, 2, 3. Most types only support certain orders (bt supports 2 or 3)
771: . -snes_linesearch_norms - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms())
772: . -snes_linesearch_minlambda - The minimum step length
773: . -snes_linesearch_maxstep - The maximum step size
774: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
775: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
776: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
777: . -snes_linesearch_max_it - The number of iterations for iterative line searches
778: . -snes_linesearch_monitor [:filename] - Print progress of line searches
779: . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
780: . -snes_linesearch_damping - The linesearch damping parameter
781: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
782: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
783: - -snes_linesearch_precheck_picard_angle - Angle used in Picard precheck method
785: Logically Collective on SNESLineSearch
787: Level: intermediate
789: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(),
790: SNESLineSearchType, SNESLineSearchSetComputeNorms()
791: @*/
792: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
793: {
794: PetscErrorCode ierr;
795: const char *deft = SNESLINESEARCHBASIC;
796: char type[256];
797: PetscBool flg, set;
798: PetscViewer viewer;
801: SNESLineSearchRegisterAll();
803: PetscObjectOptionsBegin((PetscObject)linesearch);
804: if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
805: PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
806: if (flg) {
807: SNESLineSearchSetType(linesearch,type);
808: } else if (!((PetscObject)linesearch)->type_name) {
809: SNESLineSearchSetType(linesearch,deft);
810: }
812: PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject) linesearch)->options,((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);
813: if (set) {
814: SNESLineSearchSetDefaultMonitor(linesearch,viewer);
815: PetscViewerDestroy(&viewer);
816: }
817: SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);
819: /* tolerances */
820: PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);
821: PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);
822: PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);
823: PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);
824: PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);
825: PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);
827: /* damping parameters */
828: PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);
830: PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL);
832: /* precheck */
833: PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);
834: if (set) {
835: if (flg) {
836: linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
838: PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
839: "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);
840: SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
841: } else {
842: SNESLineSearchSetPreCheck(linesearch,NULL,NULL);
843: }
844: }
845: PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);
846: PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);
848: if (linesearch->ops->setfromoptions) {
849: (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);
850: }
852: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);
853: PetscOptionsEnd();
854: return(0);
855: }
857: /*@
858: SNESLineSearchView - Prints useful information about the line search
860: Input Parameters:
861: . linesearch - linesearch context
863: Logically Collective on SNESLineSearch
865: Level: intermediate
867: .seealso: SNESLineSearchCreate()
868: @*/
869: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
870: {
872: PetscBool iascii;
876: if (!viewer) {
877: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);
878: }
882: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
883: if (iascii) {
884: PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);
885: if (linesearch->ops->view) {
886: PetscViewerASCIIPushTab(viewer);
887: (*linesearch->ops->view)(linesearch,viewer);
888: PetscViewerASCIIPopTab(viewer);
889: }
890: PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);
891: PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);
892: PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", linesearch->max_its);
893: if (linesearch->ops->precheck) {
894: if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
895: PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n", linesearch->max_its);
896: } else {
897: PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n", linesearch->max_its);
898: }
899: }
900: if (linesearch->ops->postcheck) {
901: PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n", linesearch->max_its);
902: }
903: }
904: return(0);
905: }
907: /*@C
908: SNESLineSearchSetType - Sets the linesearch type
910: Logically Collective on SNESLineSearch
912: Input Parameters:
913: + linesearch - linesearch context
914: - type - The type of line search to be used
916: Available Types:
917: + SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
918: . SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
919: . SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
920: . SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
921: . SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
922: - SNESLINESEARCHSHELL - User provided SNESLineSearch implementation
924: Options Database:
925: . -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
927: Level: intermediate
929: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions()
930: @*/
931: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
932: {
933: PetscErrorCode ierr,(*r)(SNESLineSearch);
934: PetscBool match;
940: PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
941: if (match) return(0);
943: PetscFunctionListFind(SNESLineSearchList,type,&r);
944: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
945: /* Destroy the previous private linesearch context */
946: if (linesearch->ops->destroy) {
947: (*(linesearch)->ops->destroy)(linesearch);
949: linesearch->ops->destroy = NULL;
950: }
951: /* Reinitialize function pointers in SNESLineSearchOps structure */
952: linesearch->ops->apply = 0;
953: linesearch->ops->view = 0;
954: linesearch->ops->setfromoptions = 0;
955: linesearch->ops->destroy = 0;
957: PetscObjectChangeTypeName((PetscObject)linesearch,type);
958: (*r)(linesearch);
959: return(0);
960: }
962: /*@
963: SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
965: Input Parameters:
966: + linesearch - linesearch context
967: - snes - The snes instance
969: Level: developer
971: Notes:
972: This happens automatically when the line search is obtained/created with
973: SNESGetLineSearch(). This routine is therefore mainly called within SNES
974: implementations.
976: Level: developer
978: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
979: @*/
980: PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
981: {
985: linesearch->snes = snes;
986: return(0);
987: }
989: /*@
990: SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
991: Having an associated SNES is necessary because most line search implementations must be able to
992: evaluate the function using SNESComputeFunction() for the associated SNES. This routine
993: is used in the line search implementations when one must get this associated SNES instance.
995: Input Parameters:
996: . linesearch - linesearch context
998: Output Parameters:
999: . snes - The snes instance
1001: Level: developer
1003: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1004: @*/
1005: PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1006: {
1010: *snes = linesearch->snes;
1011: return(0);
1012: }
1014: /*@
1015: SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
1017: Input Parameters:
1018: . linesearch - linesearch context
1020: Output Parameters:
1021: . lambda - The last steplength computed during SNESLineSearchApply()
1023: Level: advanced
1025: Notes:
1026: This is useful in methods where the solver is ill-scaled and
1027: requires some adaptive notion of the difference in scale between the
1028: solution and the function. For instance, SNESQN may be scaled by the
1029: line search lambda using the argument -snes_qn_scaling ls.
1031: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1032: @*/
1033: PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1034: {
1038: *lambda = linesearch->lambda;
1039: return(0);
1040: }
1042: /*@
1043: SNESLineSearchSetLambda - Sets the linesearch steplength.
1045: Input Parameters:
1046: + linesearch - linesearch context
1047: - lambda - The last steplength.
1049: Notes:
1050: This routine is typically used within implementations of SNESLineSearchApply()
1051: to set the final steplength. This routine (and SNESLineSearchGetLambda()) were
1052: added in order to facilitate Quasi-Newton methods that use the previous steplength
1053: as an inner scaling parameter.
1055: Level: advanced
1057: .seealso: SNESLineSearchGetLambda()
1058: @*/
1059: PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1060: {
1063: linesearch->lambda = lambda;
1064: return(0);
1065: }
1067: /*@
1068: SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include
1069: tolerances for the relative and absolute change in the function norm, the change
1070: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1071: and the maximum number of iterations the line search procedure may take.
1073: Input Parameters:
1074: . linesearch - linesearch context
1076: Output Parameters:
1077: + steptol - The minimum steplength
1078: . maxstep - The maximum steplength
1079: . rtol - The relative tolerance for iterative line searches
1080: . atol - The absolute tolerance for iterative line searches
1081: . ltol - The change in lambda tolerance for iterative line searches
1082: - max_it - The maximum number of iterations of the line search
1084: Level: intermediate
1086: Notes:
1087: Different line searches may implement these parameters slightly differently as
1088: the type requires.
1090: .seealso: SNESLineSearchSetTolerances()
1091: @*/
1092: PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1093: {
1096: if (steptol) {
1098: *steptol = linesearch->steptol;
1099: }
1100: if (maxstep) {
1102: *maxstep = linesearch->maxstep;
1103: }
1104: if (rtol) {
1106: *rtol = linesearch->rtol;
1107: }
1108: if (atol) {
1110: *atol = linesearch->atol;
1111: }
1112: if (ltol) {
1114: *ltol = linesearch->ltol;
1115: }
1116: if (max_its) {
1118: *max_its = linesearch->max_its;
1119: }
1120: return(0);
1121: }
1123: /*@
1124: SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include
1125: tolerances for the relative and absolute change in the function norm, the change
1126: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1127: and the maximum number of iterations the line search procedure may take.
1129: Input Parameters:
1130: + linesearch - linesearch context
1131: . steptol - The minimum steplength
1132: . maxstep - The maximum steplength
1133: . rtol - The relative tolerance for iterative line searches
1134: . atol - The absolute tolerance for iterative line searches
1135: . ltol - The change in lambda tolerance for iterative line searches
1136: - max_it - The maximum number of iterations of the line search
1138: Notes:
1139: The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1140: place of an argument.
1142: Level: intermediate
1144: .seealso: SNESLineSearchGetTolerances()
1145: @*/
1146: PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1147: {
1157: if (steptol!= PETSC_DEFAULT) {
1158: if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
1159: linesearch->steptol = steptol;
1160: }
1162: if (maxstep!= PETSC_DEFAULT) {
1163: if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1164: linesearch->maxstep = maxstep;
1165: }
1167: if (rtol != PETSC_DEFAULT) {
1168: 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);
1169: linesearch->rtol = rtol;
1170: }
1172: if (atol != PETSC_DEFAULT) {
1173: if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1174: linesearch->atol = atol;
1175: }
1177: if (ltol != PETSC_DEFAULT) {
1178: if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %14.12e must be non-negative",(double)ltol);
1179: linesearch->ltol = ltol;
1180: }
1182: if (max_its != PETSC_DEFAULT) {
1183: if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1184: linesearch->max_its = max_its;
1185: }
1186: return(0);
1187: }
1189: /*@
1190: SNESLineSearchGetDamping - Gets the line search damping parameter.
1192: Input Parameters:
1193: . linesearch - linesearch context
1195: Output Parameters:
1196: . damping - The damping parameter
1198: Level: advanced
1200: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1201: @*/
1203: PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1204: {
1208: *damping = linesearch->damping;
1209: return(0);
1210: }
1212: /*@
1213: SNESLineSearchSetDamping - Sets the line search damping paramter.
1215: Input Parameters:
1216: + linesearch - linesearch context
1217: - damping - The damping parameter
1219: Options Database:
1220: . -snes_linesearch_damping
1221: Level: intermediate
1223: Notes:
1224: The basic line search merely takes the update step scaled by the damping parameter.
1225: The use of the damping parameter in the l2 and cp line searches is much more subtle;
1226: it is used as a starting point in calculating the secant step. However, the eventual
1227: step may be of greater length than the damping parameter. In the bt line search it is
1228: used as the maximum possible step length, as the bt line search only backtracks.
1230: .seealso: SNESLineSearchGetDamping()
1231: @*/
1232: PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1233: {
1236: linesearch->damping = damping;
1237: return(0);
1238: }
1240: /*@
1241: SNESLineSearchGetOrder - Gets the line search approximation order.
1243: Input Parameters:
1244: . linesearch - linesearch context
1246: Output Parameters:
1247: . order - The order
1249: Possible Values for order:
1250: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1251: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1252: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1254: Level: intermediate
1256: .seealso: SNESLineSearchSetOrder()
1257: @*/
1259: PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1260: {
1264: *order = linesearch->order;
1265: return(0);
1266: }
1268: /*@
1269: SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
1271: Input Parameters:
1272: + linesearch - linesearch context
1273: - order - The damping parameter
1275: Level: intermediate
1277: Possible Values for order:
1278: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1279: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1280: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1282: Notes:
1283: Variable orders are supported by the following line searches:
1284: + bt - cubic and quadratic
1285: - cp - linear and quadratic
1287: .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1288: @*/
1289: PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1290: {
1293: linesearch->order = order;
1294: return(0);
1295: }
1297: /*@
1298: SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1300: Input Parameters:
1301: . linesearch - linesearch context
1303: Output Parameters:
1304: + xnorm - The norm of the current solution
1305: . fnorm - The norm of the current function
1306: - ynorm - The norm of the current update
1308: Notes:
1309: This function is mainly called from SNES implementations.
1311: Level: developer
1313: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1314: @*/
1315: PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1316: {
1319: if (xnorm) *xnorm = linesearch->xnorm;
1320: if (fnorm) *fnorm = linesearch->fnorm;
1321: if (ynorm) *ynorm = linesearch->ynorm;
1322: return(0);
1323: }
1325: /*@
1326: SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1328: Input Parameters:
1329: + linesearch - linesearch context
1330: . xnorm - The norm of the current solution
1331: . fnorm - The norm of the current function
1332: - ynorm - The norm of the current update
1334: Level: advanced
1336: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1337: @*/
1338: PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1339: {
1342: linesearch->xnorm = xnorm;
1343: linesearch->fnorm = fnorm;
1344: linesearch->ynorm = ynorm;
1345: return(0);
1346: }
1348: /*@
1349: SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1351: Input Parameters:
1352: . linesearch - linesearch context
1354: Options Database Keys:
1355: . -snes_linesearch_norms - turn norm computation on or off
1357: Level: intermediate
1359: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1360: @*/
1361: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1362: {
1364: SNES snes;
1367: if (linesearch->norms) {
1368: if (linesearch->ops->vinorm) {
1369: SNESLineSearchGetSNES(linesearch, &snes);
1370: VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1371: VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1372: (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1373: } else {
1374: VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1375: VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1376: VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1377: VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1378: VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1379: VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1380: }
1381: }
1382: return(0);
1383: }
1385: /*@
1386: SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
1388: Input Parameters:
1389: + linesearch - linesearch context
1390: - flg - indicates whether or not to compute norms
1392: Options Database Keys:
1393: . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch
1395: Notes:
1396: This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm.
1398: Level: intermediate
1400: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1401: @*/
1402: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1403: {
1405: linesearch->norms = flg;
1406: return(0);
1407: }
1409: /*@
1410: SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1412: Input Parameters:
1413: . linesearch - linesearch context
1415: Output Parameters:
1416: + X - Solution vector
1417: . F - Function vector
1418: . Y - Search direction vector
1419: . W - Solution work vector
1420: - G - Function work vector
1422: Notes:
1423: At the beginning of a line search application, X should contain a
1424: solution and the vector F the function computed at X. At the end of the
1425: line search application, X should contain the new solution, and F the
1426: function evaluated at the new solution.
1428: These vectors are owned by the SNESLineSearch and should not be destroyed by the caller
1430: Level: advanced
1432: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1433: @*/
1434: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1435: {
1438: if (X) {
1440: *X = linesearch->vec_sol;
1441: }
1442: if (F) {
1444: *F = linesearch->vec_func;
1445: }
1446: if (Y) {
1448: *Y = linesearch->vec_update;
1449: }
1450: if (W) {
1452: *W = linesearch->vec_sol_new;
1453: }
1454: if (G) {
1456: *G = linesearch->vec_func_new;
1457: }
1458: return(0);
1459: }
1461: /*@
1462: SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1464: Input Parameters:
1465: + linesearch - linesearch context
1466: . X - Solution vector
1467: . F - Function vector
1468: . Y - Search direction vector
1469: . W - Solution work vector
1470: - G - Function work vector
1472: Level: advanced
1474: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1475: @*/
1476: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1477: {
1480: if (X) {
1482: linesearch->vec_sol = X;
1483: }
1484: if (F) {
1486: linesearch->vec_func = F;
1487: }
1488: if (Y) {
1490: linesearch->vec_update = Y;
1491: }
1492: if (W) {
1494: linesearch->vec_sol_new = W;
1495: }
1496: if (G) {
1498: linesearch->vec_func_new = G;
1499: }
1500: return(0);
1501: }
1503: /*@C
1504: SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1505: SNES options in the database.
1507: Logically Collective on SNESLineSearch
1509: Input Parameters:
1510: + snes - the SNES context
1511: - prefix - the prefix to prepend to all option names
1513: Notes:
1514: A hyphen (-) must NOT be given at the beginning of the prefix name.
1515: The first character of all runtime options is AUTOMATICALLY the hyphen.
1517: Level: advanced
1519: .seealso: SNESGetOptionsPrefix()
1520: @*/
1521: PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1522: {
1527: PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1528: return(0);
1529: }
1531: /*@C
1532: SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1533: SNESLineSearch options in the database.
1535: Not Collective
1537: Input Parameter:
1538: . linesearch - the SNESLineSearch context
1540: Output Parameter:
1541: . prefix - pointer to the prefix string used
1543: Notes:
1544: On the fortran side, the user should pass in a string 'prefix' of
1545: sufficient length to hold the prefix.
1547: Level: advanced
1549: .seealso: SNESAppendOptionsPrefix()
1550: @*/
1551: PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1552: {
1557: PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1558: return(0);
1559: }
1561: /*@C
1562: SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1564: Input Parameter:
1565: + linesearch - the SNESLineSearch context
1566: - nwork - the number of work vectors
1568: Level: developer
1570: .seealso: SNESSetWorkVecs()
1571: @*/
1572: PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1573: {
1577: if (linesearch->vec_sol) {
1578: VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1579: } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1580: return(0);
1581: }
1583: /*@
1584: SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1586: Input Parameters:
1587: . linesearch - linesearch context
1589: Output Parameters:
1590: . result - The success or failure status
1592: Notes:
1593: This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1594: (and set the SNES convergence accordingly).
1596: Level: intermediate
1598: .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1599: @*/
1600: PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1601: {
1605: *result = linesearch->result;
1606: return(0);
1607: }
1609: /*@
1610: SNESLineSearchSetReason - Sets the success/failure status of the last line search application
1612: Input Parameters:
1613: + linesearch - linesearch context
1614: - result - The success or failure status
1616: Notes:
1617: This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1618: the success or failure of the line search method.
1620: Level: developer
1622: .seealso: SNESLineSearchGetSResult()
1623: @*/
1624: PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1625: {
1628: linesearch->result = result;
1629: return(0);
1630: }
1632: /*@C
1633: SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
1635: Input Parameters:
1636: + snes - nonlinear context obtained from SNESCreate()
1637: . projectfunc - function for projecting the function to the bounds
1638: - normfunc - function for computing the norm of an active set
1640: Logically Collective on SNES
1642: Calling sequence of projectfunc:
1643: .vb
1644: projectfunc (SNES snes, Vec X)
1645: .ve
1647: Input parameters for projectfunc:
1648: + snes - nonlinear context
1649: - X - current solution
1651: Output parameters for projectfunc:
1652: . X - Projected solution
1654: Calling sequence of normfunc:
1655: .vb
1656: projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1657: .ve
1659: Input parameters for normfunc:
1660: + snes - nonlinear context
1661: . X - current solution
1662: - F - current residual
1664: Output parameters for normfunc:
1665: . fnorm - VI-specific norm of the function
1667: Notes:
1668: The VI solvers require projection of the solution to the feasible set. projectfunc should implement this.
1670: The VI solvers require special evaluation of the function norm such that the norm is only calculated
1671: on the inactive set. This should be implemented by normfunc.
1673: Level: developer
1675: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1676: @*/
1677: PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1678: {
1681: if (projectfunc) linesearch->ops->viproject = projectfunc;
1682: if (normfunc) linesearch->ops->vinorm = normfunc;
1683: return(0);
1684: }
1686: /*@C
1687: SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
1689: Input Parameters:
1690: . linesearch - the line search context, obtain with SNESGetLineSearch()
1692: Output Parameters:
1693: + projectfunc - function for projecting the function to the bounds
1694: - normfunc - function for computing the norm of an active set
1696: Logically Collective on SNES
1698: Level: developer
1700: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1701: @*/
1702: PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1703: {
1705: if (projectfunc) *projectfunc = linesearch->ops->viproject;
1706: if (normfunc) *normfunc = linesearch->ops->vinorm;
1707: return(0);
1708: }
1710: /*@C
1711: SNESLineSearchRegister - See SNESLineSearchRegister()
1713: Level: advanced
1714: @*/
1715: PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1716: {
1720: SNESInitializePackage();
1721: PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1722: return(0);
1723: }