Actual source code: linesearch.c
petsc-3.10.2 2018-10-09
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: .keywords: SNESLineSearch, nonlinear, set, monitor
32: .seealso: SNESGetLineSearch(), SNESLineSearchMonitorDefault(), SNESLineSearchMonitorSet()
33: @*/
34: PetscErrorCode SNESLineSearchMonitorCancel(SNESLineSearch ls)
35: {
37: PetscInt i;
41: for (i=0; i<ls->numbermonitors; i++) {
42: if (ls->monitordestroy[i]) {
43: (*ls->monitordestroy[i])(&ls->monitorcontext[i]);
44: }
45: }
46: ls->numbermonitors = 0;
47: return(0);
48: }
50: /*@
51: SNESLineSearchMonitor - runs the user provided monitor routines, if they exist
53: Collective on SNES
55: Input Parameters:
56: . ls - the linesearch object
58: Notes:
59: This routine is called by the SNES implementations.
60: It does not typically need to be called by the user.
62: Level: developer
64: .seealso: SNESGetLineSearch(), SNESLineSearchMonitorSet()
65: @*/
66: PetscErrorCode SNESLineSearchMonitor(SNESLineSearch ls)
67: {
69: PetscInt i,n = ls->numbermonitors;
72: for (i=0; i<n; i++) {
73: (*ls->monitorftns[i])(ls,ls->monitorcontext[i]);
74: }
75: return(0);
76: }
78: /*@C
79: SNESLineSearchMonitorSet - Sets an ADDITIONAL function that is to be used at every
80: iteration of the nonlinear solver to display the iteration's
81: progress.
83: Logically Collective on SNESLineSearch
85: Input Parameters:
86: + ls - the SNESLineSearch context
87: . f - the monitor function
88: . mctx - [optional] user-defined context for private data for the
89: monitor routine (use NULL if no context is desired)
90: - monitordestroy - [optional] routine that frees monitor context
91: (may be NULL)
93: Notes:
94: Several different monitoring routines may be set by calling
95: SNESLineSearchMonitorSet() multiple times; all will be called in the
96: order in which they were set.
98: Fortran Notes:
99: Only a single monitor function can be set for each SNESLineSearch object
101: Level: intermediate
103: .keywords: SNESLineSearch, nonlinear, set, monitor
105: .seealso: SNESGetLineSearch(), SNESLineSearchMonitorDefault(), SNESLineSearchMonitorCancel()
106: @*/
107: PetscErrorCode SNESLineSearchMonitorSet(SNESLineSearch ls,PetscErrorCode (*f)(SNESLineSearch,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
108: {
110: PetscInt i;
111: PetscBool identical;
115: for (i=0; i<ls->numbermonitors;i++) {
116: PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))ls->monitorftns[i],ls->monitorcontext[i],ls->monitordestroy[i],&identical);
117: if (identical) return(0);
118: }
119: if (ls->numbermonitors >= MAXSNESLSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
120: ls->monitorftns[ls->numbermonitors] = f;
121: ls->monitordestroy[ls->numbermonitors] = monitordestroy;
122: ls->monitorcontext[ls->numbermonitors++] = (void*)mctx;
123: return(0);
124: }
126: /*@C
127: SNESLineSearchMonitorSolutionUpdate - Monitors each update a new function value the linesearch tries
129: Collective on SNESLineSearch
131: Input Parameters:
132: + ls - the SNES linesearch object
133: - vf - the context for the monitor, in this case it is an ASCII PetscViewer and format
135: Level: intermediate
137: .keywords: SNES, nonlinear, default, monitor, norm
139: .seealso: SNESGetLineSearch(), SNESMonitorSet(), SNESMonitorSolution()
140: @*/
141: PetscErrorCode SNESLineSearchMonitorSolutionUpdate(SNESLineSearch ls,PetscViewerAndFormat *vf)
142: {
144: PetscViewer viewer = vf->viewer;
145: Vec Y,W,G;
148: SNESLineSearchGetVecs(ls,NULL,NULL,&Y,&W,&G);
149: PetscViewerPushFormat(viewer,vf->format);
150: PetscViewerASCIIPrintf(viewer,"LineSearch attempted update to solution \n");
151: VecView(Y,viewer);
152: PetscViewerASCIIPrintf(viewer,"LineSearch attempted new solution \n");
153: VecView(W,viewer);
154: PetscViewerASCIIPrintf(viewer,"LineSearch attempted updated function value\n");
155: VecView(G,viewer);
156: PetscViewerPopFormat(viewer);
157: return(0);
158: }
160: /*@
161: SNESLineSearchCreate - Creates the line search context.
163: Logically Collective on Comm
165: Input Parameters:
166: . comm - MPI communicator for the line search (typically from the associated SNES context).
168: Output Parameters:
169: . outlinesearch - the new linesearch context
171: Level: developer
173: Notes:
174: The preferred calling sequence for users is to use SNESGetLineSearch() to acquire the SNESLineSearch instance
175: already associated with the SNES. This function is for developer use.
177: .keywords: LineSearch, create, context
179: .seealso: LineSearchDestroy(), SNESGetLineSearch()
180: @*/
182: PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
183: {
185: SNESLineSearch linesearch;
189: SNESInitializePackage();
190: *outlinesearch = NULL;
192: PetscHeaderCreate(linesearch,SNESLINESEARCH_CLASSID, "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView);
194: linesearch->vec_sol_new = NULL;
195: linesearch->vec_func_new = NULL;
196: linesearch->vec_sol = NULL;
197: linesearch->vec_func = NULL;
198: linesearch->vec_update = NULL;
200: linesearch->lambda = 1.0;
201: linesearch->fnorm = 1.0;
202: linesearch->ynorm = 1.0;
203: linesearch->xnorm = 1.0;
204: linesearch->result = SNES_LINESEARCH_SUCCEEDED;
205: linesearch->norms = PETSC_TRUE;
206: linesearch->keeplambda = PETSC_FALSE;
207: linesearch->damping = 1.0;
208: linesearch->maxstep = 1e8;
209: linesearch->steptol = 1e-12;
210: linesearch->rtol = 1e-8;
211: linesearch->atol = 1e-15;
212: linesearch->ltol = 1e-8;
213: linesearch->precheckctx = NULL;
214: linesearch->postcheckctx = NULL;
215: linesearch->max_its = 1;
216: linesearch->setupcalled = PETSC_FALSE;
217: *outlinesearch = linesearch;
218: return(0);
219: }
221: /*@
222: SNESLineSearchSetUp - Prepares the line search for being applied by allocating
223: any required vectors.
225: Collective on SNESLineSearch
227: Input Parameters:
228: . linesearch - The LineSearch instance.
230: Notes:
231: For most cases, this needn't be called by users or outside of SNESLineSearchApply().
232: The only current case where this is called outside of this is for the VI
233: solvers, which modify the solution and work vectors before the first call
234: of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be
235: allocated upfront.
237: Level: advanced
239: .keywords: SNESLineSearch, SetUp
241: .seealso: SNESGetLineSearch(), SNESLineSearchReset()
242: @*/
244: PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
245: {
249: if (!((PetscObject)linesearch)->type_name) {
250: SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);
251: }
252: if (!linesearch->setupcalled) {
253: if (!linesearch->vec_sol_new) {
254: VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);
255: }
256: if (!linesearch->vec_func_new) {
257: VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);
258: }
259: if (linesearch->ops->setup) {
260: (*linesearch->ops->setup)(linesearch);
261: }
262: if (!linesearch->ops->snesfunc) {SNESLineSearchSetFunction(linesearch,SNESComputeFunction);}
263: linesearch->lambda = linesearch->damping;
264: linesearch->setupcalled = PETSC_TRUE;
265: }
266: return(0);
267: }
270: /*@
271: SNESLineSearchReset - Undoes the SNESLineSearchSetUp() and deletes any Vecs or Mats allocated by the line search.
273: Collective on SNESLineSearch
275: Input Parameters:
276: . linesearch - The LineSearch instance.
278: Notes:
279: Usually only called by SNESReset()
281: Level: developer
283: .keywords: SNESLineSearch, Reset
285: .seealso: SNESGetLineSearch(), SNESLineSearchSetUp()
286: @*/
288: PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
289: {
293: if (linesearch->ops->reset) (*linesearch->ops->reset)(linesearch);
295: VecDestroy(&linesearch->vec_sol_new);
296: VecDestroy(&linesearch->vec_func_new);
298: VecDestroyVecs(linesearch->nwork, &linesearch->work);
300: linesearch->nwork = 0;
301: linesearch->setupcalled = PETSC_FALSE;
302: return(0);
303: }
305: /*@C
306: SNESLineSearchSetFunction - Sets the function evaluation used by the SNES line search
308: Input Parameters:
309: . linesearch - the SNESLineSearch context
310: + func - function evaluation routine
312: Level: developer
314: Notes:
315: This is used internally by PETSc and not called by users
317: .keywords: get, linesearch, pre-check
319: .seealso: SNESGetLineSearch(), SNESSetFunction()
320: @*/
321: PetscErrorCode SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
322: {
325: linesearch->ops->snesfunc = func;
326: return(0);
327: }
329: /*@C
330: SNESLineSearchSetPreCheck - Sets a user function that is called after the initial search direction has been computed but
331: before the line search routine has been applied. Allows the user to adjust the result of (usually a linear solve) that
332: determined the search direction.
334: Logically Collective on SNESLineSearch
336: Input Parameters:
337: + linesearch - the SNESLineSearch context
338: . func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for the calling sequence
339: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
341: Level: intermediate
343: .keywords: set, linesearch, pre-check
345: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
346: @*/
347: PetscErrorCode SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
348: {
351: if (func) linesearch->ops->precheck = func;
352: if (ctx) linesearch->precheckctx = ctx;
353: return(0);
354: }
356: /*@C
357: SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine.
359: Input Parameters:
360: . linesearch - the SNESLineSearch context
362: Output Parameters:
363: + func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for calling sequence
364: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
366: Level: intermediate
368: .keywords: get, linesearch, pre-check
370: .seealso: SNESGetLineSearch(), SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck()
371: @*/
372: PetscErrorCode SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
373: {
376: if (func) *func = linesearch->ops->precheck;
377: if (ctx) *ctx = linesearch->precheckctx;
378: return(0);
379: }
381: /*@C
382: SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step
383: direction and length. Allows the user a chance to change or override the decision of the line search routine
385: Logically Collective on SNESLineSearch
387: Input Parameters:
388: + linesearch - the SNESLineSearch context
389: . func - [optional] function evaluation routine, see SNESLineSearchPostCheck() for the calling sequence
390: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
392: Level: intermediate
394: .keywords: set, linesearch, post-check
396: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchGetPostCheck()
397: @*/
398: PetscErrorCode SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
399: {
402: if (func) linesearch->ops->postcheck = func;
403: if (ctx) linesearch->postcheckctx = ctx;
404: return(0);
405: }
407: /*@C
408: SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.
410: Input Parameters:
411: . linesearch - the SNESLineSearch context
413: Output Parameters:
414: + func - [optional] function evaluation routine, see for the calling sequence SNESLineSearchPostCheck()
415: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
417: Level: intermediate
419: .keywords: get, linesearch, post-check
421: .seealso: SNESGetLineSearch(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck()
422: @*/
423: PetscErrorCode SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
424: {
427: if (func) *func = linesearch->ops->postcheck;
428: if (ctx) *ctx = linesearch->postcheckctx;
429: return(0);
430: }
432: /*@
433: SNESLineSearchPreCheck - Prepares the line search for being applied.
435: Logically Collective on SNESLineSearch
437: Input Parameters:
438: + linesearch - The linesearch instance.
439: . X - The current solution
440: - Y - The step direction
442: Output Parameters:
443: . changed - Indicator that the precheck routine has changed anything
445: Level: developer
447: .keywords: SNESLineSearch, Create
449: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck()
450: @*/
451: PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
452: {
456: *changed = PETSC_FALSE;
457: if (linesearch->ops->precheck) {
458: (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);
460: }
461: return(0);
462: }
464: /*@
465: SNESLineSearchPostCheck - Prepares the line search for being applied.
467: Logically Collective on SNESLineSearch
469: Input Parameters:
470: + linesearch - The linesearch context
471: . X - The last solution
472: . Y - The step direction
473: - W - The updated solution, W = X + lambda*Y for some lambda
475: Output Parameters:
476: + changed_Y - Indicator if the direction Y has been changed.
477: - changed_W - Indicator if the new candidate solution W has been changed.
479: Level: developer
481: .keywords: SNESLineSearch, Create
483: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPrecheck(), SNESLineSearchGetPrecheck()
484: @*/
485: PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
486: {
490: *changed_Y = PETSC_FALSE;
491: *changed_W = PETSC_FALSE;
492: if (linesearch->ops->postcheck) {
493: (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);
496: }
497: return(0);
498: }
500: /*@C
501: SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration
503: Logically Collective on SNESLineSearch
505: Input Arguments:
506: + linesearch - linesearch context
507: . X - base state for this step
508: . Y - initial correction
509: - ctx - context for this function
511: Output Arguments:
512: + Y - correction, possibly modified
513: - changed - flag indicating that Y was modified
515: Options Database Key:
516: + -snes_linesearch_precheck_picard - activate this routine
517: - -snes_linesearch_precheck_picard_angle - angle
519: Level: advanced
521: Notes:
522: This function should be passed to SNESLineSearchSetPreCheck()
524: The justification for this method involves the linear convergence of a Picard iteration
525: so the Picard linearization should be provided in place of the "Jacobian". This correction
526: is generally not useful when using a Newton linearization.
528: Reference:
529: Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.
531: .seealso: SNESGetLineSearch(), SNESLineSearchSetPreCheck()
532: @*/
533: PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
534: {
536: PetscReal angle = *(PetscReal*)linesearch->precheckctx;
537: Vec Ylast;
538: PetscScalar dot;
539: PetscInt iter;
540: PetscReal ynorm,ylastnorm,theta,angle_radians;
541: SNES snes;
544: SNESLineSearchGetSNES(linesearch, &snes);
545: PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);
546: if (!Ylast) {
547: VecDuplicate(Y,&Ylast);
548: PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);
549: PetscObjectDereference((PetscObject)Ylast);
550: }
551: SNESGetIterationNumber(snes,&iter);
552: if (iter < 2) {
553: VecCopy(Y,Ylast);
554: *changed = PETSC_FALSE;
555: return(0);
556: }
558: VecDot(Y,Ylast,&dot);
559: VecNorm(Y,NORM_2,&ynorm);
560: VecNorm(Ylast,NORM_2,&ylastnorm);
561: /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
562: theta = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
563: angle_radians = angle * PETSC_PI / 180.;
564: if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
565: /* Modify the step Y */
566: PetscReal alpha,ydiffnorm;
567: VecAXPY(Ylast,-1.0,Y);
568: VecNorm(Ylast,NORM_2,&ydiffnorm);
569: alpha = ylastnorm / ydiffnorm;
570: VecCopy(Y,Ylast);
571: VecScale(Y,alpha);
572: 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);
573: } else {
574: PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);
575: VecCopy(Y,Ylast);
576: *changed = PETSC_FALSE;
577: }
578: return(0);
579: }
581: /*@
582: SNESLineSearchApply - Computes the line-search update.
584: Collective on SNESLineSearch
586: Input Parameters:
587: + linesearch - The linesearch context
588: . X - The current solution
589: . F - The current function
590: . fnorm - The current norm
591: - Y - The search direction
593: Output Parameters:
594: + X - The new solution
595: . F - The new function
596: - fnorm - The new function norm
598: Options Database Keys:
599: + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell
600: . -snes_linesearch_monitor [:filename] - Print progress of line searches
601: . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping)
602: . -snes_linesearch_norms - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms())
603: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
604: - -snes_linesearch_max_it - The number of iterations for iterative line searches
606: Notes:
607: This is typically called from within a SNESSolve() implementation in order to
608: help with convergence of the nonlinear method. Various SNES types use line searches
609: in different ways, but the overarching theme is that a line search is used to determine
610: an optimal damping parameter of a step at each iteration of the method. Each
611: application of the line search may invoke SNESComputeFunction() several times, and
612: therefore may be fairly expensive.
614: Level: Intermediate
616: .keywords: SNESLineSearch, Create
618: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(),
619: SNESLineSearchType, SNESLineSearchSetType()
620: @*/
621: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
622: {
631: linesearch->result = SNES_LINESEARCH_SUCCEEDED;
633: linesearch->vec_sol = X;
634: linesearch->vec_update = Y;
635: linesearch->vec_func = F;
637: SNESLineSearchSetUp(linesearch);
639: if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
641: if (fnorm) linesearch->fnorm = *fnorm;
642: else {
643: VecNorm(F, NORM_2, &linesearch->fnorm);
644: }
646: PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y);
648: (*linesearch->ops->apply)(linesearch);
650: PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y);
652: if (fnorm) *fnorm = linesearch->fnorm;
653: return(0);
654: }
656: /*@
657: SNESLineSearchDestroy - Destroys the line search instance.
659: Collective on SNESLineSearch
661: Input Parameters:
662: . linesearch - The linesearch context
664: Level: developer
666: .keywords: SNESLineSearch, Destroy
668: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
669: @*/
670: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
671: {
675: if (!*linesearch) return(0);
677: if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; return(0);}
678: PetscObjectSAWsViewOff((PetscObject)*linesearch);
679: SNESLineSearchReset(*linesearch);
680: if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
681: PetscViewerDestroy(&(*linesearch)->monitor);
682: SNESLineSearchMonitorCancel((*linesearch));
683: PetscHeaderDestroy(linesearch);
684: return(0);
685: }
687: /*@
688: SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.
690: Input Parameters:
691: + linesearch - the linesearch object
692: - viewer - an ASCII PetscViewer or NULL to turn off monitor
694: Logically Collective on SNESLineSearch
696: Options Database:
697: . -snes_linesearch_monitor [:filename] - enables the monitor
699: Level: intermediate
701: Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with
702: SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the
703: line search that are not visible to the other monitors.
705: .seealso: SNESGetLineSearch(), SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor()
706: @*/
707: PetscErrorCode SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
708: {
712: if (viewer) {PetscObjectReference((PetscObject)viewer);}
713: PetscViewerDestroy(&linesearch->monitor);
714: linesearch->monitor = viewer;
715: return(0);
716: }
718: /*@
719: SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.
721: Input Parameter:
722: . linesearch - linesearch context
724: Output Parameter:
725: . monitor - monitor context
727: Logically Collective on SNES
729: Options Database Keys:
730: . -snes_linesearch_monitor - enables the monitor
732: Level: intermediate
734: .seealso: SNESGetLineSearch(), SNESLineSearchSetDefaultMonitor(), PetscViewer
735: @*/
736: PetscErrorCode SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
737: {
740: if (monitor) {
742: *monitor = linesearch->monitor;
743: }
744: return(0);
745: }
747: /*@C
748: SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
750: Collective on SNESLineSearch
752: Input Parameters:
753: + ls - LineSearch object you wish to monitor
754: . name - the monitor type one is seeking
755: . help - message indicating what monitoring is done
756: . manual - manual page for the monitor
757: . monitor - the monitor function
758: - 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
760: Level: developer
762: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
763: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
764: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
765: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
766: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
767: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
768: PetscOptionsFList(), PetscOptionsEList()
769: @*/
770: PetscErrorCode SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
771: {
772: PetscErrorCode ierr;
773: PetscViewer viewer;
774: PetscViewerFormat format;
775: PetscBool flg;
778: PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject)ls)->prefix,name,&viewer,&format,&flg);
779: if (flg) {
780: PetscViewerAndFormat *vf;
781: PetscViewerAndFormatCreate(viewer,format,&vf);
782: PetscObjectDereference((PetscObject)viewer);
783: if (monitorsetup) {
784: (*monitorsetup)(ls,vf);
785: }
786: SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
787: }
788: return(0);
789: }
791: /*@
792: SNESLineSearchSetFromOptions - Sets options for the line search
794: Input Parameters:
795: . linesearch - linesearch context
797: Options Database Keys:
798: + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
799: . -snes_linesearch_order <order> - 1, 2, 3. Most types only support certain orders (bt supports 2 or 3)
800: . -snes_linesearch_norms - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms())
801: . -snes_linesearch_minlambda - The minimum step length
802: . -snes_linesearch_maxstep - The maximum step size
803: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
804: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
805: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
806: . -snes_linesearch_max_it - The number of iterations for iterative line searches
807: . -snes_linesearch_monitor [:filename] - Print progress of line searches
808: . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
809: . -snes_linesearch_damping - The linesearch damping parameter
810: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
811: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
812: - -snes_linesearch_precheck_picard_angle - Angle used in picard precheck method
814: Logically Collective on SNESLineSearch
816: Level: intermediate
818: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(),
819: SNESLineSearchType, SNESLineSearchSetComputeNorms()
820: @*/
821: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
822: {
823: PetscErrorCode ierr;
824: const char *deft = SNESLINESEARCHBASIC;
825: char type[256];
826: PetscBool flg, set;
827: PetscViewer viewer;
830: SNESLineSearchRegisterAll();
832: PetscObjectOptionsBegin((PetscObject)linesearch);
833: if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
834: PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
835: if (flg) {
836: SNESLineSearchSetType(linesearch,type);
837: } else if (!((PetscObject)linesearch)->type_name) {
838: SNESLineSearchSetType(linesearch,deft);
839: }
841: PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);
842: if (set) {
843: SNESLineSearchSetDefaultMonitor(linesearch,viewer);
844: PetscViewerDestroy(&viewer);
845: }
846: SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);
848: /* tolerances */
849: PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);
850: PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);
851: PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);
852: PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);
853: PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);
854: PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);
856: /* damping parameters */
857: PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);
859: PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL);
861: /* precheck */
862: PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);
863: if (set) {
864: if (flg) {
865: linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
867: PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
868: "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);
869: SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
870: } else {
871: SNESLineSearchSetPreCheck(linesearch,NULL,NULL);
872: }
873: }
874: PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);
875: PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);
877: if (linesearch->ops->setfromoptions) {
878: (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);
879: }
881: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);
882: PetscOptionsEnd();
883: return(0);
884: }
886: /*@
887: SNESLineSearchView - Prints useful information about the line search
889: Input Parameters:
890: . linesearch - linesearch context
892: Logically Collective on SNESLineSearch
894: Level: intermediate
896: .seealso: SNESLineSearchCreate()
897: @*/
898: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
899: {
901: PetscBool iascii;
905: if (!viewer) {
906: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);
907: }
911: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
912: if (iascii) {
913: PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);
914: if (linesearch->ops->view) {
915: PetscViewerASCIIPushTab(viewer);
916: (*linesearch->ops->view)(linesearch,viewer);
917: PetscViewerASCIIPopTab(viewer);
918: }
919: PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);
920: PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);
921: PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", linesearch->max_its);
922: if (linesearch->ops->precheck) {
923: if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
924: PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n", linesearch->max_its);
925: } else {
926: PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n", linesearch->max_its);
927: }
928: }
929: if (linesearch->ops->postcheck) {
930: PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n", linesearch->max_its);
931: }
932: }
933: return(0);
934: }
936: /*@C
937: SNESLineSearchSetType - Sets the linesearch type
939: Logically Collective on SNESLineSearch
941: Input Parameters:
942: + linesearch - linesearch context
943: - type - The type of line search to be used
945: Available Types:
946: + SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
947: . SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
948: . SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
949: . SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
950: . SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
951: - SNESLINESEARCHSHELL - User provided SNESLineSearch implementation
953: Options Database:
954: . -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
956: Level: intermediate
958: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions()
959: @*/
960: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
961: {
962: PetscErrorCode ierr,(*r)(SNESLineSearch);
963: PetscBool match;
969: PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
970: if (match) return(0);
972: PetscFunctionListFind(SNESLineSearchList,type,&r);
973: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
974: /* Destroy the previous private linesearch context */
975: if (linesearch->ops->destroy) {
976: (*(linesearch)->ops->destroy)(linesearch);
978: linesearch->ops->destroy = NULL;
979: }
980: /* Reinitialize function pointers in SNESLineSearchOps structure */
981: linesearch->ops->apply = 0;
982: linesearch->ops->view = 0;
983: linesearch->ops->setfromoptions = 0;
984: linesearch->ops->destroy = 0;
986: PetscObjectChangeTypeName((PetscObject)linesearch,type);
987: (*r)(linesearch);
988: return(0);
989: }
991: /*@
992: SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
994: Input Parameters:
995: + linesearch - linesearch context
996: - snes - The snes instance
998: Level: developer
1000: Notes:
1001: This happens automatically when the line search is obtained/created with
1002: SNESGetLineSearch(). This routine is therefore mainly called within SNES
1003: implementations.
1005: Level: developer
1007: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1008: @*/
1009: PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
1010: {
1014: linesearch->snes = snes;
1015: return(0);
1016: }
1018: /*@
1019: SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
1020: Having an associated SNES is necessary because most line search implementations must be able to
1021: evaluate the function using SNESComputeFunction() for the associated SNES. This routine
1022: is used in the line search implementations when one must get this associated SNES instance.
1024: Input Parameters:
1025: . linesearch - linesearch context
1027: Output Parameters:
1028: . snes - The snes instance
1030: Level: developer
1032: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
1033: @*/
1034: PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1035: {
1039: *snes = linesearch->snes;
1040: return(0);
1041: }
1043: /*@
1044: SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
1046: Input Parameters:
1047: . linesearch - linesearch context
1049: Output Parameters:
1050: . lambda - The last steplength computed during SNESLineSearchApply()
1052: Level: advanced
1054: Notes:
1055: This is useful in methods where the solver is ill-scaled and
1056: requires some adaptive notion of the difference in scale between the
1057: solution and the function. For instance, SNESQN may be scaled by the
1058: line search lambda using the argument -snes_qn_scaling ls.
1060: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1061: @*/
1062: PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1063: {
1067: *lambda = linesearch->lambda;
1068: return(0);
1069: }
1071: /*@
1072: SNESLineSearchSetLambda - Sets the linesearch steplength.
1074: Input Parameters:
1075: + linesearch - linesearch context
1076: - lambda - The last steplength.
1078: Notes:
1079: This routine is typically used within implementations of SNESLineSearchApply()
1080: to set the final steplength. This routine (and SNESLineSearchGetLambda()) were
1081: added in order to facilitate Quasi-Newton methods that use the previous steplength
1082: as an inner scaling parameter.
1084: Level: advanced
1086: .seealso: SNESLineSearchGetLambda()
1087: @*/
1088: PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1089: {
1092: linesearch->lambda = lambda;
1093: return(0);
1094: }
1096: /*@
1097: SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include
1098: tolerances for the relative and absolute change in the function norm, the change
1099: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1100: and the maximum number of iterations the line search procedure may take.
1102: Input Parameters:
1103: . linesearch - linesearch context
1105: Output Parameters:
1106: + steptol - The minimum steplength
1107: . maxstep - The maximum steplength
1108: . rtol - The relative tolerance for iterative line searches
1109: . atol - The absolute tolerance for iterative line searches
1110: . ltol - The change in lambda tolerance for iterative line searches
1111: - max_it - The maximum number of iterations of the line search
1113: Level: intermediate
1115: Notes:
1116: Different line searches may implement these parameters slightly differently as
1117: the type requires.
1119: .seealso: SNESLineSearchSetTolerances()
1120: @*/
1121: PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1122: {
1125: if (steptol) {
1127: *steptol = linesearch->steptol;
1128: }
1129: if (maxstep) {
1131: *maxstep = linesearch->maxstep;
1132: }
1133: if (rtol) {
1135: *rtol = linesearch->rtol;
1136: }
1137: if (atol) {
1139: *atol = linesearch->atol;
1140: }
1141: if (ltol) {
1143: *ltol = linesearch->ltol;
1144: }
1145: if (max_its) {
1147: *max_its = linesearch->max_its;
1148: }
1149: return(0);
1150: }
1152: /*@
1153: SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include
1154: tolerances for the relative and absolute change in the function norm, the change
1155: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1156: and the maximum number of iterations the line search procedure may take.
1158: Input Parameters:
1159: + linesearch - linesearch context
1160: . steptol - The minimum steplength
1161: . maxstep - The maximum steplength
1162: . rtol - The relative tolerance for iterative line searches
1163: . atol - The absolute tolerance for iterative line searches
1164: . ltol - The change in lambda tolerance for iterative line searches
1165: - max_it - The maximum number of iterations of the line search
1167: Notes:
1168: The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1169: place of an argument.
1171: Level: intermediate
1173: .seealso: SNESLineSearchGetTolerances()
1174: @*/
1175: PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1176: {
1186: if (steptol!= PETSC_DEFAULT) {
1187: if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
1188: linesearch->steptol = steptol;
1189: }
1191: if (maxstep!= PETSC_DEFAULT) {
1192: if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1193: linesearch->maxstep = maxstep;
1194: }
1196: if (rtol != PETSC_DEFAULT) {
1197: 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);
1198: linesearch->rtol = rtol;
1199: }
1201: if (atol != PETSC_DEFAULT) {
1202: if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1203: linesearch->atol = atol;
1204: }
1206: if (ltol != PETSC_DEFAULT) {
1207: if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %14.12e must be non-negative",(double)ltol);
1208: linesearch->ltol = ltol;
1209: }
1211: if (max_its != PETSC_DEFAULT) {
1212: if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1213: linesearch->max_its = max_its;
1214: }
1215: return(0);
1216: }
1218: /*@
1219: SNESLineSearchGetDamping - Gets the line search damping parameter.
1221: Input Parameters:
1222: . linesearch - linesearch context
1224: Output Parameters:
1225: . damping - The damping parameter
1227: Level: advanced
1229: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1230: @*/
1232: PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1233: {
1237: *damping = linesearch->damping;
1238: return(0);
1239: }
1241: /*@
1242: SNESLineSearchSetDamping - Sets the line search damping paramter.
1244: Input Parameters:
1245: + linesearch - linesearch context
1246: - damping - The damping parameter
1248: Options Database:
1249: . -snes_linesearch_damping
1250: Level: intermediate
1252: Notes:
1253: The basic line search merely takes the update step scaled by the damping parameter.
1254: The use of the damping parameter in the l2 and cp line searches is much more subtle;
1255: it is used as a starting point in calculating the secant step. However, the eventual
1256: step may be of greater length than the damping parameter. In the bt line search it is
1257: used as the maximum possible step length, as the bt line search only backtracks.
1259: .seealso: SNESLineSearchGetDamping()
1260: @*/
1261: PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1262: {
1265: linesearch->damping = damping;
1266: return(0);
1267: }
1269: /*@
1270: SNESLineSearchGetOrder - Gets the line search approximation order.
1272: Input Parameters:
1273: . linesearch - linesearch context
1275: Output Parameters:
1276: . order - The order
1278: Possible Values for order:
1279: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1280: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1281: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1283: Level: intermediate
1285: .seealso: SNESLineSearchSetOrder()
1286: @*/
1288: PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1289: {
1293: *order = linesearch->order;
1294: return(0);
1295: }
1297: /*@
1298: SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
1300: Input Parameters:
1301: . linesearch - linesearch context
1302: . order - The damping parameter
1304: Level: intermediate
1306: Possible Values for order:
1307: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1308: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1309: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1311: Notes:
1312: Variable orders are supported by the following line searches:
1313: + bt - cubic and quadratic
1314: - cp - linear and quadratic
1316: .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1317: @*/
1318: PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1319: {
1322: linesearch->order = order;
1323: return(0);
1324: }
1326: /*@
1327: SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1329: Input Parameters:
1330: . linesearch - linesearch context
1332: Output Parameters:
1333: + xnorm - The norm of the current solution
1334: . fnorm - The norm of the current function
1335: - ynorm - The norm of the current update
1337: Notes:
1338: This function is mainly called from SNES implementations.
1340: Level: developer
1342: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1343: @*/
1344: PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1345: {
1348: if (xnorm) *xnorm = linesearch->xnorm;
1349: if (fnorm) *fnorm = linesearch->fnorm;
1350: if (ynorm) *ynorm = linesearch->ynorm;
1351: return(0);
1352: }
1354: /*@
1355: SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1357: Input Parameters:
1358: + linesearch - linesearch context
1359: . xnorm - The norm of the current solution
1360: . fnorm - The norm of the current function
1361: - ynorm - The norm of the current update
1363: Level: advanced
1365: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1366: @*/
1367: PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1368: {
1371: linesearch->xnorm = xnorm;
1372: linesearch->fnorm = fnorm;
1373: linesearch->ynorm = ynorm;
1374: return(0);
1375: }
1377: /*@
1378: SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1380: Input Parameters:
1381: . linesearch - linesearch context
1383: Options Database Keys:
1384: . -snes_linesearch_norms - turn norm computation on or off
1386: Level: intermediate
1388: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1389: @*/
1390: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1391: {
1393: SNES snes;
1396: if (linesearch->norms) {
1397: if (linesearch->ops->vinorm) {
1398: SNESLineSearchGetSNES(linesearch, &snes);
1399: VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1400: VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1401: (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1402: } else {
1403: VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1404: VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1405: VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1406: VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1407: VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1408: VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1409: }
1410: }
1411: return(0);
1412: }
1414: /*@
1415: SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
1417: Input Parameters:
1418: + linesearch - linesearch context
1419: - flg - indicates whether or not to compute norms
1421: Options Database Keys:
1422: . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch
1424: Notes:
1425: This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm.
1427: Level: intermediate
1429: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1430: @*/
1431: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1432: {
1434: linesearch->norms = flg;
1435: return(0);
1436: }
1438: /*@
1439: SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1441: Input Parameters:
1442: . linesearch - linesearch context
1444: Output Parameters:
1445: + X - Solution vector
1446: . F - Function vector
1447: . Y - Search direction vector
1448: . W - Solution work vector
1449: - G - Function work vector
1451: Notes:
1452: At the beginning of a line search application, X should contain a
1453: solution and the vector F the function computed at X. At the end of the
1454: line search application, X should contain the new solution, and F the
1455: function evaluated at the new solution.
1457: These vectors are owned by the SNESLineSearch and should not be destroyed by the caller
1459: Level: advanced
1461: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1462: @*/
1463: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1464: {
1467: if (X) {
1469: *X = linesearch->vec_sol;
1470: }
1471: if (F) {
1473: *F = linesearch->vec_func;
1474: }
1475: if (Y) {
1477: *Y = linesearch->vec_update;
1478: }
1479: if (W) {
1481: *W = linesearch->vec_sol_new;
1482: }
1483: if (G) {
1485: *G = linesearch->vec_func_new;
1486: }
1487: return(0);
1488: }
1490: /*@
1491: SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1493: Input Parameters:
1494: + linesearch - linesearch context
1495: . X - Solution vector
1496: . F - Function vector
1497: . Y - Search direction vector
1498: . W - Solution work vector
1499: - G - Function work vector
1501: Level: advanced
1503: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1504: @*/
1505: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1506: {
1509: if (X) {
1511: linesearch->vec_sol = X;
1512: }
1513: if (F) {
1515: linesearch->vec_func = F;
1516: }
1517: if (Y) {
1519: linesearch->vec_update = Y;
1520: }
1521: if (W) {
1523: linesearch->vec_sol_new = W;
1524: }
1525: if (G) {
1527: linesearch->vec_func_new = G;
1528: }
1529: return(0);
1530: }
1532: /*@C
1533: SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1534: SNES options in the database.
1536: Logically Collective on SNESLineSearch
1538: Input Parameters:
1539: + snes - the SNES context
1540: - prefix - the prefix to prepend to all option names
1542: Notes:
1543: A hyphen (-) must NOT be given at the beginning of the prefix name.
1544: The first character of all runtime options is AUTOMATICALLY the hyphen.
1546: Level: advanced
1548: .keywords: SNESLineSearch, append, options, prefix, database
1550: .seealso: SNESGetOptionsPrefix()
1551: @*/
1552: PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1553: {
1558: PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1559: return(0);
1560: }
1562: /*@C
1563: SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1564: SNESLineSearch options in the database.
1566: Not Collective
1568: Input Parameter:
1569: . linesearch - the SNESLineSearch context
1571: Output Parameter:
1572: . prefix - pointer to the prefix string used
1574: Notes:
1575: On the fortran side, the user should pass in a string 'prefix' of
1576: sufficient length to hold the prefix.
1578: Level: advanced
1580: .keywords: SNESLineSearch, get, options, prefix, database
1582: .seealso: SNESAppendOptionsPrefix()
1583: @*/
1584: PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1585: {
1590: PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1591: return(0);
1592: }
1594: /*@C
1595: SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1597: Input Parameter:
1598: + linesearch - the SNESLineSearch context
1599: - nwork - the number of work vectors
1601: Level: developer
1603: .keywords: SNESLineSearch, work, vector
1605: .seealso: SNESSetWorkVecs()
1606: @*/
1607: PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1608: {
1612: if (linesearch->vec_sol) {
1613: VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1614: } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1615: return(0);
1616: }
1618: /*@
1619: SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1621: Input Parameters:
1622: . linesearch - linesearch context
1624: Output Parameters:
1625: . result - The success or failure status
1627: Notes:
1628: This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1629: (and set the SNES convergence accordingly).
1631: Level: intermediate
1633: .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1634: @*/
1635: PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1636: {
1640: *result = linesearch->result;
1641: return(0);
1642: }
1644: /*@
1645: SNESLineSearchSetReason - Sets the success/failure status of the last line search application
1647: Input Parameters:
1648: + linesearch - linesearch context
1649: - result - The success or failure status
1651: Notes:
1652: This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1653: the success or failure of the line search method.
1655: Level: developer
1657: .seealso: SNESLineSearchGetSResult()
1658: @*/
1659: PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1660: {
1663: linesearch->result = result;
1664: return(0);
1665: }
1667: /*@C
1668: SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
1670: Input Parameters:
1671: + snes - nonlinear context obtained from SNESCreate()
1672: . projectfunc - function for projecting the function to the bounds
1673: - normfunc - function for computing the norm of an active set
1675: Logically Collective on SNES
1677: Calling sequence of projectfunc:
1678: .vb
1679: projectfunc (SNES snes, Vec X)
1680: .ve
1682: Input parameters for projectfunc:
1683: + snes - nonlinear context
1684: - X - current solution
1686: Output parameters for projectfunc:
1687: . X - Projected solution
1689: Calling sequence of normfunc:
1690: .vb
1691: projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1692: .ve
1694: Input parameters for normfunc:
1695: + snes - nonlinear context
1696: . X - current solution
1697: - F - current residual
1699: Output parameters for normfunc:
1700: . fnorm - VI-specific norm of the function
1702: Notes:
1703: The VI solvers require projection of the solution to the feasible set. projectfunc should implement this.
1705: The VI solvers require special evaluation of the function norm such that the norm is only calculated
1706: on the inactive set. This should be implemented by normfunc.
1708: Level: developer
1710: .keywords: SNES, line search, VI, nonlinear, set, line search
1712: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1713: @*/
1714: PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1715: {
1718: if (projectfunc) linesearch->ops->viproject = projectfunc;
1719: if (normfunc) linesearch->ops->vinorm = normfunc;
1720: return(0);
1721: }
1723: /*@C
1724: SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
1726: Input Parameters:
1727: . linesearch - the line search context, obtain with SNESGetLineSearch()
1729: Output Parameters:
1730: + projectfunc - function for projecting the function to the bounds
1731: - normfunc - function for computing the norm of an active set
1733: Logically Collective on SNES
1735: Level: developer
1737: .keywords: SNES, line search, VI, nonlinear, get, line search
1739: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1740: @*/
1741: PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1742: {
1744: if (projectfunc) *projectfunc = linesearch->ops->viproject;
1745: if (normfunc) *normfunc = linesearch->ops->vinorm;
1746: return(0);
1747: }
1749: /*@C
1750: SNESLineSearchRegister - See SNESLineSearchRegister()
1752: Level: advanced
1753: @*/
1754: PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1755: {
1759: SNESInitializePackage();
1760: PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1761: return(0);
1762: }