xref: /petsc/src/snes/linesearch/interface/linesearch.c (revision f0b8451846536e860da8da89b03aa043fd955a08)
1af0996ceSBarry Smith #include <petsc/private/linesearchimpl.h> /*I "petscsnes.h" I*/
2bf7f4e0aSPeter Brune 
3f1c6b773SPeter Brune PetscBool         SNESLineSearchRegisterAllCalled = PETSC_FALSE;
40298fd71SBarry Smith PetscFunctionList SNESLineSearchList              = NULL;
5bf7f4e0aSPeter Brune 
6f1c6b773SPeter Brune PetscClassId  SNESLINESEARCH_CLASSID;
757a83faaSBarry Smith PetscLogEvent SNESLINESEARCH_Apply;
8bf7f4e0aSPeter Brune 
9dcf2fd19SBarry Smith /*@
10dcf2fd19SBarry Smith    SNESLineSearchMonitorCancel - Clears all the monitor functions for a SNESLineSearch object.
11dcf2fd19SBarry Smith 
12dcf2fd19SBarry Smith    Logically Collective on SNESLineSearch
13dcf2fd19SBarry Smith 
14dcf2fd19SBarry Smith    Input Parameters:
15dcf2fd19SBarry Smith .  ls - the SNESLineSearch context
16dcf2fd19SBarry Smith 
17dcf2fd19SBarry Smith    Options Database Key:
18dcf2fd19SBarry Smith .  -snes_linesearch_monitor_cancel - cancels all monitors that have been hardwired
19dcf2fd19SBarry Smith     into a code by calls to SNESLineSearchMonitorSet(), but does not cancel those
20dcf2fd19SBarry Smith     set via the options database
21dcf2fd19SBarry Smith 
22dcf2fd19SBarry Smith    Notes:
23dcf2fd19SBarry Smith    There is no way to clear one specific monitor from a SNESLineSearch object.
24dcf2fd19SBarry Smith 
25dcf2fd19SBarry Smith    This does not clear the monitor set with SNESLineSearchSetDefaultMonitor() use SNESLineSearchSetDefaultMonitor(ls,NULL) to cancel
26dcf2fd19SBarry Smith    that one.
27dcf2fd19SBarry Smith 
28dcf2fd19SBarry Smith    Level: intermediate
29dcf2fd19SBarry Smith 
30db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESLineSearchMonitorDefault()`, `SNESLineSearchMonitorSet()`
31dcf2fd19SBarry Smith @*/
32dcf2fd19SBarry Smith PetscErrorCode  SNESLineSearchMonitorCancel(SNESLineSearch ls)
33dcf2fd19SBarry Smith {
34dcf2fd19SBarry Smith   PetscInt       i;
35dcf2fd19SBarry Smith 
36dcf2fd19SBarry Smith   PetscFunctionBegin;
37dcf2fd19SBarry Smith   PetscValidHeaderSpecific(ls,SNESLINESEARCH_CLASSID,1);
38dcf2fd19SBarry Smith   for (i=0; i<ls->numbermonitors; i++) {
39dcf2fd19SBarry Smith     if (ls->monitordestroy[i]) {
409566063dSJacob Faibussowitsch       PetscCall((*ls->monitordestroy[i])(&ls->monitorcontext[i]));
41dcf2fd19SBarry Smith     }
42dcf2fd19SBarry Smith   }
43dcf2fd19SBarry Smith   ls->numbermonitors = 0;
44dcf2fd19SBarry Smith   PetscFunctionReturn(0);
45dcf2fd19SBarry Smith }
46dcf2fd19SBarry Smith 
47dcf2fd19SBarry Smith /*@
48dcf2fd19SBarry Smith    SNESLineSearchMonitor - runs the user provided monitor routines, if they exist
49dcf2fd19SBarry Smith 
50dcf2fd19SBarry Smith    Collective on SNES
51dcf2fd19SBarry Smith 
52dcf2fd19SBarry Smith    Input Parameters:
53dcf2fd19SBarry Smith .  ls - the linesearch object
54dcf2fd19SBarry Smith 
55dcf2fd19SBarry Smith    Notes:
56dcf2fd19SBarry Smith    This routine is called by the SNES implementations.
57dcf2fd19SBarry Smith    It does not typically need to be called by the user.
58dcf2fd19SBarry Smith 
59dcf2fd19SBarry Smith    Level: developer
60dcf2fd19SBarry Smith 
61db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESLineSearchMonitorSet()`
62dcf2fd19SBarry Smith @*/
63dcf2fd19SBarry Smith PetscErrorCode  SNESLineSearchMonitor(SNESLineSearch ls)
64dcf2fd19SBarry Smith {
65dcf2fd19SBarry Smith   PetscInt       i,n = ls->numbermonitors;
66dcf2fd19SBarry Smith 
67dcf2fd19SBarry Smith   PetscFunctionBegin;
68dcf2fd19SBarry Smith   for (i=0; i<n; i++) {
699566063dSJacob Faibussowitsch     PetscCall((*ls->monitorftns[i])(ls,ls->monitorcontext[i]));
70dcf2fd19SBarry Smith   }
71dcf2fd19SBarry Smith   PetscFunctionReturn(0);
72dcf2fd19SBarry Smith }
73dcf2fd19SBarry Smith 
74dcf2fd19SBarry Smith /*@C
75dcf2fd19SBarry Smith    SNESLineSearchMonitorSet - Sets an ADDITIONAL function that is to be used at every
76dcf2fd19SBarry Smith    iteration of the nonlinear solver to display the iteration's
77dcf2fd19SBarry Smith    progress.
78dcf2fd19SBarry Smith 
79dcf2fd19SBarry Smith    Logically Collective on SNESLineSearch
80dcf2fd19SBarry Smith 
81dcf2fd19SBarry Smith    Input Parameters:
82dcf2fd19SBarry Smith +  ls - the SNESLineSearch context
83dcf2fd19SBarry Smith .  f - the monitor function
84dcf2fd19SBarry Smith .  mctx - [optional] user-defined context for private data for the
85dcf2fd19SBarry Smith           monitor routine (use NULL if no context is desired)
86dcf2fd19SBarry Smith -  monitordestroy - [optional] routine that frees monitor context
87dcf2fd19SBarry Smith           (may be NULL)
88dcf2fd19SBarry Smith 
89dcf2fd19SBarry Smith    Notes:
90dcf2fd19SBarry Smith    Several different monitoring routines may be set by calling
91dcf2fd19SBarry Smith    SNESLineSearchMonitorSet() multiple times; all will be called in the
92dcf2fd19SBarry Smith    order in which they were set.
93dcf2fd19SBarry Smith 
9495452b02SPatrick Sanan    Fortran Notes:
9595452b02SPatrick Sanan     Only a single monitor function can be set for each SNESLineSearch object
96dcf2fd19SBarry Smith 
97dcf2fd19SBarry Smith    Level: intermediate
98dcf2fd19SBarry Smith 
99db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESLineSearchMonitorDefault()`, `SNESLineSearchMonitorCancel()`
100dcf2fd19SBarry Smith @*/
101dcf2fd19SBarry Smith PetscErrorCode  SNESLineSearchMonitorSet(SNESLineSearch ls,PetscErrorCode (*f)(SNESLineSearch,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
102dcf2fd19SBarry Smith {
10378064530SBarry Smith   PetscInt       i;
10478064530SBarry Smith   PetscBool      identical;
10578064530SBarry Smith 
106dcf2fd19SBarry Smith   PetscFunctionBegin;
107dcf2fd19SBarry Smith   PetscValidHeaderSpecific(ls,SNESLINESEARCH_CLASSID,1);
10878064530SBarry Smith   for (i=0; i<ls->numbermonitors;i++) {
1099566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))ls->monitorftns[i],ls->monitorcontext[i],ls->monitordestroy[i],&identical));
11078064530SBarry Smith     if (identical) PetscFunctionReturn(0);
11178064530SBarry Smith   }
1125f80ce2aSJacob Faibussowitsch   PetscCheck(ls->numbermonitors < MAXSNESLSMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
113dcf2fd19SBarry Smith   ls->monitorftns[ls->numbermonitors]          = f;
114dcf2fd19SBarry Smith   ls->monitordestroy[ls->numbermonitors]   = monitordestroy;
115dcf2fd19SBarry Smith   ls->monitorcontext[ls->numbermonitors++] = (void*)mctx;
116dcf2fd19SBarry Smith   PetscFunctionReturn(0);
117dcf2fd19SBarry Smith }
118dcf2fd19SBarry Smith 
119dcf2fd19SBarry Smith /*@C
120dcf2fd19SBarry Smith    SNESLineSearchMonitorSolutionUpdate - Monitors each update a new function value the linesearch tries
121dcf2fd19SBarry Smith 
122dcf2fd19SBarry Smith    Collective on SNESLineSearch
123dcf2fd19SBarry Smith 
124dcf2fd19SBarry Smith    Input Parameters:
125dcf2fd19SBarry Smith +  ls - the SNES linesearch object
126d12e167eSBarry Smith -  vf - the context for the monitor, in this case it is an ASCII PetscViewer and format
127dcf2fd19SBarry Smith 
128dcf2fd19SBarry Smith    Level: intermediate
129dcf2fd19SBarry Smith 
130db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESMonitorSet()`, `SNESMonitorSolution()`
131dcf2fd19SBarry Smith @*/
132d12e167eSBarry Smith PetscErrorCode  SNESLineSearchMonitorSolutionUpdate(SNESLineSearch ls,PetscViewerAndFormat *vf)
133dcf2fd19SBarry Smith {
134d12e167eSBarry Smith   PetscViewer    viewer = vf->viewer;
135dcf2fd19SBarry Smith   Vec            Y,W,G;
136dcf2fd19SBarry Smith 
137dcf2fd19SBarry Smith   PetscFunctionBegin;
1389566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchGetVecs(ls,NULL,NULL,&Y,&W,&G));
1399566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
1409566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"LineSearch attempted update to solution \n"));
1419566063dSJacob Faibussowitsch   PetscCall(VecView(Y,viewer));
1429566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"LineSearch attempted new solution \n"));
1439566063dSJacob Faibussowitsch   PetscCall(VecView(W,viewer));
1449566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"LineSearch attempted updated function value\n"));
1459566063dSJacob Faibussowitsch   PetscCall(VecView(G,viewer));
1469566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
147dcf2fd19SBarry Smith   PetscFunctionReturn(0);
148dcf2fd19SBarry Smith }
149dcf2fd19SBarry Smith 
150f40b411bSPeter Brune /*@
151cd7522eaSPeter Brune    SNESLineSearchCreate - Creates the line search context.
152f40b411bSPeter Brune 
153cd7522eaSPeter Brune    Logically Collective on Comm
154f40b411bSPeter Brune 
155f40b411bSPeter Brune    Input Parameters:
156cd7522eaSPeter Brune .  comm - MPI communicator for the line search (typically from the associated SNES context).
157f40b411bSPeter Brune 
158f40b411bSPeter Brune    Output Parameters:
1598e557f58SPeter Brune .  outlinesearch - the new linesearch context
160f40b411bSPeter Brune 
161162e0bf5SPeter Brune    Level: developer
162162e0bf5SPeter Brune 
163162e0bf5SPeter Brune    Notes:
164162e0bf5SPeter Brune    The preferred calling sequence for users is to use SNESGetLineSearch() to acquire the SNESLineSearch instance
165162e0bf5SPeter Brune    already associated with the SNES.  This function is for developer use.
166f40b411bSPeter Brune 
167db781477SPatrick Sanan .seealso: `LineSearchDestroy()`, `SNESGetLineSearch()`
168f40b411bSPeter Brune @*/
169f40b411bSPeter Brune 
170bf388a1fSBarry Smith PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
171bf388a1fSBarry Smith {
172f1c6b773SPeter Brune   SNESLineSearch linesearch;
173bf388a1fSBarry Smith 
174bf7f4e0aSPeter Brune   PetscFunctionBegin;
175ea5d4fccSPeter Brune   PetscValidPointer(outlinesearch,2);
1769566063dSJacob Faibussowitsch   PetscCall(SNESInitializePackage());
1770298fd71SBarry Smith   *outlinesearch = NULL;
178f5af7f23SKarl Rupp 
1799566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(linesearch,SNESLINESEARCH_CLASSID, "SNESLineSearch","Linesearch","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView));
180bf7f4e0aSPeter Brune 
1810298fd71SBarry Smith   linesearch->vec_sol_new  = NULL;
1820298fd71SBarry Smith   linesearch->vec_func_new = NULL;
1830298fd71SBarry Smith   linesearch->vec_sol      = NULL;
1840298fd71SBarry Smith   linesearch->vec_func     = NULL;
1850298fd71SBarry Smith   linesearch->vec_update   = NULL;
1869bd66eb0SPeter Brune 
187bf7f4e0aSPeter Brune   linesearch->lambda       = 1.0;
188bf7f4e0aSPeter Brune   linesearch->fnorm        = 1.0;
189bf7f4e0aSPeter Brune   linesearch->ynorm        = 1.0;
190bf7f4e0aSPeter Brune   linesearch->xnorm        = 1.0;
191422a814eSBarry Smith   linesearch->result       = SNES_LINESEARCH_SUCCEEDED;
192bf7f4e0aSPeter Brune   linesearch->norms        = PETSC_TRUE;
193bf7f4e0aSPeter Brune   linesearch->keeplambda   = PETSC_FALSE;
194bf7f4e0aSPeter Brune   linesearch->damping      = 1.0;
195bf7f4e0aSPeter Brune   linesearch->maxstep      = 1e8;
196bf7f4e0aSPeter Brune   linesearch->steptol      = 1e-12;
197516fe3c3SPeter Brune   linesearch->rtol         = 1e-8;
198516fe3c3SPeter Brune   linesearch->atol         = 1e-15;
199516fe3c3SPeter Brune   linesearch->ltol         = 1e-8;
2000298fd71SBarry Smith   linesearch->precheckctx  = NULL;
2010298fd71SBarry Smith   linesearch->postcheckctx = NULL;
20259405d5eSPeter Brune   linesearch->max_its      = 1;
203bf7f4e0aSPeter Brune   linesearch->setupcalled  = PETSC_FALSE;
2043add74b1SBarry Smith   linesearch->monitor      = NULL;
205bf7f4e0aSPeter Brune   *outlinesearch           = linesearch;
206bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
207bf7f4e0aSPeter Brune }
208bf7f4e0aSPeter Brune 
209f40b411bSPeter Brune /*@
21078bcb3b5SPeter Brune    SNESLineSearchSetUp - Prepares the line search for being applied by allocating
21178bcb3b5SPeter Brune    any required vectors.
212f40b411bSPeter Brune 
213cd7522eaSPeter Brune    Collective on SNESLineSearch
214f40b411bSPeter Brune 
215f40b411bSPeter Brune    Input Parameters:
216f40b411bSPeter Brune .  linesearch - The LineSearch instance.
217f40b411bSPeter Brune 
218cd7522eaSPeter Brune    Notes:
219f190f2fcSBarry Smith    For most cases, this needn't be called by users or outside of SNESLineSearchApply().
220cd7522eaSPeter Brune    The only current case where this is called outside of this is for the VI
22178bcb3b5SPeter Brune    solvers, which modify the solution and work vectors before the first call
222cd7522eaSPeter Brune    of SNESLineSearchApply, requiring the SNESLineSearch work vectors to be
223cd7522eaSPeter Brune    allocated upfront.
224cd7522eaSPeter Brune 
22578bcb3b5SPeter Brune    Level: advanced
226f40b411bSPeter Brune 
227db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESLineSearchReset()`
228f40b411bSPeter Brune @*/
229f40b411bSPeter Brune 
230bf388a1fSBarry Smith PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
231bf388a1fSBarry Smith {
232bf7f4e0aSPeter Brune   PetscFunctionBegin;
233bf7f4e0aSPeter Brune   if (!((PetscObject)linesearch)->type_name) {
2349566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetType(linesearch,SNESLINESEARCHBASIC));
235bf7f4e0aSPeter Brune   }
236bf7f4e0aSPeter Brune   if (!linesearch->setupcalled) {
2379bd66eb0SPeter Brune     if (!linesearch->vec_sol_new) {
2389566063dSJacob Faibussowitsch       PetscCall(VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new));
2399bd66eb0SPeter Brune     }
2409bd66eb0SPeter Brune     if (!linesearch->vec_func_new) {
2419566063dSJacob Faibussowitsch       PetscCall(VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new));
2429bd66eb0SPeter Brune     }
2431baa6e33SBarry Smith     if (linesearch->ops->setup) PetscCall((*linesearch->ops->setup)(linesearch));
2449566063dSJacob Faibussowitsch     if (!linesearch->ops->snesfunc) PetscCall(SNESLineSearchSetFunction(linesearch,SNESComputeFunction));
245bf7f4e0aSPeter Brune     linesearch->lambda      = linesearch->damping;
246bf7f4e0aSPeter Brune     linesearch->setupcalled = PETSC_TRUE;
247bf7f4e0aSPeter Brune   }
248bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
249bf7f4e0aSPeter Brune }
250bf7f4e0aSPeter Brune 
251f40b411bSPeter Brune /*@
252f190f2fcSBarry Smith    SNESLineSearchReset - Undoes the SNESLineSearchSetUp() and deletes any Vecs or Mats allocated by the line search.
253f40b411bSPeter Brune 
254f1c6b773SPeter Brune    Collective on SNESLineSearch
255f40b411bSPeter Brune 
256f40b411bSPeter Brune    Input Parameters:
257f40b411bSPeter Brune .  linesearch - The LineSearch instance.
258f40b411bSPeter Brune 
25995452b02SPatrick Sanan    Notes:
26095452b02SPatrick Sanan     Usually only called by SNESReset()
261f190f2fcSBarry Smith 
262f190f2fcSBarry Smith    Level: developer
263f40b411bSPeter Brune 
264db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESLineSearchSetUp()`
265f40b411bSPeter Brune @*/
266f40b411bSPeter Brune 
267bf388a1fSBarry Smith PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
268bf388a1fSBarry Smith {
269bf7f4e0aSPeter Brune   PetscFunctionBegin;
2709566063dSJacob Faibussowitsch   if (linesearch->ops->reset) PetscCall((*linesearch->ops->reset)(linesearch));
271f5af7f23SKarl Rupp 
2729566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&linesearch->vec_sol_new));
2739566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&linesearch->vec_func_new));
274bf7f4e0aSPeter Brune 
2759566063dSJacob Faibussowitsch   PetscCall(VecDestroyVecs(linesearch->nwork, &linesearch->work));
276f5af7f23SKarl Rupp 
277bf7f4e0aSPeter Brune   linesearch->nwork       = 0;
278bf7f4e0aSPeter Brune   linesearch->setupcalled = PETSC_FALSE;
279bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
280bf7f4e0aSPeter Brune }
281bf7f4e0aSPeter Brune 
282ed07d7d7SPeter Brune /*@C
283f190f2fcSBarry Smith    SNESLineSearchSetFunction - Sets the function evaluation used by the SNES line search
284ed07d7d7SPeter Brune 
285ed07d7d7SPeter Brune    Input Parameters:
286ed07d7d7SPeter Brune .  linesearch - the SNESLineSearch context
287f190f2fcSBarry Smith +  func       - function evaluation routine
288ed07d7d7SPeter Brune 
289ed07d7d7SPeter Brune    Level: developer
290ed07d7d7SPeter Brune 
29195452b02SPatrick Sanan    Notes:
29295452b02SPatrick Sanan     This is used internally by PETSc and not called by users
293f190f2fcSBarry Smith 
294db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESSetFunction()`
295ed07d7d7SPeter Brune @*/
296ed07d7d7SPeter Brune PetscErrorCode  SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES,Vec,Vec))
297ed07d7d7SPeter Brune {
298ed07d7d7SPeter Brune   PetscFunctionBegin;
299ed07d7d7SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
300ed07d7d7SPeter Brune   linesearch->ops->snesfunc = func;
301ed07d7d7SPeter Brune   PetscFunctionReturn(0);
302ed07d7d7SPeter Brune }
303ed07d7d7SPeter Brune 
30486d74e61SPeter Brune /*@C
305f190f2fcSBarry Smith    SNESLineSearchSetPreCheck - Sets a user function that is called after the initial search direction has been computed but
306df3898eeSBarry Smith          before the line search routine has been applied. Allows the user to adjust the result of (usually a linear solve) that
307f190f2fcSBarry Smith          determined the search direction.
30886d74e61SPeter Brune 
309f1c6b773SPeter Brune    Logically Collective on SNESLineSearch
31086d74e61SPeter Brune 
31186d74e61SPeter Brune    Input Parameters:
312f1c6b773SPeter Brune +  linesearch - the SNESLineSearch context
31384238204SBarry Smith .  func - [optional] function evaluation routine, see SNESLineSearchPreCheck() for the calling sequence
314f190f2fcSBarry Smith -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
31586d74e61SPeter Brune 
31686d74e61SPeter Brune    Level: intermediate
31786d74e61SPeter Brune 
318*f0b84518SBarry Smith    Notes:
319*f0b84518SBarry Smith    Use `SNESLineSearchSetPostCheck()` to change the step after the line search.
320*f0b84518SBarry Smith    search is complete.
321*f0b84518SBarry Smith 
322*f0b84518SBarry Smith    Use `SNESVISetVariableBounds()` and `SNESVISetComputeVariableBounds()` to cause `SNES` to automatically control the ranges of variables allowed.
323*f0b84518SBarry Smith 
324*f0b84518SBarry Smith .seealso: `SNESGetLineSearch()`, `SNESLineSearchPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchGetPreCheck()`,
325*f0b84518SBarry Smith           `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESSetFunctionDomainError()`, `SNESSetJacobianDomainError()
326*f0b84518SBarry Smith 
32786d74e61SPeter Brune @*/
328f190f2fcSBarry Smith PetscErrorCode  SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void *ctx)
32986d74e61SPeter Brune {
3309bd66eb0SPeter Brune   PetscFunctionBegin;
331f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
332f190f2fcSBarry Smith   if (func) linesearch->ops->precheck = func;
33386d74e61SPeter Brune   if (ctx) linesearch->precheckctx = ctx;
33486d74e61SPeter Brune   PetscFunctionReturn(0);
33586d74e61SPeter Brune }
33686d74e61SPeter Brune 
33786d74e61SPeter Brune /*@C
33853deb899SBarry Smith    SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine.
33986d74e61SPeter Brune 
340f899ff85SJose E. Roman    Input Parameter:
341f1c6b773SPeter Brune .  linesearch - the SNESLineSearch context
34286d74e61SPeter Brune 
34386d74e61SPeter Brune    Output Parameters:
34484238204SBarry Smith +  func       - [optional] function evaluation routine, see SNESLineSearchPreCheck() for calling sequence
345f190f2fcSBarry Smith -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
34686d74e61SPeter Brune 
34786d74e61SPeter Brune    Level: intermediate
34886d74e61SPeter Brune 
349db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESGetLineSearch()`, `SNESLineSearchPreCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`
35086d74e61SPeter Brune @*/
351f190f2fcSBarry Smith PetscErrorCode  SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,PetscBool*,void*),void **ctx)
35286d74e61SPeter Brune {
3539bd66eb0SPeter Brune   PetscFunctionBegin;
354f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
355f190f2fcSBarry Smith   if (func) *func = linesearch->ops->precheck;
35686d74e61SPeter Brune   if (ctx) *ctx = linesearch->precheckctx;
35786d74e61SPeter Brune   PetscFunctionReturn(0);
35886d74e61SPeter Brune }
35986d74e61SPeter Brune 
36086d74e61SPeter Brune /*@C
361f190f2fcSBarry Smith    SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step
362f190f2fcSBarry Smith        direction and length. Allows the user a chance to change or override the decision of the line search routine
36386d74e61SPeter Brune 
364f1c6b773SPeter Brune    Logically Collective on SNESLineSearch
36586d74e61SPeter Brune 
36686d74e61SPeter Brune    Input Parameters:
367f1c6b773SPeter Brune +  linesearch - the SNESLineSearch context
36884238204SBarry Smith .  func - [optional] function evaluation routine, see SNESLineSearchPostCheck()  for the calling sequence
369f190f2fcSBarry Smith -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
37086d74e61SPeter Brune 
37186d74e61SPeter Brune    Level: intermediate
37286d74e61SPeter Brune 
373*f0b84518SBarry Smith    Notes:
374*f0b84518SBarry Smith    Use `SNESLineSearchSetPreCheck()` to change the step before the line search.
375*f0b84518SBarry Smith    search is complete.
376*f0b84518SBarry Smith 
377*f0b84518SBarry Smith    Use `SNESVISetVariableBounds()` and `SNESVISetComputeVariableBounds()` to cause `SNES` to automatically control the ranges of variables allowed.
378*f0b84518SBarry Smith 
379*f0b84518SBarry Smith .seealso: `SNESGetLineSearch()`, `SNESLineSearchPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`, `SNESLineSearchGetPostCheck()`,
380*f0b84518SBarry Smith           `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESSetFunctionDomainError()`, `SNESSetJacobianDomainError()
38186d74e61SPeter Brune @*/
382f190f2fcSBarry Smith PetscErrorCode  SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void *ctx)
38386d74e61SPeter Brune {
38486d74e61SPeter Brune   PetscFunctionBegin;
385f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
386f190f2fcSBarry Smith   if (func) linesearch->ops->postcheck = func;
38786d74e61SPeter Brune   if (ctx) linesearch->postcheckctx = ctx;
38886d74e61SPeter Brune   PetscFunctionReturn(0);
38986d74e61SPeter Brune }
39086d74e61SPeter Brune 
39186d74e61SPeter Brune /*@C
392f1c6b773SPeter Brune    SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.
39386d74e61SPeter Brune 
394f899ff85SJose E. Roman    Input Parameter:
395f1c6b773SPeter Brune .  linesearch - the SNESLineSearch context
39686d74e61SPeter Brune 
39786d74e61SPeter Brune    Output Parameters:
39884238204SBarry Smith +  func - [optional] function evaluation routine, see for the calling sequence SNESLineSearchPostCheck()
399f190f2fcSBarry Smith -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
40086d74e61SPeter Brune 
40186d74e61SPeter Brune    Level: intermediate
40286d74e61SPeter Brune 
403db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESLineSearchGetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchPostCheck()`, `SNESLineSearchSetPreCheck()`
40486d74e61SPeter Brune @*/
405f190f2fcSBarry Smith PetscErrorCode  SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*),void **ctx)
40686d74e61SPeter Brune {
4079bd66eb0SPeter Brune   PetscFunctionBegin;
408f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
409f190f2fcSBarry Smith   if (func) *func = linesearch->ops->postcheck;
41086d74e61SPeter Brune   if (ctx) *ctx = linesearch->postcheckctx;
41186d74e61SPeter Brune   PetscFunctionReturn(0);
41286d74e61SPeter Brune }
41386d74e61SPeter Brune 
414f40b411bSPeter Brune /*@
415f1c6b773SPeter Brune    SNESLineSearchPreCheck - Prepares the line search for being applied.
416f40b411bSPeter Brune 
417cd7522eaSPeter Brune    Logically Collective on SNESLineSearch
418f40b411bSPeter Brune 
419f40b411bSPeter Brune    Input Parameters:
4207b1df9c1SPeter Brune +  linesearch - The linesearch instance.
4217b1df9c1SPeter Brune .  X - The current solution
4227b1df9c1SPeter Brune -  Y - The step direction
423f40b411bSPeter Brune 
424f40b411bSPeter Brune    Output Parameters:
4258e557f58SPeter Brune .  changed - Indicator that the precheck routine has changed anything
426f40b411bSPeter Brune 
427*f0b84518SBarry Smith    Level: advanced
428f40b411bSPeter Brune 
429*f0b84518SBarry Smith .seealso: `SNESGetLineSearch()`, `SNESLineSearchPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`, `SNESLineSearchSetPostCheck()`,
430*f0b84518SBarry Smith           `SNESLineSearchGetPostCheck()``
431f40b411bSPeter Brune @*/
4327b1df9c1SPeter Brune PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed)
433bf7f4e0aSPeter Brune {
434bf7f4e0aSPeter Brune   PetscFunctionBegin;
435bf7f4e0aSPeter Brune   *changed = PETSC_FALSE;
4366b2b7091SBarry Smith   if (linesearch->ops->precheck) {
4379566063dSJacob Faibussowitsch     PetscCall((*linesearch->ops->precheck)(linesearch, X, Y, changed, linesearch->precheckctx));
43838bcdd5aSPeter Brune     PetscValidLogicalCollectiveBool(linesearch,*changed,4);
439bf7f4e0aSPeter Brune   }
440bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
441bf7f4e0aSPeter Brune }
442bf7f4e0aSPeter Brune 
443f40b411bSPeter Brune /*@
444ef46b1a6SStefano Zampini    SNESLineSearchPostCheck - Hook to modify step direction or updated solution after a successful linesearch
445f40b411bSPeter Brune 
446cd7522eaSPeter Brune    Logically Collective on SNESLineSearch
447f40b411bSPeter Brune 
448f40b411bSPeter Brune    Input Parameters:
4497b1df9c1SPeter Brune +  linesearch - The linesearch context
4507b1df9c1SPeter Brune .  X - The last solution
4517b1df9c1SPeter Brune .  Y - The step direction
4527b1df9c1SPeter Brune -  W - The updated solution, W = X + lambda*Y for some lambda
453f40b411bSPeter Brune 
454f40b411bSPeter Brune    Output Parameters:
45578bcb3b5SPeter Brune +  changed_Y - Indicator if the direction Y has been changed.
45678bcb3b5SPeter Brune -  changed_W - Indicator if the new candidate solution W has been changed.
457f40b411bSPeter Brune 
458f190f2fcSBarry Smith    Level: developer
459f40b411bSPeter Brune 
460db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESLineSearchPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPrecheck()`, `SNESLineSearchGetPrecheck()`
461f40b411bSPeter Brune @*/
4627b1df9c1SPeter Brune PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch,Vec X,Vec Y,Vec W,PetscBool *changed_Y,PetscBool *changed_W)
463bf7f4e0aSPeter Brune {
464bf7f4e0aSPeter Brune   PetscFunctionBegin;
465bf7f4e0aSPeter Brune   *changed_Y = PETSC_FALSE;
466bf7f4e0aSPeter Brune   *changed_W = PETSC_FALSE;
4676b2b7091SBarry Smith   if (linesearch->ops->postcheck) {
4689566063dSJacob Faibussowitsch     PetscCall((*linesearch->ops->postcheck)(linesearch,X,Y,W,changed_Y,changed_W,linesearch->postcheckctx));
46938bcdd5aSPeter Brune     PetscValidLogicalCollectiveBool(linesearch,*changed_Y,5);
47038bcdd5aSPeter Brune     PetscValidLogicalCollectiveBool(linesearch,*changed_W,6);
47186d74e61SPeter Brune   }
47286d74e61SPeter Brune   PetscFunctionReturn(0);
47386d74e61SPeter Brune }
47486d74e61SPeter Brune 
47586d74e61SPeter Brune /*@C
47686d74e61SPeter Brune    SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration
47786d74e61SPeter Brune 
478cd7522eaSPeter Brune    Logically Collective on SNESLineSearch
47986d74e61SPeter Brune 
4804165533cSJose E. Roman    Input Parameters:
48186d74e61SPeter Brune +  linesearch - linesearch context
48286d74e61SPeter Brune .  X - base state for this step
483907376e6SBarry Smith -  ctx - context for this function
48486d74e61SPeter Brune 
48597bb3fdcSJose E. Roman    Input/Output Parameter:
48697bb3fdcSJose E. Roman .  Y - correction, possibly modified
48797bb3fdcSJose E. Roman 
48897bb3fdcSJose E. Roman    Output Parameter:
48997bb3fdcSJose E. Roman .  changed - flag indicating that Y was modified
49086d74e61SPeter Brune 
49186d74e61SPeter Brune    Options Database Key:
492cd7522eaSPeter Brune +  -snes_linesearch_precheck_picard - activate this routine
493cd7522eaSPeter Brune -  -snes_linesearch_precheck_picard_angle - angle
49486d74e61SPeter Brune 
49586d74e61SPeter Brune    Level: advanced
49686d74e61SPeter Brune 
49786d74e61SPeter Brune    Notes:
49886d74e61SPeter Brune    This function should be passed to SNESLineSearchSetPreCheck()
49986d74e61SPeter Brune 
50086d74e61SPeter Brune    The justification for this method involves the linear convergence of a Picard iteration
50186d74e61SPeter Brune    so the Picard linearization should be provided in place of the "Jacobian". This correction
50286d74e61SPeter Brune    is generally not useful when using a Newton linearization.
50386d74e61SPeter Brune 
50486d74e61SPeter Brune    Reference:
50586d74e61SPeter Brune    Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.
50686d74e61SPeter Brune 
507db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESLineSearchSetPreCheck()`
50886d74e61SPeter Brune @*/
509f1c6b773SPeter Brune PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
51086d74e61SPeter Brune {
51186d74e61SPeter Brune   PetscReal      angle = *(PetscReal*)linesearch->precheckctx;
51286d74e61SPeter Brune   Vec            Ylast;
51386d74e61SPeter Brune   PetscScalar    dot;
51486d74e61SPeter Brune   PetscInt       iter;
51586d74e61SPeter Brune   PetscReal      ynorm,ylastnorm,theta,angle_radians;
51686d74e61SPeter Brune   SNES           snes;
51786d74e61SPeter Brune 
51886d74e61SPeter Brune   PetscFunctionBegin;
5199566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchGetSNES(linesearch, &snes));
5209566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast));
52186d74e61SPeter Brune   if (!Ylast) {
5229566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(Y,&Ylast));
5239566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast));
5249566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)Ylast));
52586d74e61SPeter Brune   }
5269566063dSJacob Faibussowitsch   PetscCall(SNESGetIterationNumber(snes,&iter));
52786d74e61SPeter Brune   if (iter < 2) {
5289566063dSJacob Faibussowitsch     PetscCall(VecCopy(Y,Ylast));
52986d74e61SPeter Brune     *changed = PETSC_FALSE;
53086d74e61SPeter Brune     PetscFunctionReturn(0);
53186d74e61SPeter Brune   }
53286d74e61SPeter Brune 
5339566063dSJacob Faibussowitsch   PetscCall(VecDot(Y,Ylast,&dot));
5349566063dSJacob Faibussowitsch   PetscCall(VecNorm(Y,NORM_2,&ynorm));
5359566063dSJacob Faibussowitsch   PetscCall(VecNorm(Ylast,NORM_2,&ylastnorm));
53686d74e61SPeter Brune   /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
537255453a1SBarry Smith   theta         = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
53886d74e61SPeter Brune   angle_radians = angle * PETSC_PI / 180.;
53986d74e61SPeter Brune   if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
54086d74e61SPeter Brune     /* Modify the step Y */
54186d74e61SPeter Brune     PetscReal alpha,ydiffnorm;
5429566063dSJacob Faibussowitsch     PetscCall(VecAXPY(Ylast,-1.0,Y));
5439566063dSJacob Faibussowitsch     PetscCall(VecNorm(Ylast,NORM_2,&ydiffnorm));
544f85e2ce2SBarry Smith     alpha = (ydiffnorm > .001*ylastnorm) ? ylastnorm / ydiffnorm : 1000.0;
5459566063dSJacob Faibussowitsch     PetscCall(VecCopy(Y,Ylast));
5469566063dSJacob Faibussowitsch     PetscCall(VecScale(Y,alpha));
5479566063dSJacob Faibussowitsch     PetscCall(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));
548a47ec85fSBarry Smith     *changed = PETSC_TRUE;
54986d74e61SPeter Brune   } else {
5509566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n",(double)(theta*180./PETSC_PI),(double)angle));
5519566063dSJacob Faibussowitsch     PetscCall(VecCopy(Y,Ylast));
55286d74e61SPeter Brune     *changed = PETSC_FALSE;
553bf7f4e0aSPeter Brune   }
554bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
555bf7f4e0aSPeter Brune }
556bf7f4e0aSPeter Brune 
557f40b411bSPeter Brune /*@
558cd7522eaSPeter Brune    SNESLineSearchApply - Computes the line-search update.
559f40b411bSPeter Brune 
560f1c6b773SPeter Brune    Collective on SNESLineSearch
561f40b411bSPeter Brune 
562f40b411bSPeter Brune    Input Parameters:
5638e557f58SPeter Brune +  linesearch - The linesearch context
5648e557f58SPeter Brune -  Y - The search direction
565f40b411bSPeter Brune 
5666b867d5aSJose E. Roman    Input/Output Parameters:
5676b867d5aSJose E. Roman +  X - The current solution, on output the new solution
5686b867d5aSJose E. Roman .  F - The current function, on output the new function
5696b867d5aSJose E. Roman -  fnorm - The current norm, on output the new function norm
570f40b411bSPeter Brune 
571cd7522eaSPeter Brune    Options Database Keys:
5720b00b554SBarry Smith + -snes_linesearch_type - basic (or equivalently none), bt, l2, cp, nleqerr, shell
573dcf2fd19SBarry Smith . -snes_linesearch_monitor [:filename] - Print progress of line searches
5741fe24845SBarry Smith . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping)
5751fe24845SBarry Smith . -snes_linesearch_norms   - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms())
5763c7d6663SPeter Brune . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
5773c7d6663SPeter Brune - -snes_linesearch_max_it - The number of iterations for iterative line searches
578cd7522eaSPeter Brune 
579cd7522eaSPeter Brune    Notes:
580cd7522eaSPeter Brune    This is typically called from within a SNESSolve() implementation in order to
581cd7522eaSPeter Brune    help with convergence of the nonlinear method.  Various SNES types use line searches
582cd7522eaSPeter Brune    in different ways, but the overarching theme is that a line search is used to determine
583cd7522eaSPeter Brune    an optimal damping parameter of a step at each iteration of the method.  Each
58484238204SBarry Smith    application of the line search may invoke SNESComputeFunction() several times, and
585cd7522eaSPeter Brune    therefore may be fairly expensive.
586cd7522eaSPeter Brune 
587f40b411bSPeter Brune    Level: Intermediate
588f40b411bSPeter Brune 
589db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESLineSearchCreate()`, `SNESLineSearchPreCheck()`, `SNESLineSearchPostCheck()`, `SNESSolve()`, `SNESComputeFunction()`, `SNESLineSearchSetComputeNorms()`,
590db781477SPatrick Sanan           `SNESLineSearchType`, `SNESLineSearchSetType()`
591f40b411bSPeter Brune @*/
592bf388a1fSBarry Smith PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y)
593bf388a1fSBarry Smith {
594bf388a1fSBarry Smith   PetscFunctionBegin;
595f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
596bf7f4e0aSPeter Brune   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
597bf7f4e0aSPeter Brune   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
598064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(Y,VEC_CLASSID,5);
599bf7f4e0aSPeter Brune 
600422a814eSBarry Smith   linesearch->result = SNES_LINESEARCH_SUCCEEDED;
601bf7f4e0aSPeter Brune 
602bf7f4e0aSPeter Brune   linesearch->vec_sol    = X;
603bf7f4e0aSPeter Brune   linesearch->vec_update = Y;
604bf7f4e0aSPeter Brune   linesearch->vec_func   = F;
605bf7f4e0aSPeter Brune 
6069566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchSetUp(linesearch));
607bf7f4e0aSPeter Brune 
608f5af7f23SKarl Rupp   if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
609bf7f4e0aSPeter Brune 
610f5af7f23SKarl Rupp   if (fnorm) linesearch->fnorm = *fnorm;
611f5af7f23SKarl Rupp   else {
6129566063dSJacob Faibussowitsch     PetscCall(VecNorm(F, NORM_2, &linesearch->fnorm));
613bf7f4e0aSPeter Brune   }
614bf7f4e0aSPeter Brune 
6159566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(SNESLINESEARCH_Apply,linesearch,X,F,Y));
616bf7f4e0aSPeter Brune 
6179566063dSJacob Faibussowitsch   PetscCall((*linesearch->ops->apply)(linesearch));
618bf7f4e0aSPeter Brune 
6199566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(SNESLINESEARCH_Apply,linesearch,X,F,Y));
620bf7f4e0aSPeter Brune 
621f5af7f23SKarl Rupp   if (fnorm) *fnorm = linesearch->fnorm;
622bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
623bf7f4e0aSPeter Brune }
624bf7f4e0aSPeter Brune 
625f40b411bSPeter Brune /*@
626f1c6b773SPeter Brune    SNESLineSearchDestroy - Destroys the line search instance.
627f40b411bSPeter Brune 
628f1c6b773SPeter Brune    Collective on SNESLineSearch
629f40b411bSPeter Brune 
630f40b411bSPeter Brune    Input Parameters:
6318e557f58SPeter Brune .  linesearch - The linesearch context
632f40b411bSPeter Brune 
63384238204SBarry Smith    Level: developer
634f40b411bSPeter Brune 
635db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESLineSearchCreate()`, `SNESLineSearchReset()`, `SNESDestroy()`
636f40b411bSPeter Brune @*/
637bf388a1fSBarry Smith PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch)
638bf388a1fSBarry Smith {
639bf7f4e0aSPeter Brune   PetscFunctionBegin;
640bf7f4e0aSPeter Brune   if (!*linesearch) PetscFunctionReturn(0);
641f1c6b773SPeter Brune   PetscValidHeaderSpecific((*linesearch),SNESLINESEARCH_CLASSID,1);
6429e5d0892SLisandro Dalcin   if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = NULL; PetscFunctionReturn(0);}
6439566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsViewOff((PetscObject)*linesearch));
6449566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchReset(*linesearch));
645f5af7f23SKarl Rupp   if ((*linesearch)->ops->destroy) (*linesearch)->ops->destroy(*linesearch);
6469566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*linesearch)->monitor));
6479566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchMonitorCancel((*linesearch)));
6489566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(linesearch));
649bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
650bf7f4e0aSPeter Brune }
651bf7f4e0aSPeter Brune 
652f40b411bSPeter Brune /*@
653dcf2fd19SBarry Smith    SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.
654bf7f4e0aSPeter Brune 
655bf7f4e0aSPeter Brune    Input Parameters:
656dcf2fd19SBarry Smith +  linesearch - the linesearch object
657dcf2fd19SBarry Smith -  viewer - an ASCII PetscViewer or NULL to turn off monitor
658bf7f4e0aSPeter Brune 
659dcf2fd19SBarry Smith    Logically Collective on SNESLineSearch
660bf7f4e0aSPeter Brune 
661bf7f4e0aSPeter Brune    Options Database:
662dcf2fd19SBarry Smith .   -snes_linesearch_monitor [:filename] - enables the monitor
663bf7f4e0aSPeter Brune 
664bf7f4e0aSPeter Brune    Level: intermediate
665bf7f4e0aSPeter Brune 
666dcf2fd19SBarry Smith    Developer Note: This monitor is implemented differently than the other SNESLineSearchMonitors that are set with
667d12e167eSBarry Smith      SNESLineSearchMonitorSet() since it is called in many locations of the line search routines to display aspects of the
668d12e167eSBarry Smith      line search that are not visible to the other monitors.
669dcf2fd19SBarry Smith 
670db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESLineSearchGetDefaultMonitor()`, `PetscViewer`, `SNESLineSearchSetMonitor()`
671bf7f4e0aSPeter Brune @*/
672dcf2fd19SBarry Smith PetscErrorCode  SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
673bf7f4e0aSPeter Brune {
674bf7f4e0aSPeter Brune   PetscFunctionBegin;
6759566063dSJacob Faibussowitsch   if (viewer) PetscCall(PetscObjectReference((PetscObject)viewer));
6769566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&linesearch->monitor));
677dcf2fd19SBarry Smith   linesearch->monitor = viewer;
678bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
679bf7f4e0aSPeter Brune }
680bf7f4e0aSPeter Brune 
681f40b411bSPeter Brune /*@
682dcf2fd19SBarry Smith    SNESLineSearchGetDefaultMonitor - Gets the PetscViewer instance for the line search monitor.
6836a388c36SPeter Brune 
684f190f2fcSBarry Smith    Input Parameter:
6858e557f58SPeter Brune .  linesearch - linesearch context
686f40b411bSPeter Brune 
687f190f2fcSBarry Smith    Output Parameter:
6888e557f58SPeter Brune .  monitor - monitor context
689f40b411bSPeter Brune 
690f40b411bSPeter Brune    Logically Collective on SNES
691f40b411bSPeter Brune 
692f40b411bSPeter Brune    Options Database Keys:
6938e557f58SPeter Brune .   -snes_linesearch_monitor - enables the monitor
694f40b411bSPeter Brune 
695f40b411bSPeter Brune    Level: intermediate
696f40b411bSPeter Brune 
697db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESLineSearchSetDefaultMonitor()`, `PetscViewer`
698f40b411bSPeter Brune @*/
699dcf2fd19SBarry Smith PetscErrorCode  SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
7006a388c36SPeter Brune {
7016a388c36SPeter Brune   PetscFunctionBegin;
702f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
7036a388c36SPeter Brune   *monitor = linesearch->monitor;
7046a388c36SPeter Brune   PetscFunctionReturn(0);
7056a388c36SPeter Brune }
7066a388c36SPeter Brune 
707dcf2fd19SBarry Smith /*@C
708dcf2fd19SBarry Smith    SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
709dcf2fd19SBarry Smith 
710dcf2fd19SBarry Smith    Collective on SNESLineSearch
711dcf2fd19SBarry Smith 
712dcf2fd19SBarry Smith    Input Parameters:
713dcf2fd19SBarry Smith +  ls - LineSearch object you wish to monitor
714dcf2fd19SBarry Smith .  name - the monitor type one is seeking
715dcf2fd19SBarry Smith .  help - message indicating what monitoring is done
716dcf2fd19SBarry Smith .  manual - manual page for the monitor
717dcf2fd19SBarry Smith .  monitor - the monitor function
718dcf2fd19SBarry Smith -  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
719dcf2fd19SBarry Smith 
720dcf2fd19SBarry Smith    Level: developer
721dcf2fd19SBarry Smith 
722db781477SPatrick Sanan .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
723db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
724db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
725db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
726c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
727db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
728db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
729dcf2fd19SBarry Smith @*/
730d12e167eSBarry Smith PetscErrorCode  SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNESLineSearch,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNESLineSearch,PetscViewerAndFormat*))
731dcf2fd19SBarry Smith {
732dcf2fd19SBarry Smith   PetscViewer       viewer;
733dcf2fd19SBarry Smith   PetscViewerFormat format;
734dcf2fd19SBarry Smith   PetscBool         flg;
735dcf2fd19SBarry Smith 
736dcf2fd19SBarry Smith   PetscFunctionBegin;
7379566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls),((PetscObject) ls)->options,((PetscObject)ls)->prefix,name,&viewer,&format,&flg));
738dcf2fd19SBarry Smith   if (flg) {
739d12e167eSBarry Smith     PetscViewerAndFormat *vf;
7409566063dSJacob Faibussowitsch     PetscCall(PetscViewerAndFormatCreate(viewer,format,&vf));
7419566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)viewer));
7421baa6e33SBarry Smith     if (monitorsetup) PetscCall((*monitorsetup)(ls,vf));
7439566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchMonitorSet(ls,(PetscErrorCode (*)(SNESLineSearch,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy));
744dcf2fd19SBarry Smith   }
745dcf2fd19SBarry Smith   PetscFunctionReturn(0);
746dcf2fd19SBarry Smith }
747dcf2fd19SBarry Smith 
748f40b411bSPeter Brune /*@
749f1c6b773SPeter Brune    SNESLineSearchSetFromOptions - Sets options for the line search
750f40b411bSPeter Brune 
751f899ff85SJose E. Roman    Input Parameter:
7528e557f58SPeter Brune .  linesearch - linesearch context
753f40b411bSPeter Brune 
754f40b411bSPeter Brune    Options Database Keys:
7550b00b554SBarry Smith + -snes_linesearch_type <type> - basic (or equivalently none), bt, l2, cp, nleqerr, shell
7563c7d6663SPeter Brune . -snes_linesearch_order <order> - 1, 2, 3.  Most types only support certain orders (bt supports 2 or 3)
7571fe24845SBarry Smith . -snes_linesearch_norms   - Turn on/off the linesearch norms for the basic linesearch typem (SNESLineSearchSetComputeNorms())
75871eef1aeSPeter Brune . -snes_linesearch_minlambda - The minimum step length
7591a9b3a06SPeter Brune . -snes_linesearch_maxstep - The maximum step size
7601a9b3a06SPeter Brune . -snes_linesearch_rtol - Relative tolerance for iterative line searches
7611a9b3a06SPeter Brune . -snes_linesearch_atol - Absolute tolerance for iterative line searches
7621a9b3a06SPeter Brune . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
7631a9b3a06SPeter Brune . -snes_linesearch_max_it - The number of iterations for iterative line searches
764dcf2fd19SBarry Smith . -snes_linesearch_monitor [:filename] - Print progress of line searches
765dcf2fd19SBarry Smith . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
7668e557f58SPeter Brune . -snes_linesearch_damping - The linesearch damping parameter
767cd7522eaSPeter Brune . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
7681a9b3a06SPeter Brune . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
769d8d34be6SBarry Smith - -snes_linesearch_precheck_picard_angle - Angle used in Picard precheck method
770f40b411bSPeter Brune 
771f1c6b773SPeter Brune    Logically Collective on SNESLineSearch
772f40b411bSPeter Brune 
773f40b411bSPeter Brune    Level: intermediate
774f40b411bSPeter Brune 
775db781477SPatrick Sanan .seealso: `SNESLineSearchCreate()`, `SNESLineSearchSetOrder()`, `SNESLineSearchSetType()`, `SNESLineSearchSetTolerances()`, `SNESLineSearchSetDamping()`, `SNESLineSearchPreCheckPicard()`,
776db781477SPatrick Sanan           `SNESLineSearchType`, `SNESLineSearchSetComputeNorms()`
777f40b411bSPeter Brune @*/
778bf388a1fSBarry Smith PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
779bf388a1fSBarry Smith {
7801a4f838cSPeter Brune   const char        *deft = SNESLINESEARCHBASIC;
781bf7f4e0aSPeter Brune   char              type[256];
782bf7f4e0aSPeter Brune   PetscBool         flg, set;
783dcf2fd19SBarry Smith   PetscViewer       viewer;
784bf388a1fSBarry Smith 
785bf7f4e0aSPeter Brune   PetscFunctionBegin;
7869566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchRegisterAll());
787bf7f4e0aSPeter Brune 
788d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)linesearch);
789f5af7f23SKarl Rupp   if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
7909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-snes_linesearch_type","Linesearch type","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg));
791bf7f4e0aSPeter Brune   if (flg) {
7929566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetType(linesearch,type));
793bf7f4e0aSPeter Brune   } else if (!((PetscObject)linesearch)->type_name) {
7949566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetType(linesearch,deft));
795bf7f4e0aSPeter Brune   }
796bf7f4e0aSPeter Brune 
7979566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch),((PetscObject) linesearch)->options,((PetscObject)linesearch)->prefix,"-snes_linesearch_monitor",&viewer,NULL,&set));
798dcf2fd19SBarry Smith   if (set) {
7999566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetDefaultMonitor(linesearch,viewer));
8009566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
801dcf2fd19SBarry Smith   }
8029566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchMonitorSetFromOptions(linesearch,"-snes_linesearch_monitor_solution_update","View correction at each iteration","SNESLineSearchMonitorSolutionUpdate",SNESLineSearchMonitorSolutionUpdate,NULL));
803bf7f4e0aSPeter Brune 
8041a9b3a06SPeter Brune   /* tolerances */
8059566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_minlambda","Minimum step length","SNESLineSearchSetTolerances",linesearch->steptol,&linesearch->steptol,NULL));
8069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_maxstep","Maximum step size","SNESLineSearchSetTolerances",linesearch->maxstep,&linesearch->maxstep,NULL));
8079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_rtol","Relative tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->rtol,&linesearch->rtol,NULL));
8089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_atol","Absolute tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->atol,&linesearch->atol,NULL));
8099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_ltol","Change in lambda tolerance for iterative line search","SNESLineSearchSetTolerances",linesearch->ltol,&linesearch->ltol,NULL));
8109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","SNESLineSearchSetTolerances",linesearch->max_its,&linesearch->max_its,NULL));
8117a35526eSPeter Brune 
8121a9b3a06SPeter Brune   /* damping parameters */
8139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,NULL));
8141a9b3a06SPeter Brune 
8159566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,NULL));
8161a9b3a06SPeter Brune 
8171a9b3a06SPeter Brune   /* precheck */
8189566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set));
8197a35526eSPeter Brune   if (set) {
8207a35526eSPeter Brune     if (flg) {
8217a35526eSPeter Brune       linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
822f5af7f23SKarl Rupp 
823d0609cedSBarry Smith       PetscCall(PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction","none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,NULL));
8249566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle));
8257a35526eSPeter Brune     } else {
8269566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchSetPreCheck(linesearch,NULL,NULL));
8277a35526eSPeter Brune     }
8287a35526eSPeter Brune   }
8299566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_linesearch_order","Order of approximation used in the line search","SNESLineSearchSetOrder",linesearch->order,&linesearch->order,NULL));
8309566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,NULL));
8317a35526eSPeter Brune 
8321baa6e33SBarry Smith   if (linesearch->ops->setfromoptions) PetscCall((*linesearch->ops->setfromoptions)(PetscOptionsObject,linesearch));
8335a9b6599SPeter Brune 
8349566063dSJacob Faibussowitsch   PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)linesearch));
835d0609cedSBarry Smith   PetscOptionsEnd();
836bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
837bf7f4e0aSPeter Brune }
838bf7f4e0aSPeter Brune 
839f40b411bSPeter Brune /*@
840f190f2fcSBarry Smith    SNESLineSearchView - Prints useful information about the line search
841f40b411bSPeter Brune 
842f40b411bSPeter Brune    Input Parameters:
8438e557f58SPeter Brune .  linesearch - linesearch context
844f40b411bSPeter Brune 
845f1c6b773SPeter Brune    Logically Collective on SNESLineSearch
846f40b411bSPeter Brune 
847f40b411bSPeter Brune    Level: intermediate
848f40b411bSPeter Brune 
849db781477SPatrick Sanan .seealso: `SNESLineSearchCreate()`
850f40b411bSPeter Brune @*/
851bf388a1fSBarry Smith PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
852bf388a1fSBarry Smith {
8537f1410a3SPeter Brune   PetscBool      iascii;
854bf388a1fSBarry Smith 
855bf7f4e0aSPeter Brune   PetscFunctionBegin;
8567f1410a3SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
8577f1410a3SPeter Brune   if (!viewer) {
8589566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch),&viewer));
8597f1410a3SPeter Brune   }
8607f1410a3SPeter Brune   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
8617f1410a3SPeter Brune   PetscCheckSameComm(linesearch,1,viewer,2);
862f40b411bSPeter Brune 
8639566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
8647f1410a3SPeter Brune   if (iascii) {
8659566063dSJacob Faibussowitsch     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)linesearch,viewer));
8667f1410a3SPeter Brune     if (linesearch->ops->view) {
8679566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushTab(viewer));
8689566063dSJacob Faibussowitsch       PetscCall((*linesearch->ops->view)(linesearch,viewer));
8699566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
8707f1410a3SPeter Brune     }
8719566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep,(double)linesearch->steptol));
8729566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol,(double)linesearch->atol,(double)linesearch->ltol));
87363a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  maximum iterations=%" PetscInt_FMT "\n", linesearch->max_its));
8746b2b7091SBarry Smith     if (linesearch->ops->precheck) {
8756b2b7091SBarry Smith       if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
87663a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"  using precheck step to speed up Picard convergence\n"));
8777f1410a3SPeter Brune       } else {
87863a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"  using user-defined precheck step\n"));
8797f1410a3SPeter Brune       }
8807f1410a3SPeter Brune     }
8816b2b7091SBarry Smith     if (linesearch->ops->postcheck) {
88263a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  using user-defined postcheck step\n"));
8837f1410a3SPeter Brune     }
8847f1410a3SPeter Brune   }
885bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
886bf7f4e0aSPeter Brune }
887bf7f4e0aSPeter Brune 
888ea5d4fccSPeter Brune /*@C
889a80ff896SJed Brown    SNESLineSearchGetType - Gets the linesearch type
890a80ff896SJed Brown 
891a80ff896SJed Brown    Logically Collective on SNESLineSearch
892a80ff896SJed Brown 
893a80ff896SJed Brown    Input Parameters:
894a80ff896SJed Brown .  linesearch - linesearch context
895a80ff896SJed Brown 
896a80ff896SJed Brown    Output Parameters:
897a80ff896SJed Brown -  type - The type of line search, or NULL if not set
898a80ff896SJed Brown 
899a80ff896SJed Brown    Level: intermediate
900a80ff896SJed Brown 
901db781477SPatrick Sanan .seealso: `SNESLineSearchCreate()`, `SNESLineSearchType`, `SNESLineSearchSetFromOptions()`, `SNESLineSearchSetType()`
902a80ff896SJed Brown @*/
903a80ff896SJed Brown PetscErrorCode SNESLineSearchGetType(SNESLineSearch linesearch, SNESLineSearchType *type)
904a80ff896SJed Brown {
905a80ff896SJed Brown   PetscFunctionBegin;
906a80ff896SJed Brown   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
907dadcf809SJacob Faibussowitsch   PetscValidPointer(type,2);
908a80ff896SJed Brown   *type = ((PetscObject)linesearch)->type_name;
909a80ff896SJed Brown   PetscFunctionReturn(0);
910a80ff896SJed Brown }
911a80ff896SJed Brown 
912a80ff896SJed Brown /*@C
913f1c6b773SPeter Brune    SNESLineSearchSetType - Sets the linesearch type
914f40b411bSPeter Brune 
915f190f2fcSBarry Smith    Logically Collective on SNESLineSearch
916f190f2fcSBarry Smith 
917f40b411bSPeter Brune    Input Parameters:
9188e557f58SPeter Brune +  linesearch - linesearch context
919f40b411bSPeter Brune -  type - The type of line search to be used
920f40b411bSPeter Brune 
921cd7522eaSPeter Brune    Available Types:
9220b00b554SBarry Smith +  SNESLINESEARCHBASIC - (or equivalently SNESLINESEARCHNONE) Simple damping line search, defaults to using the full Newton step
9231fe24845SBarry Smith .  SNESLINESEARCHBT - Backtracking line search over the L2 norm of the function
9241fe24845SBarry Smith .  SNESLINESEARCHL2 - Secant line search over the L2 norm of the function
9251fe24845SBarry Smith .  SNESLINESEARCHCP - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
9261fe24845SBarry Smith .  SNESLINESEARCHNLEQERR - Affine-covariant error-oriented linesearch
9271fe24845SBarry Smith -  SNESLINESEARCHSHELL - User provided SNESLineSearch implementation
9281fe24845SBarry Smith 
9291fe24845SBarry Smith    Options Database:
9300b00b554SBarry Smith .  -snes_linesearch_type <type> - basic (or equivalently none), bt, l2, cp, nleqerr, shell
931cd7522eaSPeter Brune 
932f40b411bSPeter Brune    Level: intermediate
933f40b411bSPeter Brune 
934db781477SPatrick Sanan .seealso: `SNESLineSearchCreate()`, `SNESLineSearchType`, `SNESLineSearchSetFromOptions()`, `SNESLineSearchGetType()`
935f40b411bSPeter Brune @*/
93619fd82e9SBarry Smith PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
937bf7f4e0aSPeter Brune {
938bf7f4e0aSPeter Brune   PetscBool      match;
9395f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(SNESLineSearch);
940bf7f4e0aSPeter Brune 
941bf7f4e0aSPeter Brune   PetscFunctionBegin;
942f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
943bf7f4e0aSPeter Brune   PetscValidCharPointer(type,2);
944bf7f4e0aSPeter Brune 
9459566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch,type,&match));
946bf7f4e0aSPeter Brune   if (match) PetscFunctionReturn(0);
947bf7f4e0aSPeter Brune 
9489566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(SNESLineSearchList,type,&r));
9495f80ce2aSJacob Faibussowitsch   PetscCheck(r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
950bf7f4e0aSPeter Brune   /* Destroy the previous private linesearch context */
951bf7f4e0aSPeter Brune   if (linesearch->ops->destroy) {
9529566063dSJacob Faibussowitsch     PetscCall((*(linesearch)->ops->destroy)(linesearch));
9530298fd71SBarry Smith     linesearch->ops->destroy = NULL;
954bf7f4e0aSPeter Brune   }
955f1c6b773SPeter Brune   /* Reinitialize function pointers in SNESLineSearchOps structure */
9569e5d0892SLisandro Dalcin   linesearch->ops->apply          = NULL;
9579e5d0892SLisandro Dalcin   linesearch->ops->view           = NULL;
9589e5d0892SLisandro Dalcin   linesearch->ops->setfromoptions = NULL;
9599e5d0892SLisandro Dalcin   linesearch->ops->destroy        = NULL;
960bf7f4e0aSPeter Brune 
9619566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)linesearch,type));
9629566063dSJacob Faibussowitsch   PetscCall((*r)(linesearch));
963bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
964bf7f4e0aSPeter Brune }
965bf7f4e0aSPeter Brune 
966f40b411bSPeter Brune /*@
96778bcb3b5SPeter Brune    SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation.
968f40b411bSPeter Brune 
969f40b411bSPeter Brune    Input Parameters:
9708e557f58SPeter Brune +  linesearch - linesearch context
971f40b411bSPeter Brune -  snes - The snes instance
972f40b411bSPeter Brune 
97378bcb3b5SPeter Brune    Level: developer
97478bcb3b5SPeter Brune 
97578bcb3b5SPeter Brune    Notes:
976f190f2fcSBarry Smith    This happens automatically when the line search is obtained/created with
9777601faf0SJed Brown    SNESGetLineSearch().  This routine is therefore mainly called within SNES
97878bcb3b5SPeter Brune    implementations.
979f40b411bSPeter Brune 
9808141a3b9SPeter Brune    Level: developer
981f40b411bSPeter Brune 
982db781477SPatrick Sanan .seealso: `SNESLineSearchGetSNES()`, `SNESLineSearchSetVecs()`, `SNES`
983f40b411bSPeter Brune @*/
984bf388a1fSBarry Smith PetscErrorCode  SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
985bf388a1fSBarry Smith {
986bf7f4e0aSPeter Brune   PetscFunctionBegin;
987f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
988bf7f4e0aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
989bf7f4e0aSPeter Brune   linesearch->snes = snes;
990bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
991bf7f4e0aSPeter Brune }
992bf7f4e0aSPeter Brune 
993f40b411bSPeter Brune /*@
9948141a3b9SPeter Brune    SNESLineSearchGetSNES - Gets the SNES instance associated with the line search.
9958141a3b9SPeter Brune    Having an associated SNES is necessary because most line search implementations must be able to
9968141a3b9SPeter Brune    evaluate the function using SNESComputeFunction() for the associated SNES.  This routine
9978141a3b9SPeter Brune    is used in the line search implementations when one must get this associated SNES instance.
998f40b411bSPeter Brune 
999f40b411bSPeter Brune    Input Parameters:
10008e557f58SPeter Brune .  linesearch - linesearch context
1001f40b411bSPeter Brune 
1002f40b411bSPeter Brune    Output Parameters:
1003f40b411bSPeter Brune .  snes - The snes instance
1004f40b411bSPeter Brune 
10058141a3b9SPeter Brune    Level: developer
1006f40b411bSPeter Brune 
1007db781477SPatrick Sanan .seealso: `SNESLineSearchGetSNES()`, `SNESLineSearchSetVecs()`, `SNES`
1008f40b411bSPeter Brune @*/
1009bf388a1fSBarry Smith PetscErrorCode  SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1010bf388a1fSBarry Smith {
1011bf7f4e0aSPeter Brune   PetscFunctionBegin;
1012f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
10136a388c36SPeter Brune   PetscValidPointer(snes,2);
1014bf7f4e0aSPeter Brune   *snes = linesearch->snes;
1015bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
1016bf7f4e0aSPeter Brune }
1017bf7f4e0aSPeter Brune 
1018f40b411bSPeter Brune /*@
1019f1c6b773SPeter Brune    SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
1020f40b411bSPeter Brune 
1021f40b411bSPeter Brune    Input Parameters:
10228e557f58SPeter Brune .  linesearch - linesearch context
1023f40b411bSPeter Brune 
1024f40b411bSPeter Brune    Output Parameters:
1025cd7522eaSPeter Brune .  lambda - The last steplength computed during SNESLineSearchApply()
1026f40b411bSPeter Brune 
102778bcb3b5SPeter Brune    Level: advanced
102878bcb3b5SPeter Brune 
10298e557f58SPeter Brune    Notes:
10308e557f58SPeter Brune    This is useful in methods where the solver is ill-scaled and
103178bcb3b5SPeter Brune    requires some adaptive notion of the difference in scale between the
103278bcb3b5SPeter Brune    solution and the function.  For instance, SNESQN may be scaled by the
103378bcb3b5SPeter Brune    line search lambda using the argument -snes_qn_scaling ls.
103478bcb3b5SPeter Brune 
1035db781477SPatrick Sanan .seealso: `SNESLineSearchSetLambda()`, `SNESLineSearchGetDamping()`, `SNESLineSearchApply()`
1036f40b411bSPeter Brune @*/
1037f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
10386a388c36SPeter Brune {
10396a388c36SPeter Brune   PetscFunctionBegin;
1040f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1041534a8f05SLisandro Dalcin   PetscValidRealPointer(lambda, 2);
10426a388c36SPeter Brune   *lambda = linesearch->lambda;
10436a388c36SPeter Brune   PetscFunctionReturn(0);
10446a388c36SPeter Brune }
10456a388c36SPeter Brune 
1046f40b411bSPeter Brune /*@
1047f1c6b773SPeter Brune    SNESLineSearchSetLambda - Sets the linesearch steplength.
1048f40b411bSPeter Brune 
1049f40b411bSPeter Brune    Input Parameters:
10508e557f58SPeter Brune +  linesearch - linesearch context
1051f40b411bSPeter Brune -  lambda - The last steplength.
1052f40b411bSPeter Brune 
1053cd7522eaSPeter Brune    Notes:
1054f190f2fcSBarry Smith    This routine is typically used within implementations of SNESLineSearchApply()
1055cd7522eaSPeter Brune    to set the final steplength.  This routine (and SNESLineSearchGetLambda()) were
1056cd7522eaSPeter Brune    added in order to facilitate Quasi-Newton methods that use the previous steplength
1057cd7522eaSPeter Brune    as an inner scaling parameter.
1058cd7522eaSPeter Brune 
105978bcb3b5SPeter Brune    Level: advanced
1060f40b411bSPeter Brune 
1061db781477SPatrick Sanan .seealso: `SNESLineSearchGetLambda()`
1062f40b411bSPeter Brune @*/
1063f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
10646a388c36SPeter Brune {
10656a388c36SPeter Brune   PetscFunctionBegin;
1066f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
10676a388c36SPeter Brune   linesearch->lambda = lambda;
10686a388c36SPeter Brune   PetscFunctionReturn(0);
10696a388c36SPeter Brune }
10706a388c36SPeter Brune 
1071f40b411bSPeter Brune /*@
10723c7d6663SPeter Brune    SNESLineSearchGetTolerances - Gets the tolerances for the linesearch.  These include
107378bcb3b5SPeter Brune    tolerances for the relative and absolute change in the function norm, the change
107478bcb3b5SPeter Brune    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
107578bcb3b5SPeter Brune    and the maximum number of iterations the line search procedure may take.
1076f40b411bSPeter Brune 
1077f899ff85SJose E. Roman    Input Parameter:
10788e557f58SPeter Brune .  linesearch - linesearch context
1079f40b411bSPeter Brune 
1080f40b411bSPeter Brune    Output Parameters:
1081516fe3c3SPeter Brune +  steptol - The minimum steplength
10826cc8e53bSPeter Brune .  maxstep - The maximum steplength
1083516fe3c3SPeter Brune .  rtol    - The relative tolerance for iterative line searches
1084516fe3c3SPeter Brune .  atol    - The absolute tolerance for iterative line searches
1085516fe3c3SPeter Brune .  ltol    - The change in lambda tolerance for iterative line searches
1086516fe3c3SPeter Brune -  max_it  - The maximum number of iterations of the line search
1087f40b411bSPeter Brune 
108878bcb3b5SPeter Brune    Level: intermediate
108978bcb3b5SPeter Brune 
109078bcb3b5SPeter Brune    Notes:
109178bcb3b5SPeter Brune    Different line searches may implement these parameters slightly differently as
10923c7d6663SPeter Brune    the type requires.
1093516fe3c3SPeter Brune 
1094db781477SPatrick Sanan .seealso: `SNESLineSearchSetTolerances()`
1095f40b411bSPeter Brune @*/
1096f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
10976a388c36SPeter Brune {
10986a388c36SPeter Brune   PetscFunctionBegin;
1099f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1100516fe3c3SPeter Brune   if (steptol) {
1101534a8f05SLisandro Dalcin     PetscValidRealPointer(steptol, 2);
11026a388c36SPeter Brune     *steptol = linesearch->steptol;
1103516fe3c3SPeter Brune   }
1104516fe3c3SPeter Brune   if (maxstep) {
1105534a8f05SLisandro Dalcin     PetscValidRealPointer(maxstep, 3);
1106516fe3c3SPeter Brune     *maxstep = linesearch->maxstep;
1107516fe3c3SPeter Brune   }
1108516fe3c3SPeter Brune   if (rtol) {
1109534a8f05SLisandro Dalcin     PetscValidRealPointer(rtol, 4);
1110516fe3c3SPeter Brune     *rtol = linesearch->rtol;
1111516fe3c3SPeter Brune   }
1112516fe3c3SPeter Brune   if (atol) {
1113534a8f05SLisandro Dalcin     PetscValidRealPointer(atol, 5);
1114516fe3c3SPeter Brune     *atol = linesearch->atol;
1115516fe3c3SPeter Brune   }
1116516fe3c3SPeter Brune   if (ltol) {
1117534a8f05SLisandro Dalcin     PetscValidRealPointer(ltol, 6);
1118516fe3c3SPeter Brune     *ltol = linesearch->ltol;
1119516fe3c3SPeter Brune   }
1120516fe3c3SPeter Brune   if (max_its) {
1121534a8f05SLisandro Dalcin     PetscValidIntPointer(max_its, 7);
1122516fe3c3SPeter Brune     *max_its = linesearch->max_its;
1123516fe3c3SPeter Brune   }
11246a388c36SPeter Brune   PetscFunctionReturn(0);
11256a388c36SPeter Brune }
11266a388c36SPeter Brune 
1127f40b411bSPeter Brune /*@
11283c7d6663SPeter Brune    SNESLineSearchSetTolerances -  Gets the tolerances for the linesearch.  These include
112978bcb3b5SPeter Brune    tolerances for the relative and absolute change in the function norm, the change
113078bcb3b5SPeter Brune    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
113178bcb3b5SPeter Brune    and the maximum number of iterations the line search procedure may take.
1132f40b411bSPeter Brune 
1133f40b411bSPeter Brune    Input Parameters:
11348e557f58SPeter Brune +  linesearch - linesearch context
1135516fe3c3SPeter Brune .  steptol - The minimum steplength
11366cc8e53bSPeter Brune .  maxstep - The maximum steplength
1137516fe3c3SPeter Brune .  rtol    - The relative tolerance for iterative line searches
1138516fe3c3SPeter Brune .  atol    - The absolute tolerance for iterative line searches
1139516fe3c3SPeter Brune .  ltol    - The change in lambda tolerance for iterative line searches
1140516fe3c3SPeter Brune -  max_it  - The maximum number of iterations of the line search
1141f40b411bSPeter Brune 
114278bcb3b5SPeter Brune    Notes:
11433c7d6663SPeter Brune    The user may choose to not set any of the tolerances using PETSC_DEFAULT in
114478bcb3b5SPeter Brune    place of an argument.
1145f40b411bSPeter Brune 
114678bcb3b5SPeter Brune    Level: intermediate
1147516fe3c3SPeter Brune 
1148db781477SPatrick Sanan .seealso: `SNESLineSearchGetTolerances()`
1149f40b411bSPeter Brune @*/
1150f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
11516a388c36SPeter Brune {
11526a388c36SPeter Brune   PetscFunctionBegin;
1153f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1154d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch,steptol,2);
1155d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch,maxstep,3);
1156d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch,rtol,4);
1157d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch,atol,5);
1158d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch,ltol,6);
1159d3952184SSatish Balay   PetscValidLogicalCollectiveInt(linesearch,max_its,7);
1160d3952184SSatish Balay 
1161d3952184SSatish Balay   if (steptol!= PETSC_DEFAULT) {
11625f80ce2aSJacob Faibussowitsch     PetscCheck(steptol >= 0.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Minimum step length %14.12e must be non-negative",(double)steptol);
11636a388c36SPeter Brune     linesearch->steptol = steptol;
1164d3952184SSatish Balay   }
1165d3952184SSatish Balay 
1166d3952184SSatish Balay   if (maxstep!= PETSC_DEFAULT) {
11675f80ce2aSJacob Faibussowitsch     PetscCheck(maxstep >= 0.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum step length %14.12e must be non-negative",(double)maxstep);
1168516fe3c3SPeter Brune     linesearch->maxstep = maxstep;
1169d3952184SSatish Balay   }
1170d3952184SSatish Balay 
1171d3952184SSatish Balay   if (rtol != PETSC_DEFAULT) {
11722061ca32SJunchao Zhang     PetscCheck(rtol >= 0.0 && rtol < 1.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %14.12e must be non-negative and less than 1.0",(double)rtol);
1173516fe3c3SPeter Brune     linesearch->rtol = rtol;
1174d3952184SSatish Balay   }
1175d3952184SSatish Balay 
1176d3952184SSatish Balay   if (atol != PETSC_DEFAULT) {
11775f80ce2aSJacob Faibussowitsch     PetscCheck(atol >= 0.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %14.12e must be non-negative",(double)atol);
1178516fe3c3SPeter Brune     linesearch->atol = atol;
1179d3952184SSatish Balay   }
1180d3952184SSatish Balay 
1181d3952184SSatish Balay   if (ltol != PETSC_DEFAULT) {
11825f80ce2aSJacob Faibussowitsch     PetscCheck(ltol >= 0.0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Lambda tolerance %14.12e must be non-negative",(double)ltol);
1183516fe3c3SPeter Brune     linesearch->ltol = ltol;
1184d3952184SSatish Balay   }
1185d3952184SSatish Balay 
1186d3952184SSatish Balay   if (max_its != PETSC_DEFAULT) {
118763a3b9bcSJacob Faibussowitsch     PetscCheck(max_its >= 0,PetscObjectComm((PetscObject)linesearch),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %" PetscInt_FMT " must be non-negative",max_its);
1188516fe3c3SPeter Brune     linesearch->max_its = max_its;
1189d3952184SSatish Balay   }
11906a388c36SPeter Brune   PetscFunctionReturn(0);
11916a388c36SPeter Brune }
11926a388c36SPeter Brune 
1193f40b411bSPeter Brune /*@
1194f1c6b773SPeter Brune    SNESLineSearchGetDamping - Gets the line search damping parameter.
1195f40b411bSPeter Brune 
1196f40b411bSPeter Brune    Input Parameters:
11978e557f58SPeter Brune .  linesearch - linesearch context
1198f40b411bSPeter Brune 
1199f40b411bSPeter Brune    Output Parameters:
12008e557f58SPeter Brune .  damping - The damping parameter
1201f40b411bSPeter Brune 
120278bcb3b5SPeter Brune    Level: advanced
1203f40b411bSPeter Brune 
1204db781477SPatrick Sanan .seealso: `SNESLineSearchGetStepTolerance()`, `SNESQN`
1205f40b411bSPeter Brune @*/
1206f40b411bSPeter Brune 
1207f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
12086a388c36SPeter Brune {
12096a388c36SPeter Brune   PetscFunctionBegin;
1210f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1211534a8f05SLisandro Dalcin   PetscValidRealPointer(damping, 2);
12126a388c36SPeter Brune   *damping = linesearch->damping;
12136a388c36SPeter Brune   PetscFunctionReturn(0);
12146a388c36SPeter Brune }
12156a388c36SPeter Brune 
1216f40b411bSPeter Brune /*@
1217fd292e60Sprj-    SNESLineSearchSetDamping - Sets the line search damping parameter.
1218f40b411bSPeter Brune 
1219f40b411bSPeter Brune    Input Parameters:
122003fd4120SBarry Smith +  linesearch - linesearch context
122103fd4120SBarry Smith -  damping - The damping parameter
1222f40b411bSPeter Brune 
122303fd4120SBarry Smith    Options Database:
122403fd4120SBarry Smith .   -snes_linesearch_damping
1225f40b411bSPeter Brune    Level: intermediate
1226f40b411bSPeter Brune 
1227cd7522eaSPeter Brune    Notes:
12280b00b554SBarry Smith    The basic (also known as the none) line search merely takes the update step scaled by the damping parameter.
1229cd7522eaSPeter Brune    The use of the damping parameter in the l2 and cp line searches is much more subtle;
123078bcb3b5SPeter Brune    it is used as a starting point in calculating the secant step. However, the eventual
1231cd7522eaSPeter Brune    step may be of greater length than the damping parameter.  In the bt line search it is
1232cd7522eaSPeter Brune    used as the maximum possible step length, as the bt line search only backtracks.
1233cd7522eaSPeter Brune 
1234db781477SPatrick Sanan .seealso: `SNESLineSearchGetDamping()`
1235f40b411bSPeter Brune @*/
1236f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
12376a388c36SPeter Brune {
12386a388c36SPeter Brune   PetscFunctionBegin;
1239f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
12406a388c36SPeter Brune   linesearch->damping = damping;
12416a388c36SPeter Brune   PetscFunctionReturn(0);
12426a388c36SPeter Brune }
12436a388c36SPeter Brune 
124459405d5eSPeter Brune /*@
124559405d5eSPeter Brune    SNESLineSearchGetOrder - Gets the line search approximation order.
124659405d5eSPeter Brune 
124759405d5eSPeter Brune    Input Parameters:
124878bcb3b5SPeter Brune .  linesearch - linesearch context
124959405d5eSPeter Brune 
125059405d5eSPeter Brune    Output Parameters:
12518e557f58SPeter Brune .  order - The order
125259405d5eSPeter Brune 
125378bcb3b5SPeter Brune    Possible Values for order:
12543c7d6663SPeter Brune +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
12553c7d6663SPeter Brune .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
12563c7d6663SPeter Brune -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
125778bcb3b5SPeter Brune 
125859405d5eSPeter Brune    Level: intermediate
125959405d5eSPeter Brune 
1260db781477SPatrick Sanan .seealso: `SNESLineSearchSetOrder()`
126159405d5eSPeter Brune @*/
126259405d5eSPeter Brune 
1263b000cd8dSPeter Brune PetscErrorCode  SNESLineSearchGetOrder(SNESLineSearch linesearch,PetscInt *order)
126459405d5eSPeter Brune {
126559405d5eSPeter Brune   PetscFunctionBegin;
126659405d5eSPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1267534a8f05SLisandro Dalcin   PetscValidIntPointer(order, 2);
126859405d5eSPeter Brune   *order = linesearch->order;
126959405d5eSPeter Brune   PetscFunctionReturn(0);
127059405d5eSPeter Brune }
127159405d5eSPeter Brune 
127259405d5eSPeter Brune /*@
12731f8196a2SJed Brown    SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
127459405d5eSPeter Brune 
127559405d5eSPeter Brune    Input Parameters:
1276a2b725a8SWilliam Gropp +  linesearch - linesearch context
1277a2b725a8SWilliam Gropp -  order - The damping parameter
127859405d5eSPeter Brune 
127959405d5eSPeter Brune    Level: intermediate
128059405d5eSPeter Brune 
128178bcb3b5SPeter Brune    Possible Values for order:
12823c7d6663SPeter Brune +  1 or SNES_LINESEARCH_ORDER_LINEAR - linear order
12833c7d6663SPeter Brune .  2 or SNES_LINESEARCH_ORDER_QUADRATIC - quadratic order
12843c7d6663SPeter Brune -  3 or SNES_LINESEARCH_ORDER_CUBIC - cubic order
128578bcb3b5SPeter Brune 
128659405d5eSPeter Brune    Notes:
128759405d5eSPeter Brune    Variable orders are supported by the following line searches:
128878bcb3b5SPeter Brune +  bt - cubic and quadratic
128978bcb3b5SPeter Brune -  cp - linear and quadratic
129059405d5eSPeter Brune 
1291db781477SPatrick Sanan .seealso: `SNESLineSearchGetOrder()`, `SNESLineSearchSetDamping()`
129259405d5eSPeter Brune @*/
1293b000cd8dSPeter Brune PetscErrorCode  SNESLineSearchSetOrder(SNESLineSearch linesearch,PetscInt order)
129459405d5eSPeter Brune {
129559405d5eSPeter Brune   PetscFunctionBegin;
129659405d5eSPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
129759405d5eSPeter Brune   linesearch->order = order;
129859405d5eSPeter Brune   PetscFunctionReturn(0);
129959405d5eSPeter Brune }
130059405d5eSPeter Brune 
1301f40b411bSPeter Brune /*@
1302f1c6b773SPeter Brune    SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1303f40b411bSPeter Brune 
1304f899ff85SJose E. Roman    Input Parameter:
130578bcb3b5SPeter Brune .  linesearch - linesearch context
1306f40b411bSPeter Brune 
1307f40b411bSPeter Brune    Output Parameters:
1308f40b411bSPeter Brune +  xnorm - The norm of the current solution
1309f40b411bSPeter Brune .  fnorm - The norm of the current function
1310f40b411bSPeter Brune -  ynorm - The norm of the current update
1311f40b411bSPeter Brune 
1312cd7522eaSPeter Brune    Notes:
1313cd7522eaSPeter Brune    This function is mainly called from SNES implementations.
1314cd7522eaSPeter Brune 
131578bcb3b5SPeter Brune    Level: developer
1316f40b411bSPeter Brune 
1317db781477SPatrick Sanan .seealso: `SNESLineSearchSetNorms()` `SNESLineSearchGetVecs()`
1318f40b411bSPeter Brune @*/
1319f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
1320bf7f4e0aSPeter Brune {
1321bf7f4e0aSPeter Brune   PetscFunctionBegin;
1322f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1323f5af7f23SKarl Rupp   if (xnorm) *xnorm = linesearch->xnorm;
1324f5af7f23SKarl Rupp   if (fnorm) *fnorm = linesearch->fnorm;
1325f5af7f23SKarl Rupp   if (ynorm) *ynorm = linesearch->ynorm;
1326bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
1327bf7f4e0aSPeter Brune }
1328bf7f4e0aSPeter Brune 
1329f40b411bSPeter Brune /*@
1330f1c6b773SPeter Brune    SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1331f40b411bSPeter Brune 
1332f40b411bSPeter Brune    Input Parameters:
133378bcb3b5SPeter Brune +  linesearch - linesearch context
1334f40b411bSPeter Brune .  xnorm - The norm of the current solution
1335f40b411bSPeter Brune .  fnorm - The norm of the current function
1336f40b411bSPeter Brune -  ynorm - The norm of the current update
1337f40b411bSPeter Brune 
133878bcb3b5SPeter Brune    Level: advanced
1339f40b411bSPeter Brune 
1340db781477SPatrick Sanan .seealso: `SNESLineSearchGetNorms()`, `SNESLineSearchSetVecs()`
1341f40b411bSPeter Brune @*/
1342f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
13436a388c36SPeter Brune {
13446a388c36SPeter Brune   PetscFunctionBegin;
1345f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
13466a388c36SPeter Brune   linesearch->xnorm = xnorm;
13476a388c36SPeter Brune   linesearch->fnorm = fnorm;
13486a388c36SPeter Brune   linesearch->ynorm = ynorm;
13496a388c36SPeter Brune   PetscFunctionReturn(0);
13506a388c36SPeter Brune }
13516a388c36SPeter Brune 
1352f40b411bSPeter Brune /*@
1353f1c6b773SPeter Brune    SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1354f40b411bSPeter Brune 
1355f40b411bSPeter Brune    Input Parameters:
135678bcb3b5SPeter Brune .  linesearch - linesearch context
1357f40b411bSPeter Brune 
1358f40b411bSPeter Brune    Options Database Keys:
13598e557f58SPeter Brune .   -snes_linesearch_norms - turn norm computation on or off
1360f40b411bSPeter Brune 
1361f40b411bSPeter Brune    Level: intermediate
1362f40b411bSPeter Brune 
1363db781477SPatrick Sanan .seealso: `SNESLineSearchGetNorms`, `SNESLineSearchSetNorms()`, `SNESLineSearchSetComputeNorms()`
1364f40b411bSPeter Brune @*/
1365f1c6b773SPeter Brune PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
13666a388c36SPeter Brune {
13679bd66eb0SPeter Brune   SNES           snes;
1368bf388a1fSBarry Smith 
13696a388c36SPeter Brune   PetscFunctionBegin;
13706a388c36SPeter Brune   if (linesearch->norms) {
13719bd66eb0SPeter Brune     if (linesearch->ops->vinorm) {
13729566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchGetSNES(linesearch, &snes));
13739566063dSJacob Faibussowitsch       PetscCall(VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm));
13749566063dSJacob Faibussowitsch       PetscCall(VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm));
13759566063dSJacob Faibussowitsch       PetscCall((*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm));
13769bd66eb0SPeter Brune     } else {
13779566063dSJacob Faibussowitsch       PetscCall(VecNormBegin(linesearch->vec_func,   NORM_2, &linesearch->fnorm));
13789566063dSJacob Faibussowitsch       PetscCall(VecNormBegin(linesearch->vec_sol,    NORM_2, &linesearch->xnorm));
13799566063dSJacob Faibussowitsch       PetscCall(VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm));
13809566063dSJacob Faibussowitsch       PetscCall(VecNormEnd(linesearch->vec_func,     NORM_2, &linesearch->fnorm));
13819566063dSJacob Faibussowitsch       PetscCall(VecNormEnd(linesearch->vec_sol,      NORM_2, &linesearch->xnorm));
13829566063dSJacob Faibussowitsch       PetscCall(VecNormEnd(linesearch->vec_update,   NORM_2, &linesearch->ynorm));
13836a388c36SPeter Brune     }
13849bd66eb0SPeter Brune   }
13856a388c36SPeter Brune   PetscFunctionReturn(0);
13866a388c36SPeter Brune }
13876a388c36SPeter Brune 
13886f263ca3SPeter Brune /*@
13896f263ca3SPeter Brune    SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
13906f263ca3SPeter Brune 
13916f263ca3SPeter Brune    Input Parameters:
139278bcb3b5SPeter Brune +  linesearch  - linesearch context
139378bcb3b5SPeter Brune -  flg  - indicates whether or not to compute norms
13946f263ca3SPeter Brune 
13956f263ca3SPeter Brune    Options Database Keys:
13960b00b554SBarry Smith .   -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic (none) linesearch
13976f263ca3SPeter Brune 
13986f263ca3SPeter Brune    Notes:
13990b00b554SBarry Smith    This is most relevant to the SNESLINESEARCHBASIC (or equivalently SNESLINESEARCHNONE) line search type since most line searches have a stopping criteria involving the norm.
14006f263ca3SPeter Brune 
14016f263ca3SPeter Brune    Level: intermediate
14026f263ca3SPeter Brune 
1403db781477SPatrick Sanan .seealso: `SNESLineSearchGetNorms()`, `SNESLineSearchSetNorms()`, `SNESLineSearchComputeNorms()`, `SNESLINESEARCHBASIC`
14046f263ca3SPeter Brune @*/
14056f263ca3SPeter Brune PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
14066f263ca3SPeter Brune {
14076f263ca3SPeter Brune   PetscFunctionBegin;
14086f263ca3SPeter Brune   linesearch->norms = flg;
14096f263ca3SPeter Brune   PetscFunctionReturn(0);
14106f263ca3SPeter Brune }
14116f263ca3SPeter Brune 
1412f40b411bSPeter Brune /*@
1413f1c6b773SPeter Brune    SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1414f40b411bSPeter Brune 
1415f899ff85SJose E. Roman    Input Parameter:
141678bcb3b5SPeter Brune .  linesearch - linesearch context
1417f40b411bSPeter Brune 
1418f40b411bSPeter Brune    Output Parameters:
14196232e825SPeter Brune +  X - Solution vector
14206232e825SPeter Brune .  F - Function vector
14216232e825SPeter Brune .  Y - Search direction vector
14226232e825SPeter Brune .  W - Solution work vector
14236232e825SPeter Brune -  G - Function work vector
14246232e825SPeter Brune 
14257bba9028SPeter Brune    Notes:
14267bba9028SPeter Brune    At the beginning of a line search application, X should contain a
14276232e825SPeter Brune    solution and the vector F the function computed at X.  At the end of the
14286232e825SPeter Brune    line search application, X should contain the new solution, and F the
14296232e825SPeter Brune    function evaluated at the new solution.
1430f40b411bSPeter Brune 
14312a7a6963SBarry Smith    These vectors are owned by the SNESLineSearch and should not be destroyed by the caller
14322a7a6963SBarry Smith 
143378bcb3b5SPeter Brune    Level: advanced
1434f40b411bSPeter Brune 
1435db781477SPatrick Sanan .seealso: `SNESLineSearchGetNorms()`, `SNESLineSearchSetVecs()`
1436f40b411bSPeter Brune @*/
1437bf388a1fSBarry Smith PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G)
1438bf388a1fSBarry Smith {
14396a388c36SPeter Brune   PetscFunctionBegin;
1440f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
14416a388c36SPeter Brune   if (X) {
14426a388c36SPeter Brune     PetscValidPointer(X, 2);
14436a388c36SPeter Brune     *X = linesearch->vec_sol;
14446a388c36SPeter Brune   }
14456a388c36SPeter Brune   if (F) {
14466a388c36SPeter Brune     PetscValidPointer(F, 3);
14476a388c36SPeter Brune     *F = linesearch->vec_func;
14486a388c36SPeter Brune   }
14496a388c36SPeter Brune   if (Y) {
14506a388c36SPeter Brune     PetscValidPointer(Y, 4);
14516a388c36SPeter Brune     *Y = linesearch->vec_update;
14526a388c36SPeter Brune   }
14536a388c36SPeter Brune   if (W) {
14546a388c36SPeter Brune     PetscValidPointer(W, 5);
14556a388c36SPeter Brune     *W = linesearch->vec_sol_new;
14566a388c36SPeter Brune   }
14576a388c36SPeter Brune   if (G) {
14586a388c36SPeter Brune     PetscValidPointer(G, 6);
14596a388c36SPeter Brune     *G = linesearch->vec_func_new;
14606a388c36SPeter Brune   }
14616a388c36SPeter Brune   PetscFunctionReturn(0);
14626a388c36SPeter Brune }
14636a388c36SPeter Brune 
1464f40b411bSPeter Brune /*@
1465f1c6b773SPeter Brune    SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1466f40b411bSPeter Brune 
1467f40b411bSPeter Brune    Input Parameters:
146878bcb3b5SPeter Brune +  linesearch - linesearch context
14696232e825SPeter Brune .  X - Solution vector
14706232e825SPeter Brune .  F - Function vector
14716232e825SPeter Brune .  Y - Search direction vector
14726232e825SPeter Brune .  W - Solution work vector
14736232e825SPeter Brune -  G - Function work vector
1474f40b411bSPeter Brune 
147578bcb3b5SPeter Brune    Level: advanced
1476f40b411bSPeter Brune 
1477db781477SPatrick Sanan .seealso: `SNESLineSearchSetNorms()`, `SNESLineSearchGetVecs()`
1478f40b411bSPeter Brune @*/
1479bf388a1fSBarry Smith PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G)
1480bf388a1fSBarry Smith {
14816a388c36SPeter Brune   PetscFunctionBegin;
1482f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
14836a388c36SPeter Brune   if (X) {
14846a388c36SPeter Brune     PetscValidHeaderSpecific(X,VEC_CLASSID,2);
14856a388c36SPeter Brune     linesearch->vec_sol = X;
14866a388c36SPeter Brune   }
14876a388c36SPeter Brune   if (F) {
14886a388c36SPeter Brune     PetscValidHeaderSpecific(F,VEC_CLASSID,3);
14896a388c36SPeter Brune     linesearch->vec_func = F;
14906a388c36SPeter Brune   }
14916a388c36SPeter Brune   if (Y) {
14926a388c36SPeter Brune     PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
14936a388c36SPeter Brune     linesearch->vec_update = Y;
14946a388c36SPeter Brune   }
14956a388c36SPeter Brune   if (W) {
14966a388c36SPeter Brune     PetscValidHeaderSpecific(W,VEC_CLASSID,5);
14976a388c36SPeter Brune     linesearch->vec_sol_new = W;
14986a388c36SPeter Brune   }
14996a388c36SPeter Brune   if (G) {
15006a388c36SPeter Brune     PetscValidHeaderSpecific(G,VEC_CLASSID,6);
15016a388c36SPeter Brune     linesearch->vec_func_new = G;
15026a388c36SPeter Brune   }
15036a388c36SPeter Brune   PetscFunctionReturn(0);
15046a388c36SPeter Brune }
15056a388c36SPeter Brune 
1506e7058c64SPeter Brune /*@C
1507f1c6b773SPeter Brune    SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1508e7058c64SPeter Brune    SNES options in the database.
1509e7058c64SPeter Brune 
1510cd7522eaSPeter Brune    Logically Collective on SNESLineSearch
1511e7058c64SPeter Brune 
1512e7058c64SPeter Brune    Input Parameters:
1513e7058c64SPeter Brune +  snes - the SNES context
1514e7058c64SPeter Brune -  prefix - the prefix to prepend to all option names
1515e7058c64SPeter Brune 
1516e7058c64SPeter Brune    Notes:
1517e7058c64SPeter Brune    A hyphen (-) must NOT be given at the beginning of the prefix name.
1518e7058c64SPeter Brune    The first character of all runtime options is AUTOMATICALLY the hyphen.
1519e7058c64SPeter Brune 
1520e7058c64SPeter Brune    Level: advanced
1521e7058c64SPeter Brune 
1522db781477SPatrick Sanan .seealso: `SNESGetOptionsPrefix()`
1523e7058c64SPeter Brune @*/
1524f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1525e7058c64SPeter Brune {
1526e7058c64SPeter Brune   PetscFunctionBegin;
1527f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
15289566063dSJacob Faibussowitsch   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix));
1529e7058c64SPeter Brune   PetscFunctionReturn(0);
1530e7058c64SPeter Brune }
1531e7058c64SPeter Brune 
1532e7058c64SPeter Brune /*@C
1533f1c6b773SPeter Brune    SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1534f1c6b773SPeter Brune    SNESLineSearch options in the database.
1535e7058c64SPeter Brune 
1536e7058c64SPeter Brune    Not Collective
1537e7058c64SPeter Brune 
1538e7058c64SPeter Brune    Input Parameter:
1539cd7522eaSPeter Brune .  linesearch - the SNESLineSearch context
1540e7058c64SPeter Brune 
1541e7058c64SPeter Brune    Output Parameter:
1542e7058c64SPeter Brune .  prefix - pointer to the prefix string used
1543e7058c64SPeter Brune 
15448e557f58SPeter Brune    Notes:
15458e557f58SPeter Brune    On the fortran side, the user should pass in a string 'prefix' of
1546e7058c64SPeter Brune    sufficient length to hold the prefix.
1547e7058c64SPeter Brune 
1548e7058c64SPeter Brune    Level: advanced
1549e7058c64SPeter Brune 
1550db781477SPatrick Sanan .seealso: `SNESAppendOptionsPrefix()`
1551e7058c64SPeter Brune @*/
1552f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1553e7058c64SPeter Brune {
1554e7058c64SPeter Brune   PetscFunctionBegin;
1555f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
15569566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix));
1557e7058c64SPeter Brune   PetscFunctionReturn(0);
1558e7058c64SPeter Brune }
1559bf7f4e0aSPeter Brune 
15608d359177SBarry Smith /*@C
1561fa0ddf94SBarry Smith    SNESLineSearchSetWorkVecs - Gets work vectors for the line search.
1562f40b411bSPeter Brune 
1563d8d19677SJose E. Roman    Input Parameters:
1564f1c6b773SPeter Brune +  linesearch - the SNESLineSearch context
1565f40b411bSPeter Brune -  nwork - the number of work vectors
1566f40b411bSPeter Brune 
1567f40b411bSPeter Brune    Level: developer
1568f40b411bSPeter Brune 
1569db781477SPatrick Sanan .seealso: `SNESSetWorkVecs()`
1570f40b411bSPeter Brune @*/
1571fa0ddf94SBarry Smith PetscErrorCode  SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1572bf7f4e0aSPeter Brune {
1573bf7f4e0aSPeter Brune   PetscFunctionBegin;
1574bf7f4e0aSPeter Brune   if (linesearch->vec_sol) {
15759566063dSJacob Faibussowitsch     PetscCall(VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work));
15768d359177SBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1577bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
1578bf7f4e0aSPeter Brune }
1579bf7f4e0aSPeter Brune 
1580f40b411bSPeter Brune /*@
1581422a814eSBarry Smith    SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1582f40b411bSPeter Brune 
1583f40b411bSPeter Brune    Input Parameters:
158478bcb3b5SPeter Brune .  linesearch - linesearch context
1585f40b411bSPeter Brune 
1586f40b411bSPeter Brune    Output Parameters:
1587422a814eSBarry Smith .  result - The success or failure status
1588f40b411bSPeter Brune 
1589cd7522eaSPeter Brune    Notes:
1590c98378a5SBarry Smith    This is typically called after SNESLineSearchApply() in order to determine if the line-search failed
1591cd7522eaSPeter Brune    (and set the SNES convergence accordingly).
1592cd7522eaSPeter Brune 
1593f40b411bSPeter Brune    Level: intermediate
1594f40b411bSPeter Brune 
1595db781477SPatrick Sanan .seealso: `SNESLineSearchSetReason()`, `SNESLineSearchReason`
1596f40b411bSPeter Brune @*/
1597422a814eSBarry Smith PetscErrorCode  SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1598bf7f4e0aSPeter Brune {
1599bf7f4e0aSPeter Brune   PetscFunctionBegin;
1600f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1601422a814eSBarry Smith   PetscValidPointer(result, 2);
1602422a814eSBarry Smith   *result = linesearch->result;
1603bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
1604bf7f4e0aSPeter Brune }
1605bf7f4e0aSPeter Brune 
1606f40b411bSPeter Brune /*@
1607422a814eSBarry Smith    SNESLineSearchSetReason - Sets the success/failure status of the last line search application
1608f40b411bSPeter Brune 
1609f40b411bSPeter Brune    Input Parameters:
161078bcb3b5SPeter Brune +  linesearch - linesearch context
1611422a814eSBarry Smith -  result - The success or failure status
1612f40b411bSPeter Brune 
1613cd7522eaSPeter Brune    Notes:
1614cd7522eaSPeter Brune    This is typically called in a SNESLineSearchApply() or SNESLineSearchShell implementation to set
1615cd7522eaSPeter Brune    the success or failure of the line search method.
1616cd7522eaSPeter Brune 
161778bcb3b5SPeter Brune    Level: developer
1618f40b411bSPeter Brune 
1619db781477SPatrick Sanan .seealso: `SNESLineSearchGetSResult()`
1620f40b411bSPeter Brune @*/
1621422a814eSBarry Smith PetscErrorCode  SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
16226a388c36SPeter Brune {
16236a388c36SPeter Brune   PetscFunctionBegin;
16245fd66863SKarl Rupp   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1625422a814eSBarry Smith   linesearch->result = result;
16266a388c36SPeter Brune   PetscFunctionReturn(0);
16276a388c36SPeter Brune }
16286a388c36SPeter Brune 
16299bd66eb0SPeter Brune /*@C
1630f1c6b773SPeter Brune    SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
16319bd66eb0SPeter Brune 
16329bd66eb0SPeter Brune    Input Parameters:
16339bd66eb0SPeter Brune +  snes - nonlinear context obtained from SNESCreate()
16349bd66eb0SPeter Brune .  projectfunc - function for projecting the function to the bounds
16359bd66eb0SPeter Brune -  normfunc - function for computing the norm of an active set
16369bd66eb0SPeter Brune 
16379bd66eb0SPeter Brune    Logically Collective on SNES
16389bd66eb0SPeter Brune 
16399bd66eb0SPeter Brune    Calling sequence of projectfunc:
16409bd66eb0SPeter Brune .vb
16419bd66eb0SPeter Brune    projectfunc (SNES snes, Vec X)
16429bd66eb0SPeter Brune .ve
16439bd66eb0SPeter Brune 
16449bd66eb0SPeter Brune     Input parameters for projectfunc:
16459bd66eb0SPeter Brune +   snes - nonlinear context
16469bd66eb0SPeter Brune -   X - current solution
16479bd66eb0SPeter Brune 
1648cd7522eaSPeter Brune     Output parameters for projectfunc:
16499bd66eb0SPeter Brune .   X - Projected solution
16509bd66eb0SPeter Brune 
16519bd66eb0SPeter Brune    Calling sequence of normfunc:
16529bd66eb0SPeter Brune .vb
16539bd66eb0SPeter Brune    projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
16549bd66eb0SPeter Brune .ve
16559bd66eb0SPeter Brune 
1656cd7522eaSPeter Brune     Input parameters for normfunc:
16579bd66eb0SPeter Brune +   snes - nonlinear context
16589bd66eb0SPeter Brune .   X - current solution
16599bd66eb0SPeter Brune -   F - current residual
16609bd66eb0SPeter Brune 
1661cd7522eaSPeter Brune     Output parameters for normfunc:
16629bd66eb0SPeter Brune .   fnorm - VI-specific norm of the function
16639bd66eb0SPeter Brune 
1664cd7522eaSPeter Brune     Notes:
1665cd7522eaSPeter Brune     The VI solvers require projection of the solution to the feasible set.  projectfunc should implement this.
1666cd7522eaSPeter Brune 
1667cd7522eaSPeter Brune     The VI solvers require special evaluation of the function norm such that the norm is only calculated
1668cd7522eaSPeter Brune     on the inactive set.  This should be implemented by normfunc.
16699bd66eb0SPeter Brune 
16709bd66eb0SPeter Brune     Level: developer
16719bd66eb0SPeter Brune 
1672db781477SPatrick Sanan .seealso: `SNESLineSearchGetVIFunctions()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchSetPreCheck()`
16739bd66eb0SPeter Brune @*/
167425acbd8eSLisandro Dalcin PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
16759bd66eb0SPeter Brune {
16769bd66eb0SPeter Brune   PetscFunctionBegin;
1677f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
16789bd66eb0SPeter Brune   if (projectfunc) linesearch->ops->viproject = projectfunc;
16799bd66eb0SPeter Brune   if (normfunc) linesearch->ops->vinorm = normfunc;
16809bd66eb0SPeter Brune   PetscFunctionReturn(0);
16819bd66eb0SPeter Brune }
16829bd66eb0SPeter Brune 
16839bd66eb0SPeter Brune /*@C
1684f1c6b773SPeter Brune    SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
16859bd66eb0SPeter Brune 
1686f899ff85SJose E. Roman    Input Parameter:
1687907376e6SBarry Smith .  linesearch - the line search context, obtain with SNESGetLineSearch()
16889bd66eb0SPeter Brune 
16899bd66eb0SPeter Brune    Output Parameters:
16909bd66eb0SPeter Brune +  projectfunc - function for projecting the function to the bounds
16919bd66eb0SPeter Brune -  normfunc - function for computing the norm of an active set
16929bd66eb0SPeter Brune 
16939bd66eb0SPeter Brune    Logically Collective on SNES
16949bd66eb0SPeter Brune 
16959bd66eb0SPeter Brune     Level: developer
16969bd66eb0SPeter Brune 
1697db781477SPatrick Sanan .seealso: `SNESLineSearchSetVIFunctions()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchGetPreCheck()`
16989bd66eb0SPeter Brune @*/
169925acbd8eSLisandro Dalcin PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
17009bd66eb0SPeter Brune {
17019bd66eb0SPeter Brune   PetscFunctionBegin;
17029bd66eb0SPeter Brune   if (projectfunc) *projectfunc = linesearch->ops->viproject;
17039bd66eb0SPeter Brune   if (normfunc) *normfunc = linesearch->ops->vinorm;
17049bd66eb0SPeter Brune   PetscFunctionReturn(0);
17059bd66eb0SPeter Brune }
17069bd66eb0SPeter Brune 
1707bf7f4e0aSPeter Brune /*@C
17081c84c290SBarry Smith   SNESLineSearchRegister - See SNESLineSearchRegister()
1709bf7f4e0aSPeter Brune 
1710bf7f4e0aSPeter Brune   Level: advanced
1711bf7f4e0aSPeter Brune @*/
1712bdf89e91SBarry Smith PetscErrorCode  SNESLineSearchRegister(const char sname[],PetscErrorCode (*function)(SNESLineSearch))
1713bf7f4e0aSPeter Brune {
1714bf7f4e0aSPeter Brune   PetscFunctionBegin;
17159566063dSJacob Faibussowitsch   PetscCall(SNESInitializePackage());
17169566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&SNESLineSearchList,sname,function));
1717bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
1718bf7f4e0aSPeter Brune }
1719