Actual source code: linesearch.c
petsc-3.13.6 2020-09-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: Section 1.5 Writing Application Codes with PETSc 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: SNESLineSearchGetType - Gets the linesearch type
910: Logically Collective on SNESLineSearch
912: Input Parameters:
913: . linesearch - linesearch context
915: Output Parameters:
916: - type - The type of line search, or NULL if not set
918: Level: intermediate
920: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchSetType()
921: @*/
922: PetscErrorCode SNESLineSearchGetType(SNESLineSearch linesearch, SNESLineSearchType *type)
923: {
927: *type = ((PetscObject)linesearch)->type_name;
928: return(0);
929: }
931: /*@C
932: SNESLineSearchSetType - Sets the linesearch type
934: Logically Collective on SNESLineSearch
936: Input Parameters:
937: + linesearch - linesearch context
938: - type - The type of line search to be used
940: Available Types:
941: + SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
942: . SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
943: . SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
944: . SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
945: . SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
946: - SNESLINESEARCHSHELL - User provided SNESLineSearch implementation
948: Options Database:
949: . -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
951: Level: intermediate
953: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchGetType()
954: @*/
955: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
956: {
957: PetscErrorCode ierr,(*r)(SNESLineSearch);
958: PetscBool match;
964: PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
965: if (match) return(0);
967: PetscFunctionListFind(SNESLineSearchList,type,&r);
968: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
969: /* Destroy the previous private linesearch context */
970: if (linesearch->ops->destroy) {
971: (*(linesearch)->ops->destroy)(linesearch);
973: linesearch->ops->destroy = NULL;
974: }
975: /* Reinitialize function pointers in SNESLineSearchOps structure */
976: linesearch->ops->apply = 0;
977: linesearch->ops->view = 0;
978: linesearch->ops->setfromoptions = 0;
979: linesearch->ops->destroy = 0;
981: PetscObjectChangeTypeName((PetscObject)linesearch,type);
982: (*r)(linesearch);
983: return(0);
984: }
986: /*@
987: SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
989: Input Parameters:
990: + linesearch - linesearch context
991: - snes - The snes instance
993: Level: developer
995: Notes:
996: This happens automatically when the line search is obtained/created with
997: SNESGetLineSearch(). This routine is therefore mainly called within SNES
998: implementations.
1000: Level: developer
1002: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1003: @*/
1004: PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
1005: {
1009: linesearch->snes = snes;
1010: return(0);
1011: }
1013: /*@
1014: SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
1015: Having an associated SNES is necessary because most line search implementations must be able to
1016: evaluate the function using SNESComputeFunction() for the associated SNES. This routine
1017: is used in the line search implementations when one must get this associated SNES instance.
1019: Input Parameters:
1020: . linesearch - linesearch context
1022: Output Parameters:
1023: . snes - The snes instance
1025: Level: developer
1027: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1028: @*/
1029: PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1030: {
1034: *snes = linesearch->snes;
1035: return(0);
1036: }
1038: /*@
1039: SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
1041: Input Parameters:
1042: . linesearch - linesearch context
1044: Output Parameters:
1045: . lambda - The last steplength computed during SNESLineSearchApply()
1047: Level: advanced
1049: Notes:
1050: This is useful in methods where the solver is ill-scaled and
1051: requires some adaptive notion of the difference in scale between the
1052: solution and the function. For instance, SNESQN may be scaled by the
1053: line search lambda using the argument -snes_qn_scaling ls.
1055: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1056: @*/
1057: PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1058: {
1062: *lambda = linesearch->lambda;
1063: return(0);
1064: }
1066: /*@
1067: SNESLineSearchSetLambda - Sets the linesearch steplength.
1069: Input Parameters:
1070: + linesearch - linesearch context
1071: - lambda - The last steplength.
1073: Notes:
1074: This routine is typically used within implementations of SNESLineSearchApply()
1075: to set the final steplength. This routine (and SNESLineSearchGetLambda()) were
1076: added in order to facilitate Quasi-Newton methods that use the previous steplength
1077: as an inner scaling parameter.
1079: Level: advanced
1081: .seealso: SNESLineSearchGetLambda()
1082: @*/
1083: PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1084: {
1087: linesearch->lambda = lambda;
1088: return(0);
1089: }
1091: /*@
1092: SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include
1093: tolerances for the relative and absolute change in the function norm, the change
1094: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1095: and the maximum number of iterations the line search procedure may take.
1097: Input Parameters:
1098: . linesearch - linesearch context
1100: Output Parameters:
1101: + steptol - The minimum steplength
1102: . maxstep - The maximum steplength
1103: . rtol - The relative tolerance for iterative line searches
1104: . atol - The absolute tolerance for iterative line searches
1105: . ltol - The change in lambda tolerance for iterative line searches
1106: - max_it - The maximum number of iterations of the line search
1108: Level: intermediate
1110: Notes:
1111: Different line searches may implement these parameters slightly differently as
1112: the type requires.
1114: .seealso: SNESLineSearchSetTolerances()
1115: @*/
1116: PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1117: {
1120: if (steptol) {
1122: *steptol = linesearch->steptol;
1123: }
1124: if (maxstep) {
1126: *maxstep = linesearch->maxstep;
1127: }
1128: if (rtol) {
1130: *rtol = linesearch->rtol;
1131: }
1132: if (atol) {
1134: *atol = linesearch->atol;
1135: }
1136: if (ltol) {
1138: *ltol = linesearch->ltol;
1139: }
1140: if (max_its) {
1142: *max_its = linesearch->max_its;
1143: }
1144: return(0);
1145: }
1147: /*@
1148: SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include
1149: tolerances for the relative and absolute change in the function norm, the change
1150: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1151: and the maximum number of iterations the line search procedure may take.
1153: Input Parameters:
1154: + linesearch - linesearch context
1155: . steptol - The minimum steplength
1156: . maxstep - The maximum steplength
1157: . rtol - The relative tolerance for iterative line searches
1158: . atol - The absolute tolerance for iterative line searches
1159: . ltol - The change in lambda tolerance for iterative line searches
1160: - max_it - The maximum number of iterations of the line search
1162: Notes:
1163: The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1164: place of an argument.
1166: Level: intermediate
1168: .seealso: SNESLineSearchGetTolerances()
1169: @*/
1170: PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1171: {
1181: if (steptol!= PETSC_DEFAULT) {
1182: if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
1183: linesearch->steptol = steptol;
1184: }
1186: if (maxstep!= PETSC_DEFAULT) {
1187: if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1188: linesearch->maxstep = maxstep;
1189: }
1191: if (rtol != PETSC_DEFAULT) {
1192: 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);
1193: linesearch->rtol = rtol;
1194: }
1196: if (atol != PETSC_DEFAULT) {
1197: if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1198: linesearch->atol = atol;
1199: }
1201: if (ltol != PETSC_DEFAULT) {
1202: if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %14.12e must be non-negative",(double)ltol);
1203: linesearch->ltol = ltol;
1204: }
1206: if (max_its != PETSC_DEFAULT) {
1207: if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1208: linesearch->max_its = max_its;
1209: }
1210: return(0);
1211: }
1213: /*@
1214: SNESLineSearchGetDamping - Gets the line search damping parameter.
1216: Input Parameters:
1217: . linesearch - linesearch context
1219: Output Parameters:
1220: . damping - The damping parameter
1222: Level: advanced
1224: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1225: @*/
1227: PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1228: {
1232: *damping = linesearch->damping;
1233: return(0);
1234: }
1236: /*@
1237: SNESLineSearchSetDamping - Sets the line search damping parameter.
1239: Input Parameters:
1240: + linesearch - linesearch context
1241: - damping - The damping parameter
1243: Options Database:
1244: . -snes_linesearch_damping
1245: Level: intermediate
1247: Notes:
1248: The basic line search merely takes the update step scaled by the damping parameter.
1249: The use of the damping parameter in the l2 and cp line searches is much more subtle;
1250: it is used as a starting point in calculating the secant step. However, the eventual
1251: step may be of greater length than the damping parameter. In the bt line search it is
1252: used as the maximum possible step length, as the bt line search only backtracks.
1254: .seealso: SNESLineSearchGetDamping()
1255: @*/
1256: PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1257: {
1260: linesearch->damping = damping;
1261: return(0);
1262: }
1264: /*@
1265: SNESLineSearchGetOrder - Gets the line search approximation order.
1267: Input Parameters:
1268: . linesearch - linesearch context
1270: Output Parameters:
1271: . order - The order
1273: Possible Values for order:
1274: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1275: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1276: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1278: Level: intermediate
1280: .seealso: SNESLineSearchSetOrder()
1281: @*/
1283: PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1284: {
1288: *order = linesearch->order;
1289: return(0);
1290: }
1292: /*@
1293: SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
1295: Input Parameters:
1296: + linesearch - linesearch context
1297: - order - The damping parameter
1299: Level: intermediate
1301: Possible Values for order:
1302: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1303: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1304: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1306: Notes:
1307: Variable orders are supported by the following line searches:
1308: + bt - cubic and quadratic
1309: - cp - linear and quadratic
1311: .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1312: @*/
1313: PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1314: {
1317: linesearch->order = order;
1318: return(0);
1319: }
1321: /*@
1322: SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1324: Input Parameters:
1325: . linesearch - linesearch context
1327: Output Parameters:
1328: + xnorm - The norm of the current solution
1329: . fnorm - The norm of the current function
1330: - ynorm - The norm of the current update
1332: Notes:
1333: This function is mainly called from SNES implementations.
1335: Level: developer
1337: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1338: @*/
1339: PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1340: {
1343: if (xnorm) *xnorm = linesearch->xnorm;
1344: if (fnorm) *fnorm = linesearch->fnorm;
1345: if (ynorm) *ynorm = linesearch->ynorm;
1346: return(0);
1347: }
1349: /*@
1350: SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1352: Input Parameters:
1353: + linesearch - linesearch context
1354: . xnorm - The norm of the current solution
1355: . fnorm - The norm of the current function
1356: - ynorm - The norm of the current update
1358: Level: advanced
1360: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1361: @*/
1362: PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1363: {
1366: linesearch->xnorm = xnorm;
1367: linesearch->fnorm = fnorm;
1368: linesearch->ynorm = ynorm;
1369: return(0);
1370: }
1372: /*@
1373: SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1375: Input Parameters:
1376: . linesearch - linesearch context
1378: Options Database Keys:
1379: . -snes_linesearch_norms - turn norm computation on or off
1381: Level: intermediate
1383: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1384: @*/
1385: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1386: {
1388: SNES snes;
1391: if (linesearch->norms) {
1392: if (linesearch->ops->vinorm) {
1393: SNESLineSearchGetSNES(linesearch, &snes);
1394: VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1395: VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1396: (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1397: } else {
1398: VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1399: VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1400: VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1401: VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1402: VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1403: VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1404: }
1405: }
1406: return(0);
1407: }
1409: /*@
1410: SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
1412: Input Parameters:
1413: + linesearch - linesearch context
1414: - flg - indicates whether or not to compute norms
1416: Options Database Keys:
1417: . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch
1419: Notes:
1420: This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm.
1422: Level: intermediate
1424: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1425: @*/
1426: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1427: {
1429: linesearch->norms = flg;
1430: return(0);
1431: }
1433: /*@
1434: SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1436: Input Parameters:
1437: . linesearch - linesearch context
1439: Output Parameters:
1440: + X - Solution vector
1441: . F - Function vector
1442: . Y - Search direction vector
1443: . W - Solution work vector
1444: - G - Function work vector
1446: Notes:
1447: At the beginning of a line search Section 1.5 Writing Application Codes with PETSc, X should contain a
1448: solution and the vector F the function computed at X. At the end of the
1449: line search Section 1.5 Writing Application Codes with PETSc, X should contain the new solution, and F the
1450: function evaluated at the new solution.
1452: These vectors are owned by the SNESLineSearch and should not be destroyed by the caller
1454: Level: advanced
1456: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1457: @*/
1458: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1459: {
1462: if (X) {
1464: *X = linesearch->vec_sol;
1465: }
1466: if (F) {
1468: *F = linesearch->vec_func;
1469: }
1470: if (Y) {
1472: *Y = linesearch->vec_update;
1473: }
1474: if (W) {
1476: *W = linesearch->vec_sol_new;
1477: }
1478: if (G) {
1480: *G = linesearch->vec_func_new;
1481: }
1482: return(0);
1483: }
1485: /*@
1486: SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1488: Input Parameters:
1489: + linesearch - linesearch context
1490: . X - Solution vector
1491: . F - Function vector
1492: . Y - Search direction vector
1493: . W - Solution work vector
1494: - G - Function work vector
1496: Level: advanced
1498: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1499: @*/
1500: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1501: {
1504: if (X) {
1506: linesearch->vec_sol = X;
1507: }
1508: if (F) {
1510: linesearch->vec_func = F;
1511: }
1512: if (Y) {
1514: linesearch->vec_update = Y;
1515: }
1516: if (W) {
1518: linesearch->vec_sol_new = W;
1519: }
1520: if (G) {
1522: linesearch->vec_func_new = G;
1523: }
1524: return(0);
1525: }
1527: /*@C
1528: SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1529: SNES options in the database.
1531: Logically Collective on SNESLineSearch
1533: Input Parameters:
1534: + snes - the SNES context
1535: - prefix - the prefix to prepend to all option names
1537: Notes:
1538: A hyphen (-) must NOT be given at the beginning of the prefix name.
1539: The first character of all runtime options is AUTOMATICALLY the hyphen.
1541: Level: advanced
1543: .seealso: SNESGetOptionsPrefix()
1544: @*/
1545: PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1546: {
1551: PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1552: return(0);
1553: }
1555: /*@C
1556: SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1557: SNESLineSearch options in the database.
1559: Not Collective
1561: Input Parameter:
1562: . linesearch - the SNESLineSearch context
1564: Output Parameter:
1565: . prefix - pointer to the prefix string used
1567: Notes:
1568: On the fortran side, the user should pass in a string 'prefix' of
1569: sufficient length to hold the prefix.
1571: Level: advanced
1573: .seealso: SNESAppendOptionsPrefix()
1574: @*/
1575: PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1576: {
1581: PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1582: return(0);
1583: }
1585: /*@C
1586: SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1588: Input Parameter:
1589: + linesearch - the SNESLineSearch context
1590: - nwork - the number of work vectors
1592: Level: developer
1594: .seealso: SNESSetWorkVecs()
1595: @*/
1596: PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1597: {
1601: if (linesearch->vec_sol) {
1602: VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1603: } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1604: return(0);
1605: }
1607: /*@
1608: SNESLineSearchGetReason - Gets the success/failure status of the last line search Section 1.5 Writing Application Codes with PETSc
1610: Input Parameters:
1611: . linesearch - linesearch context
1613: Output Parameters:
1614: . result - The success or failure status
1616: Notes:
1617: This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1618: (and set the SNES convergence accordingly).
1620: Level: intermediate
1622: .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1623: @*/
1624: PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1625: {
1629: *result = linesearch->result;
1630: return(0);
1631: }
1633: /*@
1634: SNESLineSearchSetReason - Sets the success/failure status of the last line search Section 1.5 Writing Application Codes with PETSc
1636: Input Parameters:
1637: + linesearch - linesearch context
1638: - result - The success or failure status
1640: Notes:
1641: This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1642: the success or failure of the line search method.
1644: Level: developer
1646: .seealso: SNESLineSearchGetSResult()
1647: @*/
1648: PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1649: {
1652: linesearch->result = result;
1653: return(0);
1654: }
1656: /*@C
1657: SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
1659: Input Parameters:
1660: + snes - nonlinear context obtained from SNESCreate()
1661: . projectfunc - function for projecting the function to the bounds
1662: - normfunc - function for computing the norm of an active set
1664: Logically Collective on SNES
1666: Calling sequence of projectfunc:
1667: .vb
1668: projectfunc (SNES snes, Vec X)
1669: .ve
1671: Input parameters for projectfunc:
1672: + snes - nonlinear context
1673: - X - current solution
1675: Output parameters for projectfunc:
1676: . X - Projected solution
1678: Calling sequence of normfunc:
1679: .vb
1680: projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1681: .ve
1683: Input parameters for normfunc:
1684: + snes - nonlinear context
1685: . X - current solution
1686: - F - current residual
1688: Output parameters for normfunc:
1689: . fnorm - VI-specific norm of the function
1691: Notes:
1692: The VI solvers require projection of the solution to the feasible set. projectfunc should implement this.
1694: The VI solvers require special evaluation of the function norm such that the norm is only calculated
1695: on the inactive set. This should be implemented by normfunc.
1697: Level: developer
1699: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1700: @*/
1701: PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1702: {
1705: if (projectfunc) linesearch->ops->viproject = projectfunc;
1706: if (normfunc) linesearch->ops->vinorm = normfunc;
1707: return(0);
1708: }
1710: /*@C
1711: SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
1713: Input Parameters:
1714: . linesearch - the line search context, obtain with SNESGetLineSearch()
1716: Output Parameters:
1717: + projectfunc - function for projecting the function to the bounds
1718: - normfunc - function for computing the norm of an active set
1720: Logically Collective on SNES
1722: Level: developer
1724: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1725: @*/
1726: PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1727: {
1729: if (projectfunc) *projectfunc = linesearch->ops->viproject;
1730: if (normfunc) *normfunc = linesearch->ops->vinorm;
1731: return(0);
1732: }
1734: /*@C
1735: SNESLineSearchRegister - See SNESLineSearchRegister()
1737: Level: advanced
1738: @*/
1739: PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1740: {
1744: SNESInitializePackage();
1745: PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1746: return(0);
1747: }