Actual source code: linesearch.c
petsc-dev 2014-02-02
1: #include <petsc-private/linesearchimpl.h> /*I "petscsnes.h" I*/
3: PetscBool SNESLineSearchRegisterAllCalled = PETSC_FALSE;
4: PetscFunctionList SNESLineSearchList = NULL;
6: PetscClassId SNESLINESEARCH_CLASSID;
7: PetscLogEvent SNESLineSearch_Apply;
11: /*@
12: SNESLineSearchCreate - Creates the line search context.
14: Logically Collective on Comm
16: Input Parameters:
17: . comm - MPI communicator for the line search (typically from the associated SNES context).
19: Output Parameters:
20: . outlinesearch - the new linesearch context
22: Level: beginner
24: .keywords: LineSearch, create, context
26: .seealso: LineSearchDestroy()
27: @*/
29: PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
30: {
32: SNESLineSearch linesearch;
36: SNESInitializePackage();
37: *outlinesearch = NULL;
39: PetscHeaderCreate(linesearch,_p_LineSearch,struct _LineSearchOps,SNESLINESEARCH_CLASSID, "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView);
41: linesearch->ops->precheck = NULL;
42: linesearch->ops->postcheck = NULL;
44: linesearch->vec_sol_new = NULL;
45: linesearch->vec_func_new = NULL;
46: linesearch->vec_sol = NULL;
47: linesearch->vec_func = NULL;
48: linesearch->vec_update = NULL;
50: linesearch->lambda = 1.0;
51: linesearch->fnorm = 1.0;
52: linesearch->ynorm = 1.0;
53: linesearch->xnorm = 1.0;
54: linesearch->success = PETSC_TRUE;
55: linesearch->norms = PETSC_TRUE;
56: linesearch->keeplambda = PETSC_FALSE;
57: linesearch->damping = 1.0;
58: linesearch->maxstep = 1e8;
59: linesearch->steptol = 1e-12;
60: linesearch->rtol = 1e-8;
61: linesearch->atol = 1e-15;
62: linesearch->ltol = 1e-8;
63: linesearch->precheckctx = NULL;
64: linesearch->postcheckctx = NULL;
65: linesearch->max_its = 1;
66: linesearch->setupcalled = PETSC_FALSE;
67: *outlinesearch = linesearch;
68: return(0);
69: }
73: /*@
74: SNESLineSearchSetUp - Prepares the line search for being applied by allocating
75: any required vectors.
77: Collective on SNESLineSearch
79: Input Parameters:
80: . linesearch - The LineSearch instance.
82: Notes:
83: For most cases, this needn't be called outside of SNESLineSearchApply().
84: The only current case where this is called outside of this is for the VI
85: solvers, which modify the solution and work vectors before the first call
86: of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be
87: allocated upfront.
89: Level: advanced
91: .keywords: SNESLineSearch, SetUp
93: .seealso: SNESLineSearchReset()
94: @*/
96: PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
97: {
101: if (!((PetscObject)linesearch)->type_name) {
102: SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC);
103: }
104: if (!linesearch->setupcalled) {
105: if (!linesearch->vec_sol_new) {
106: VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);
107: }
108: if (!linesearch->vec_func_new) {
109: VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);
110: }
111: if (linesearch->ops->setup) {
112: (*linesearch->ops->setup)(linesearch);
113: }
114: if (!linesearch->ops->snesfunc) {SNESLineSearchSetFunction(linesearch,SNESComputeFunction);}
115: linesearch->lambda = linesearch->damping;
116: linesearch->setupcalled = PETSC_TRUE;
117: }
118: return(0);
119: }
124: /*@
125: SNESLineSearchReset - Undoes the SetUp and deletes any Vecs or Mats allocated by the line search.
127: Collective on SNESLineSearch
129: Input Parameters:
130: . linesearch - The LineSearch instance.
132: Level: intermediate
134: .keywords: SNESLineSearch, Reset
136: .seealso: SNESLineSearchSetUp()
137: @*/
139: PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
140: {
144: if (linesearch->ops->reset) (*linesearch->ops->reset)(linesearch);
146: VecDestroy(&linesearch->vec_sol_new);
147: VecDestroy(&linesearch->vec_func_new);
149: VecDestroyVecs(linesearch->nwork, &linesearch->work);
151: linesearch->nwork = 0;
152: linesearch->setupcalled = PETSC_FALSE;
153: return(0);
154: }
158: /*@C
159: SNESLineSearchSetPreCheck - Sets the function evaluation context on the
161: Input Parameters:
162: . linesearch - the SNESLineSearch context
164: Output Parameters:
165: + func - [optional] function evaluation routine
167: Level: developer
169: .keywords: get, linesearch, pre-check
171: .seealso: SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck()
172: @*/
173: PetscErrorCode SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
174: {
177: linesearch->ops->snesfunc = func;
178: return(0);
179: }
182: /*MC
183: SNESLineSearchPreCheckFunction - functional form passed to check before line search is called
185: Synopsis:
186: #include <petscsnes.h>
187: SNESLineSearchPreCheckFunction(SNESLineSearch snes,Vec x,Vec y, PetscBool *changed);
189: Input Parameters:
190: + x - solution vector
191: . y - search direction vector
192: - changed - flag to indicate the precheck changed x or y.
194: Level: advanced
196: .seealso: SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck()
197: M*/
201: /*@C
202: SNESLineSearchSetPreCheck - Sets a pre-check function for the line search routine.
204: Logically Collective on SNESLineSearch
206: Input Parameters:
207: + linesearch - the SNESLineSearch context
208: . SNESLineSearchPreCheckFunction - [optional] function evaluation routine
209: - ctx - [optional] user-defined context for private data for the
210: function evaluation routine (may be NULL)
213: Level: intermediate
215: .keywords: set, linesearch, pre-check
217: .seealso: SNESLineSearchSetPostCheck()
218: @*/
219: PetscErrorCode SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*SNESLineSearchPreCheckFunction)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
220: {
223: if (SNESLineSearchPreCheckFunction) linesearch->ops->precheck = SNESLineSearchPreCheckFunction;
224: if (ctx) linesearch->precheckctx = ctx;
225: return(0);
226: }
230: /*@C
231: SNESLineSearchSetPreCheck - Gets the pre-check function for the line search routine.
233: Input Parameters:
234: . linesearch - the SNESLineSearch context
236: Output Parameters:
237: + func - [optional] function evaluation routine
238: - ctx - [optional] user-defined context for private data for the
239: function evaluation routine (may be NULL)
241: Level: intermediate
243: .keywords: get, linesearch, pre-check
245: .seealso: SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck()
246: @*/
247: PetscErrorCode SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**SNESLineSearchPreCheckFunction)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
248: {
251: if (SNESLineSearchPreCheckFunction) *SNESLineSearchPreCheckFunction = linesearch->ops->precheck;
252: if (ctx) *ctx = linesearch->precheckctx;
253: return(0);
254: }
256: /*MC
257: SNESLineSearchPostheckFunction - functional form that is called after line search is complete
259: Synopsis:
260: #include <petscsnes.h>
261: SNESLineSearchPostheckFunction(SNESLineSearch linesearch,Vec x,Vec y, Vec w, *changed_y, PetscBool *changed_w);
263: Input Parameters:
264: + x - old solution vector
265: . y - search direction vector
266: . w - new solution vector
267: . changed_y - indicates that the line search changed y
268: - changed_w - indicates that the line search changed w
270: Level: advanced
272: .seealso: SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck()
273: M*/
277: /*@C
278: SNESLineSearchSetPostCheck - Sets a post-check function for the line search routine.
280: Logically Collective on SNESLineSearch
282: Input Parameters:
283: + linesearch - the SNESLineSearch context
284: . SNESLineSearchPostCheckFunction - [optional] function evaluation routine
285: - ctx - [optional] user-defined context for private data for the
286: function evaluation routine (may be NULL)
288: Level: intermediate
290: .keywords: set, linesearch, post-check
292: .seealso: SNESLineSearchSetPreCheck()
293: @*/
294: PetscErrorCode SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*SNESLineSearchPostCheckFunction)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
295: {
298: if (SNESLineSearchPostCheckFunction) linesearch->ops->postcheck = SNESLineSearchPostCheckFunction;
299: if (ctx) linesearch->postcheckctx = ctx;
300: return(0);
301: }
305: /*@C
306: SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.
308: Input Parameters:
309: . linesearch - the SNESLineSearch context
311: Output Parameters:
312: + SNESLineSearchPostCheckFunction - [optional] function evaluation routine
313: - ctx - [optional] user-defined context for private data for the
314: function evaluation routine (may be NULL)
316: Level: intermediate
318: .keywords: get, linesearch, post-check
320: .seealso: SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck()
321: @*/
322: PetscErrorCode SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**SNESLineSearchPostCheckFunction)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
323: {
326: if (SNESLineSearchPostCheckFunction) *SNESLineSearchPostCheckFunction = linesearch->ops->postcheck;
327: if (ctx) *ctx = linesearch->postcheckctx;
328: return(0);
329: }
333: /*@
334: SNESLineSearchPreCheck - Prepares the line search for being applied.
336: Logically Collective on SNESLineSearch
338: Input Parameters:
339: + linesearch - The linesearch instance.
340: . X - The current solution
341: - Y - The step direction
343: Output Parameters:
344: . changed - Indicator that the precheck routine has changed anything
346: Level: Beginner
348: .keywords: SNESLineSearch, Create
350: .seealso: SNESLineSearchPostCheck()
351: @*/
352: PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
353: {
357: *changed = PETSC_FALSE;
358: if (linesearch->ops->precheck) {
359: (*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx);
361: }
362: return(0);
363: }
367: /*@
368: SNESLineSearchPostCheck - Prepares the line search for being applied.
370: Logically Collective on SNESLineSearch
372: Input Parameters:
373: + linesearch - The linesearch context
374: . X - The last solution
375: . Y - The step direction
376: - W - The updated solution, W = X + lambda*Y for some lambda
378: Output Parameters:
379: + changed_Y - Indicator if the direction Y has been changed.
380: - changed_W - Indicator if the new candidate solution W has been changed.
382: Level: Intermediate
384: .keywords: SNESLineSearch, Create
386: .seealso: SNESLineSearchPreCheck()
387: @*/
388: PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
389: {
393: *changed_Y = PETSC_FALSE;
394: *changed_W = PETSC_FALSE;
395: if (linesearch->ops->postcheck) {
396: (*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx);
399: }
400: return(0);
401: }
405: /*@C
406: SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration
408: Logically Collective on SNESLineSearch
410: Input Arguments:
411: + linesearch - linesearch context
412: . X - base state for this step
413: . Y - initial correction
415: Output Arguments:
416: + Y - correction, possibly modified
417: - changed - flag indicating that Y was modified
419: Options Database Key:
420: + -snes_linesearch_precheck_picard - activate this routine
421: - -snes_linesearch_precheck_picard_angle - angle
423: Level: advanced
425: Notes:
426: This function should be passed to SNESLineSearchSetPreCheck()
428: The justification for this method involves the linear convergence of a Picard iteration
429: so the Picard linearization should be provided in place of the "Jacobian". This correction
430: is generally not useful when using a Newton linearization.
432: Reference:
433: Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.
435: .seealso: SNESLineSearchSetPreCheck()
436: @*/
437: PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
438: {
440: PetscReal angle = *(PetscReal*)linesearch->precheckctx;
441: Vec Ylast;
442: PetscScalar dot;
443: PetscInt iter;
444: PetscReal ynorm,ylastnorm,theta,angle_radians;
445: SNES snes;
448: SNESLineSearchGetSNES(linesearch, &snes);
449: PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);
450: if (!Ylast) {
451: VecDuplicate(Y,&Ylast);
452: PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);
453: PetscObjectDereference((PetscObject)Ylast);
454: }
455: SNESGetIterationNumber(snes,&iter);
456: if (iter < 2) {
457: VecCopy(Y,Ylast);
458: *changed = PETSC_FALSE;
459: return(0);
460: }
462: VecDot(Y,Ylast,&dot);
463: VecNorm(Y,NORM_2,&ynorm);
464: VecNorm(Ylast,NORM_2,&ylastnorm);
465: /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
466: theta = acos((double)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
467: angle_radians = angle * PETSC_PI / 180.;
468: if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
469: /* Modify the step Y */
470: PetscReal alpha,ydiffnorm;
471: VecAXPY(Ylast,-1.0,Y);
472: VecNorm(Ylast,NORM_2,&ydiffnorm);
473: alpha = ylastnorm / ydiffnorm;
474: VecCopy(Y,Ylast);
475: VecScale(Y,alpha);
476: 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);
477: } else {
478: PetscInfo2(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle);
479: VecCopy(Y,Ylast);
480: *changed = PETSC_FALSE;
481: }
482: return(0);
483: }
487: /*@
488: SNESLineSearchApply - Computes the line-search update.
490: Collective on SNESLineSearch
492: Input Parameters:
493: + linesearch - The linesearch context
494: . X - The current solution
495: . F - The current function
496: . fnorm - The current norm
497: - Y - The search direction
499: Output Parameters:
500: + X - The new solution
501: . F - The new function
502: - fnorm - The new function norm
504: Options Database Keys:
505: + -snes_linesearch_type - basic, bt, l2, cp, shell
506: . -snes_linesearch_monitor - Print progress of line searches
507: . -snes_linesearch_damping - The linesearch damping parameter
508: . -snes_linesearch_norms - Turn on/off the linesearch norms
509: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
510: - -snes_linesearch_max_it - The number of iterations for iterative line searches
512: Notes:
513: This is typically called from within a SNESSolve() implementation in order to
514: help with convergence of the nonlinear method. Various SNES types use line searches
515: in different ways, but the overarching theme is that a line search is used to determine
516: an optimal damping parameter of a step at each iteration of the method. Each
517: application of the line search may invoke SNESComputeFunction several times, and
518: therefore may be fairly expensive.
520: Level: Intermediate
522: .keywords: SNESLineSearch, Create
524: .seealso: SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck(), SNESSolve(), SNESComputeFunction()
525: @*/
526: PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
527: {
536: linesearch->success = PETSC_TRUE;
538: linesearch->vec_sol = X;
539: linesearch->vec_update = Y;
540: linesearch->vec_func = F;
542: SNESLineSearchSetUp(linesearch);
544: if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
546: if (fnorm) linesearch->fnorm = *fnorm;
547: else {
548: VecNorm(F, NORM_2, &linesearch->fnorm);
549: }
551: PetscLogEventBegin(SNESLineSearch_Apply,linesearch,X,F,Y);
553: (*linesearch->ops->apply)(linesearch);
555: PetscLogEventEnd(SNESLineSearch_Apply,linesearch,X,F,Y);
557: if (fnorm) *fnorm = linesearch->fnorm;
558: return(0);
559: }
563: /*@
564: SNESLineSearchDestroy - Destroys the line search instance.
566: Collective on SNESLineSearch
568: Input Parameters:
569: . linesearch - The linesearch context
571: Level: Intermediate
573: .keywords: SNESLineSearch, Destroy
575: .seealso: SNESLineSearchCreate(), SNESLineSearchReset(), SNESDestroy()
576: @*/
577: PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
578: {
582: if (!*linesearch) return(0);
584: if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; return(0);}
585: PetscObjectSAWsViewOff((PetscObject)*linesearch);
586: SNESLineSearchReset(*linesearch);
587: if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
588: PetscViewerDestroy(&(*linesearch)->monitor);
589: PetscHeaderDestroy(linesearch);
590: return(0);
591: }
595: /*@
596: SNESLineSearchSetMonitor - Turns on/off printing useful information and debugging output about the line search.
598: Input Parameters:
599: + snes - nonlinear context obtained from SNESCreate()
600: - flg - PETSC_TRUE to monitor the line search
602: Logically Collective on SNES
604: Options Database:
605: . -snes_linesearch_monitor - enables the monitor
607: Level: intermediate
610: .seealso: SNESLineSearchGetMonitor(), PetscViewer
611: @*/
612: PetscErrorCode SNESLineSearchSetMonitor(SNESLineSearch linesearch, PetscBool flg)
613: {
617: if (flg && !linesearch->monitor) {
618: PetscViewerASCIIOpen(PetscObjectComm((PetscObject)linesearch),"stdout",&linesearch->monitor);
619: } else if (!flg && linesearch->monitor) {
620: PetscViewerDestroy(&linesearch->monitor);
621: }
622: return(0);
623: }
627: /*@
628: SNESLineSearchGetMonitor - Gets the PetscViewer instance for the line search monitor.
630: Input Parameters:
631: . linesearch - linesearch context
633: Input Parameters:
634: . monitor - monitor context
636: Logically Collective on SNES
639: Options Database Keys:
640: . -snes_linesearch_monitor - enables the monitor
642: Level: intermediate
645: .seealso: SNESLineSearchSetMonitor(), PetscViewer
646: @*/
647: PetscErrorCode SNESLineSearchGetMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
648: {
651: if (monitor) {
653: *monitor = linesearch->monitor;
654: }
655: return(0);
656: }
660: /*@
661: SNESLineSearchSetFromOptions - Sets options for the line search
663: Input Parameters:
664: . linesearch - linesearch context
666: Options Database Keys:
667: + -snes_linesearch_type <type> - basic, bt, l2, cp, shell
668: . -snes_linesearch_order <order> - 1, 2, 3. Most types only support certain orders (bt supports 2 or 3)
669: . -snes_linesearch_norms - Turn on/off the linesearch norms for the basic linesearch type
670: . -snes_linesearch_minlambda - The minimum step length
671: . -snes_linesearch_maxstep - The maximum step size
672: . -snes_linesearch_rtol - Relative tolerance for iterative line searches
673: . -snes_linesearch_atol - Absolute tolerance for iterative line searches
674: . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
675: . -snes_linesearch_max_it - The number of iterations for iterative line searches
676: . -snes_linesearch_monitor - Print progress of line searches
677: . -snes_linesearch_damping - The linesearch damping parameter
678: . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
679: . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
680: - -snes_linesearch_precheck_picard_angle - Angle used in picard precheck method
682: Logically Collective on SNESLineSearch
684: Level: intermediate
686: .seealso: SNESLineSearchCreate(), SNESLineSearchSetOrder(), SNESLineSearchSetType(), SNESLineSearchSetTolerances(), SNESLineSearchSetDamping(), SNESLineSearchPreCheckPicard()
687: @*/
688: PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
689: {
691: const char *deft = SNESLINESEARCHBASIC;
692: char type[256];
693: PetscBool flg, set;
696: if (!SNESLineSearchRegisterAllCalled) {SNESLineSearchRegisterAll();}
698: PetscObjectOptionsBegin((PetscObject)linesearch);
699: if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
700: PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);
701: if (flg) {
702: SNESLineSearchSetType(linesearch,type);
703: } else if (!((PetscObject)linesearch)->type_name) {
704: SNESLineSearchSetType(linesearch,deft);
705: }
707: PetscOptionsBool("-snes_linesearch_monitor","Print progress of line searches","SNESSNESLineSearchSetMonitor",
708: linesearch->monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);
709: if (set) {SNESLineSearchSetMonitor(linesearch,flg);}
711: /* tolerances */
712: PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,0);
713: PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,0);
714: PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,0);
715: PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,0);
716: PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,0);
717: PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,0);
719: /* damping parameters */
720: PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,0);
722: PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,0);
724: /* precheck */
725: PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);
726: if (set) {
727: if (flg) {
728: linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
730: PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
731: "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL);
732: SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);
733: } else {
734: SNESLineSearchSetPreCheck(linesearch,NULL,NULL);
735: }
736: }
737: PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,0);
738: PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,0);
740: if (linesearch->ops->setfromoptions) {
741: (*linesearch->ops->setfromoptions)(linesearch);
742: }
744: PetscObjectProcessOptionsHandlers((PetscObject)linesearch);
745: PetscOptionsEnd();
746: return(0);
747: }
751: /*@
752: SNESLineSearchView - Prints useful information about the line search not
753: related to an individual call.
755: Input Parameters:
756: . linesearch - linesearch context
758: Logically Collective on SNESLineSearch
760: Level: intermediate
762: .seealso: SNESLineSearchCreate()
763: @*/
764: PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
765: {
767: PetscBool iascii;
771: if (!viewer) {
772: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer);
773: }
777: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
778: if (iascii) {
779: PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer);
780: if (linesearch->ops->view) {
781: PetscViewerASCIIPushTab(viewer);
782: (*linesearch->ops->view)(linesearch,viewer);
783: PetscViewerASCIIPopTab(viewer);
784: }
785: PetscViewerASCIIPrintf(viewer," maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol);
786: PetscViewerASCIIPrintf(viewer," tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol);
787: PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", linesearch->max_its);
788: if (linesearch->ops->precheck) {
789: if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
790: PetscViewerASCIIPrintf(viewer," using precheck step to speed up Picard convergence\n", linesearch->max_its);
791: } else {
792: PetscViewerASCIIPrintf(viewer," using user-defined precheck step\n", linesearch->max_its);
793: }
794: }
795: if (linesearch->ops->postcheck) {
796: PetscViewerASCIIPrintf(viewer," using user-defined postcheck step\n", linesearch->max_its);
797: }
798: }
799: return(0);
800: }
804: /*@C
805: SNESLineSearchSetType - Sets the linesearch type
807: Input Parameters:
808: + linesearch - linesearch context
809: - type - The type of line search to be used
811: Available Types:
812: + basic - Simple damping line search.
813: . bt - Backtracking line search over the L2 norm of the function
814: . l2 - Secant line search over the L2 norm of the function
815: . cp - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
816: - shell - User provided SNESLineSearch implementation
818: Logically Collective on SNESLineSearch
820: Level: intermediate
823: .seealso: SNESLineSearchCreate()
824: @*/
825: PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
826: {
827: PetscErrorCode ierr,(*r)(SNESLineSearch);
828: PetscBool match;
834: PetscObjectTypeCompare((PetscObject)linesearch,type,&match);
835: if (match) return(0);
837: PetscFunctionListFind(SNESLineSearchList,type,&r);
838: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
839: /* Destroy the previous private linesearch context */
840: if (linesearch->ops->destroy) {
841: (*(linesearch)->ops->destroy)(linesearch);
843: linesearch->ops->destroy = NULL;
844: }
845: /* Reinitialize function pointers in SNESLineSearchOps structure */
846: linesearch->ops->apply = 0;
847: linesearch->ops->view = 0;
848: linesearch->ops->setfromoptions = 0;
849: linesearch->ops->destroy = 0;
851: PetscObjectChangeTypeName((PetscObject)linesearch,type);
852: (*r)(linesearch);
853: return(0);
854: }
858: /*@
859: SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
861: Input Parameters:
862: + linesearch - linesearch context
863: - snes - The snes instance
865: Level: developer
867: Notes:
868: This happens automatically when the line search is gotten/created with
869: SNESGetLineSearch(). This routine is therefore mainly called within SNES
870: implementations.
872: Level: developer
874: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
875: @*/
876: PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
877: {
881: linesearch->snes = snes;
882: return(0);
883: }
887: /*@
888: SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
889: Having an associated SNES is necessary because most line search implementations must be able to
890: evaluate the function using SNESComputeFunction() for the associated SNES. This routine
891: is used in the line search implementations when one must get this associated SNES instance.
893: Input Parameters:
894: . linesearch - linesearch context
896: Output Parameters:
897: . snes - The snes instance
899: Level: developer
901: .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs(), SNES
902: @*/
903: PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
904: {
908: *snes = linesearch->snes;
909: return(0);
910: }
914: /*@
915: SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
917: Input Parameters:
918: . linesearch - linesearch context
920: Output Parameters:
921: . lambda - The last steplength computed during SNESLineSearchApply()
923: Level: advanced
925: Notes:
926: This is useful in methods where the solver is ill-scaled and
927: requires some adaptive notion of the difference in scale between the
928: solution and the function. For instance, SNESQN may be scaled by the
929: line search lambda using the argument -snes_qn_scaling ls.
932: .seealso: SNESLineSearchSetLambda(), SNESLineSearchGetDamping(), SNESLineSearchApply()
933: @*/
934: PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
935: {
939: *lambda = linesearch->lambda;
940: return(0);
941: }
945: /*@
946: SNESLineSearchSetLambda - Sets the linesearch steplength.
948: Input Parameters:
949: + linesearch - linesearch context
950: - lambda - The last steplength.
952: Notes:
953: This routine is typically used within implementations of SNESLineSearchApply
954: to set the final steplength. This routine (and SNESLineSearchGetLambda()) were
955: added in order to facilitate Quasi-Newton methods that use the previous steplength
956: as an inner scaling parameter.
958: Level: advanced
960: .seealso: SNESLineSearchGetLambda()
961: @*/
962: PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
963: {
966: linesearch->lambda = lambda;
967: return(0);
968: }
970: #undef __FUNCT__
972: /*@
973: SNESLineSearchGetTolerances - Gets the tolerances for the linesearch. These include
974: tolerances for the relative and absolute change in the function norm, the change
975: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
976: and the maximum number of iterations the line search procedure may take.
978: Input Parameters:
979: . linesearch - linesearch context
981: Output Parameters:
982: + steptol - The minimum steplength
983: . maxstep - The maximum steplength
984: . rtol - The relative tolerance for iterative line searches
985: . atol - The absolute tolerance for iterative line searches
986: . ltol - The change in lambda tolerance for iterative line searches
987: - max_it - The maximum number of iterations of the line search
989: Level: intermediate
991: Notes:
992: Different line searches may implement these parameters slightly differently as
993: the type requires.
995: .seealso: SNESLineSearchSetTolerances()
996: @*/
997: PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
998: {
1001: if (steptol) {
1003: *steptol = linesearch->steptol;
1004: }
1005: if (maxstep) {
1007: *maxstep = linesearch->maxstep;
1008: }
1009: if (rtol) {
1011: *rtol = linesearch->rtol;
1012: }
1013: if (atol) {
1015: *atol = linesearch->atol;
1016: }
1017: if (ltol) {
1019: *ltol = linesearch->ltol;
1020: }
1021: if (max_its) {
1023: *max_its = linesearch->max_its;
1024: }
1025: return(0);
1026: }
1028: #undef __FUNCT__
1030: /*@
1031: SNESLineSearchSetTolerances - Gets the tolerances for the linesearch. These include
1032: tolerances for the relative and absolute change in the function norm, the change
1033: in lambda for iterative line searches, the minimum steplength, the maximum steplength,
1034: and the maximum number of iterations the line search procedure may take.
1036: Input Parameters:
1037: + linesearch - linesearch context
1038: . steptol - The minimum steplength
1039: . maxstep - The maximum steplength
1040: . rtol - The relative tolerance for iterative line searches
1041: . atol - The absolute tolerance for iterative line searches
1042: . ltol - The change in lambda tolerance for iterative line searches
1043: - max_it - The maximum number of iterations of the line search
1045: Notes:
1046: The user may choose to not set any of the tolerances using PETSC_DEFAULT in
1047: place of an argument.
1049: Level: intermediate
1051: .seealso: SNESLineSearchGetTolerances()
1052: @*/
1053: PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1054: {
1064: if (steptol!= PETSC_DEFAULT) {
1065: if (steptol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
1066: linesearch->steptol = steptol;
1067: }
1069: if (maxstep!= PETSC_DEFAULT) {
1070: if (maxstep < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1071: linesearch->maxstep = maxstep;
1072: }
1074: if (rtol != PETSC_DEFAULT) {
1075: 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);
1076: linesearch->rtol = rtol;
1077: }
1079: if (atol != PETSC_DEFAULT) {
1080: if (atol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1081: linesearch->atol = atol;
1082: }
1084: if (ltol != PETSC_DEFAULT) {
1085: if (ltol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Labmda tolerance %14.12e must be non-negative",(double)ltol);
1086: linesearch->ltol = ltol;
1087: }
1089: if (max_its != PETSC_DEFAULT) {
1090: if (max_its < 0) SETERRQ1(PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",max_its);
1091: linesearch->max_its = max_its;
1092: }
1093: return(0);
1094: }
1098: /*@
1099: SNESLineSearchGetDamping - Gets the line search damping parameter.
1101: Input Parameters:
1102: . linesearch - linesearch context
1104: Output Parameters:
1105: . damping - The damping parameter
1107: Level: advanced
1109: .seealso: SNESLineSearchGetStepTolerance(), SNESQN
1110: @*/
1112: PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
1113: {
1117: *damping = linesearch->damping;
1118: return(0);
1119: }
1123: /*@
1124: SNESLineSearchSetDamping - Sets the line search damping paramter.
1126: Input Parameters:
1127: . linesearch - linesearch context
1128: . damping - The damping parameter
1130: Level: intermediate
1132: Notes:
1133: The basic line search merely takes the update step scaled by the damping parameter.
1134: The use of the damping parameter in the l2 and cp line searches is much more subtle;
1135: it is used as a starting point in calculating the secant step. However, the eventual
1136: step may be of greater length than the damping parameter. In the bt line search it is
1137: used as the maximum possible step length, as the bt line search only backtracks.
1139: .seealso: SNESLineSearchGetDamping()
1140: @*/
1141: PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
1142: {
1145: linesearch->damping = damping;
1146: return(0);
1147: }
1151: /*@
1152: SNESLineSearchGetOrder - Gets the line search approximation order.
1154: Input Parameters:
1155: . linesearch - linesearch context
1157: Output Parameters:
1158: . order - The order
1160: Possible Values for order:
1161: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1162: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1163: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1165: Level: intermediate
1167: .seealso: SNESLineSearchSetOrder()
1168: @*/
1170: PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
1171: {
1175: *order = linesearch->order;
1176: return(0);
1177: }
1181: /*@
1182: SNESLineSearchSetOrder - Sets the line search damping paramter.
1184: Input Parameters:
1185: . linesearch - linesearch context
1186: . order - The damping parameter
1188: Level: intermediate
1190: Possible Values for order:
1191: + 1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
1192: . 2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
1193: - 3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
1195: Notes:
1196: Variable orders are supported by the following line searches:
1197: + bt - cubic and quadratic
1198: - cp - linear and quadratic
1200: .seealso: SNESLineSearchGetOrder()
1201: @*/
1202: PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
1203: {
1206: linesearch->order = order;
1207: return(0);
1208: }
1212: /*@
1213: SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1215: Input Parameters:
1216: . linesearch - linesearch context
1218: Output Parameters:
1219: + xnorm - The norm of the current solution
1220: . fnorm - The norm of the current function
1221: - ynorm - The norm of the current update
1223: Notes:
1224: This function is mainly called from SNES implementations.
1226: Level: developer
1228: .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
1229: @*/
1230: PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1231: {
1234: if (xnorm) *xnorm = linesearch->xnorm;
1235: if (fnorm) *fnorm = linesearch->fnorm;
1236: if (ynorm) *ynorm = linesearch->ynorm;
1237: return(0);
1238: }
1242: /*@
1243: SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1245: Input Parameters:
1246: + linesearch - linesearch context
1247: . xnorm - The norm of the current solution
1248: . fnorm - The norm of the current function
1249: - ynorm - The norm of the current update
1251: Level: advanced
1253: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1254: @*/
1255: PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1256: {
1259: linesearch->xnorm = xnorm;
1260: linesearch->fnorm = fnorm;
1261: linesearch->ynorm = ynorm;
1262: return(0);
1263: }
1267: /*@
1268: SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1270: Input Parameters:
1271: . linesearch - linesearch context
1273: Options Database Keys:
1274: . -snes_linesearch_norms - turn norm computation on or off
1276: Level: intermediate
1278: .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms(), SNESLineSearchSetComputeNorms()
1279: @*/
1280: PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1281: {
1283: SNES snes;
1286: if (linesearch->norms) {
1287: if (linesearch->ops->vinorm) {
1288: SNESLineSearchGetSNES(linesearch, &snes);
1289: VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1290: VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1291: (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);
1292: } else {
1293: VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1294: VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1295: VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1296: VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm);
1297: VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm);
1298: VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm);
1299: }
1300: }
1301: return(0);
1302: }
1306: /*@
1307: SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
1309: Input Parameters:
1310: + linesearch - linesearch context
1311: - flg - indicates whether or not to compute norms
1313: Options Database Keys:
1314: . -snes_linesearch_norms - turn norm computation on or off
1316: Notes:
1317: This is most relevant to the SNESLINESEARCHBASIC line search type.
1319: Level: intermediate
1321: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetNorms(), SNESLineSearchComputeNorms(), SNESLINESEARCHBASIC
1322: @*/
1323: PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1324: {
1326: linesearch->norms = flg;
1327: return(0);
1328: }
1332: /*@
1333: SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1335: Input Parameters:
1336: . linesearch - linesearch context
1338: Output Parameters:
1339: + X - Solution vector
1340: . F - Function vector
1341: . Y - Search direction vector
1342: . W - Solution work vector
1343: - G - Function work vector
1345: Notes:
1346: At the beginning of a line search application, X should contain a
1347: solution and the vector F the function computed at X. At the end of the
1348: line search application, X should contain the new solution, and F the
1349: function evaluated at the new solution.
1351: Level: advanced
1353: .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1354: @*/
1355: PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1356: {
1359: if (X) {
1361: *X = linesearch->vec_sol;
1362: }
1363: if (F) {
1365: *F = linesearch->vec_func;
1366: }
1367: if (Y) {
1369: *Y = linesearch->vec_update;
1370: }
1371: if (W) {
1373: *W = linesearch->vec_sol_new;
1374: }
1375: if (G) {
1377: *G = linesearch->vec_func_new;
1378: }
1379: return(0);
1380: }
1384: /*@
1385: SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1387: Input Parameters:
1388: + linesearch - linesearch context
1389: . X - Solution vector
1390: . F - Function vector
1391: . Y - Search direction vector
1392: . W - Solution work vector
1393: - G - Function work vector
1395: Level: advanced
1397: .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1398: @*/
1399: PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1400: {
1403: if (X) {
1405: linesearch->vec_sol = X;
1406: }
1407: if (F) {
1409: linesearch->vec_func = F;
1410: }
1411: if (Y) {
1413: linesearch->vec_update = Y;
1414: }
1415: if (W) {
1417: linesearch->vec_sol_new = W;
1418: }
1419: if (G) {
1421: linesearch->vec_func_new = G;
1422: }
1423: return(0);
1424: }
1428: /*@C
1429: SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1430: SNES options in the database.
1432: Logically Collective on SNESLineSearch
1434: Input Parameters:
1435: + snes - the SNES context
1436: - prefix - the prefix to prepend to all option names
1438: Notes:
1439: A hyphen (-) must NOT be given at the beginning of the prefix name.
1440: The first character of all runtime options is AUTOMATICALLY the hyphen.
1442: Level: advanced
1444: .keywords: SNESLineSearch, append, options, prefix, database
1446: .seealso: SNESGetOptionsPrefix()
1447: @*/
1448: PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1449: {
1454: PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);
1455: return(0);
1456: }
1460: /*@C
1461: SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1462: SNESLineSearch options in the database.
1464: Not Collective
1466: Input Parameter:
1467: . linesearch - the SNESLineSearch context
1469: Output Parameter:
1470: . prefix - pointer to the prefix string used
1472: Notes:
1473: On the fortran side, the user should pass in a string 'prefix' of
1474: sufficient length to hold the prefix.
1476: Level: advanced
1478: .keywords: SNESLineSearch, get, options, prefix, database
1480: .seealso: SNESAppendOptionsPrefix()
1481: @*/
1482: PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1483: {
1488: PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);
1489: return(0);
1490: }
1494: /*@C
1495: SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1497: Input Parameter:
1498: + linesearch - the SNESLineSearch context
1499: - nwork - the number of work vectors
1501: Level: developer
1503: Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations
1505: .keywords: SNESLineSearch, work, vector
1507: .seealso: SNESSetWorkVecs()
1508: @*/
1509: PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1510: {
1514: if (linesearch->vec_sol) {
1515: VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);
1516: } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1517: return(0);
1518: }
1522: /*@
1523: SNESLineSearchGetSuccess - Gets the success/failure status of the last line search application
1525: Input Parameters:
1526: . linesearch - linesearch context
1528: Output Parameters:
1529: . success - The success or failure status
1531: Notes:
1532: This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1533: (and set the SNES convergence accordingly).
1535: Level: intermediate
1537: .seealso: SNESLineSearchSetSuccess()
1538: @*/
1539: PetscErrorCode SNESLineSearchGetSuccess(SNESLineSearch linesearch, PetscBool *success)
1540: {
1544: if (success) *success = linesearch->success;
1545: return(0);
1546: }
1550: /*@
1551: SNESLineSearchSetSuccess - Sets the success/failure status of the last line search application
1553: Input Parameters:
1554: + linesearch - linesearch context
1555: - success - The success or failure status
1557: Notes:
1558: This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1559: the success or failure of the line search method.
1561: Level: developer
1563: .seealso: SNESLineSearchGetSuccess()
1564: @*/
1565: PetscErrorCode SNESLineSearchSetSuccess(SNESLineSearch linesearch, PetscBool success)
1566: {
1569: linesearch->success = success;
1570: return(0);
1571: }
1575: /*@C
1576: SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
1578: Input Parameters:
1579: + snes - nonlinear context obtained from SNESCreate()
1580: . projectfunc - function for projecting the function to the bounds
1581: - normfunc - function for computing the norm of an active set
1583: Logically Collective on SNES
1585: Calling sequence of projectfunc:
1586: .vb
1587: projectfunc (SNES snes, Vec X)
1588: .ve
1590: Input parameters for projectfunc:
1591: + snes - nonlinear context
1592: - X - current solution
1594: Output parameters for projectfunc:
1595: . X - Projected solution
1597: Calling sequence of normfunc:
1598: .vb
1599: projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
1600: .ve
1602: Input parameters for normfunc:
1603: + snes - nonlinear context
1604: . X - current solution
1605: - F - current residual
1607: Output parameters for normfunc:
1608: . fnorm - VI-specific norm of the function
1610: Notes:
1611: The VI solvers require projection of the solution to the feasible set. projectfunc should implement this.
1613: The VI solvers require special evaluation of the function norm such that the norm is only calculated
1614: on the inactive set. This should be implemented by normfunc.
1616: Level: developer
1618: .keywords: SNES, line search, VI, nonlinear, set, line search
1620: .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
1621: @*/
1622: extern PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1623: {
1626: if (projectfunc) linesearch->ops->viproject = projectfunc;
1627: if (normfunc) linesearch->ops->vinorm = normfunc;
1628: return(0);
1629: }
1633: /*@C
1634: SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
1636: Input Parameters:
1637: . snes - nonlinear context obtained from SNESCreate()
1639: Output Parameters:
1640: + projectfunc - function for projecting the function to the bounds
1641: - normfunc - function for computing the norm of an active set
1643: Logically Collective on SNES
1645: Level: developer
1647: .keywords: SNES, line search, VI, nonlinear, get, line search
1649: .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
1650: @*/
1651: extern PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1652: {
1654: if (projectfunc) *projectfunc = linesearch->ops->viproject;
1655: if (normfunc) *normfunc = linesearch->ops->vinorm;
1656: return(0);
1657: }
1661: /*@C
1662: SNESLineSearchRegister - See SNESLineSearchRegister()
1664: Level: advanced
1665: @*/
1666: PetscErrorCode SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1667: {
1671: PetscFunctionListAdd(&SNESLineSearchList,sname,function);
1672: return(0);
1673: }