Actual source code: linesearch.c
1: #include <petsc/private/linesearchimpl.h>
3: PetscBool SNESLineSearchRegisterAllCalled = PETSC_FALSE;
4: PetscFunctionList SNESLineSearchList = NULL;
6: PetscClassId SNESLINESEARCH_CLASSID;
7: PetscLogEvent SNESLINESEARCH_Apply;
9: /*@
10: SNESLineSearchMonitorCancel - Clears all the monitor functions for a SNESLineSearch object.
12: Logically Collective on SNESLineSearch
14: Input Parameters:
15: . ls - the SNESLineSearch context
17: Options Database Key:
18: . -snes_linesearch_monitor_cancel - cancels all monitors that have been hardwired
19: into a code by calls to SNESLineSearchMonitorSet(), but does not cancel those
20: set via the options database
22: Notes:
23: There is no way to clear one specific monitor from a SNESLineSearch object.
25: This does not clear the monitor set with SNESLineSearchSetDefaultMonitor() use SNESLineSearchSetDefaultMonitor(ls,NULL) to cancel
26: that one.
28: Level: intermediate
30: .seealso: SNESGetLineSearch(), SNESLineSearchMonitorDefault(), SNESLineSearchMonitorSet()
31: @*/
32: PetscErrorCode SNESLineSearchMonitorCancel(SNESLineSearch ls)
33: {
34: PetscInt i;
37: for (i=0; i<ls->numbermonitors; i++) {
38: if (ls->monitordestroy[i]) {
39: (*ls->monitordestroy[i])(&ls->monitorcontext[i]);
40: }
41: }
42: ls->numbermonitors = 0;
43: return 0;
44: }
46: /*@
47: SNESLineSearchMonitor - runs the user provided monitor routines, if they exist
49: Collective on SNES
51: Input Parameters:
52: . ls - the linesearch object
54: Notes:
55: This routine is called by the SNES implementations.
56: It does not typically need to be called by the user.
58: Level: developer
60: .seealso: SNESGetLineSearch(), SNESLineSearchMonitorSet()
61: @*/
62: PetscErrorCode SNESLineSearchMonitor(SNESLineSearch ls)
63: {
64: PetscInt i,n = ls->numbermonitors;
66: for (i=0; i<n; i++) {
67: (*ls->monitorftns[i])(ls,ls->monitorcontext[i]);
68: }
69: return 0;
70: }
72: /*@C
73: SNESLineSearchMonitorSet - Sets an ADDITIONAL function that is to be used at every
74: iteration of the nonlinear solver to display the iteration's
75: progress.
77: Logically Collective on SNESLineSearch
79: Input Parameters:
80: + ls - the SNESLineSearch context
81: . f - the monitor function
82: . mctx - [optional] user-defined context for private data for the
83: monitor routine (use NULL if no context is desired)
84: - monitordestroy - [optional] routine that frees monitor context
85: (may be NULL)
87: Notes:
88: Several different monitoring routines may be set by calling
89: SNESLineSearchMonitorSet() multiple times; all will be called in the
90: order in which they were set.
92: Fortran Notes:
93: Only a single monitor function can be set for each SNESLineSearch object
95: Level: intermediate
97: .seealso: SNESGetLineSearch(), SNESLineSearchMonitorDefault(), SNESLineSearchMonitorCancel()
98: @*/
99: PetscErrorCode SNESLineSearchMonitorSet(SNESLineSearch ls,PetscErrorCode (*f)(SNESLineSearch,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
100: {
101: PetscInt i;
102: PetscBool identical;
105: for (i=0; i<ls->numbermonitors;i++) {
106: PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))ls->monitorftns[i],ls->monitorcontext[i],ls->monitordestroy[i],&identical);
107: if (identical) return 0;
108: }
110: ls->monitorftns[ls->numbermonitors] = f;
111: ls->monitordestroy[ls->numbermonitors] = monitordestroy;
112: ls->monitorcontext[ls->numbermonitors++] = (void*)mctx;
113: return 0;
114: }
116: /*@C
117: SNESLineSearchMonitorSolutionUpdate - Monitors each update a new function value the linesearch tries
119: Collective on SNESLineSearch
121: Input Parameters:
122: + ls - the SNES linesearch object
123: - vf - the context for the monitor, in this case it is an ASCII PetscViewer and format
125: Level: intermediate
127: .seealso: SNESGetLineSearch(), SNESMonitorSet(), SNESMonitorSolution()
128: @*/
129: PetscErrorCode SNESLineSearchMonitorSolutionUpdate(SNESLineSearch ls,PetscViewerAndFormat *vf)
130: {
131: PetscViewer viewer = vf->viewer;
132: Vec Y,W,G;
134: SNESLineSearchGetVecs(ls,NULL,NULL,&Y,&W,&G);
135: PetscViewerPushFormat(viewer,vf->format);
136: PetscViewerASCIIPrintf(viewer,"LineSearch attempted update to solution \n");
137: VecView(Y,viewer);
138: PetscViewerASCIIPrintf(viewer,"LineSearch attempted new solution \n");
139: VecView(W,viewer);
140: PetscViewerASCIIPrintf(viewer,"LineSearch attempted updated function value\n");
141: VecView(G,viewer);
142: PetscViewerPopFormat(viewer);
143: return 0;
144: }
146: /*@
147: SNESLineSearchCreate - Creates the line search context.
149: Logically Collective on Comm
151: Input Parameters:
152: . comm - MPI communicator for the line search (typically from the associated SNES context).
154: Output Parameters:
155: . outlinesearch - the new linesearch context
157: Level: developer
159: Notes:
160: The preferred calling sequence for users is to use SNESGetLineSearch() to acquire the SNESLineSearch instance
161: already associated with the SNES. This function is for developer use.
163: .seealso: LineSearchDestroy(), SNESGetLineSearch()
164: @*/
166: PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
167: {
168: SNESLineSearch linesearch;
171: SNESInitializePackage();
172: *outlinesearch = NULL;
174: PetscHeaderCreate(linesearch,SNESLINESEARCH_CLASSID, "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView);
176: linesearch->vec_sol_new = NULL;
177: linesearch->vec_func_new = NULL;
178: linesearch->vec_sol = NULL;
179: linesearch->vec_func = NULL;
180: linesearch->vec_update = NULL;
182: linesearch->lambda = 1.0;
183: linesearch->fnorm = 1.0;
184: linesearch->ynorm = 1.0;
185: linesearch->xnorm = 1.0;
186: linesearch->result = SNES_LINESEARCH_SUCCEEDED;
187: linesearch->norms = PETSC_TRUE;
188: linesearch->keeplambda = PETSC_FALSE;
189: linesearch->damping = 1.0;
190: linesearch->maxstep = 1e8;
191: linesearch->steptol = 1e-12;
192: linesearch->rtol = 1e-8;
193: linesearch->atol = 1e-15;
194: linesearch->ltol = 1e-8;
195: linesearch->precheckctx = NULL;
196: linesearch->postcheckctx = NULL;
197: linesearch->max_its = 1;
198: linesearch->setupcalled = PETSC_FALSE;
199: linesearch->monitor = NULL;
200: *outlinesearch = linesearch;
201: return 0;
202: }
204: /*@
205: SNESLineSearchSetUp - Prepares the line search for being applied by allocating
206: any required vectors.
208: Collective on SNESLineSearch
210: Input Parameters:
211: . linesearch - The LineSearch instance.
213: Notes:
214: For most cases, this needn't be called by users or outside of SNESLineSearchApply().
215: The only current case where this is called outside of this is for the VI
216: solvers, which modify the solution and work vectors before the first call
217: of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be
218: allocated upfront.
220: Level: advanced
222: .seealso: SNESGetLineSearch(), SNESLineSearchReset()
223: @*/
225: PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
226: {
227: if (!((PetscObject)linesearch)->type_name) {
228: SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);
229: }
230: if (!linesearch->setupcalled) {
231: if (!linesearch->vec_sol_new) {
232: VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);
233: }
234: if (!linesearch->vec_func_new) {
235: VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);
236: }
237: if (linesearch->ops->setup) {
238: (*linesearch->ops->setup)(linesearch);
239: }
240: if (!linesearch->ops->snesfunc) SNESLineSearchSetFunction(linesearch,SNESComputeFunction);
241: linesearch->lambda = linesearch->damping;
242: linesearch->setupcalled = PETSC_TRUE;
243: }
244: return 0;
245: }
247: /*@
248: SNESLineSearchReset - Undoes the SNESLineSearchSetUp() and deletes any Vecs or Mats allocated by the line search.
250: Collective on SNESLineSearch
252: Input Parameters:
253: . linesearch - The LineSearch instance.
255: Notes:
256: Usually only called by SNESReset()
258: Level: developer
260: .seealso: SNESGetLineSearch(), SNESLineSearchSetUp()
261: @*/
263: PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
264: {
265: if (linesearch->ops->reset) (*linesearch->ops->reset)(linesearch);
267: VecDestroy(&linesearch->vec_sol_new);
268: VecDestroy(&linesearch->vec_func_new);
270: VecDestroyVecs(linesearch->nwork, &linesearch->work);
272: linesearch->nwork = 0;
273: linesearch->setupcalled = PETSC_FALSE;
274: return 0;
275: }
277: /*@C
278: SNESLineSearchSetFunction - Sets the function evaluation used by the SNES line search
280: Input Parameters:
281: . linesearch - the SNESLineSearch context
282: + func - function evaluation routine
284: Level: developer
286: Notes:
287: This is used internally by PETSc and not called by users
289: .seealso: SNESGetLineSearch(), SNESSetFunction()
290: @*/
291: PetscErrorCode SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
292: {
294: linesearch->ops->snesfunc = func;
295: return 0;
296: }
298: /*@C
299: SNESLineSearchSetPreCheck - Sets a user function that is called after the initial search direction has been computed but
300: before the line search routine has been applied. Allows the user to adjust the result of (usually a linear solve) that
301: determined the search direction.
303: Logically Collective on SNESLineSearch
305: Input Parameters:
306: + linesearch - the SNESLineSearch context
307: . func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for the calling sequence
308: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
310: Level: intermediate
312: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
313: @*/
314: PetscErrorCode SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
315: {
317: if (func) linesearch->ops->precheck = func;
318: if (ctx) linesearch->precheckctx = ctx;
319: return 0;
320: }
322: /*@C
323: SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine.
325: Input Parameter:
326: . linesearch - the SNESLineSearch context
328: Output Parameters:
329: + func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for calling sequence
330: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
332: Level: intermediate
334: .seealso: SNESGetLineSearch(), SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck()
335: @*/
336: PetscErrorCode SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
337: {
339: if (func) *func = linesearch->ops->precheck;
340: if (ctx) *ctx = linesearch->precheckctx;
341: return 0;
342: }
344: /*@C
345: SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step
346: direction and length. Allows the user a chance to change or override the decision of the line search routine
348: Logically Collective on SNESLineSearch
350: Input Parameters:
351: + linesearch - the SNESLineSearch context
352: . func - [optional] function evaluation routine, see SNESLineSearchPostCheck() for the calling sequence
353: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
355: Level: intermediate
357: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchGetPostCheck()
358: @*/
359: PetscErrorCode SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
360: {
362: if (func) linesearch->ops->postcheck = func;
363: if (ctx) linesearch->postcheckctx = ctx;
364: return 0;
365: }
367: /*@C
368: SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.
370: Input Parameter:
371: . linesearch - the SNESLineSearch context
373: Output Parameters:
374: + func - [optional] function evaluation routine, see for the calling sequence SNESLineSearchPostCheck()
375: - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
377: Level: intermediate
379: .seealso: SNESGetLineSearch(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck()
380: @*/
381: PetscErrorCode SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
382: {
384: if (func) *func = linesearch->ops->postcheck;
385: if (ctx) *ctx = linesearch->postcheckctx;
386: return 0;
387: }
389: /*@
390: SNESLineSearchPreCheck - Prepares the line search for being applied.
392: Logically Collective on SNESLineSearch
394: Input Parameters:
395: + linesearch - The linesearch instance.
396: . X - The current solution
397: - Y - The step direction
399: Output Parameters:
400: . changed - Indicator that the precheck routine has changed anything
402: Level: developer
404: .seealso: SNESGetLineSearch(), SNESLineSearchPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck()
405: @*/
406: PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
407: {
408: *changed = PETSC_FALSE;
409: if (linesearch->ops->precheck) {
410: (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);
412: }
413: return 0;
414: }
416: /*@
417: SNESLineSearchPostCheck - Prepares the line search for being applied.
419: Logically Collective on SNESLineSearch
421: Input Parameters:
422: + linesearch - The linesearch context
423: . X - The last solution
424: . Y - The step direction
425: - W - The updated solution, W = X + lambda*Y for some lambda
427: Output Parameters:
428: + changed_Y - Indicator if the direction Y has been changed.
429: - changed_W - Indicator if the new candidate solution W has been changed.
431: Level: developer
433: .seealso: SNESGetLineSearch(), SNESLineSearchPreCheck(), SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPrecheck(), SNESLineSearchGetPrecheck()
434: @*/
435: PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
436: {
437: *changed_Y = PETSC_FALSE;
438: *changed_W = PETSC_FALSE;
439: if (linesearch->ops->postcheck) {
440: (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);
443: }
444: return 0;
445: }
447: /*@C
448: SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration
450: Logically Collective on SNESLineSearch
452: Input Parameters:
453: + linesearch - linesearch context
454: . X - base state for this step
455: - ctx - context for this function
457: Input/Output Parameter:
458: . Y - correction, possibly modified
460: Output Parameter:
461: . changed - flag indicating that Y was modified
463: Options Database Key:
464: + -snes_linesearch_precheck_picard - activate this routine
465: - -snes_linesearch_precheck_picard_angle - angle
467: Level: advanced
469: Notes:
470: This function should be passed to SNESLineSearchSetPreCheck()
472: The justification for this method involves the linear convergence of a Picard iteration
473: so the Picard linearization should be provided in place of the "Jacobian". This correction
474: is generally not useful when using a Newton linearization.
476: Reference:
477: Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.
479: .seealso: SNESGetLineSearch(), SNESLineSearchSetPreCheck()
480: @*/
481: PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
482: {
483: PetscReal angle = *(PetscReal*)linesearch->precheckctx;
484: Vec Ylast;
485: PetscScalar dot;
486: PetscInt iter;
487: PetscReal ynorm,ylastnorm,theta,angle_radians;
488: SNES snes;
490: SNESLineSearchGetSNES(linesearch, &snes);
491: PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);
492: if (!Ylast) {
493: VecDuplicate(Y,&Ylast);
494: PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);
495: PetscObjectDereference((PetscObject)Ylast);
496: }
497: SNESGetIterationNumber(snes,&iter);
498: if (iter < 2) {
499: VecCopy(Y,Ylast);
500: *changed = PETSC_FALSE;
501: return 0;
502: }
504: VecDot(Y,Ylast,&dot);
505: VecNorm(Y,NORM_2,&ynorm);
506: VecNorm(Ylast,NORM_2,&ylastnorm);
507: /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
508: theta = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
509: angle_radians = angle * PETSC_PI / 180.;
510: if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
511: /* Modify the step Y */
512: PetscReal alpha,ydiffnorm;
513: VecAXPY(Ylast,-1.0,Y);
514: VecNorm(Ylast,NORM_2,&ydiffnorm);
515: alpha = (ydiffnorm > .001*ylastnorm) ? ylastnorm / ydiffnorm : 1000.0;
516: VecCopy(Y,Ylast);
517: VecScale(Y,alpha);
518: PetscInfo(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);
519: *changed = PETSC_TRUE;
520: } else {
521: PetscInfo(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);
522: VecCopy(Y,Ylast);
523: *changed = PETSC_FALSE;
524: }
525: return 0;
526: }
528: /*@
529: SNESLineSearchApply - Computes the line-search update.
531: Collective on SNESLineSearch
533: Input Parameters:
534: + linesearch - The linesearch context
535: - Y - The search direction
537: Input/Output Parameters:
538: + X - The current solution, on output the new solution
539: . F - The current function, on output the new function
540: - fnorm - The current norm, on output the new function norm
542: Options Database Keys:
543: + -snes_linesearch_type - basic, bt, l2, cp, nleqerr, shell
544: . -snes_linesearch_monitor [:filename] - Print progress of line searches
545: . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping)
546: . -snes_linesearch_norms - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms())
547: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
548: - -snes_linesearch_max_it - The number of iterations for iterative line searches
550: Notes:
551: This is typically called from within a SNESSolve() implementation in order to
552: help with convergence of the nonlinear method. Various SNES types use line searches
553: in different ways, but the overarching theme is that a line search is used to determine
554: an optimal damping parameter of a step at each iteration of the method. Each
555: application of the line search may invoke SNESComputeFunction() several times, and
556: therefore may be fairly expensive.
558: Level: Intermediate
560: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction(), SNESLineSearchSetComputeNorms(),
561: SNESLineSearchType, SNESLineSearchSetType()
562: @*/
563: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
564: {
570: linesearch->result = SNES_LINESEARCH_SUCCEEDED;
572: linesearch->vec_sol = X;
573: linesearch->vec_update = Y;
574: linesearch->vec_func = F;
576: SNESLineSearchSetUp(linesearch);
578: if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
580: if (fnorm) linesearch->fnorm = *fnorm;
581: else {
582: VecNorm(F, NORM_2, &linesearch->fnorm);
583: }
585: PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y);
587: (*linesearch->ops->apply)(linesearch);
589: PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y);
591: if (fnorm) *fnorm = linesearch->fnorm;
592: return 0;
593: }
595: /*@
596: SNESLineSearchDestroy - Destroys the line search instance.
598: Collective on SNESLineSearch
600: Input Parameters:
601: . linesearch - The linesearch context
603: Level: developer
605: .seealso: SNESGetLineSearch(), SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
606: @*/
607: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
608: {
609: if (!*linesearch) return 0;
611: if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = NULL; return 0;}
612: PetscObjectSAWsViewOff((PetscObject)*linesearch);
613: SNESLineSearchReset(*linesearch);
614: if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
615: PetscViewerDestroy(&(*linesearch)->monitor);
616: SNESLineSearchMonitorCancel((*linesearch));
617: PetscHeaderDestroy(linesearch);
618: return 0;
619: }
621: /*@
622: SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.
624: Input Parameters:
625: + linesearch - the linesearch object
626: - viewer - an ASCII PetscViewer or NULL to turn off monitor
628: Logically Collective on SNESLineSearch
630: Options Database:
631: . -snes_linesearch_monitor [:filename] - enables the monitor
633: Level: intermediate
635: Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with
636: SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the
637: line search that are not visible to the other monitors.
639: .seealso: SNESGetLineSearch(), SNESLineSearchGetDefaultMonitor(), PetscViewer, SNESLineSearchSetMonitor()
640: @*/
641: PetscErrorCode SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
642: {
643: if (viewer) PetscObjectReference((PetscObject)viewer);
644: PetscViewerDestroy(&linesearch->monitor);
645: linesearch->monitor = viewer;
646: return 0;
647: }
649: /*@
650: SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.
652: Input Parameter:
653: . linesearch - linesearch context
655: Output Parameter:
656: . monitor - monitor context
658: Logically Collective on SNES
660: Options Database Keys:
661: . -snes_linesearch_monitor - enables the monitor
663: Level: intermediate
665: .seealso: SNESGetLineSearch(), SNESLineSearchSetDefaultMonitor(), PetscViewer
666: @*/
667: PetscErrorCode SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
668: {
670: *monitor = linesearch->monitor;
671: return 0;
672: }
674: /*@C
675: SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
677: Collective on SNESLineSearch
679: Input Parameters:
680: + ls - LineSearch object you wish to monitor
681: . name - the monitor type one is seeking
682: . help - message indicating what monitoring is done
683: . manual - manual page for the monitor
684: . monitor - the monitor function
685: - 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
687: Level: developer
689: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
690: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
691: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
692: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
693: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
694: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
695: PetscOptionsFList(), PetscOptionsEList()
696: @*/
697: PetscErrorCode SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
698: {
699: PetscViewer viewer;
700: PetscViewerFormat format;
701: PetscBool flg;
703: PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject) ls)->options,((PetscObject)ls)->prefix,name,&viewer,&format,&flg);
704: if (flg) {
705: PetscViewerAndFormat *vf;
706: PetscViewerAndFormatCreate(viewer,format,&vf);
707: PetscObjectDereference((PetscObject)viewer);
708: if (monitorsetup) {
709: (*monitorsetup)(ls,vf);
710: }
711: SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
712: }
713: return 0;
714: }
716: /*@
717: SNESLineSearchSetFromOptions - Sets options for the line search
719: Input Parameter:
720: . linesearch - linesearch context
722: Options Database Keys:
723: + -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
724: . -snes_linesearch_order <order> - 1, 2, 3. Most types only support certain orders (bt supports 2 or 3)
725: . -snes_linesearch_norms - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms())
726: . -snes_linesearch_minlambda - The minimum step length
727: . -snes_linesearch_maxstep - The maximum step size
728: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
729: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
730: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
731: . -snes_linesearch_max_it - The number of iterations for iterative line searches
732: . -snes_linesearch_monitor [:filename] - Print progress of line searches
733: . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
734: . -snes_linesearch_damping - The linesearch damping parameter
735: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
736: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
737: - -snes_linesearch_precheck_picard_angle - Angle used in Picard precheck method
739: Logically Collective on SNESLineSearch
741: Level: intermediate
743: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard(),
744: SNESLineSearchType, SNESLineSearchSetComputeNorms()
745: @*/
746: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
747: {
748: PetscErrorCode ierr;
749: const char *deft = SNESLINESEARCHBASIC;
750: char type[256];
751: PetscBool flg, set;
752: PetscViewer viewer;
754: SNESLineSearchRegisterAll();
756: PetscObjectOptionsBegin((PetscObject)linesearch);
757: if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
758: PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
759: if (flg) {
760: SNESLineSearchSetType(linesearch,type);
761: } else if (!((PetscObject)linesearch)->type_name) {
762: SNESLineSearchSetType(linesearch,deft);
763: }
765: PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject) linesearch)->options,((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set);
766: if (set) {
767: SNESLineSearchSetDefaultMonitor(linesearch,viewer);
768: PetscViewerDestroy(&viewer);
769: }
770: SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL);
772: /* tolerances */
773: PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL);
774: PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL);
775: PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL);
776: PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL);
777: PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL);
778: PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL);
780: /* damping parameters */
781: PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL);
783: PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL);
785: /* precheck */
786: PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);
787: if (set) {
788: if (flg) {
789: linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
791: PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
792: "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);
793: SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
794: } else {
795: SNESLineSearchSetPreCheck(linesearch,NULL,NULL);
796: }
797: }
798: PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL);
799: PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL);
801: if (linesearch->ops->setfromoptions) {
802: (*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch);
803: }
805: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch);
806: PetscOptionsEnd();
807: return 0;
808: }
810: /*@
811: SNESLineSearchView - Prints useful information about the line search
813: Input Parameters:
814: . linesearch - linesearch context
816: Logically Collective on SNESLineSearch
818: Level: intermediate
820: .seealso: SNESLineSearchCreate()
821: @*/
822: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
823: {
824: PetscBool iascii;
827: if (!viewer) {
828: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);
829: }
833: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
834: if (iascii) {
835: PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);
836: if (linesearch->ops->view) {
837: PetscViewerASCIIPushTab(viewer);
838: (*linesearch->ops->view)(linesearch,viewer);
839: PetscViewerASCIIPopTab(viewer);
840: }
841: PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);
842: PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);
843: PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", linesearch->max_its);
844: if (linesearch->ops->precheck) {
845: if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
846: PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n", linesearch->max_its);
847: } else {
848: PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n", linesearch->max_its);
849: }
850: }
851: if (linesearch->ops->postcheck) {
852: PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n", linesearch->max_its);
853: }
854: }
855: return 0;
856: }
858: /*@C
859: SNESLineSearchGetType - Gets the linesearch type
861: Logically Collective on SNESLineSearch
863: Input Parameters:
864: . linesearch - linesearch context
866: Output Parameters:
867: - type - The type of line search, or NULL if not set
869: Level: intermediate
871: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchSetType()
872: @*/
873: PetscErrorCode SNESLineSearchGetType(SNESLineSearch linesearch, SNESLineSearchType *type)
874: {
877: *type = ((PetscObject)linesearch)->type_name;
878: return 0;
879: }
881: /*@C
882: SNESLineSearchSetType - Sets the linesearch type
884: Logically Collective on SNESLineSearch
886: Input Parameters:
887: + linesearch - linesearch context
888: - type - The type of line search to be used
890: Available Types:
891: + SNESLINESEARCHBASIC - Simple damping line search, defaults to using the full Newton step
892: . SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
893: . SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
894: . SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
895: . SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
896: - SNESLINESEARCHSHELL - User provided SNESLineSearch implementation
898: Options Database:
899: . -snes_linesearch_type <type> - basic, bt, l2, cp, nleqerr, shell
901: Level: intermediate
903: .seealso: SNESLineSearchCreate(), SNESLineSearchType, SNESLineSearchSetFromOptions(), SNESLineSearchGetType()
904: @*/
905: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
906: {
907: PetscBool match;
908: PetscErrorCode (*r)(SNESLineSearch);
913: PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
914: if (match) return 0;
916: PetscFunctionListFind(SNESLineSearchList,type,&r);
918: /* Destroy the previous private linesearch context */
919: if (linesearch->ops->destroy) {
920: (*(linesearch)->ops->destroy)(linesearch);
921: linesearch->ops->destroy = NULL;
922: }
923: /* Reinitialize function pointers in SNESLineSearchOps structure */
924: linesearch->ops->apply = NULL;
925: linesearch->ops->view = NULL;
926: linesearch->ops->setfromoptions = NULL;
927: linesearch->ops->destroy = NULL;
929: PetscObjectChangeTypeName((PetscObject)linesearch,type);
930: (*r)(linesearch);
931: return 0;
932: }
934: /*@
935: SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
937: Input Parameters:
938: + linesearch - linesearch context
939: - snes - The snes instance
941: Level: developer
943: Notes:
944: This happens automatically when the line search is obtained/created with
945: SNESGetLineSearch(). This routine is therefore mainly called within SNES
946: implementations.
948: Level: developer
950: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
951: @*/
952: PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
953: {
956: linesearch->snes = snes;
957: return 0;
958: }
960: /*@
961: SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
962: Having an associated SNES is necessary because most line search implementations must be able to
963: evaluate the function using SNESComputeFunction() for the associated SNES. This routine
964: is used in the line search implementations when one must get this associated SNES instance.
966: Input Parameters:
967: . linesearch - linesearch context
969: Output Parameters:
970: . snes - The snes instance
972: Level: developer
974: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
975: @*/
976: PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
977: {
980: *snes = linesearch->snes;
981: return 0;
982: }
984: /*@
985: SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
987: Input Parameters:
988: . linesearch - linesearch context
990: Output Parameters:
991: . lambda - The last steplength computed during SNESLineSearchApply()
993: Level: advanced
995: Notes:
996: This is useful in methods where the solver is ill-scaled and
997: requires some adaptive notion of the difference in scale between the
998: solution and the function. For instance, SNESQN may be scaled by the
999: line search lambda using the argument -snes_qn_scaling ls.
1001: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
1002: @*/
1003: PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
1004: {
1007: *lambda = linesearch->lambda;
1008: return 0;
1009: }
1011: /*@
1012: SNESLineSearchSetLambda - Sets the linesearch steplength.
1014: Input Parameters:
1015: + linesearch - linesearch context
1016: - lambda - The last steplength.
1018: Notes:
1019: This routine is typically used within implementations of SNESLineSearchApply()
1020: to set the final steplength. This routine (and SNESLineSearchGetLambda()) were
1021: added in order to facilitate Quasi-Newton methods that use the previous steplength
1022: as an inner scaling parameter.
1024: Level: advanced
1026: .seealso: SNESLineSearchGetLambda()
1027: @*/
1028: PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1029: {
1031: linesearch->lambda = lambda;
1032: return 0;
1033: }
1035: /*@
1036: SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include
1037: tolerances for the relative and absolute change in the function norm, the change
1038: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1039: and the maximum number of iterations the line search procedure may take.
1041: Input Parameter:
1042: . linesearch - linesearch context
1044: Output Parameters:
1045: + steptol - The minimum steplength
1046: . maxstep - The maximum steplength
1047: . rtol - The relative tolerance for iterative line searches
1048: . atol - The absolute tolerance for iterative line searches
1049: . ltol - The change in lambda tolerance for iterative line searches
1050: - max_it - The maximum number of iterations of the line search
1052: Level: intermediate
1054: Notes:
1055: Different line searches may implement these parameters slightly differently as
1056: the type requires.
1058: .seealso: SNESLineSearchSetTolerances()
1059: @*/
1060: PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1061: {
1063: if (steptol) {
1065: *steptol = linesearch->steptol;
1066: }
1067: if (maxstep) {
1069: *maxstep = linesearch->maxstep;
1070: }
1071: if (rtol) {
1073: *rtol = linesearch->rtol;
1074: }
1075: if (atol) {
1077: *atol = linesearch->atol;
1078: }
1079: if (ltol) {
1081: *ltol = linesearch->ltol;
1082: }
1083: if (max_its) {
1085: *max_its = linesearch->max_its;
1086: }
1087: return 0;
1088: }
1090: /*@
1091: SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include
1092: tolerances for the relative and absolute change in the function norm, the change
1093: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1094: and the maximum number of iterations the line search procedure may take.
1096: Input Parameters:
1097: + linesearch - linesearch context
1098: . steptol - The minimum steplength
1099: . maxstep - The maximum steplength
1100: . rtol - The relative tolerance for iterative line searches
1101: . atol - The absolute tolerance for iterative line searches
1102: . ltol - The change in lambda tolerance for iterative line searches
1103: - max_it - The maximum number of iterations of the line search
1105: Notes:
1106: The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1107: place of an argument.
1109: Level: intermediate
1111: .seealso: SNESLineSearchGetTolerances()
1112: @*/
1113: PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1114: {
1123: if (steptol!= PETSC_DEFAULT) {
1125: linesearch->steptol = steptol;
1126: }
1128: if (maxstep!= PETSC_DEFAULT) {
1130: linesearch->maxstep = maxstep;
1131: }
1133: if (rtol != PETSC_DEFAULT) {
1135: linesearch->rtol = rtol;
1136: }
1138: if (atol != PETSC_DEFAULT) {
1140: linesearch->atol = atol;
1141: }
1143: if (ltol != PETSC_DEFAULT) {
1145: linesearch->ltol = ltol;
1146: }
1148: if (max_its != PETSC_DEFAULT) {
1150: linesearch->max_its = max_its;
1151: }
1152: return 0;
1153: }
1155: /*@
1156: SNESLineSearchGetDamping - Gets the line search damping parameter.
1158: Input Parameters:
1159: . linesearch - linesearch context
1161: Output Parameters:
1162: . damping - The damping parameter
1164: Level: advanced
1166: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1167: @*/
1169: PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1170: {
1173: *damping = linesearch->damping;
1174: return 0;
1175: }
1177: /*@
1178: SNESLineSearchSetDamping - Sets the line search damping parameter.
1180: Input Parameters:
1181: + linesearch - linesearch context
1182: - damping - The damping parameter
1184: Options Database:
1185: . -snes_linesearch_damping
1186: Level: intermediate
1188: Notes:
1189: The basic line search merely takes the update step scaled by the damping parameter.
1190: The use of the damping parameter in the l2 and cp line searches is much more subtle;
1191: it is used as a starting point in calculating the secant step. However, the eventual
1192: step may be of greater length than the damping parameter. In the bt line search it is
1193: used as the maximum possible step length, as the bt line search only backtracks.
1195: .seealso: SNESLineSearchGetDamping()
1196: @*/
1197: PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1198: {
1200: linesearch->damping = damping;
1201: return 0;
1202: }
1204: /*@
1205: SNESLineSearchGetOrder - Gets the line search approximation order.
1207: Input Parameters:
1208: . linesearch - linesearch context
1210: Output Parameters:
1211: . order - The order
1213: Possible Values for order:
1214: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1215: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1216: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1218: Level: intermediate
1220: .seealso: SNESLineSearchSetOrder()
1221: @*/
1223: PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1224: {
1227: *order = linesearch->order;
1228: return 0;
1229: }
1231: /*@
1232: SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
1234: Input Parameters:
1235: + linesearch - linesearch context
1236: - order - The damping parameter
1238: Level: intermediate
1240: Possible Values for order:
1241: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1242: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1243: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1245: Notes:
1246: Variable orders are supported by the following line searches:
1247: + bt - cubic and quadratic
1248: - cp - linear and quadratic
1250: .seealso: SNESLineSearchGetOrder(), SNESLineSearchSetDamping()
1251: @*/
1252: PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1253: {
1255: linesearch->order = order;
1256: return 0;
1257: }
1259: /*@
1260: SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1262: Input Parameter:
1263: . linesearch - linesearch context
1265: Output Parameters:
1266: + xnorm - The norm of the current solution
1267: . fnorm - The norm of the current function
1268: - ynorm - The norm of the current update
1270: Notes:
1271: This function is mainly called from SNES implementations.
1273: Level: developer
1275: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1276: @*/
1277: PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1278: {
1280: if (xnorm) *xnorm = linesearch->xnorm;
1281: if (fnorm) *fnorm = linesearch->fnorm;
1282: if (ynorm) *ynorm = linesearch->ynorm;
1283: return 0;
1284: }
1286: /*@
1287: SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1289: Input Parameters:
1290: + linesearch - linesearch context
1291: . xnorm - The norm of the current solution
1292: . fnorm - The norm of the current function
1293: - ynorm - The norm of the current update
1295: Level: advanced
1297: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1298: @*/
1299: PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1300: {
1302: linesearch->xnorm = xnorm;
1303: linesearch->fnorm = fnorm;
1304: linesearch->ynorm = ynorm;
1305: return 0;
1306: }
1308: /*@
1309: SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1311: Input Parameters:
1312: . linesearch - linesearch context
1314: Options Database Keys:
1315: . -snes_linesearch_norms - turn norm computation on or off
1317: Level: intermediate
1319: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1320: @*/
1321: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1322: {
1323: SNES snes;
1325: if (linesearch->norms) {
1326: if (linesearch->ops->vinorm) {
1327: SNESLineSearchGetSNES(linesearch, &snes);
1328: VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1329: VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1330: (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1331: } else {
1332: VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1333: VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1334: VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1335: VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1336: VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1337: VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1338: }
1339: }
1340: return 0;
1341: }
1343: /*@
1344: SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
1346: Input Parameters:
1347: + linesearch - linesearch context
1348: - flg - indicates whether or not to compute norms
1350: Options Database Keys:
1351: . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic linesearch
1353: Notes:
1354: This is most relevant to the SNESLINESEARCHBASIC line search type since most line searches have a stopping criteria involving the norm.
1356: Level: intermediate
1358: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1359: @*/
1360: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1361: {
1362: linesearch->norms = flg;
1363: return 0;
1364: }
1366: /*@
1367: SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1369: Input Parameter:
1370: . linesearch - linesearch context
1372: Output Parameters:
1373: + X - Solution vector
1374: . F - Function vector
1375: . Y - Search direction vector
1376: . W - Solution work vector
1377: - G - Function work vector
1379: Notes:
1380: At the beginning of a line search application, X should contain a
1381: solution and the vector F the function computed at X. At the end of the
1382: line search application, X should contain the new solution, and F the
1383: function evaluated at the new solution.
1385: These vectors are owned by the SNESLineSearch and should not be destroyed by the caller
1387: Level: advanced
1389: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1390: @*/
1391: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1392: {
1394: if (X) {
1396: *X = linesearch->vec_sol;
1397: }
1398: if (F) {
1400: *F = linesearch->vec_func;
1401: }
1402: if (Y) {
1404: *Y = linesearch->vec_update;
1405: }
1406: if (W) {
1408: *W = linesearch->vec_sol_new;
1409: }
1410: if (G) {
1412: *G = linesearch->vec_func_new;
1413: }
1414: return 0;
1415: }
1417: /*@
1418: SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1420: Input Parameters:
1421: + linesearch - linesearch context
1422: . X - Solution vector
1423: . F - Function vector
1424: . Y - Search direction vector
1425: . W - Solution work vector
1426: - G - Function work vector
1428: Level: advanced
1430: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1431: @*/
1432: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1433: {
1435: if (X) {
1437: linesearch->vec_sol = X;
1438: }
1439: if (F) {
1441: linesearch->vec_func = F;
1442: }
1443: if (Y) {
1445: linesearch->vec_update = Y;
1446: }
1447: if (W) {
1449: linesearch->vec_sol_new = W;
1450: }
1451: if (G) {
1453: linesearch->vec_func_new = G;
1454: }
1455: return 0;
1456: }
1458: /*@C
1459: SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1460: SNES options in the database.
1462: Logically Collective on SNESLineSearch
1464: Input Parameters:
1465: + snes - the SNES context
1466: - prefix - the prefix to prepend to all option names
1468: Notes:
1469: A hyphen (-) must NOT be given at the beginning of the prefix name.
1470: The first character of all runtime options is AUTOMATICALLY the hyphen.
1472: Level: advanced
1474: .seealso: SNESGetOptionsPrefix()
1475: @*/
1476: PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1477: {
1479: PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1480: return 0;
1481: }
1483: /*@C
1484: SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1485: SNESLineSearch options in the database.
1487: Not Collective
1489: Input Parameter:
1490: . linesearch - the SNESLineSearch context
1492: Output Parameter:
1493: . prefix - pointer to the prefix string used
1495: Notes:
1496: On the fortran side, the user should pass in a string 'prefix' of
1497: sufficient length to hold the prefix.
1499: Level: advanced
1501: .seealso: SNESAppendOptionsPrefix()
1502: @*/
1503: PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1504: {
1506: PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1507: return 0;
1508: }
1510: /*@C
1511: SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1513: Input Parameters:
1514: + linesearch - the SNESLineSearch context
1515: - nwork - the number of work vectors
1517: Level: developer
1519: .seealso: SNESSetWorkVecs()
1520: @*/
1521: PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1522: {
1523: if (linesearch->vec_sol) {
1524: VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1525: } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1526: return 0;
1527: }
1529: /*@
1530: SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1532: Input Parameters:
1533: . linesearch - linesearch context
1535: Output Parameters:
1536: . result - The success or failure status
1538: Notes:
1539: This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1540: (and set the SNES convergence accordingly).
1542: Level: intermediate
1544: .seealso: SNESLineSearchSetReason(), SNESLineSearchReason
1545: @*/
1546: PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1547: {
1550: *result = linesearch->result;
1551: return 0;
1552: }
1554: /*@
1555: SNESLineSearchSetReason - Sets the success/failure status of the last line search application
1557: Input Parameters:
1558: + linesearch - linesearch context
1559: - result - The success or failure status
1561: Notes:
1562: This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1563: the success or failure of the line search method.
1565: Level: developer
1567: .seealso: SNESLineSearchGetSResult()
1568: @*/
1569: PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1570: {
1572: linesearch->result = result;
1573: return 0;
1574: }
1576: /*@C
1577: SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
1579: Input Parameters:
1580: + snes - nonlinear context obtained from SNESCreate()
1581: . projectfunc - function for projecting the function to the bounds
1582: - normfunc - function for computing the norm of an active set
1584: Logically Collective on SNES
1586: Calling sequence of projectfunc:
1587: .vb
1588: projectfunc (SNES snes, Vec X)
1589: .ve
1591: Input parameters for projectfunc:
1592: + snes - nonlinear context
1593: - X - current solution
1595: Output parameters for projectfunc:
1596: . X - Projected solution
1598: Calling sequence of normfunc:
1599: .vb
1600: projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1601: .ve
1603: Input parameters for normfunc:
1604: + snes - nonlinear context
1605: . X - current solution
1606: - F - current residual
1608: Output parameters for normfunc:
1609: . fnorm - VI-specific norm of the function
1611: Notes:
1612: The VI solvers require projection of the solution to the feasible set. projectfunc should implement this.
1614: The VI solvers require special evaluation of the function norm such that the norm is only calculated
1615: on the inactive set. This should be implemented by normfunc.
1617: Level: developer
1619: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1620: @*/
1621: PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1622: {
1624: if (projectfunc) linesearch->ops->viproject = projectfunc;
1625: if (normfunc) linesearch->ops->vinorm = normfunc;
1626: return 0;
1627: }
1629: /*@C
1630: SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
1632: Input Parameter:
1633: . linesearch - the line search context, obtain with SNESGetLineSearch()
1635: Output Parameters:
1636: + projectfunc - function for projecting the function to the bounds
1637: - normfunc - function for computing the norm of an active set
1639: Logically Collective on SNES
1641: Level: developer
1643: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1644: @*/
1645: PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1646: {
1647: if (projectfunc) *projectfunc = linesearch->ops->viproject;
1648: if (normfunc) *normfunc = linesearch->ops->vinorm;
1649: return 0;
1650: }
1652: /*@C
1653: SNESLineSearchRegister - See SNESLineSearchRegister()
1655: Level: advanced
1656: @*/
1657: PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1658: {
1659: SNESInitializePackage();
1660: PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1661: return 0;
1662: }