xref: /petsc/src/snes/linesearch/interface/linesearch.c (revision 2fe279fdf3e687a416e4eadb7d3c7a82d60442c6)
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 /*@
10f6dfbefdSBarry Smith    SNESLineSearchMonitorCancel - Clears all the monitor functions for a `SNESLineSearch` object.
11dcf2fd19SBarry Smith 
12c3339decSBarry Smith    Logically Collective
13dcf2fd19SBarry Smith 
14*2fe279fdSBarry Smith    Input Parameter:
15f6dfbefdSBarry 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
19f6dfbefdSBarry Smith     into a code by calls to `SNESLineSearchMonitorSet()`, but does not cancel those
20dcf2fd19SBarry Smith     set via the options database
21dcf2fd19SBarry Smith 
2220f4b53cSBarry Smith    Level: advanced
2320f4b53cSBarry Smith 
24dcf2fd19SBarry Smith    Notes:
25f6dfbefdSBarry Smith    There is no way to clear one specific monitor from a `SNESLineSearch` object.
26dcf2fd19SBarry Smith 
27f6dfbefdSBarry Smith    This does not clear the monitor set with `SNESLineSearchSetDefaultMonitor()` use `SNESLineSearchSetDefaultMonitor`(ls,NULL) to cancel
28dcf2fd19SBarry Smith    that one.
29dcf2fd19SBarry Smith 
30f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchMonitorDefault()`, `SNESLineSearchMonitorSet()`
31dcf2fd19SBarry Smith @*/
32d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchMonitorCancel(SNESLineSearch ls)
33d71ae5a4SJacob Faibussowitsch {
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++) {
3948a46eb9SPierre Jolivet     if (ls->monitordestroy[i]) PetscCall((*ls->monitordestroy[i])(&ls->monitorcontext[i]));
40dcf2fd19SBarry Smith   }
41dcf2fd19SBarry Smith   ls->numbermonitors = 0;
423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
43dcf2fd19SBarry Smith }
44dcf2fd19SBarry Smith 
45dcf2fd19SBarry Smith /*@
46dcf2fd19SBarry Smith    SNESLineSearchMonitor - runs the user provided monitor routines, if they exist
47dcf2fd19SBarry Smith 
48c3339decSBarry Smith    Collective
49dcf2fd19SBarry Smith 
50*2fe279fdSBarry Smith    Input Parameter:
51dcf2fd19SBarry Smith .  ls - the linesearch object
52dcf2fd19SBarry Smith 
53*2fe279fdSBarry Smith    Level: developer
54*2fe279fdSBarry Smith 
55f6dfbefdSBarry Smith    Note:
5620f4b53cSBarry Smith    This routine is called by the `SNES` implementations.
57dcf2fd19SBarry Smith    It does not typically need to be called by the user.
58dcf2fd19SBarry Smith 
59f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchMonitorSet()`
60dcf2fd19SBarry Smith @*/
61d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchMonitor(SNESLineSearch ls)
62d71ae5a4SJacob Faibussowitsch {
63dcf2fd19SBarry Smith   PetscInt i, n = ls->numbermonitors;
64dcf2fd19SBarry Smith 
65dcf2fd19SBarry Smith   PetscFunctionBegin;
6648a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall((*ls->monitorftns[i])(ls, ls->monitorcontext[i]));
673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
68dcf2fd19SBarry Smith }
69dcf2fd19SBarry Smith 
70dcf2fd19SBarry Smith /*@C
71dcf2fd19SBarry Smith    SNESLineSearchMonitorSet - Sets an ADDITIONAL function that is to be used at every
72dcf2fd19SBarry Smith    iteration of the nonlinear solver to display the iteration's
73dcf2fd19SBarry Smith    progress.
74dcf2fd19SBarry Smith 
75c3339decSBarry Smith    Logically Collective
76dcf2fd19SBarry Smith 
77dcf2fd19SBarry Smith    Input Parameters:
78f6dfbefdSBarry Smith +  ls - the `SNESLineSearch` context
79dcf2fd19SBarry Smith .  f - the monitor function
80dcf2fd19SBarry Smith .  mctx - [optional] user-defined context for private data for the
8120f4b53cSBarry Smith           monitor routine (use `NULL` if no context is desired)
82dcf2fd19SBarry Smith -  monitordestroy - [optional] routine that frees monitor context
8320f4b53cSBarry Smith           (may be `NULL`)
8420f4b53cSBarry Smith 
8520f4b53cSBarry Smith    Level: intermediate
86dcf2fd19SBarry Smith 
87f6dfbefdSBarry Smith    Note:
88dcf2fd19SBarry Smith    Several different monitoring routines may be set by calling
89f6dfbefdSBarry Smith    `SNESLineSearchMonitorSet()` multiple times; all will be called in the
90dcf2fd19SBarry Smith    order in which they were set.
91dcf2fd19SBarry Smith 
92f6dfbefdSBarry Smith    Fortran Note:
93f6dfbefdSBarry Smith    Only a single monitor function can be set for each `SNESLineSearch` object
94dcf2fd19SBarry Smith 
95f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchMonitorDefault()`, `SNESLineSearchMonitorCancel()`
96dcf2fd19SBarry Smith @*/
97d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchMonitorSet(SNESLineSearch ls, PetscErrorCode (*f)(SNESLineSearch, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **))
98d71ae5a4SJacob Faibussowitsch {
9978064530SBarry Smith   PetscInt  i;
10078064530SBarry Smith   PetscBool identical;
10178064530SBarry Smith 
102dcf2fd19SBarry Smith   PetscFunctionBegin;
103dcf2fd19SBarry Smith   PetscValidHeaderSpecific(ls, SNESLINESEARCH_CLASSID, 1);
10478064530SBarry Smith   for (i = 0; i < ls->numbermonitors; i++) {
1059566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))ls->monitorftns[i], ls->monitorcontext[i], ls->monitordestroy[i], &identical));
1063ba16761SJacob Faibussowitsch     if (identical) PetscFunctionReturn(PETSC_SUCCESS);
10778064530SBarry Smith   }
1085f80ce2aSJacob Faibussowitsch   PetscCheck(ls->numbermonitors < MAXSNESLSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set");
109dcf2fd19SBarry Smith   ls->monitorftns[ls->numbermonitors]      = f;
110dcf2fd19SBarry Smith   ls->monitordestroy[ls->numbermonitors]   = monitordestroy;
111dcf2fd19SBarry Smith   ls->monitorcontext[ls->numbermonitors++] = (void *)mctx;
1123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
113dcf2fd19SBarry Smith }
114dcf2fd19SBarry Smith 
115dcf2fd19SBarry Smith /*@C
116f6dfbefdSBarry Smith    SNESLineSearchMonitorSolutionUpdate - Monitors each update of the function value the linesearch tries
117dcf2fd19SBarry Smith 
118c3339decSBarry Smith    Collective
119dcf2fd19SBarry Smith 
120dcf2fd19SBarry Smith    Input Parameters:
121f6dfbefdSBarry Smith +  ls - the `SNES` linesearch object
122f6dfbefdSBarry Smith -  vf - the context for the monitor, in this case it is an `PetscViewerAndFormat`
123dcf2fd19SBarry Smith 
124dcf2fd19SBarry Smith    Level: intermediate
125dcf2fd19SBarry Smith 
126f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESMonitorSet()`, `SNESMonitorSolution()`
127dcf2fd19SBarry Smith @*/
128d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchMonitorSolutionUpdate(SNESLineSearch ls, PetscViewerAndFormat *vf)
129d71ae5a4SJacob Faibussowitsch {
130d12e167eSBarry Smith   PetscViewer viewer = vf->viewer;
131dcf2fd19SBarry Smith   Vec         Y, W, G;
132dcf2fd19SBarry Smith 
133dcf2fd19SBarry Smith   PetscFunctionBegin;
1349566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchGetVecs(ls, NULL, NULL, &Y, &W, &G));
1359566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
1369566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "LineSearch attempted update to solution \n"));
1379566063dSJacob Faibussowitsch   PetscCall(VecView(Y, viewer));
1389566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "LineSearch attempted new solution \n"));
1399566063dSJacob Faibussowitsch   PetscCall(VecView(W, viewer));
1409566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "LineSearch attempted updated function value\n"));
1419566063dSJacob Faibussowitsch   PetscCall(VecView(G, viewer));
1429566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
1433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
144dcf2fd19SBarry Smith }
145dcf2fd19SBarry Smith 
146f40b411bSPeter Brune /*@
147cd7522eaSPeter Brune    SNESLineSearchCreate - Creates the line search context.
148f40b411bSPeter Brune 
149f6dfbefdSBarry Smith    Logically Collective
150f40b411bSPeter Brune 
151*2fe279fdSBarry Smith    Input Parameter:
152f6dfbefdSBarry Smith .  comm - MPI communicator for the line search (typically from the associated `SNES` context).
153f40b411bSPeter Brune 
154*2fe279fdSBarry Smith    Output Parameter:
1558e557f58SPeter Brune .  outlinesearch - the new linesearch context
156f40b411bSPeter Brune 
157162e0bf5SPeter Brune    Level: developer
158162e0bf5SPeter Brune 
159f6dfbefdSBarry Smith    Note:
160f6dfbefdSBarry Smith    The preferred calling sequence for users is to use `SNESGetLineSearch()` to acquire the `SNESLineSearch` instance
161f6dfbefdSBarry Smith    already associated with the `SNES`.
162f40b411bSPeter Brune 
163f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `LineSearchDestroy()`, `SNESGetLineSearch()`
164f40b411bSPeter Brune @*/
165d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
166d71ae5a4SJacob Faibussowitsch {
167f1c6b773SPeter Brune   SNESLineSearch linesearch;
168bf388a1fSBarry Smith 
169bf7f4e0aSPeter Brune   PetscFunctionBegin;
170ea5d4fccSPeter Brune   PetscValidPointer(outlinesearch, 2);
1719566063dSJacob Faibussowitsch   PetscCall(SNESInitializePackage());
1720298fd71SBarry Smith   *outlinesearch = NULL;
173f5af7f23SKarl Rupp 
1749566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(linesearch, SNESLINESEARCH_CLASSID, "SNESLineSearch", "Linesearch", "SNESLineSearch", comm, SNESLineSearchDestroy, SNESLineSearchView));
175bf7f4e0aSPeter Brune 
1760298fd71SBarry Smith   linesearch->vec_sol_new  = NULL;
1770298fd71SBarry Smith   linesearch->vec_func_new = NULL;
1780298fd71SBarry Smith   linesearch->vec_sol      = NULL;
1790298fd71SBarry Smith   linesearch->vec_func     = NULL;
1800298fd71SBarry Smith   linesearch->vec_update   = NULL;
1819bd66eb0SPeter Brune 
182bf7f4e0aSPeter Brune   linesearch->lambda       = 1.0;
183bf7f4e0aSPeter Brune   linesearch->fnorm        = 1.0;
184bf7f4e0aSPeter Brune   linesearch->ynorm        = 1.0;
185bf7f4e0aSPeter Brune   linesearch->xnorm        = 1.0;
186422a814eSBarry Smith   linesearch->result       = SNES_LINESEARCH_SUCCEEDED;
187bf7f4e0aSPeter Brune   linesearch->norms        = PETSC_TRUE;
188bf7f4e0aSPeter Brune   linesearch->keeplambda   = PETSC_FALSE;
189bf7f4e0aSPeter Brune   linesearch->damping      = 1.0;
190bf7f4e0aSPeter Brune   linesearch->maxstep      = 1e8;
191bf7f4e0aSPeter Brune   linesearch->steptol      = 1e-12;
192516fe3c3SPeter Brune   linesearch->rtol         = 1e-8;
193516fe3c3SPeter Brune   linesearch->atol         = 1e-15;
194516fe3c3SPeter Brune   linesearch->ltol         = 1e-8;
1950298fd71SBarry Smith   linesearch->precheckctx  = NULL;
1960298fd71SBarry Smith   linesearch->postcheckctx = NULL;
19759405d5eSPeter Brune   linesearch->max_its      = 1;
198bf7f4e0aSPeter Brune   linesearch->setupcalled  = PETSC_FALSE;
1993add74b1SBarry Smith   linesearch->monitor      = NULL;
200bf7f4e0aSPeter Brune   *outlinesearch           = linesearch;
2013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
202bf7f4e0aSPeter Brune }
203bf7f4e0aSPeter Brune 
204f40b411bSPeter Brune /*@
20578bcb3b5SPeter Brune    SNESLineSearchSetUp - Prepares the line search for being applied by allocating
20678bcb3b5SPeter Brune    any required vectors.
207f40b411bSPeter Brune 
208c3339decSBarry Smith    Collective
209f40b411bSPeter Brune 
210*2fe279fdSBarry Smith    Input Parameter:
211f6dfbefdSBarry Smith .  linesearch - The `SNESLineSearch` instance.
212f40b411bSPeter Brune 
21320f4b53cSBarry Smith    Level: advanced
21420f4b53cSBarry Smith 
215f6dfbefdSBarry Smith    Note:
216f6dfbefdSBarry Smith    For most cases, this needn't be called by users or outside of `SNESLineSearchApply()`.
217cd7522eaSPeter Brune    The only current case where this is called outside of this is for the VI
21878bcb3b5SPeter Brune    solvers, which modify the solution and work vectors before the first call
219f6dfbefdSBarry Smith    of `SNESLineSearchApply()`, requiring the `SNESLineSearch` work vectors to be
220cd7522eaSPeter Brune    allocated upfront.
221cd7522eaSPeter Brune 
222f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchReset()`
223f40b411bSPeter Brune @*/
224f40b411bSPeter Brune 
225d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
226d71ae5a4SJacob Faibussowitsch {
227bf7f4e0aSPeter Brune   PetscFunctionBegin;
22848a46eb9SPierre Jolivet   if (!((PetscObject)linesearch)->type_name) PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHBASIC));
229bf7f4e0aSPeter Brune   if (!linesearch->setupcalled) {
23048a46eb9SPierre Jolivet     if (!linesearch->vec_sol_new) PetscCall(VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new));
23148a46eb9SPierre Jolivet     if (!linesearch->vec_func_new) PetscCall(VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new));
232dbbe0bcdSBarry Smith     if (linesearch->ops->setup) PetscUseTypeMethod(linesearch, setup);
2339566063dSJacob Faibussowitsch     if (!linesearch->ops->snesfunc) PetscCall(SNESLineSearchSetFunction(linesearch, SNESComputeFunction));
234bf7f4e0aSPeter Brune     linesearch->lambda      = linesearch->damping;
235bf7f4e0aSPeter Brune     linesearch->setupcalled = PETSC_TRUE;
236bf7f4e0aSPeter Brune   }
2373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
238bf7f4e0aSPeter Brune }
239bf7f4e0aSPeter Brune 
240f40b411bSPeter Brune /*@
241f6dfbefdSBarry Smith    SNESLineSearchReset - Undoes the `SNESLineSearchSetUp()` and deletes any `Vec`s or `Mat`s allocated by the line search.
242f40b411bSPeter Brune 
243c3339decSBarry Smith    Collective
244f40b411bSPeter Brune 
245*2fe279fdSBarry Smith    Input Parameter:
246f6dfbefdSBarry Smith .  linesearch - The `SNESLineSearch` instance.
247f40b411bSPeter Brune 
24820f4b53cSBarry Smith    Level: developer
24920f4b53cSBarry Smith 
250f6dfbefdSBarry Smith    Note:
251f6dfbefdSBarry Smith     Usually only called by `SNESReset()`
252f190f2fcSBarry Smith 
253f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchSetUp()`
254f40b411bSPeter Brune @*/
255f40b411bSPeter Brune 
256d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
257d71ae5a4SJacob Faibussowitsch {
258bf7f4e0aSPeter Brune   PetscFunctionBegin;
259dbbe0bcdSBarry Smith   if (linesearch->ops->reset) PetscUseTypeMethod(linesearch, reset);
260f5af7f23SKarl Rupp 
2619566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&linesearch->vec_sol_new));
2629566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&linesearch->vec_func_new));
263bf7f4e0aSPeter Brune 
2649566063dSJacob Faibussowitsch   PetscCall(VecDestroyVecs(linesearch->nwork, &linesearch->work));
265f5af7f23SKarl Rupp 
266bf7f4e0aSPeter Brune   linesearch->nwork       = 0;
267bf7f4e0aSPeter Brune   linesearch->setupcalled = PETSC_FALSE;
2683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
269bf7f4e0aSPeter Brune }
270bf7f4e0aSPeter Brune 
271ed07d7d7SPeter Brune /*@C
272f6dfbefdSBarry Smith    SNESLineSearchSetFunction - Sets the function evaluation used by the `SNES` line search
273f6dfbefdSBarry Smith `
274ed07d7d7SPeter Brune    Input Parameters:
275f6dfbefdSBarry Smith .  linesearch - the `SNESLineSearch` context
276f6dfbefdSBarry Smith +  func       - function evaluation routine, this is usually the function provided with `SNESSetFunction()`
277ed07d7d7SPeter Brune 
278ed07d7d7SPeter Brune    Level: developer
279ed07d7d7SPeter Brune 
280f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESSetFunction()`
281ed07d7d7SPeter Brune @*/
282d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES, Vec, Vec))
283d71ae5a4SJacob Faibussowitsch {
284ed07d7d7SPeter Brune   PetscFunctionBegin;
285ed07d7d7SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
286ed07d7d7SPeter Brune   linesearch->ops->snesfunc = func;
2873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
288ed07d7d7SPeter Brune }
289ed07d7d7SPeter Brune 
29086d74e61SPeter Brune /*@C
291f190f2fcSBarry Smith    SNESLineSearchSetPreCheck - Sets a user function that is called after the initial search direction has been computed but
292df3898eeSBarry Smith          before the line search routine has been applied. Allows the user to adjust the result of (usually a linear solve) that
293f190f2fcSBarry Smith          determined the search direction.
29486d74e61SPeter Brune 
295c3339decSBarry Smith    Logically Collective
29686d74e61SPeter Brune 
29786d74e61SPeter Brune    Input Parameters:
298f6dfbefdSBarry Smith +  linesearch - the `SNESLineSearch` context
29920f4b53cSBarry Smith .  func - [optional] function evaluation routine,  for the calling sequence see `SNESLineSearchPreCheck()`
30020f4b53cSBarry Smith -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`)
30186d74e61SPeter Brune 
30286d74e61SPeter Brune    Level: intermediate
30386d74e61SPeter Brune 
304f6dfbefdSBarry Smith    Note:
305f0b84518SBarry Smith    Use `SNESLineSearchSetPostCheck()` to change the step after the line search.
306f0b84518SBarry Smith    search is complete.
307f0b84518SBarry Smith 
308f0b84518SBarry Smith    Use `SNESVISetVariableBounds()` and `SNESVISetComputeVariableBounds()` to cause `SNES` to automatically control the ranges of variables allowed.
309f0b84518SBarry Smith 
310f0b84518SBarry Smith .seealso: `SNESGetLineSearch()`, `SNESLineSearchPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchGetPreCheck()`,
311f0b84518SBarry Smith           `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESSetFunctionDomainError()`, `SNESSetJacobianDomainError()
312f0b84518SBarry Smith 
31386d74e61SPeter Brune @*/
314d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch, Vec, Vec, PetscBool *, void *), void *ctx)
315d71ae5a4SJacob Faibussowitsch {
3169bd66eb0SPeter Brune   PetscFunctionBegin;
317f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
318f190f2fcSBarry Smith   if (func) linesearch->ops->precheck = func;
31986d74e61SPeter Brune   if (ctx) linesearch->precheckctx = ctx;
3203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32186d74e61SPeter Brune }
32286d74e61SPeter Brune 
32386d74e61SPeter Brune /*@C
32453deb899SBarry Smith    SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine.
32586d74e61SPeter Brune 
326f899ff85SJose E. Roman    Input Parameter:
327f6dfbefdSBarry Smith .  linesearch - the `SNESLineSearch` context
32886d74e61SPeter Brune 
32986d74e61SPeter Brune    Output Parameters:
33020f4b53cSBarry Smith +  func       - [optional] function evaluation routine,  for calling sequence see `SNESLineSearchPreCheck`
33120f4b53cSBarry Smith -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`)
33286d74e61SPeter Brune 
33386d74e61SPeter Brune    Level: intermediate
33486d74e61SPeter Brune 
335f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESGetLineSearch()`, `SNESLineSearchPreCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`
33686d74e61SPeter Brune @*/
337d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch, Vec, Vec, PetscBool *, void *), void **ctx)
338d71ae5a4SJacob Faibussowitsch {
3399bd66eb0SPeter Brune   PetscFunctionBegin;
340f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
341f190f2fcSBarry Smith   if (func) *func = linesearch->ops->precheck;
34286d74e61SPeter Brune   if (ctx) *ctx = linesearch->precheckctx;
3433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34486d74e61SPeter Brune }
34586d74e61SPeter Brune 
34686d74e61SPeter Brune /*@C
347f190f2fcSBarry Smith    SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step
348f190f2fcSBarry Smith        direction and length. Allows the user a chance to change or override the decision of the line search routine
34986d74e61SPeter Brune 
35020f4b53cSBarry Smith    Logically Collective
35186d74e61SPeter Brune 
35286d74e61SPeter Brune    Input Parameters:
353f6dfbefdSBarry Smith +  linesearch - the `SNESLineSearch` context
35420f4b53cSBarry Smith .  func - [optional] function evaluation routine,   for the calling sequence see `SNESLineSearchPostCheck`
35520f4b53cSBarry Smith -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`)
35686d74e61SPeter Brune 
35786d74e61SPeter Brune    Level: intermediate
35886d74e61SPeter Brune 
359f0b84518SBarry Smith    Notes:
360f0b84518SBarry Smith    Use `SNESLineSearchSetPreCheck()` to change the step before the line search.
361f0b84518SBarry Smith    search is complete.
362f0b84518SBarry Smith 
363f0b84518SBarry Smith    Use `SNESVISetVariableBounds()` and `SNESVISetComputeVariableBounds()` to cause `SNES` to automatically control the ranges of variables allowed.
364f0b84518SBarry Smith 
365f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`, `SNESLineSearchGetPostCheck()`,
366f0b84518SBarry Smith           `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESSetFunctionDomainError()`, `SNESSetJacobianDomainError()
36786d74e61SPeter Brune @*/
368d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch, Vec, Vec, Vec, PetscBool *, PetscBool *, void *), void *ctx)
369d71ae5a4SJacob Faibussowitsch {
37086d74e61SPeter Brune   PetscFunctionBegin;
371f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
372f190f2fcSBarry Smith   if (func) linesearch->ops->postcheck = func;
37386d74e61SPeter Brune   if (ctx) linesearch->postcheckctx = ctx;
3743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
37586d74e61SPeter Brune }
37686d74e61SPeter Brune 
37786d74e61SPeter Brune /*@C
378f1c6b773SPeter Brune    SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.
37986d74e61SPeter Brune 
380f899ff85SJose E. Roman    Input Parameter:
381f6dfbefdSBarry Smith .  linesearch - the `SNESLineSearch` context
38286d74e61SPeter Brune 
38386d74e61SPeter Brune    Output Parameters:
384f6dfbefdSBarry Smith +  func - [optional] function evaluation routine, see for the calling sequence `SNESLineSearchPostCheck`
38520f4b53cSBarry Smith -  ctx        - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`)
38686d74e61SPeter Brune 
38786d74e61SPeter Brune    Level: intermediate
38886d74e61SPeter Brune 
389f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchGetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchPostCheck()`, `SNESLineSearchSetPreCheck()`
39086d74e61SPeter Brune @*/
391d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch, Vec, Vec, Vec, PetscBool *, PetscBool *, void *), void **ctx)
392d71ae5a4SJacob Faibussowitsch {
3939bd66eb0SPeter Brune   PetscFunctionBegin;
394f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
395f190f2fcSBarry Smith   if (func) *func = linesearch->ops->postcheck;
39686d74e61SPeter Brune   if (ctx) *ctx = linesearch->postcheckctx;
3973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39886d74e61SPeter Brune }
39986d74e61SPeter Brune 
400f40b411bSPeter Brune /*@
401f1c6b773SPeter Brune    SNESLineSearchPreCheck - Prepares the line search for being applied.
402f40b411bSPeter Brune 
403c3339decSBarry Smith    Logically Collective
404f40b411bSPeter Brune 
405f40b411bSPeter Brune    Input Parameters:
4067b1df9c1SPeter Brune +  linesearch - The linesearch instance.
4077b1df9c1SPeter Brune .  X - The current solution
4087b1df9c1SPeter Brune -  Y - The step direction
409f40b411bSPeter Brune 
410*2fe279fdSBarry Smith    Output Parameter:
4118e557f58SPeter Brune .  changed - Indicator that the precheck routine has changed anything
412f40b411bSPeter Brune 
413f0b84518SBarry Smith    Level: advanced
414f40b411bSPeter Brune 
415f6dfbefdSBarry Smith    Note:
416f6dfbefdSBarry Smith    This calls any function provided with `SNESLineSearchSetPreCheck()`
417f6dfbefdSBarry Smith 
418f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`, `SNESLineSearchSetPostCheck()`,
419f0b84518SBarry Smith           `SNESLineSearchGetPostCheck()``
420f40b411bSPeter Brune @*/
421d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch, Vec X, Vec Y, PetscBool *changed)
422d71ae5a4SJacob Faibussowitsch {
423bf7f4e0aSPeter Brune   PetscFunctionBegin;
424bf7f4e0aSPeter Brune   *changed = PETSC_FALSE;
4256b2b7091SBarry Smith   if (linesearch->ops->precheck) {
426dbbe0bcdSBarry Smith     PetscUseTypeMethod(linesearch, precheck, X, Y, changed, linesearch->precheckctx);
42738bcdd5aSPeter Brune     PetscValidLogicalCollectiveBool(linesearch, *changed, 4);
428bf7f4e0aSPeter Brune   }
4293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
430bf7f4e0aSPeter Brune }
431bf7f4e0aSPeter Brune 
432f40b411bSPeter Brune /*@
433ef46b1a6SStefano Zampini    SNESLineSearchPostCheck - Hook to modify step direction or updated solution after a successful linesearch
434f40b411bSPeter Brune 
435c3339decSBarry Smith    Logically Collective
436f40b411bSPeter Brune 
437f40b411bSPeter Brune    Input Parameters:
4387b1df9c1SPeter Brune +  linesearch - The linesearch context
4397b1df9c1SPeter Brune .  X - The last solution
4407b1df9c1SPeter Brune .  Y - The step direction
4417b1df9c1SPeter Brune -  W - The updated solution, W = X + lambda*Y for some lambda
442f40b411bSPeter Brune 
443f40b411bSPeter Brune    Output Parameters:
44478bcb3b5SPeter Brune +  changed_Y - Indicator if the direction Y has been changed.
44578bcb3b5SPeter Brune -  changed_W - Indicator if the new candidate solution W has been changed.
446f40b411bSPeter Brune 
44720f4b53cSBarry Smith    Level: developer
44820f4b53cSBarry Smith 
449f6dfbefdSBarry Smith    Note:
450f6dfbefdSBarry Smith    This calls any function provided with `SNESLineSearchSetPreCheck()`
451f6dfbefdSBarry Smith 
452db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`, `SNESLineSearchPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPrecheck()`, `SNESLineSearchGetPrecheck()`
453f40b411bSPeter Brune @*/
454d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch, Vec X, Vec Y, Vec W, PetscBool *changed_Y, PetscBool *changed_W)
455d71ae5a4SJacob Faibussowitsch {
456bf7f4e0aSPeter Brune   PetscFunctionBegin;
457bf7f4e0aSPeter Brune   *changed_Y = PETSC_FALSE;
458bf7f4e0aSPeter Brune   *changed_W = PETSC_FALSE;
4596b2b7091SBarry Smith   if (linesearch->ops->postcheck) {
460dbbe0bcdSBarry Smith     PetscUseTypeMethod(linesearch, postcheck, X, Y, W, changed_Y, changed_W, linesearch->postcheckctx);
46138bcdd5aSPeter Brune     PetscValidLogicalCollectiveBool(linesearch, *changed_Y, 5);
46238bcdd5aSPeter Brune     PetscValidLogicalCollectiveBool(linesearch, *changed_W, 6);
46386d74e61SPeter Brune   }
4643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
46586d74e61SPeter Brune }
46686d74e61SPeter Brune 
46786d74e61SPeter Brune /*@C
46886d74e61SPeter Brune    SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration
46986d74e61SPeter Brune 
470c3339decSBarry Smith    Logically Collective
47186d74e61SPeter Brune 
4724165533cSJose E. Roman    Input Parameters:
47386d74e61SPeter Brune +  linesearch - linesearch context
47486d74e61SPeter Brune .  X - base state for this step
475907376e6SBarry Smith -  ctx - context for this function
47686d74e61SPeter Brune 
47797bb3fdcSJose E. Roman    Input/Output Parameter:
47897bb3fdcSJose E. Roman .  Y - correction, possibly modified
47997bb3fdcSJose E. Roman 
48097bb3fdcSJose E. Roman    Output Parameter:
48197bb3fdcSJose E. Roman .  changed - flag indicating that Y was modified
48286d74e61SPeter Brune 
48386d74e61SPeter Brune    Options Database Key:
484cd7522eaSPeter Brune +  -snes_linesearch_precheck_picard - activate this routine
485cd7522eaSPeter Brune -  -snes_linesearch_precheck_picard_angle - angle
48686d74e61SPeter Brune 
48786d74e61SPeter Brune    Level: advanced
48886d74e61SPeter Brune 
48986d74e61SPeter Brune    Notes:
490f6dfbefdSBarry Smith    This function should be passed to `SNESLineSearchSetPreCheck()`
49186d74e61SPeter Brune 
49286d74e61SPeter Brune    The justification for this method involves the linear convergence of a Picard iteration
49386d74e61SPeter Brune    so the Picard linearization should be provided in place of the "Jacobian". This correction
49486d74e61SPeter Brune    is generally not useful when using a Newton linearization.
49586d74e61SPeter Brune 
49686d74e61SPeter Brune    Reference:
497f6dfbefdSBarry Smith  . - * - Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.
49886d74e61SPeter Brune 
499f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESSetPicard()`, `SNESGetLineSearch()`, `SNESLineSearchSetPreCheck()`
50086d74e61SPeter Brune @*/
501d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch, Vec X, Vec Y, PetscBool *changed, void *ctx)
502d71ae5a4SJacob Faibussowitsch {
50386d74e61SPeter Brune   PetscReal   angle = *(PetscReal *)linesearch->precheckctx;
50486d74e61SPeter Brune   Vec         Ylast;
50586d74e61SPeter Brune   PetscScalar dot;
50686d74e61SPeter Brune   PetscInt    iter;
50786d74e61SPeter Brune   PetscReal   ynorm, ylastnorm, theta, angle_radians;
50886d74e61SPeter Brune   SNES        snes;
50986d74e61SPeter Brune 
51086d74e61SPeter Brune   PetscFunctionBegin;
5119566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchGetSNES(linesearch, &snes));
5129566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)snes, "SNESLineSearchPreCheckPicard_Ylast", (PetscObject *)&Ylast));
51386d74e61SPeter Brune   if (!Ylast) {
5149566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(Y, &Ylast));
5159566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompose((PetscObject)snes, "SNESLineSearchPreCheckPicard_Ylast", (PetscObject)Ylast));
5169566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)Ylast));
51786d74e61SPeter Brune   }
5189566063dSJacob Faibussowitsch   PetscCall(SNESGetIterationNumber(snes, &iter));
51986d74e61SPeter Brune   if (iter < 2) {
5209566063dSJacob Faibussowitsch     PetscCall(VecCopy(Y, Ylast));
52186d74e61SPeter Brune     *changed = PETSC_FALSE;
5223ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
52386d74e61SPeter Brune   }
52486d74e61SPeter Brune 
5259566063dSJacob Faibussowitsch   PetscCall(VecDot(Y, Ylast, &dot));
5269566063dSJacob Faibussowitsch   PetscCall(VecNorm(Y, NORM_2, &ynorm));
5279566063dSJacob Faibussowitsch   PetscCall(VecNorm(Ylast, NORM_2, &ylastnorm));
52886d74e61SPeter Brune   /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
529255453a1SBarry Smith   theta         = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm), -1.0, 1.0));
53086d74e61SPeter Brune   angle_radians = angle * PETSC_PI / 180.;
53186d74e61SPeter Brune   if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
53286d74e61SPeter Brune     /* Modify the step Y */
53386d74e61SPeter Brune     PetscReal alpha, ydiffnorm;
5349566063dSJacob Faibussowitsch     PetscCall(VecAXPY(Ylast, -1.0, Y));
5359566063dSJacob Faibussowitsch     PetscCall(VecNorm(Ylast, NORM_2, &ydiffnorm));
536f85e2ce2SBarry Smith     alpha = (ydiffnorm > .001 * ylastnorm) ? ylastnorm / ydiffnorm : 1000.0;
5379566063dSJacob Faibussowitsch     PetscCall(VecCopy(Y, Ylast));
5389566063dSJacob Faibussowitsch     PetscCall(VecScale(Y, alpha));
5399566063dSJacob 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));
540a47ec85fSBarry Smith     *changed = PETSC_TRUE;
54186d74e61SPeter Brune   } else {
5429566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n", (double)(theta * 180. / PETSC_PI), (double)angle));
5439566063dSJacob Faibussowitsch     PetscCall(VecCopy(Y, Ylast));
54486d74e61SPeter Brune     *changed = PETSC_FALSE;
545bf7f4e0aSPeter Brune   }
5463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
547bf7f4e0aSPeter Brune }
548bf7f4e0aSPeter Brune 
549f40b411bSPeter Brune /*@
550cd7522eaSPeter Brune    SNESLineSearchApply - Computes the line-search update.
551f40b411bSPeter Brune 
552c3339decSBarry Smith    Collective
553f40b411bSPeter Brune 
554f40b411bSPeter Brune    Input Parameters:
5558e557f58SPeter Brune +  linesearch - The linesearch context
5568e557f58SPeter Brune -  Y - The search direction
557f40b411bSPeter Brune 
5586b867d5aSJose E. Roman    Input/Output Parameters:
5596b867d5aSJose E. Roman +  X - The current solution, on output the new solution
5606b867d5aSJose E. Roman .  F - The current function, on output the new function
5616b867d5aSJose E. Roman -  fnorm - The current norm, on output the new function norm
562f40b411bSPeter Brune 
563cd7522eaSPeter Brune    Options Database Keys:
5640b00b554SBarry Smith + -snes_linesearch_type - basic (or equivalently none), bt, l2, cp, nleqerr, shell
565dcf2fd19SBarry Smith . -snes_linesearch_monitor [:filename] - Print progress of line searches
5661fe24845SBarry Smith . -snes_linesearch_damping - The linesearch damping parameter, default is 1.0 (no damping)
5671fe24845SBarry Smith . -snes_linesearch_norms   - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms())
5683c7d6663SPeter Brune . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess
5693c7d6663SPeter Brune - -snes_linesearch_max_it - The number of iterations for iterative line searches
570cd7522eaSPeter Brune 
57120f4b53cSBarry Smith    Level: Intermediate
57220f4b53cSBarry Smith 
573cd7522eaSPeter Brune    Notes:
574f6dfbefdSBarry Smith    This is typically called from within a `SNESSolve()` implementation in order to
575f6dfbefdSBarry Smith    help with convergence of the nonlinear method.  Various `SNES` types use line searches
576cd7522eaSPeter Brune    in different ways, but the overarching theme is that a line search is used to determine
577cd7522eaSPeter Brune    an optimal damping parameter of a step at each iteration of the method.  Each
578f6dfbefdSBarry Smith    application of the line search may invoke `SNESComputeFunction()` several times, and
579cd7522eaSPeter Brune    therefore may be fairly expensive.
580cd7522eaSPeter Brune 
581f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchCreate()`, `SNESLineSearchPreCheck()`, `SNESLineSearchPostCheck()`, `SNESSolve()`, `SNESComputeFunction()`, `SNESLineSearchSetComputeNorms()`,
582db781477SPatrick Sanan           `SNESLineSearchType`, `SNESLineSearchSetType()`
583f40b411bSPeter Brune @*/
584d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal *fnorm, Vec Y)
585d71ae5a4SJacob Faibussowitsch {
586bf388a1fSBarry Smith   PetscFunctionBegin;
587f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
588bf7f4e0aSPeter Brune   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
589bf7f4e0aSPeter Brune   PetscValidHeaderSpecific(F, VEC_CLASSID, 3);
590064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(Y, VEC_CLASSID, 5);
591bf7f4e0aSPeter Brune 
592422a814eSBarry Smith   linesearch->result = SNES_LINESEARCH_SUCCEEDED;
593bf7f4e0aSPeter Brune 
594bf7f4e0aSPeter Brune   linesearch->vec_sol    = X;
595bf7f4e0aSPeter Brune   linesearch->vec_update = Y;
596bf7f4e0aSPeter Brune   linesearch->vec_func   = F;
597bf7f4e0aSPeter Brune 
5989566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchSetUp(linesearch));
599bf7f4e0aSPeter Brune 
600f5af7f23SKarl Rupp   if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
601bf7f4e0aSPeter Brune 
602f5af7f23SKarl Rupp   if (fnorm) linesearch->fnorm = *fnorm;
60348a46eb9SPierre Jolivet   else PetscCall(VecNorm(F, NORM_2, &linesearch->fnorm));
604bf7f4e0aSPeter Brune 
6059566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(SNESLINESEARCH_Apply, linesearch, X, F, Y));
606bf7f4e0aSPeter Brune 
607dbbe0bcdSBarry Smith   PetscUseTypeMethod(linesearch, apply);
608bf7f4e0aSPeter Brune 
6099566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(SNESLINESEARCH_Apply, linesearch, X, F, Y));
610bf7f4e0aSPeter Brune 
611f5af7f23SKarl Rupp   if (fnorm) *fnorm = linesearch->fnorm;
6123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
613bf7f4e0aSPeter Brune }
614bf7f4e0aSPeter Brune 
615f40b411bSPeter Brune /*@
616f1c6b773SPeter Brune    SNESLineSearchDestroy - Destroys the line search instance.
617f40b411bSPeter Brune 
618c3339decSBarry Smith    Collective
619f40b411bSPeter Brune 
620*2fe279fdSBarry Smith    Input Parameter:
6218e557f58SPeter Brune .  linesearch - The linesearch context
622f40b411bSPeter Brune 
62384238204SBarry Smith    Level: developer
624f40b411bSPeter Brune 
625f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchCreate()`, `SNESLineSearchReset()`, `SNESDestroy()`
626f40b411bSPeter Brune @*/
627d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchDestroy(SNESLineSearch *linesearch)
628d71ae5a4SJacob Faibussowitsch {
629bf7f4e0aSPeter Brune   PetscFunctionBegin;
6303ba16761SJacob Faibussowitsch   if (!*linesearch) PetscFunctionReturn(PETSC_SUCCESS);
631f1c6b773SPeter Brune   PetscValidHeaderSpecific((*linesearch), SNESLINESEARCH_CLASSID, 1);
6329371c9d4SSatish Balay   if (--((PetscObject)(*linesearch))->refct > 0) {
6339371c9d4SSatish Balay     *linesearch = NULL;
6343ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6359371c9d4SSatish Balay   }
6369566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsViewOff((PetscObject)*linesearch));
6379566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchReset(*linesearch));
6383ba16761SJacob Faibussowitsch   PetscTryTypeMethod(*linesearch, destroy);
6399566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*linesearch)->monitor));
6409566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchMonitorCancel((*linesearch)));
6419566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(linesearch));
6423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
643bf7f4e0aSPeter Brune }
644bf7f4e0aSPeter Brune 
645f40b411bSPeter Brune /*@
646dcf2fd19SBarry Smith    SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.
647bf7f4e0aSPeter Brune 
648c3339decSBarry Smith    Logically Collective
649f6dfbefdSBarry Smith 
650bf7f4e0aSPeter Brune    Input Parameters:
651dcf2fd19SBarry Smith +  linesearch - the linesearch object
65220f4b53cSBarry Smith -  viewer - an `PETSCVIEWERASCII` `PetscViewer` or `NULL` to turn off monitor
653bf7f4e0aSPeter Brune 
654f6dfbefdSBarry Smith    Options Database Key:
655dcf2fd19SBarry Smith .   -snes_linesearch_monitor [:filename] - enables the monitor
656bf7f4e0aSPeter Brune 
657bf7f4e0aSPeter Brune    Level: intermediate
658bf7f4e0aSPeter Brune 
659f6dfbefdSBarry Smith    Developer Note:
660f6dfbefdSBarry Smith    This monitor is implemented differently than the other line search monitors that are set with
661f6dfbefdSBarry Smith    `SNESLineSearchMonitorSet()` since it is called in many locations of the line search routines to display aspects of the
662d12e167eSBarry Smith    line search that are not visible to the other monitors.
663dcf2fd19SBarry Smith 
664f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `PETSCVIEWERASCII`, `SNESGetLineSearch()`, `SNESLineSearchGetDefaultMonitor()`, `PetscViewer`, `SNESLineSearchSetMonitor()`,
665f6dfbefdSBarry Smith           `SNESLineSearchMonitorSetFromOptions()`
666bf7f4e0aSPeter Brune @*/
667d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
668d71ae5a4SJacob Faibussowitsch {
669bf7f4e0aSPeter Brune   PetscFunctionBegin;
6709566063dSJacob Faibussowitsch   if (viewer) PetscCall(PetscObjectReference((PetscObject)viewer));
6719566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&linesearch->monitor));
672dcf2fd19SBarry Smith   linesearch->monitor = viewer;
6733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
674bf7f4e0aSPeter Brune }
675bf7f4e0aSPeter Brune 
676f40b411bSPeter Brune /*@
677f6dfbefdSBarry Smith    SNESLineSearchGetDefaultMonitor - Gets the `PetscViewer` instance for the line search monitor.
678f6dfbefdSBarry Smith 
679c3339decSBarry Smith    Logically Collective
6806a388c36SPeter Brune 
681f190f2fcSBarry Smith    Input Parameter:
6828e557f58SPeter Brune .  linesearch - linesearch context
683f40b411bSPeter Brune 
684f190f2fcSBarry Smith    Output Parameter:
6858e557f58SPeter Brune .  monitor - monitor context
686f40b411bSPeter Brune 
687f40b411bSPeter Brune    Level: intermediate
688f40b411bSPeter Brune 
689f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchSetDefaultMonitor()`, `PetscViewer`
690f40b411bSPeter Brune @*/
691d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
692d71ae5a4SJacob Faibussowitsch {
6936a388c36SPeter Brune   PetscFunctionBegin;
694f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
6956a388c36SPeter Brune   *monitor = linesearch->monitor;
6963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6976a388c36SPeter Brune }
6986a388c36SPeter Brune 
699dcf2fd19SBarry Smith /*@C
700dcf2fd19SBarry Smith    SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
701dcf2fd19SBarry Smith 
702c3339decSBarry Smith    Collective
703dcf2fd19SBarry Smith 
704dcf2fd19SBarry Smith    Input Parameters:
705f6dfbefdSBarry Smith +  ls - `SNESLineSearch` object you wish to monitor
706dcf2fd19SBarry Smith .  name - the monitor type one is seeking
707dcf2fd19SBarry Smith .  help - message indicating what monitoring is done
708dcf2fd19SBarry Smith .  manual - manual page for the monitor
709dcf2fd19SBarry Smith .  monitor - the monitor function
710f6dfbefdSBarry 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`
711dcf2fd19SBarry Smith 
712dcf2fd19SBarry Smith    Level: developer
713dcf2fd19SBarry Smith 
714f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchSetMonitor()`, `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
715db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
716db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
717db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
718c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
719db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
720db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
721dcf2fd19SBarry Smith @*/
722d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(SNESLineSearch, PetscViewerAndFormat *), PetscErrorCode (*monitorsetup)(SNESLineSearch, PetscViewerAndFormat *))
723d71ae5a4SJacob Faibussowitsch {
724dcf2fd19SBarry Smith   PetscViewer       viewer;
725dcf2fd19SBarry Smith   PetscViewerFormat format;
726dcf2fd19SBarry Smith   PetscBool         flg;
727dcf2fd19SBarry Smith 
728dcf2fd19SBarry Smith   PetscFunctionBegin;
7299566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls), ((PetscObject)ls)->options, ((PetscObject)ls)->prefix, name, &viewer, &format, &flg));
730dcf2fd19SBarry Smith   if (flg) {
731d12e167eSBarry Smith     PetscViewerAndFormat *vf;
7329566063dSJacob Faibussowitsch     PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf));
7339566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)viewer));
7341baa6e33SBarry Smith     if (monitorsetup) PetscCall((*monitorsetup)(ls, vf));
7359566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchMonitorSet(ls, (PetscErrorCode(*)(SNESLineSearch, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy));
736dcf2fd19SBarry Smith   }
7373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
738dcf2fd19SBarry Smith }
739dcf2fd19SBarry Smith 
740f40b411bSPeter Brune /*@
741f1c6b773SPeter Brune    SNESLineSearchSetFromOptions - Sets options for the line search
742f40b411bSPeter Brune 
743c3339decSBarry Smith    Logically Collective
744f6dfbefdSBarry Smith 
745f899ff85SJose E. Roman    Input Parameter:
7468e557f58SPeter Brune .  linesearch - linesearch context
747f40b411bSPeter Brune 
748f40b411bSPeter Brune    Options Database Keys:
7490b00b554SBarry Smith + -snes_linesearch_type <type> - basic (or equivalently none), bt, l2, cp, nleqerr, shell
7503c7d6663SPeter Brune . -snes_linesearch_order <order> - 1, 2, 3.  Most types only support certain orders (bt supports 2 or 3)
751f6dfbefdSBarry Smith . -snes_linesearch_norms   - Turn on/off the linesearch norms for the basic linesearch typem (`SNESLineSearchSetComputeNorms()`)
75271eef1aeSPeter Brune . -snes_linesearch_minlambda - The minimum step length
7531a9b3a06SPeter Brune . -snes_linesearch_maxstep - The maximum step size
7541a9b3a06SPeter Brune . -snes_linesearch_rtol - Relative tolerance for iterative line searches
7551a9b3a06SPeter Brune . -snes_linesearch_atol - Absolute tolerance for iterative line searches
7561a9b3a06SPeter Brune . -snes_linesearch_ltol - Change in lambda tolerance for iterative line searches
7571a9b3a06SPeter Brune . -snes_linesearch_max_it - The number of iterations for iterative line searches
758dcf2fd19SBarry Smith . -snes_linesearch_monitor [:filename] - Print progress of line searches
759dcf2fd19SBarry Smith . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
7608e557f58SPeter Brune . -snes_linesearch_damping - The linesearch damping parameter
761cd7522eaSPeter Brune . -snes_linesearch_keeplambda - Keep the previous search length as the initial guess.
7621a9b3a06SPeter Brune . -snes_linesearch_precheck_picard - Use precheck that speeds up convergence of picard method
763d8d34be6SBarry Smith - -snes_linesearch_precheck_picard_angle - Angle used in Picard precheck method
764f40b411bSPeter Brune 
765f40b411bSPeter Brune    Level: intermediate
766f40b411bSPeter Brune 
767f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchCreate()`, `SNESLineSearchSetOrder()`, `SNESLineSearchSetType()`, `SNESLineSearchSetTolerances()`, `SNESLineSearchSetDamping()`, `SNESLineSearchPreCheckPicard()`,
768db781477SPatrick Sanan           `SNESLineSearchType`, `SNESLineSearchSetComputeNorms()`
769f40b411bSPeter Brune @*/
770d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
771d71ae5a4SJacob Faibussowitsch {
7721a4f838cSPeter Brune   const char *deft = SNESLINESEARCHBASIC;
773bf7f4e0aSPeter Brune   char        type[256];
774bf7f4e0aSPeter Brune   PetscBool   flg, set;
775dcf2fd19SBarry Smith   PetscViewer viewer;
776bf388a1fSBarry Smith 
777bf7f4e0aSPeter Brune   PetscFunctionBegin;
7789566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchRegisterAll());
779bf7f4e0aSPeter Brune 
780d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)linesearch);
781f5af7f23SKarl Rupp   if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
7829566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-snes_linesearch_type", "Linesearch type", "SNESLineSearchSetType", SNESLineSearchList, deft, type, 256, &flg));
783bf7f4e0aSPeter Brune   if (flg) {
7849566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetType(linesearch, type));
785bf7f4e0aSPeter Brune   } else if (!((PetscObject)linesearch)->type_name) {
7869566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetType(linesearch, deft));
787bf7f4e0aSPeter Brune   }
788bf7f4e0aSPeter Brune 
7899566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch), ((PetscObject)linesearch)->options, ((PetscObject)linesearch)->prefix, "-snes_linesearch_monitor", &viewer, NULL, &set));
790dcf2fd19SBarry Smith   if (set) {
7919566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetDefaultMonitor(linesearch, viewer));
7929566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
793dcf2fd19SBarry Smith   }
7949566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchMonitorSetFromOptions(linesearch, "-snes_linesearch_monitor_solution_update", "View correction at each iteration", "SNESLineSearchMonitorSolutionUpdate", SNESLineSearchMonitorSolutionUpdate, NULL));
795bf7f4e0aSPeter Brune 
7961a9b3a06SPeter Brune   /* tolerances */
7979566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_minlambda", "Minimum step length", "SNESLineSearchSetTolerances", linesearch->steptol, &linesearch->steptol, NULL));
7989566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_maxstep", "Maximum step size", "SNESLineSearchSetTolerances", linesearch->maxstep, &linesearch->maxstep, NULL));
7999566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_rtol", "Relative tolerance for iterative line search", "SNESLineSearchSetTolerances", linesearch->rtol, &linesearch->rtol, NULL));
8009566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_atol", "Absolute tolerance for iterative line search", "SNESLineSearchSetTolerances", linesearch->atol, &linesearch->atol, NULL));
8019566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_ltol", "Change in lambda tolerance for iterative line search", "SNESLineSearchSetTolerances", linesearch->ltol, &linesearch->ltol, NULL));
8029566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_linesearch_max_it", "Maximum iterations for iterative line searches", "SNESLineSearchSetTolerances", linesearch->max_its, &linesearch->max_its, NULL));
8037a35526eSPeter Brune 
8041a9b3a06SPeter Brune   /* damping parameters */
8059566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_damping", "Line search damping and initial step guess", "SNESLineSearchSetDamping", linesearch->damping, &linesearch->damping, NULL));
8061a9b3a06SPeter Brune 
8079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_linesearch_keeplambda", "Use previous lambda as damping", "SNESLineSearchSetKeepLambda", linesearch->keeplambda, &linesearch->keeplambda, NULL));
8081a9b3a06SPeter Brune 
8091a9b3a06SPeter Brune   /* precheck */
8109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_linesearch_precheck_picard", "Use a correction that sometimes improves convergence of Picard iteration", "SNESLineSearchPreCheckPicard", flg, &flg, &set));
8117a35526eSPeter Brune   if (set) {
8127a35526eSPeter Brune     if (flg) {
8137a35526eSPeter Brune       linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
814f5af7f23SKarl Rupp 
815d0609cedSBarry 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));
8169566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchSetPreCheck(linesearch, SNESLineSearchPreCheckPicard, &linesearch->precheck_picard_angle));
8177a35526eSPeter Brune     } else {
8189566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchSetPreCheck(linesearch, NULL, NULL));
8197a35526eSPeter Brune     }
8207a35526eSPeter Brune   }
8219566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_linesearch_order", "Order of approximation used in the line search", "SNESLineSearchSetOrder", linesearch->order, &linesearch->order, NULL));
8229566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_linesearch_norms", "Compute final norms in line search", "SNESLineSearchSetComputeNorms", linesearch->norms, &linesearch->norms, NULL));
8237a35526eSPeter Brune 
824dbbe0bcdSBarry Smith   PetscTryTypeMethod(linesearch, setfromoptions, PetscOptionsObject);
8255a9b6599SPeter Brune 
826dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)linesearch, PetscOptionsObject));
827d0609cedSBarry Smith   PetscOptionsEnd();
8283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
829bf7f4e0aSPeter Brune }
830bf7f4e0aSPeter Brune 
831f40b411bSPeter Brune /*@
832f190f2fcSBarry Smith    SNESLineSearchView - Prints useful information about the line search
833f40b411bSPeter Brune 
83420f4b53cSBarry Smith    Logically Collective
83520f4b53cSBarry Smith 
836f40b411bSPeter Brune    Input Parameters:
837*2fe279fdSBarry Smith +  linesearch - linesearch context
838*2fe279fdSBarry Smith -  viewer - the viewer to display the line search information
839f40b411bSPeter Brune 
840f40b411bSPeter Brune    Level: intermediate
841f40b411bSPeter Brune 
842f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `PetscViewer`, `SNESLineSearchCreate()`
843f40b411bSPeter Brune @*/
844d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
845d71ae5a4SJacob Faibussowitsch {
8467f1410a3SPeter Brune   PetscBool iascii;
847bf388a1fSBarry Smith 
848bf7f4e0aSPeter Brune   PetscFunctionBegin;
8497f1410a3SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
85048a46eb9SPierre Jolivet   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch), &viewer));
8517f1410a3SPeter Brune   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
8527f1410a3SPeter Brune   PetscCheckSameComm(linesearch, 1, viewer, 2);
853f40b411bSPeter Brune 
8549566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
8557f1410a3SPeter Brune   if (iascii) {
8569566063dSJacob Faibussowitsch     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)linesearch, viewer));
8579566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
858dbbe0bcdSBarry Smith     PetscTryTypeMethod(linesearch, view, viewer);
8599566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
8609566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep, (double)linesearch->steptol));
8619566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol, (double)linesearch->atol, (double)linesearch->ltol));
86263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum iterations=%" PetscInt_FMT "\n", linesearch->max_its));
8636b2b7091SBarry Smith     if (linesearch->ops->precheck) {
8646b2b7091SBarry Smith       if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
86563a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  using precheck step to speed up Picard convergence\n"));
8667f1410a3SPeter Brune       } else {
86763a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  using user-defined precheck step\n"));
8687f1410a3SPeter Brune       }
8697f1410a3SPeter Brune     }
87048a46eb9SPierre Jolivet     if (linesearch->ops->postcheck) PetscCall(PetscViewerASCIIPrintf(viewer, "  using user-defined postcheck step\n"));
8717f1410a3SPeter Brune   }
8723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
873bf7f4e0aSPeter Brune }
874bf7f4e0aSPeter Brune 
875ea5d4fccSPeter Brune /*@C
876a80ff896SJed Brown    SNESLineSearchGetType - Gets the linesearch type
877a80ff896SJed Brown 
878c3339decSBarry Smith    Logically Collective
879a80ff896SJed Brown 
880*2fe279fdSBarry Smith    Input Parameter:
881a80ff896SJed Brown .  linesearch - linesearch context
882a80ff896SJed Brown 
883*2fe279fdSBarry Smith    Output Parameter:
884*2fe279fdSBarry Smith .  type - The type of line search, or `NULL` if not set
885a80ff896SJed Brown 
886a80ff896SJed Brown    Level: intermediate
887a80ff896SJed Brown 
888f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchType`, `SNESLineSearchCreate()`, `SNESLineSearchType`, `SNESLineSearchSetFromOptions()`, `SNESLineSearchSetType()`
889a80ff896SJed Brown @*/
890d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetType(SNESLineSearch linesearch, SNESLineSearchType *type)
891d71ae5a4SJacob Faibussowitsch {
892a80ff896SJed Brown   PetscFunctionBegin;
893a80ff896SJed Brown   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
894dadcf809SJacob Faibussowitsch   PetscValidPointer(type, 2);
895a80ff896SJed Brown   *type = ((PetscObject)linesearch)->type_name;
8963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
897a80ff896SJed Brown }
898a80ff896SJed Brown 
899a80ff896SJed Brown /*@C
900f1c6b773SPeter Brune    SNESLineSearchSetType - Sets the linesearch type
901f40b411bSPeter Brune 
902c3339decSBarry Smith    Logically Collective
903f190f2fcSBarry Smith 
904f40b411bSPeter Brune    Input Parameters:
9058e557f58SPeter Brune +  linesearch - linesearch context
906f40b411bSPeter Brune -  type - The type of line search to be used
907f40b411bSPeter Brune 
908cd7522eaSPeter Brune    Available Types:
909f6dfbefdSBarry Smith +  `SNESLINESEARCHBASIC` - (or equivalently `SNESLINESEARCHNONE`) Simple damping line search, defaults to using the full Newton step
910f6dfbefdSBarry Smith .  `SNESLINESEARCHBT` - Backtracking line search over the L2 norm of the function
911f6dfbefdSBarry Smith .  `SNESLINESEARCHL2` - Secant line search over the L2 norm of the function
912f6dfbefdSBarry Smith .  `SNESLINESEARCHCP` - Critical point secant line search assuming F(x) = grad G(x) for some unknown G(x)
913f6dfbefdSBarry Smith .  `SNESLINESEARCHNLEQERR` - Affine-covariant error-oriented linesearch
914f6dfbefdSBarry Smith -  `SNESLINESEARCHSHELL` - User provided `SNESLineSearch` implementation
9151fe24845SBarry Smith 
9163c7db156SBarry Smith    Options Database Key:
9170b00b554SBarry Smith .  -snes_linesearch_type <type> - basic (or equivalently none), bt, l2, cp, nleqerr, shell
918cd7522eaSPeter Brune 
919f40b411bSPeter Brune    Level: intermediate
920f40b411bSPeter Brune 
921f6dfbefdSBarry Smith .seealso:  `SNESLineSearch`, `SNESLineSearchType`, `SNESLineSearchCreate()`, `SNESLineSearchType`, `SNESLineSearchSetFromOptions()`, `SNESLineSearchGetType()`
922f40b411bSPeter Brune @*/
923d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
924d71ae5a4SJacob Faibussowitsch {
925bf7f4e0aSPeter Brune   PetscBool match;
9265f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(SNESLineSearch);
927bf7f4e0aSPeter Brune 
928bf7f4e0aSPeter Brune   PetscFunctionBegin;
929f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
930bf7f4e0aSPeter Brune   PetscValidCharPointer(type, 2);
931bf7f4e0aSPeter Brune 
9329566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, type, &match));
9333ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
934bf7f4e0aSPeter Brune 
9359566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(SNESLineSearchList, type, &r));
9365f80ce2aSJacob Faibussowitsch   PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested Line Search type %s", type);
937bf7f4e0aSPeter Brune   /* Destroy the previous private linesearch context */
938bf7f4e0aSPeter Brune   if (linesearch->ops->destroy) {
9399566063dSJacob Faibussowitsch     PetscCall((*(linesearch)->ops->destroy)(linesearch));
9400298fd71SBarry Smith     linesearch->ops->destroy = NULL;
941bf7f4e0aSPeter Brune   }
942f1c6b773SPeter Brune   /* Reinitialize function pointers in SNESLineSearchOps structure */
9439e5d0892SLisandro Dalcin   linesearch->ops->apply          = NULL;
9449e5d0892SLisandro Dalcin   linesearch->ops->view           = NULL;
9459e5d0892SLisandro Dalcin   linesearch->ops->setfromoptions = NULL;
9469e5d0892SLisandro Dalcin   linesearch->ops->destroy        = NULL;
947bf7f4e0aSPeter Brune 
9489566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)linesearch, type));
9499566063dSJacob Faibussowitsch   PetscCall((*r)(linesearch));
9503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
951bf7f4e0aSPeter Brune }
952bf7f4e0aSPeter Brune 
953f40b411bSPeter Brune /*@
954f6dfbefdSBarry Smith    SNESLineSearchSetSNES - Sets the `SNES` for the linesearch for function evaluation.
955f40b411bSPeter Brune 
956f40b411bSPeter Brune    Input Parameters:
9578e557f58SPeter Brune +  linesearch - linesearch context
958f40b411bSPeter Brune -  snes - The snes instance
959f40b411bSPeter Brune 
96078bcb3b5SPeter Brune    Level: developer
96178bcb3b5SPeter Brune 
962f6dfbefdSBarry Smith    Note:
963f190f2fcSBarry Smith    This happens automatically when the line search is obtained/created with
964f6dfbefdSBarry Smith    `SNESGetLineSearch()`.  This routine is therefore mainly called within `SNES`
96578bcb3b5SPeter Brune    implementations.
966f40b411bSPeter Brune 
967f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchGetSNES()`, `SNESLineSearchSetVecs()`, `SNES`
968f40b411bSPeter Brune @*/
969d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
970d71ae5a4SJacob Faibussowitsch {
971bf7f4e0aSPeter Brune   PetscFunctionBegin;
972f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
973bf7f4e0aSPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 2);
974bf7f4e0aSPeter Brune   linesearch->snes = snes;
9753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
976bf7f4e0aSPeter Brune }
977bf7f4e0aSPeter Brune 
978f40b411bSPeter Brune /*@
979f6dfbefdSBarry Smith    SNESLineSearchGetSNES - Gets the `SNES` instance associated with the line search.
980f6dfbefdSBarry Smith    Having an associated `SNES` is necessary because most line search implementations must be able to
981f6dfbefdSBarry Smith    evaluate the function using `SNESComputeFunction()` for the associated `SNES`.  This routine
982f6dfbefdSBarry Smith    is used in the line search implementations when one must get this associated `SNES` instance.
983f6dfbefdSBarry Smith 
984f6dfbefdSBarry Smith    Not Collective
985f40b411bSPeter Brune 
986*2fe279fdSBarry Smith    Input Parameter:
9878e557f58SPeter Brune .  linesearch - linesearch context
988f40b411bSPeter Brune 
989*2fe279fdSBarry Smith    Output Parameter:
990*2fe279fdSBarry Smith .  snes - The `SNES` instance
991f40b411bSPeter Brune 
9928141a3b9SPeter Brune    Level: developer
993f40b411bSPeter Brune 
994f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESType`, `SNESLineSearchGetSNES()`, `SNESLineSearchSetVecs()`, `SNES`
995f40b411bSPeter Brune @*/
996d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
997d71ae5a4SJacob Faibussowitsch {
998bf7f4e0aSPeter Brune   PetscFunctionBegin;
999f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
10006a388c36SPeter Brune   PetscValidPointer(snes, 2);
1001bf7f4e0aSPeter Brune   *snes = linesearch->snes;
10023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1003bf7f4e0aSPeter Brune }
1004bf7f4e0aSPeter Brune 
1005f40b411bSPeter Brune /*@
1006f1c6b773SPeter Brune    SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
1007f40b411bSPeter Brune 
1008f6dfbefdSBarry Smith    Not Collective
1009f6dfbefdSBarry Smith 
1010*2fe279fdSBarry Smith    Input Parameter:
10118e557f58SPeter Brune .  linesearch - linesearch context
1012f40b411bSPeter Brune 
1013*2fe279fdSBarry Smith    Output Parameter:
1014f6dfbefdSBarry Smith .  lambda - The last steplength computed during `SNESLineSearchApply()`
1015f40b411bSPeter Brune 
101678bcb3b5SPeter Brune    Level: advanced
101778bcb3b5SPeter Brune 
1018f6dfbefdSBarry Smith    Note:
10198e557f58SPeter Brune    This is useful in methods where the solver is ill-scaled and
102078bcb3b5SPeter Brune    requires some adaptive notion of the difference in scale between the
1021f6dfbefdSBarry Smith    solution and the function.  For instance, `SNESQN` may be scaled by the
102278bcb3b5SPeter Brune    line search lambda using the argument -snes_qn_scaling ls.
102378bcb3b5SPeter Brune 
1024f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchSetLambda()`, `SNESLineSearchGetDamping()`, `SNESLineSearchApply()`
1025f40b411bSPeter Brune @*/
1026d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch, PetscReal *lambda)
1027d71ae5a4SJacob Faibussowitsch {
10286a388c36SPeter Brune   PetscFunctionBegin;
1029f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1030534a8f05SLisandro Dalcin   PetscValidRealPointer(lambda, 2);
10316a388c36SPeter Brune   *lambda = linesearch->lambda;
10323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10336a388c36SPeter Brune }
10346a388c36SPeter Brune 
1035f40b411bSPeter Brune /*@
1036f6dfbefdSBarry Smith    SNESLineSearchSetLambda - Sets the linesearch steplength
1037f40b411bSPeter Brune 
1038f40b411bSPeter Brune    Input Parameters:
10398e557f58SPeter Brune +  linesearch - linesearch context
1040f40b411bSPeter Brune -  lambda - The last steplength.
1041f40b411bSPeter Brune 
104220f4b53cSBarry Smith    Level: advanced
104320f4b53cSBarry Smith 
1044f6dfbefdSBarry Smith    Note:
1045f6dfbefdSBarry Smith    This routine is typically used within implementations of `SNESLineSearchApply()`
1046f6dfbefdSBarry Smith    to set the final steplength.  This routine (and `SNESLineSearchGetLambda()`) were
1047cd7522eaSPeter Brune    added in order to facilitate Quasi-Newton methods that use the previous steplength
1048cd7522eaSPeter Brune    as an inner scaling parameter.
1049cd7522eaSPeter Brune 
1050f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchGetLambda()`
1051f40b411bSPeter Brune @*/
1052d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1053d71ae5a4SJacob Faibussowitsch {
10546a388c36SPeter Brune   PetscFunctionBegin;
1055f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
10566a388c36SPeter Brune   linesearch->lambda = lambda;
10573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10586a388c36SPeter Brune }
10596a388c36SPeter Brune 
1060f40b411bSPeter Brune /*@
10613c7d6663SPeter Brune    SNESLineSearchGetTolerances - Gets the tolerances for the linesearch.  These include
106278bcb3b5SPeter Brune    tolerances for the relative and absolute change in the function norm, the change
106378bcb3b5SPeter Brune    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
106478bcb3b5SPeter Brune    and the maximum number of iterations the line search procedure may take.
1065f40b411bSPeter Brune 
1066f6dfbefdSBarry Smith    Not Collective
1067f6dfbefdSBarry Smith 
1068f899ff85SJose E. Roman    Input Parameter:
10698e557f58SPeter Brune .  linesearch - linesearch context
1070f40b411bSPeter Brune 
1071f40b411bSPeter Brune    Output Parameters:
1072516fe3c3SPeter Brune +  steptol - The minimum steplength
10736cc8e53bSPeter Brune .  maxstep - The maximum steplength
1074516fe3c3SPeter Brune .  rtol    - The relative tolerance for iterative line searches
1075516fe3c3SPeter Brune .  atol    - The absolute tolerance for iterative line searches
1076516fe3c3SPeter Brune .  ltol    - The change in lambda tolerance for iterative line searches
1077516fe3c3SPeter Brune -  max_it  - The maximum number of iterations of the line search
1078f40b411bSPeter Brune 
107978bcb3b5SPeter Brune    Level: intermediate
108078bcb3b5SPeter Brune 
1081f6dfbefdSBarry Smith    Note:
108278bcb3b5SPeter Brune    Different line searches may implement these parameters slightly differently as
10833c7d6663SPeter Brune    the type requires.
1084516fe3c3SPeter Brune 
1085f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchSetTolerances()`
1086f40b411bSPeter Brune @*/
1087d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch, PetscReal *steptol, PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1088d71ae5a4SJacob Faibussowitsch {
10896a388c36SPeter Brune   PetscFunctionBegin;
1090f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1091516fe3c3SPeter Brune   if (steptol) {
1092534a8f05SLisandro Dalcin     PetscValidRealPointer(steptol, 2);
10936a388c36SPeter Brune     *steptol = linesearch->steptol;
1094516fe3c3SPeter Brune   }
1095516fe3c3SPeter Brune   if (maxstep) {
1096534a8f05SLisandro Dalcin     PetscValidRealPointer(maxstep, 3);
1097516fe3c3SPeter Brune     *maxstep = linesearch->maxstep;
1098516fe3c3SPeter Brune   }
1099516fe3c3SPeter Brune   if (rtol) {
1100534a8f05SLisandro Dalcin     PetscValidRealPointer(rtol, 4);
1101516fe3c3SPeter Brune     *rtol = linesearch->rtol;
1102516fe3c3SPeter Brune   }
1103516fe3c3SPeter Brune   if (atol) {
1104534a8f05SLisandro Dalcin     PetscValidRealPointer(atol, 5);
1105516fe3c3SPeter Brune     *atol = linesearch->atol;
1106516fe3c3SPeter Brune   }
1107516fe3c3SPeter Brune   if (ltol) {
1108534a8f05SLisandro Dalcin     PetscValidRealPointer(ltol, 6);
1109516fe3c3SPeter Brune     *ltol = linesearch->ltol;
1110516fe3c3SPeter Brune   }
1111516fe3c3SPeter Brune   if (max_its) {
1112534a8f05SLisandro Dalcin     PetscValidIntPointer(max_its, 7);
1113516fe3c3SPeter Brune     *max_its = linesearch->max_its;
1114516fe3c3SPeter Brune   }
11153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11166a388c36SPeter Brune }
11176a388c36SPeter Brune 
1118f40b411bSPeter Brune /*@
11193c7d6663SPeter Brune    SNESLineSearchSetTolerances -  Gets the tolerances for the linesearch.  These include
112078bcb3b5SPeter Brune    tolerances for the relative and absolute change in the function norm, the change
112178bcb3b5SPeter Brune    in lambda for iterative line searches, the minimum steplength, the maximum steplength,
112278bcb3b5SPeter Brune    and the maximum number of iterations the line search procedure may take.
1123f40b411bSPeter Brune 
1124f6dfbefdSBarry Smith    Collective
1125f6dfbefdSBarry Smith 
1126f40b411bSPeter Brune    Input Parameters:
11278e557f58SPeter Brune +  linesearch - linesearch context
1128516fe3c3SPeter Brune .  steptol - The minimum steplength
11296cc8e53bSPeter Brune .  maxstep - The maximum steplength
1130516fe3c3SPeter Brune .  rtol    - The relative tolerance for iterative line searches
1131516fe3c3SPeter Brune .  atol    - The absolute tolerance for iterative line searches
1132516fe3c3SPeter Brune .  ltol    - The change in lambda tolerance for iterative line searches
1133516fe3c3SPeter Brune -  max_it  - The maximum number of iterations of the line search
1134f40b411bSPeter Brune 
113520f4b53cSBarry Smith    Level: intermediate
113620f4b53cSBarry Smith 
1137f6dfbefdSBarry Smith    Note:
1138f6dfbefdSBarry Smith    The user may choose to not set any of the tolerances using `PETSC_DEFAULT` in
113978bcb3b5SPeter Brune    place of an argument.
1140f40b411bSPeter Brune 
1141f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchGetTolerances()`
1142f40b411bSPeter Brune @*/
1143d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch, PetscReal steptol, PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
1144d71ae5a4SJacob Faibussowitsch {
11456a388c36SPeter Brune   PetscFunctionBegin;
1146f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1147d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch, steptol, 2);
1148d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch, maxstep, 3);
1149d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch, rtol, 4);
1150d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch, atol, 5);
1151d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch, ltol, 6);
1152d3952184SSatish Balay   PetscValidLogicalCollectiveInt(linesearch, max_its, 7);
1153d3952184SSatish Balay 
115413bcc0bdSJacob Faibussowitsch   if (steptol != (PetscReal)PETSC_DEFAULT) {
11555f80ce2aSJacob Faibussowitsch     PetscCheck(steptol >= 0.0, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_ARG_OUTOFRANGE, "Minimum step length %14.12e must be non-negative", (double)steptol);
11566a388c36SPeter Brune     linesearch->steptol = steptol;
1157d3952184SSatish Balay   }
1158d3952184SSatish Balay 
115913bcc0bdSJacob Faibussowitsch   if (maxstep != (PetscReal)PETSC_DEFAULT) {
11605f80ce2aSJacob Faibussowitsch     PetscCheck(maxstep >= 0.0, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_ARG_OUTOFRANGE, "Maximum step length %14.12e must be non-negative", (double)maxstep);
1161516fe3c3SPeter Brune     linesearch->maxstep = maxstep;
1162d3952184SSatish Balay   }
1163d3952184SSatish Balay 
116413bcc0bdSJacob Faibussowitsch   if (rtol != (PetscReal)PETSC_DEFAULT) {
11652061ca32SJunchao 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);
1166516fe3c3SPeter Brune     linesearch->rtol = rtol;
1167d3952184SSatish Balay   }
1168d3952184SSatish Balay 
116913bcc0bdSJacob Faibussowitsch   if (atol != (PetscReal)PETSC_DEFAULT) {
11705f80ce2aSJacob Faibussowitsch     PetscCheck(atol >= 0.0, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_ARG_OUTOFRANGE, "Absolute tolerance %14.12e must be non-negative", (double)atol);
1171516fe3c3SPeter Brune     linesearch->atol = atol;
1172d3952184SSatish Balay   }
1173d3952184SSatish Balay 
117413bcc0bdSJacob Faibussowitsch   if (ltol != (PetscReal)PETSC_DEFAULT) {
11755f80ce2aSJacob Faibussowitsch     PetscCheck(ltol >= 0.0, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_ARG_OUTOFRANGE, "Lambda tolerance %14.12e must be non-negative", (double)ltol);
1176516fe3c3SPeter Brune     linesearch->ltol = ltol;
1177d3952184SSatish Balay   }
1178d3952184SSatish Balay 
1179d3952184SSatish Balay   if (max_its != PETSC_DEFAULT) {
118063a3b9bcSJacob Faibussowitsch     PetscCheck(max_its >= 0, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of iterations %" PetscInt_FMT " must be non-negative", max_its);
1181516fe3c3SPeter Brune     linesearch->max_its = max_its;
1182d3952184SSatish Balay   }
11833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11846a388c36SPeter Brune }
11856a388c36SPeter Brune 
1186f40b411bSPeter Brune /*@
1187f1c6b773SPeter Brune    SNESLineSearchGetDamping - Gets the line search damping parameter.
1188f40b411bSPeter Brune 
1189*2fe279fdSBarry Smith    Input Parameter:
11908e557f58SPeter Brune .  linesearch - linesearch context
1191f40b411bSPeter Brune 
1192*2fe279fdSBarry Smith    Output Parameter:
11938e557f58SPeter Brune .  damping - The damping parameter
1194f40b411bSPeter Brune 
119578bcb3b5SPeter Brune    Level: advanced
1196f40b411bSPeter Brune 
1197db781477SPatrick Sanan .seealso: `SNESLineSearchGetStepTolerance()`, `SNESQN`
1198f40b411bSPeter Brune @*/
1199f40b411bSPeter Brune 
1200d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch, PetscReal *damping)
1201d71ae5a4SJacob Faibussowitsch {
12026a388c36SPeter Brune   PetscFunctionBegin;
1203f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1204534a8f05SLisandro Dalcin   PetscValidRealPointer(damping, 2);
12056a388c36SPeter Brune   *damping = linesearch->damping;
12063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12076a388c36SPeter Brune }
12086a388c36SPeter Brune 
1209f40b411bSPeter Brune /*@
1210fd292e60Sprj-    SNESLineSearchSetDamping - Sets the line search damping parameter.
1211f40b411bSPeter Brune 
1212f40b411bSPeter Brune    Input Parameters:
121303fd4120SBarry Smith +  linesearch - linesearch context
121403fd4120SBarry Smith -  damping - The damping parameter
1215f40b411bSPeter Brune 
1216f6dfbefdSBarry Smith    Options Database Key:
1217f6dfbefdSBarry Smith .   -snes_linesearch_damping <damping> - the damping value
1218f6dfbefdSBarry Smith 
1219f40b411bSPeter Brune    Level: intermediate
1220f40b411bSPeter Brune 
1221f6dfbefdSBarry Smith    Note:
1222f6dfbefdSBarry Smith    The `SNESLINESEARCHNONE` line search merely takes the update step scaled by the damping parameter.
1223cd7522eaSPeter Brune    The use of the damping parameter in the l2 and cp line searches is much more subtle;
122478bcb3b5SPeter Brune    it is used as a starting point in calculating the secant step. However, the eventual
1225cd7522eaSPeter Brune    step may be of greater length than the damping parameter.  In the bt line search it is
1226cd7522eaSPeter Brune    used as the maximum possible step length, as the bt line search only backtracks.
1227cd7522eaSPeter Brune 
1228f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchGetDamping()`
1229f40b411bSPeter Brune @*/
1230d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch, PetscReal damping)
1231d71ae5a4SJacob Faibussowitsch {
12326a388c36SPeter Brune   PetscFunctionBegin;
1233f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
12346a388c36SPeter Brune   linesearch->damping = damping;
12353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12366a388c36SPeter Brune }
12376a388c36SPeter Brune 
123859405d5eSPeter Brune /*@
123959405d5eSPeter Brune    SNESLineSearchGetOrder - Gets the line search approximation order.
124059405d5eSPeter Brune 
1241f6dfbefdSBarry Smith    Input Parameter:
124278bcb3b5SPeter Brune .  linesearch - linesearch context
124359405d5eSPeter Brune 
1244f6dfbefdSBarry Smith    Output Parameter:
12458e557f58SPeter Brune .  order - The order
124659405d5eSPeter Brune 
124778bcb3b5SPeter Brune    Possible Values for order:
1248f6dfbefdSBarry Smith +  1 or `SNES_LINESEARCH_ORDER_LINEAR` - linear order
1249f6dfbefdSBarry Smith .  2 or `SNES_LINESEARCH_ORDER_QUADRATIC` - quadratic order
1250f6dfbefdSBarry Smith -  3 or `SNES_LINESEARCH_ORDER_CUBIC` - cubic order
125178bcb3b5SPeter Brune 
125259405d5eSPeter Brune    Level: intermediate
125359405d5eSPeter Brune 
1254f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchSetOrder()`
125559405d5eSPeter Brune @*/
125659405d5eSPeter Brune 
1257d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch, PetscInt *order)
1258d71ae5a4SJacob Faibussowitsch {
125959405d5eSPeter Brune   PetscFunctionBegin;
126059405d5eSPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1261534a8f05SLisandro Dalcin   PetscValidIntPointer(order, 2);
126259405d5eSPeter Brune   *order = linesearch->order;
12633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
126459405d5eSPeter Brune }
126559405d5eSPeter Brune 
126659405d5eSPeter Brune /*@
12671f8196a2SJed Brown    SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
126859405d5eSPeter Brune 
126959405d5eSPeter Brune    Input Parameters:
1270a2b725a8SWilliam Gropp +  linesearch - linesearch context
1271a2b725a8SWilliam Gropp -  order - The damping parameter
127259405d5eSPeter Brune 
127359405d5eSPeter Brune    Level: intermediate
127459405d5eSPeter Brune 
127578bcb3b5SPeter Brune    Possible Values for order:
1276f6dfbefdSBarry Smith +  1 or `SNES_LINESEARCH_ORDER_LINEAR` - linear order
1277f6dfbefdSBarry Smith .  2 or `SNES_LINESEARCH_ORDER_QUADRATIC` - quadratic order
1278f6dfbefdSBarry Smith -  3 or `SNES_LINESEARCH_ORDER_CUBIC` - cubic order
127978bcb3b5SPeter Brune 
128059405d5eSPeter Brune    Notes:
128159405d5eSPeter Brune    Variable orders are supported by the following line searches:
128278bcb3b5SPeter Brune +  bt - cubic and quadratic
128378bcb3b5SPeter Brune -  cp - linear and quadratic
128459405d5eSPeter Brune 
1285f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchGetOrder()`, `SNESLineSearchSetDamping()`
128659405d5eSPeter Brune @*/
1287d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch, PetscInt order)
1288d71ae5a4SJacob Faibussowitsch {
128959405d5eSPeter Brune   PetscFunctionBegin;
129059405d5eSPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
129159405d5eSPeter Brune   linesearch->order = order;
12923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
129359405d5eSPeter Brune }
129459405d5eSPeter Brune 
1295f40b411bSPeter Brune /*@
1296f1c6b773SPeter Brune    SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
1297f40b411bSPeter Brune 
1298f6dfbefdSBarry Smith    Not Collective
1299f6dfbefdSBarry Smith 
1300f899ff85SJose E. Roman    Input Parameter:
130178bcb3b5SPeter Brune .  linesearch - linesearch context
1302f40b411bSPeter Brune 
1303f40b411bSPeter Brune    Output Parameters:
1304f40b411bSPeter Brune +  xnorm - The norm of the current solution
1305f40b411bSPeter Brune .  fnorm - The norm of the current function
1306f40b411bSPeter Brune -  ynorm - The norm of the current update
1307f40b411bSPeter Brune 
130878bcb3b5SPeter Brune    Level: developer
1309f40b411bSPeter Brune 
1310f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchSetNorms()` `SNESLineSearchGetVecs()`
1311f40b411bSPeter Brune @*/
1312d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal *xnorm, PetscReal *fnorm, PetscReal *ynorm)
1313d71ae5a4SJacob Faibussowitsch {
1314bf7f4e0aSPeter Brune   PetscFunctionBegin;
1315f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1316f5af7f23SKarl Rupp   if (xnorm) *xnorm = linesearch->xnorm;
1317f5af7f23SKarl Rupp   if (fnorm) *fnorm = linesearch->fnorm;
1318f5af7f23SKarl Rupp   if (ynorm) *ynorm = linesearch->ynorm;
13193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1320bf7f4e0aSPeter Brune }
1321bf7f4e0aSPeter Brune 
1322f40b411bSPeter Brune /*@
1323f1c6b773SPeter Brune    SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
1324f40b411bSPeter Brune 
1325c3339decSBarry Smith    Collective
1326f6dfbefdSBarry Smith 
1327f40b411bSPeter Brune    Input Parameters:
132878bcb3b5SPeter Brune +  linesearch - linesearch context
1329f40b411bSPeter Brune .  xnorm - The norm of the current solution
1330f40b411bSPeter Brune .  fnorm - The norm of the current function
1331f40b411bSPeter Brune -  ynorm - The norm of the current update
1332f40b411bSPeter Brune 
1333f6dfbefdSBarry Smith    Level: developer
1334f40b411bSPeter Brune 
1335f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchGetNorms()`, `SNESLineSearchSetVecs()`
1336f40b411bSPeter Brune @*/
1337d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1338d71ae5a4SJacob Faibussowitsch {
13396a388c36SPeter Brune   PetscFunctionBegin;
1340f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
13416a388c36SPeter Brune   linesearch->xnorm = xnorm;
13426a388c36SPeter Brune   linesearch->fnorm = fnorm;
13436a388c36SPeter Brune   linesearch->ynorm = ynorm;
13443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13456a388c36SPeter Brune }
13466a388c36SPeter Brune 
1347f40b411bSPeter Brune /*@
1348f1c6b773SPeter Brune    SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1349f40b411bSPeter Brune 
1350*2fe279fdSBarry Smith    Input Parameter:
135178bcb3b5SPeter Brune .  linesearch - linesearch context
1352f40b411bSPeter Brune 
135320f4b53cSBarry Smith    Options Database Key:
13548e557f58SPeter Brune .   -snes_linesearch_norms - turn norm computation on or off
1355f40b411bSPeter Brune 
1356f40b411bSPeter Brune    Level: intermediate
1357f40b411bSPeter Brune 
1358f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchGetNorms`, `SNESLineSearchSetNorms()`, `SNESLineSearchSetComputeNorms()`
1359f40b411bSPeter Brune @*/
1360d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1361d71ae5a4SJacob Faibussowitsch {
13629bd66eb0SPeter Brune   SNES snes;
1363bf388a1fSBarry Smith 
13646a388c36SPeter Brune   PetscFunctionBegin;
13656a388c36SPeter Brune   if (linesearch->norms) {
13669bd66eb0SPeter Brune     if (linesearch->ops->vinorm) {
13679566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchGetSNES(linesearch, &snes));
13689566063dSJacob Faibussowitsch       PetscCall(VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm));
13699566063dSJacob Faibussowitsch       PetscCall(VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm));
13709566063dSJacob Faibussowitsch       PetscCall((*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm));
13719bd66eb0SPeter Brune     } else {
13729566063dSJacob Faibussowitsch       PetscCall(VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm));
13739566063dSJacob Faibussowitsch       PetscCall(VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm));
13749566063dSJacob Faibussowitsch       PetscCall(VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm));
13759566063dSJacob Faibussowitsch       PetscCall(VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm));
13769566063dSJacob Faibussowitsch       PetscCall(VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm));
13779566063dSJacob Faibussowitsch       PetscCall(VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm));
13786a388c36SPeter Brune     }
13799bd66eb0SPeter Brune   }
13803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13816a388c36SPeter Brune }
13826a388c36SPeter Brune 
13836f263ca3SPeter Brune /*@
13846f263ca3SPeter Brune    SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
13856f263ca3SPeter Brune 
13866f263ca3SPeter Brune    Input Parameters:
138778bcb3b5SPeter Brune +  linesearch  - linesearch context
138878bcb3b5SPeter Brune -  flg  - indicates whether or not to compute norms
13896f263ca3SPeter Brune 
139020f4b53cSBarry Smith    Options Database Key:
13910b00b554SBarry Smith .   -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic (none) linesearch
13926f263ca3SPeter Brune 
139320f4b53cSBarry Smith    Level: intermediate
139420f4b53cSBarry Smith 
1395f6dfbefdSBarry Smith    Note:
1396f6dfbefdSBarry 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.
13976f263ca3SPeter Brune 
1398f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchGetNorms()`, `SNESLineSearchSetNorms()`, `SNESLineSearchComputeNorms()`, `SNESLINESEARCHBASIC`
13996f263ca3SPeter Brune @*/
1400d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1401d71ae5a4SJacob Faibussowitsch {
14026f263ca3SPeter Brune   PetscFunctionBegin;
14036f263ca3SPeter Brune   linesearch->norms = flg;
14043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14056f263ca3SPeter Brune }
14066f263ca3SPeter Brune 
1407f40b411bSPeter Brune /*@
1408f6dfbefdSBarry Smith    SNESLineSearchGetVecs - Gets the vectors from the `SNESLineSearch` context
1409f6dfbefdSBarry Smith 
1410f6dfbefdSBarry Smith    Not Collective on but the vectors are parallel
1411f40b411bSPeter Brune 
1412f899ff85SJose E. Roman    Input Parameter:
141378bcb3b5SPeter Brune .  linesearch - linesearch context
1414f40b411bSPeter Brune 
1415f40b411bSPeter Brune    Output Parameters:
14166232e825SPeter Brune +  X - Solution vector
14176232e825SPeter Brune .  F - Function vector
14186232e825SPeter Brune .  Y - Search direction vector
14196232e825SPeter Brune .  W - Solution work vector
14206232e825SPeter Brune -  G - Function work vector
14216232e825SPeter Brune 
142220f4b53cSBarry Smith    Level: advanced
142320f4b53cSBarry Smith 
14247bba9028SPeter Brune    Notes:
142520f4b53cSBarry Smith    At the beginning of a line search application, `X` should contain a
142620f4b53cSBarry Smith    solution and the vector `F` the function computed at `X`.  At the end of the
142720f4b53cSBarry Smith    line search application, `X` should contain the new solution, and `F` the
14286232e825SPeter Brune    function evaluated at the new solution.
1429f40b411bSPeter Brune 
1430f6dfbefdSBarry Smith    These vectors are owned by the `SNESLineSearch` and should not be destroyed by the caller
14312a7a6963SBarry Smith 
1432f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchGetNorms()`, `SNESLineSearchSetVecs()`
1433f40b411bSPeter Brune @*/
1434d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch, Vec *X, Vec *F, Vec *Y, Vec *W, Vec *G)
1435d71ae5a4SJacob Faibussowitsch {
14366a388c36SPeter Brune   PetscFunctionBegin;
1437f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
14386a388c36SPeter Brune   if (X) {
14396a388c36SPeter Brune     PetscValidPointer(X, 2);
14406a388c36SPeter Brune     *X = linesearch->vec_sol;
14416a388c36SPeter Brune   }
14426a388c36SPeter Brune   if (F) {
14436a388c36SPeter Brune     PetscValidPointer(F, 3);
14446a388c36SPeter Brune     *F = linesearch->vec_func;
14456a388c36SPeter Brune   }
14466a388c36SPeter Brune   if (Y) {
14476a388c36SPeter Brune     PetscValidPointer(Y, 4);
14486a388c36SPeter Brune     *Y = linesearch->vec_update;
14496a388c36SPeter Brune   }
14506a388c36SPeter Brune   if (W) {
14516a388c36SPeter Brune     PetscValidPointer(W, 5);
14526a388c36SPeter Brune     *W = linesearch->vec_sol_new;
14536a388c36SPeter Brune   }
14546a388c36SPeter Brune   if (G) {
14556a388c36SPeter Brune     PetscValidPointer(G, 6);
14566a388c36SPeter Brune     *G = linesearch->vec_func_new;
14576a388c36SPeter Brune   }
14583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14596a388c36SPeter Brune }
14606a388c36SPeter Brune 
1461f40b411bSPeter Brune /*@
1462f6dfbefdSBarry Smith    SNESLineSearchSetVecs - Sets the vectors on the `SNESLineSearch` context
1463f6dfbefdSBarry Smith 
1464c3339decSBarry Smith    Logically Collective
1465f40b411bSPeter Brune 
1466f40b411bSPeter Brune    Input Parameters:
146778bcb3b5SPeter Brune +  linesearch - linesearch context
14686232e825SPeter Brune .  X - Solution vector
14696232e825SPeter Brune .  F - Function vector
14706232e825SPeter Brune .  Y - Search direction vector
14716232e825SPeter Brune .  W - Solution work vector
14726232e825SPeter Brune -  G - Function work vector
1473f40b411bSPeter Brune 
147478bcb3b5SPeter Brune    Level: advanced
1475f40b411bSPeter Brune 
1476f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchSetNorms()`, `SNESLineSearchGetVecs()`
1477f40b411bSPeter Brune @*/
1478d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch, Vec X, Vec F, Vec Y, Vec W, Vec G)
1479d71ae5a4SJacob Faibussowitsch {
14806a388c36SPeter Brune   PetscFunctionBegin;
1481f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
14826a388c36SPeter Brune   if (X) {
14836a388c36SPeter Brune     PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
14846a388c36SPeter Brune     linesearch->vec_sol = X;
14856a388c36SPeter Brune   }
14866a388c36SPeter Brune   if (F) {
14876a388c36SPeter Brune     PetscValidHeaderSpecific(F, VEC_CLASSID, 3);
14886a388c36SPeter Brune     linesearch->vec_func = F;
14896a388c36SPeter Brune   }
14906a388c36SPeter Brune   if (Y) {
14916a388c36SPeter Brune     PetscValidHeaderSpecific(Y, VEC_CLASSID, 4);
14926a388c36SPeter Brune     linesearch->vec_update = Y;
14936a388c36SPeter Brune   }
14946a388c36SPeter Brune   if (W) {
14956a388c36SPeter Brune     PetscValidHeaderSpecific(W, VEC_CLASSID, 5);
14966a388c36SPeter Brune     linesearch->vec_sol_new = W;
14976a388c36SPeter Brune   }
14986a388c36SPeter Brune   if (G) {
14996a388c36SPeter Brune     PetscValidHeaderSpecific(G, VEC_CLASSID, 6);
15006a388c36SPeter Brune     linesearch->vec_func_new = G;
15016a388c36SPeter Brune   }
15023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15036a388c36SPeter Brune }
15046a388c36SPeter Brune 
1505e7058c64SPeter Brune /*@C
1506f1c6b773SPeter Brune    SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1507f6dfbefdSBarry Smith    `SNESLineSearch` options in the database.
1508e7058c64SPeter Brune 
1509c3339decSBarry Smith    Logically Collective
1510e7058c64SPeter Brune 
1511e7058c64SPeter Brune    Input Parameters:
1512f6dfbefdSBarry Smith +  linesearch - the `SNESLineSearch` context
1513e7058c64SPeter Brune -  prefix - the prefix to prepend to all option names
1514e7058c64SPeter Brune 
151520f4b53cSBarry Smith    Level: advanced
151620f4b53cSBarry Smith 
1517f6dfbefdSBarry Smith    Note:
1518e7058c64SPeter Brune    A hyphen (-) must NOT be given at the beginning of the prefix name.
1519e7058c64SPeter Brune    The first character of all runtime options is AUTOMATICALLY the hyphen.
1520e7058c64SPeter Brune 
1521f6dfbefdSBarry Smith .seealso: `SNESLineSearch()`, `SNESLineSearchSetFromOptions()`, `SNESGetOptionsPrefix()`
1522e7058c64SPeter Brune @*/
1523d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch, const char prefix[])
1524d71ae5a4SJacob Faibussowitsch {
1525e7058c64SPeter Brune   PetscFunctionBegin;
1526f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
15279566063dSJacob Faibussowitsch   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)linesearch, prefix));
15283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1529e7058c64SPeter Brune }
1530e7058c64SPeter Brune 
1531e7058c64SPeter Brune /*@C
1532f6dfbefdSBarry Smith    SNESLineSearchGetOptionsPrefix - Gets the prefix used for searching for all
1533f1c6b773SPeter Brune    SNESLineSearch options in the database.
1534e7058c64SPeter Brune 
1535e7058c64SPeter Brune    Not Collective
1536e7058c64SPeter Brune 
1537e7058c64SPeter Brune    Input Parameter:
1538f6dfbefdSBarry Smith .  linesearch - the `SNESLineSearch` context
1539e7058c64SPeter Brune 
1540e7058c64SPeter Brune    Output Parameter:
1541e7058c64SPeter Brune .  prefix - pointer to the prefix string used
1542e7058c64SPeter Brune 
1543e7058c64SPeter Brune    Level: advanced
1544e7058c64SPeter Brune 
154520f4b53cSBarry Smith    Fortran Note:
154620f4b53cSBarry Smith    The user should pass in a string 'prefix' of
154720f4b53cSBarry Smith    sufficient length to hold the prefix.
154820f4b53cSBarry Smith 
1549f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESAppendOptionsPrefix()`
1550e7058c64SPeter Brune @*/
1551d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch, const char *prefix[])
1552d71ae5a4SJacob Faibussowitsch {
1553e7058c64SPeter Brune   PetscFunctionBegin;
1554f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
15559566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)linesearch, prefix));
15563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1557e7058c64SPeter Brune }
1558bf7f4e0aSPeter Brune 
15598d359177SBarry Smith /*@C
1560f6dfbefdSBarry Smith    SNESLineSearchSetWorkVecs - Sets work vectors for the line search.
1561f40b411bSPeter Brune 
1562d8d19677SJose E. Roman    Input Parameters:
1563f6dfbefdSBarry Smith +  linesearch - the `SNESLineSearch` context
1564f40b411bSPeter Brune -  nwork - the number of work vectors
1565f40b411bSPeter Brune 
1566f40b411bSPeter Brune    Level: developer
1567f40b411bSPeter Brune 
1568f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESSetWorkVecs()`
1569f40b411bSPeter Brune @*/
1570d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1571d71ae5a4SJacob Faibussowitsch {
1572bf7f4e0aSPeter Brune   PetscFunctionBegin;
15730fdf79fbSJacob Faibussowitsch   PetscCheck(linesearch->vec_sol, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
15749566063dSJacob Faibussowitsch   PetscCall(VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work));
15753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1576bf7f4e0aSPeter Brune }
1577bf7f4e0aSPeter Brune 
1578f40b411bSPeter Brune /*@
1579422a814eSBarry Smith    SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1580f40b411bSPeter Brune 
1581*2fe279fdSBarry Smith    Input Parameter:
158278bcb3b5SPeter Brune .  linesearch - linesearch context
1583f40b411bSPeter Brune 
1584*2fe279fdSBarry Smith    Output Parameter:
1585422a814eSBarry Smith .  result - The success or failure status
1586f40b411bSPeter Brune 
158720f4b53cSBarry Smith    Level: developer
158820f4b53cSBarry Smith 
1589f6dfbefdSBarry Smith    Note:
1590f6dfbefdSBarry 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 
1593f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchSetReason()`, `SNESLineSearchReason`
1594f40b411bSPeter Brune @*/
1595d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1596d71ae5a4SJacob Faibussowitsch {
1597bf7f4e0aSPeter Brune   PetscFunctionBegin;
1598f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1599422a814eSBarry Smith   PetscValidPointer(result, 2);
1600422a814eSBarry Smith   *result = linesearch->result;
16013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1602bf7f4e0aSPeter Brune }
1603bf7f4e0aSPeter Brune 
1604f40b411bSPeter Brune /*@
1605422a814eSBarry Smith    SNESLineSearchSetReason - Sets the success/failure status of the last line search application
1606f40b411bSPeter Brune 
1607f40b411bSPeter Brune    Input Parameters:
160878bcb3b5SPeter Brune +  linesearch - linesearch context
1609422a814eSBarry Smith -  result - The success or failure status
1610f40b411bSPeter Brune 
161120f4b53cSBarry Smith    Level: developer
161220f4b53cSBarry Smith 
1613f6dfbefdSBarry Smith    Note:
1614f6dfbefdSBarry Smith    This is typically called in a `SNESLineSearchApply()` or a `SNESLINESEARCHSHELL` implementation to set
1615cd7522eaSPeter Brune    the success or failure of the line search method.
1616cd7522eaSPeter Brune 
1617f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchReason`, `SNESLineSearchGetSResult()`
1618f40b411bSPeter Brune @*/
1619d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1620d71ae5a4SJacob Faibussowitsch {
16216a388c36SPeter Brune   PetscFunctionBegin;
16225fd66863SKarl Rupp   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1623422a814eSBarry Smith   linesearch->result = result;
16243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16256a388c36SPeter Brune }
16266a388c36SPeter Brune 
16279bd66eb0SPeter Brune /*@C
1628f1c6b773SPeter Brune    SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
16299bd66eb0SPeter Brune 
1630c3339decSBarry Smith    Logically Collective
1631f6dfbefdSBarry Smith 
16329bd66eb0SPeter Brune    Input Parameters:
1633f6dfbefdSBarry Smith +  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 
163720f4b53cSBarry Smith    Calling sequence of `projectfunc`:
16389bd66eb0SPeter Brune .vb
163920f4b53cSBarry Smith    PetscErrorCode projectfunc(SNES snes, Vec X)
16409bd66eb0SPeter Brune .ve
16419bd66eb0SPeter Brune +   snes - nonlinear context
164220f4b53cSBarry Smith -   X - current solution, store the projected solution here
16439bd66eb0SPeter Brune 
164420f4b53cSBarry Smith    Calling sequence of `normfunc`:
16459bd66eb0SPeter Brune .vb
164620f4b53cSBarry Smith    PetscErrorCode normfunc(SNES snes, Vec X, Vec F, PetscScalar *fnorm)
16479bd66eb0SPeter Brune .ve
16489bd66eb0SPeter Brune +   snes - nonlinear context
16499bd66eb0SPeter Brune .   X - current solution
165020f4b53cSBarry Smith .   F - current residual
165120f4b53cSBarry Smith -   fnorm - VI-specific norm of the function
16529bd66eb0SPeter Brune 
1653f6dfbefdSBarry Smith     Level: advanced
16549bd66eb0SPeter Brune 
165520f4b53cSBarry Smith     Note:
165620f4b53cSBarry Smith     The VI solvers require projection of the solution to the feasible set.  `projectfunc` should implement this.
165720f4b53cSBarry Smith 
165820f4b53cSBarry Smith     The VI solvers require special evaluation of the function norm such that the norm is only calculated
165920f4b53cSBarry Smith     on the inactive set.  This should be implemented by `normfunc`.
166020f4b53cSBarry Smith 
1661f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchGetVIFunctions()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchSetPreCheck()`
16629bd66eb0SPeter Brune @*/
1663d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1664d71ae5a4SJacob Faibussowitsch {
16659bd66eb0SPeter Brune   PetscFunctionBegin;
1666f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
16679bd66eb0SPeter Brune   if (projectfunc) linesearch->ops->viproject = projectfunc;
16689bd66eb0SPeter Brune   if (normfunc) linesearch->ops->vinorm = normfunc;
16693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16709bd66eb0SPeter Brune }
16719bd66eb0SPeter Brune 
16729bd66eb0SPeter Brune /*@C
1673f1c6b773SPeter Brune    SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
16749bd66eb0SPeter Brune 
1675f6dfbefdSBarry Smith    Not Collective
1676f6dfbefdSBarry Smith 
1677f899ff85SJose E. Roman    Input Parameter:
1678f6dfbefdSBarry Smith .  linesearch - the line search context, obtain with `SNESGetLineSearch()`
16799bd66eb0SPeter Brune 
16809bd66eb0SPeter Brune    Output Parameters:
16819bd66eb0SPeter Brune +  projectfunc - function for projecting the function to the bounds
16829bd66eb0SPeter Brune -  normfunc - function for computing the norm of an active set
16839bd66eb0SPeter Brune 
1684f6dfbefdSBarry Smith     Level: advanced
16859bd66eb0SPeter Brune 
1686f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchSetVIFunctions()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchGetPreCheck()`
16879bd66eb0SPeter Brune @*/
1688d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1689d71ae5a4SJacob Faibussowitsch {
16909bd66eb0SPeter Brune   PetscFunctionBegin;
16919bd66eb0SPeter Brune   if (projectfunc) *projectfunc = linesearch->ops->viproject;
16929bd66eb0SPeter Brune   if (normfunc) *normfunc = linesearch->ops->vinorm;
16933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16949bd66eb0SPeter Brune }
16959bd66eb0SPeter Brune 
1696bf7f4e0aSPeter Brune /*@C
1697f6dfbefdSBarry Smith   SNESLineSearchRegister - register a line search method
1698bf7f4e0aSPeter Brune 
1699bf7f4e0aSPeter Brune   Level: advanced
1700f6dfbefdSBarry Smith 
1701f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESLineSearchType`, `SNESLineSearchSetType()`
1702bf7f4e0aSPeter Brune @*/
1703d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchRegister(const char sname[], PetscErrorCode (*function)(SNESLineSearch))
1704d71ae5a4SJacob Faibussowitsch {
1705bf7f4e0aSPeter Brune   PetscFunctionBegin;
17069566063dSJacob Faibussowitsch   PetscCall(SNESInitializePackage());
17079566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&SNESLineSearchList, sname, function));
17083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1709bf7f4e0aSPeter Brune }
1710