xref: /petsc/src/snes/linesearch/interface/linesearch.c (revision 1bd63e3efbce1229b47e2ec5bb1e7d27e9e9b2dd)
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 
142fe279fdSBarry 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 
27420bcc1bSBarry Smith   This does not clear the monitor set with `SNESLineSearchSetDefaultMonitor()` use `SNESLineSearchSetDefaultMonitor`(`ls`,`NULL`) to cancel it
28dcf2fd19SBarry Smith   that one.
29dcf2fd19SBarry Smith 
30420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `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 
502fe279fdSBarry Smith   Input Parameter:
51dcf2fd19SBarry Smith . ls - the linesearch object
52dcf2fd19SBarry Smith 
532fe279fdSBarry Smith   Level: developer
542fe279fdSBarry Smith 
55f6dfbefdSBarry Smith   Note:
56420bcc1bSBarry Smith   This routine is called by the `SNESLineSearch` implementations.
57dcf2fd19SBarry Smith   It does not typically need to be called by the user.
58dcf2fd19SBarry Smith 
59420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `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
80420bcc1bSBarry Smith . mctx           - [optional] user-defined context for private data for the monitor routine (use `NULL` if no context is desired)
81420bcc1bSBarry Smith - monitordestroy - [optional] routine that frees monitor context (may be `NULL`)
82420bcc1bSBarry Smith 
83420bcc1bSBarry Smith   Calling sequence of `f`:
84420bcc1bSBarry Smith + ls   - the `SNESLineSearch` context
85420bcc1bSBarry Smith - mctx - [optional] user-defined context for private data for the monitor routine
86420bcc1bSBarry Smith 
87420bcc1bSBarry Smith   Calling sequence of `monitordestroy`:
88420bcc1bSBarry Smith . mctx - [optional] user-defined context for private data for the monitor routine
8920f4b53cSBarry Smith 
9020f4b53cSBarry Smith   Level: intermediate
91dcf2fd19SBarry Smith 
92f6dfbefdSBarry Smith   Note:
93dcf2fd19SBarry Smith   Several different monitoring routines may be set by calling
94f6dfbefdSBarry Smith   `SNESLineSearchMonitorSet()` multiple times; all will be called in the
95dcf2fd19SBarry Smith   order in which they were set.
96dcf2fd19SBarry Smith 
97420bcc1bSBarry Smith   Fortran Note:
98f6dfbefdSBarry Smith   Only a single monitor function can be set for each `SNESLineSearch` object
99dcf2fd19SBarry Smith 
100420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchMonitorDefault()`, `SNESLineSearchMonitorCancel()`
101dcf2fd19SBarry Smith @*/
102420bcc1bSBarry Smith PetscErrorCode SNESLineSearchMonitorSet(SNESLineSearch ls, PetscErrorCode (*f)(SNESLineSearch ls, void *mctx), void *mctx, PetscErrorCode (*monitordestroy)(void **mctx))
103d71ae5a4SJacob Faibussowitsch {
10478064530SBarry Smith   PetscInt  i;
10578064530SBarry Smith   PetscBool identical;
10678064530SBarry Smith 
107dcf2fd19SBarry Smith   PetscFunctionBegin;
108dcf2fd19SBarry Smith   PetscValidHeaderSpecific(ls, SNESLINESEARCH_CLASSID, 1);
10978064530SBarry Smith   for (i = 0; i < ls->numbermonitors; i++) {
1109566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))ls->monitorftns[i], ls->monitorcontext[i], ls->monitordestroy[i], &identical));
1113ba16761SJacob Faibussowitsch     if (identical) PetscFunctionReturn(PETSC_SUCCESS);
11278064530SBarry Smith   }
1135f80ce2aSJacob Faibussowitsch   PetscCheck(ls->numbermonitors < MAXSNESLSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set");
114dcf2fd19SBarry Smith   ls->monitorftns[ls->numbermonitors]      = f;
115dcf2fd19SBarry Smith   ls->monitordestroy[ls->numbermonitors]   = monitordestroy;
116dcf2fd19SBarry Smith   ls->monitorcontext[ls->numbermonitors++] = (void *)mctx;
1173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
118dcf2fd19SBarry Smith }
119dcf2fd19SBarry Smith 
120dcf2fd19SBarry Smith /*@C
121f6dfbefdSBarry Smith   SNESLineSearchMonitorSolutionUpdate - Monitors each update of the function value the linesearch tries
122dcf2fd19SBarry Smith 
123c3339decSBarry Smith   Collective
124dcf2fd19SBarry Smith 
125dcf2fd19SBarry Smith   Input Parameters:
126420bcc1bSBarry Smith + ls - the `SNESLineSearch` object
127f6dfbefdSBarry Smith - vf - the context for the monitor, in this case it is an `PetscViewerAndFormat`
128dcf2fd19SBarry Smith 
129420bcc1bSBarry Smith   Options Database Key:
130420bcc1bSBarry Smith . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
131dcf2fd19SBarry Smith 
132420bcc1bSBarry Smith   Level: developer
133420bcc1bSBarry Smith 
134420bcc1bSBarry Smith   This is not normally called directly but is passed to `SNESLineSearchMonitorSet()`
135420bcc1bSBarry Smith 
136420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchMonitorSet()`, `SNESMonitorSolution()`
137dcf2fd19SBarry Smith @*/
138d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchMonitorSolutionUpdate(SNESLineSearch ls, PetscViewerAndFormat *vf)
139d71ae5a4SJacob Faibussowitsch {
140d12e167eSBarry Smith   PetscViewer viewer = vf->viewer;
141dcf2fd19SBarry Smith   Vec         Y, W, G;
142dcf2fd19SBarry Smith 
143dcf2fd19SBarry Smith   PetscFunctionBegin;
1449566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchGetVecs(ls, NULL, NULL, &Y, &W, &G));
1459566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
1469566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "LineSearch attempted update to solution \n"));
1479566063dSJacob Faibussowitsch   PetscCall(VecView(Y, viewer));
1489566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "LineSearch attempted new solution \n"));
1499566063dSJacob Faibussowitsch   PetscCall(VecView(W, viewer));
1509566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "LineSearch attempted updated function value\n"));
1519566063dSJacob Faibussowitsch   PetscCall(VecView(G, viewer));
1529566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
1533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
154dcf2fd19SBarry Smith }
155dcf2fd19SBarry Smith 
156f40b411bSPeter Brune /*@
157420bcc1bSBarry Smith   SNESLineSearchCreate - Creates a `SNESLineSearch` context.
158f40b411bSPeter Brune 
159f6dfbefdSBarry Smith   Logically Collective
160f40b411bSPeter Brune 
1612fe279fdSBarry Smith   Input Parameter:
162f6dfbefdSBarry Smith . comm - MPI communicator for the line search (typically from the associated `SNES` context).
163f40b411bSPeter Brune 
1642fe279fdSBarry Smith   Output Parameter:
1658e557f58SPeter Brune . outlinesearch - the new line search context
166f40b411bSPeter Brune 
167162e0bf5SPeter Brune   Level: developer
168162e0bf5SPeter Brune 
169f6dfbefdSBarry Smith   Note:
170420bcc1bSBarry Smith   The preferred calling sequence is to use `SNESGetLineSearch()` to acquire the `SNESLineSearch` instance
171f6dfbefdSBarry Smith   already associated with the `SNES`.
172f40b411bSPeter Brune 
173420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `LineSearchDestroy()`, `SNESGetLineSearch()`
174f40b411bSPeter Brune @*/
175d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch)
176d71ae5a4SJacob Faibussowitsch {
177f1c6b773SPeter Brune   SNESLineSearch linesearch;
178bf388a1fSBarry Smith 
179bf7f4e0aSPeter Brune   PetscFunctionBegin;
1804f572ea9SToby Isaac   PetscAssertPointer(outlinesearch, 2);
1819566063dSJacob Faibussowitsch   PetscCall(SNESInitializePackage());
1820298fd71SBarry Smith   *outlinesearch = NULL;
183f5af7f23SKarl Rupp 
1849566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(linesearch, SNESLINESEARCH_CLASSID, "SNESLineSearch", "Linesearch", "SNESLineSearch", comm, SNESLineSearchDestroy, SNESLineSearchView));
185bf7f4e0aSPeter Brune 
1860298fd71SBarry Smith   linesearch->vec_sol_new  = NULL;
1870298fd71SBarry Smith   linesearch->vec_func_new = NULL;
1880298fd71SBarry Smith   linesearch->vec_sol      = NULL;
1890298fd71SBarry Smith   linesearch->vec_func     = NULL;
1900298fd71SBarry Smith   linesearch->vec_update   = NULL;
1919bd66eb0SPeter Brune 
192bf7f4e0aSPeter Brune   linesearch->lambda       = 1.0;
193bf7f4e0aSPeter Brune   linesearch->fnorm        = 1.0;
194bf7f4e0aSPeter Brune   linesearch->ynorm        = 1.0;
195bf7f4e0aSPeter Brune   linesearch->xnorm        = 1.0;
196422a814eSBarry Smith   linesearch->result       = SNES_LINESEARCH_SUCCEEDED;
197bf7f4e0aSPeter Brune   linesearch->norms        = PETSC_TRUE;
198bf7f4e0aSPeter Brune   linesearch->keeplambda   = PETSC_FALSE;
199bf7f4e0aSPeter Brune   linesearch->damping      = 1.0;
200bf7f4e0aSPeter Brune   linesearch->maxstep      = 1e8;
201bf7f4e0aSPeter Brune   linesearch->steptol      = 1e-12;
202516fe3c3SPeter Brune   linesearch->rtol         = 1e-8;
203516fe3c3SPeter Brune   linesearch->atol         = 1e-15;
204516fe3c3SPeter Brune   linesearch->ltol         = 1e-8;
2050298fd71SBarry Smith   linesearch->precheckctx  = NULL;
2060298fd71SBarry Smith   linesearch->postcheckctx = NULL;
20759405d5eSPeter Brune   linesearch->max_its      = 1;
208bf7f4e0aSPeter Brune   linesearch->setupcalled  = PETSC_FALSE;
2093add74b1SBarry Smith   linesearch->monitor      = NULL;
210bf7f4e0aSPeter Brune   *outlinesearch           = linesearch;
2113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
212bf7f4e0aSPeter Brune }
213bf7f4e0aSPeter Brune 
214f40b411bSPeter Brune /*@
21578bcb3b5SPeter Brune   SNESLineSearchSetUp - Prepares the line search for being applied by allocating
21678bcb3b5SPeter Brune   any required vectors.
217f40b411bSPeter Brune 
218c3339decSBarry Smith   Collective
219f40b411bSPeter Brune 
2202fe279fdSBarry Smith   Input Parameter:
221f6dfbefdSBarry Smith . linesearch - The `SNESLineSearch` instance.
222f40b411bSPeter Brune 
22320f4b53cSBarry Smith   Level: advanced
22420f4b53cSBarry Smith 
225f6dfbefdSBarry Smith   Note:
226f6dfbefdSBarry Smith   For most cases, this needn't be called by users or outside of `SNESLineSearchApply()`.
227cd7522eaSPeter Brune   The only current case where this is called outside of this is for the VI
22878bcb3b5SPeter Brune   solvers, which modify the solution and work vectors before the first call
229f6dfbefdSBarry Smith   of `SNESLineSearchApply()`, requiring the `SNESLineSearch` work vectors to be
230cd7522eaSPeter Brune   allocated upfront.
231cd7522eaSPeter Brune 
232420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchReset()`
233f40b411bSPeter Brune @*/
234d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch)
235d71ae5a4SJacob Faibussowitsch {
236bf7f4e0aSPeter Brune   PetscFunctionBegin;
23748a46eb9SPierre Jolivet   if (!((PetscObject)linesearch)->type_name) PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHBASIC));
238bf7f4e0aSPeter Brune   if (!linesearch->setupcalled) {
23948a46eb9SPierre Jolivet     if (!linesearch->vec_sol_new) PetscCall(VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new));
24048a46eb9SPierre Jolivet     if (!linesearch->vec_func_new) PetscCall(VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new));
241dbbe0bcdSBarry Smith     if (linesearch->ops->setup) PetscUseTypeMethod(linesearch, setup);
2429566063dSJacob Faibussowitsch     if (!linesearch->ops->snesfunc) PetscCall(SNESLineSearchSetFunction(linesearch, SNESComputeFunction));
243bf7f4e0aSPeter Brune     linesearch->lambda      = linesearch->damping;
244bf7f4e0aSPeter Brune     linesearch->setupcalled = PETSC_TRUE;
245bf7f4e0aSPeter Brune   }
2463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
247bf7f4e0aSPeter Brune }
248bf7f4e0aSPeter Brune 
249f40b411bSPeter Brune /*@
250f6dfbefdSBarry Smith   SNESLineSearchReset - Undoes the `SNESLineSearchSetUp()` and deletes any `Vec`s or `Mat`s allocated by the line search.
251f40b411bSPeter Brune 
252c3339decSBarry Smith   Collective
253f40b411bSPeter Brune 
2542fe279fdSBarry Smith   Input Parameter:
255f6dfbefdSBarry Smith . linesearch - The `SNESLineSearch` instance.
256f40b411bSPeter Brune 
25720f4b53cSBarry Smith   Level: developer
25820f4b53cSBarry Smith 
259f6dfbefdSBarry Smith   Note:
260f6dfbefdSBarry Smith   Usually only called by `SNESReset()`
261f190f2fcSBarry Smith 
262420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchSetUp()`
263f40b411bSPeter Brune @*/
264d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch)
265d71ae5a4SJacob Faibussowitsch {
266bf7f4e0aSPeter Brune   PetscFunctionBegin;
267dbbe0bcdSBarry Smith   if (linesearch->ops->reset) PetscUseTypeMethod(linesearch, reset);
268f5af7f23SKarl Rupp 
2699566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&linesearch->vec_sol_new));
2709566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&linesearch->vec_func_new));
271bf7f4e0aSPeter Brune 
2729566063dSJacob Faibussowitsch   PetscCall(VecDestroyVecs(linesearch->nwork, &linesearch->work));
273f5af7f23SKarl Rupp 
274bf7f4e0aSPeter Brune   linesearch->nwork       = 0;
275bf7f4e0aSPeter Brune   linesearch->setupcalled = PETSC_FALSE;
2763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
277bf7f4e0aSPeter Brune }
278bf7f4e0aSPeter Brune 
279ed07d7d7SPeter Brune /*@C
280f6dfbefdSBarry Smith   SNESLineSearchSetFunction - Sets the function evaluation used by the `SNES` line search
281f6dfbefdSBarry Smith   `
282e4094ef1SJacob Faibussowitsch 
283ed07d7d7SPeter Brune   Input Parameters:
284e4094ef1SJacob Faibussowitsch + linesearch - the `SNESLineSearch` context
285e4094ef1SJacob Faibussowitsch - func       - function evaluation routine, this is usually the function provided with `SNESSetFunction()`
286ed07d7d7SPeter Brune 
287420bcc1bSBarry Smith   Calling sequence of `func`:
288420bcc1bSBarry Smith + snes - the `SNES` with which the `SNESLineSearch` context is associated with
289420bcc1bSBarry Smith . x    - the input vector
290420bcc1bSBarry Smith - f    - the computed value of the function
291420bcc1bSBarry Smith 
292ed07d7d7SPeter Brune   Level: developer
293ed07d7d7SPeter Brune 
294420bcc1bSBarry Smith   Note:
295420bcc1bSBarry Smith   By default the `SNESLineSearch` uses the function provided by `SNESSetFunction()` so this is rarely needed
296420bcc1bSBarry Smith 
297420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`, `SNESSetFunction()`
298ed07d7d7SPeter Brune @*/
299420bcc1bSBarry Smith PetscErrorCode SNESLineSearchSetFunction(SNESLineSearch linesearch, PetscErrorCode (*func)(SNES snes, Vec x, Vec f))
300d71ae5a4SJacob Faibussowitsch {
301ed07d7d7SPeter Brune   PetscFunctionBegin;
302ed07d7d7SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
303ed07d7d7SPeter Brune   linesearch->ops->snesfunc = func;
3043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
305ed07d7d7SPeter Brune }
306ed07d7d7SPeter Brune 
30786d74e61SPeter Brune /*@C
308420bcc1bSBarry Smith   SNESLineSearchSetPreCheck - Sets a function that is called after the initial search direction has been computed but
309420bcc1bSBarry Smith   before the line search routine has been applied. Allows adjusting the result of (usually a linear solve) that
310f190f2fcSBarry Smith   determined the search direction.
31186d74e61SPeter Brune 
312c3339decSBarry Smith   Logically Collective
31386d74e61SPeter Brune 
31486d74e61SPeter Brune   Input Parameters:
315f6dfbefdSBarry Smith + linesearch - the `SNESLineSearch` context
316420bcc1bSBarry Smith . func       - [optional] function evaluation routine
31720f4b53cSBarry Smith - ctx        - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`)
31886d74e61SPeter Brune 
319420bcc1bSBarry Smith   Calling sequence of `func`:
320420bcc1bSBarry Smith + ls        - the `SNESLineSearch` context
321420bcc1bSBarry Smith . x         - the current solution
322420bcc1bSBarry Smith . d         - the current seach direction
323420bcc1bSBarry Smith . changed_d - indicates if the search direction has been changed
324420bcc1bSBarry Smith - ctx       - the context passed to `SNESLineSearchSetPreCheck()`
325420bcc1bSBarry Smith 
32686d74e61SPeter Brune   Level: intermediate
32786d74e61SPeter Brune 
328f6dfbefdSBarry Smith   Note:
329420bcc1bSBarry Smith   Use `SNESLineSearchSetPostCheck()` to change the step after the line search is complete.
330f0b84518SBarry Smith 
331f0b84518SBarry Smith   Use `SNESVISetVariableBounds()` and `SNESVISetComputeVariableBounds()` to cause `SNES` to automatically control the ranges of variables allowed.
332f0b84518SBarry Smith 
333420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESGetLineSearch()`, `SNESLineSearchPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchGetPreCheck()`,
334869ba2dcSBarry Smith           `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESSetFunctionDomainError()`, `SNESSetJacobianDomainError()`
335f0b84518SBarry Smith 
33686d74e61SPeter Brune @*/
337420bcc1bSBarry Smith PetscErrorCode SNESLineSearchSetPreCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch ls, Vec x, Vec d, PetscBool *changed_d, void *ctx), void *ctx)
338d71ae5a4SJacob Faibussowitsch {
3399bd66eb0SPeter Brune   PetscFunctionBegin;
340f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
341f190f2fcSBarry Smith   if (func) linesearch->ops->precheck = func;
34286d74e61SPeter Brune   if (ctx) linesearch->precheckctx = ctx;
3433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34486d74e61SPeter Brune }
34586d74e61SPeter Brune 
34686d74e61SPeter Brune /*@C
34753deb899SBarry Smith   SNESLineSearchGetPreCheck - Gets the pre-check function for the line search routine.
34886d74e61SPeter Brune 
349f899ff85SJose E. Roman   Input Parameter:
350f6dfbefdSBarry Smith . linesearch - the `SNESLineSearch` context
35186d74e61SPeter Brune 
35286d74e61SPeter Brune   Output Parameters:
353420bcc1bSBarry Smith + func - [optional] function evaluation routine,  for calling sequence see `SNESLineSearchSetPreCheck()`
35420f4b53cSBarry Smith - ctx  - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`)
35586d74e61SPeter Brune 
35686d74e61SPeter Brune   Level: intermediate
35786d74e61SPeter Brune 
358420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchPreCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`
35986d74e61SPeter Brune @*/
360d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetPreCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch, Vec, Vec, PetscBool *, void *), void **ctx)
361d71ae5a4SJacob Faibussowitsch {
3629bd66eb0SPeter Brune   PetscFunctionBegin;
363f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
364f190f2fcSBarry Smith   if (func) *func = linesearch->ops->precheck;
36586d74e61SPeter Brune   if (ctx) *ctx = linesearch->precheckctx;
3663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
36786d74e61SPeter Brune }
36886d74e61SPeter Brune 
36986d74e61SPeter Brune /*@C
370f190f2fcSBarry Smith   SNESLineSearchSetPostCheck - Sets a user function that is called after the line search has been applied to determine the step
371f190f2fcSBarry Smith   direction and length. Allows the user a chance to change or override the decision of the line search routine
37286d74e61SPeter Brune 
37320f4b53cSBarry Smith   Logically Collective
37486d74e61SPeter Brune 
37586d74e61SPeter Brune   Input Parameters:
376f6dfbefdSBarry Smith + linesearch - the `SNESLineSearch` context
377420bcc1bSBarry Smith . func       - [optional] function evaluation routine
37820f4b53cSBarry Smith - ctx        - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`)
37986d74e61SPeter Brune 
380420bcc1bSBarry Smith   Calling sequence of `func`:
381420bcc1bSBarry Smith + ls        - the `SNESLineSearch` context
382420bcc1bSBarry Smith . x         - the current solution
383420bcc1bSBarry Smith . d         - the current seach direction
384420bcc1bSBarry Smith . w         - $ w = x + lamba*d $ for some lambda
385420bcc1bSBarry Smith . changed_d - indicates if the search direction `d` has been changed
386420bcc1bSBarry Smith . changed_w - indicates `w` has been changed
387420bcc1bSBarry Smith - ctx       - the context passed to `SNESLineSearchSetPreCheck()`
388420bcc1bSBarry Smith 
38986d74e61SPeter Brune   Level: intermediate
39086d74e61SPeter Brune 
391f0b84518SBarry Smith   Notes:
3926b095a85SStefano Zampini   Use `SNESLineSearchSetPreCheck()` to change the step before the line search is completed.
3936b095a85SStefano Zampini   The calling sequence of the callback does not contain the current scaling factor. To access the value, use `SNESLineSearchGetLambda()`.
394f0b84518SBarry Smith 
395f0b84518SBarry Smith   Use `SNESVISetVariableBounds()` and `SNESVISetComputeVariableBounds()` to cause `SNES` to automatically control the ranges of variables allowed.
396f0b84518SBarry Smith 
397420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`, `SNESLineSearchGetPostCheck()`,
398e4094ef1SJacob Faibussowitsch           `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESSetFunctionDomainError()`, `SNESSetJacobianDomainError()`
39986d74e61SPeter Brune @*/
400420bcc1bSBarry Smith PetscErrorCode SNESLineSearchSetPostCheck(SNESLineSearch linesearch, PetscErrorCode (*func)(SNESLineSearch ls, Vec x, Vec d, Vec w, PetscBool *changed_d, PetscBool *changed_w, void *ctx), void *ctx)
401d71ae5a4SJacob Faibussowitsch {
40286d74e61SPeter Brune   PetscFunctionBegin;
403f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
404f190f2fcSBarry Smith   if (func) linesearch->ops->postcheck = func;
40586d74e61SPeter Brune   if (ctx) linesearch->postcheckctx = ctx;
4063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40786d74e61SPeter Brune }
40886d74e61SPeter Brune 
40986d74e61SPeter Brune /*@C
410f1c6b773SPeter Brune   SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.
41186d74e61SPeter Brune 
412f899ff85SJose E. Roman   Input Parameter:
413f6dfbefdSBarry Smith . linesearch - the `SNESLineSearch` context
41486d74e61SPeter Brune 
41586d74e61SPeter Brune   Output Parameters:
416420bcc1bSBarry Smith + func - [optional] function evaluation routine, see for the calling sequence `SNESLineSearchSetPostCheck()`
41720f4b53cSBarry Smith - ctx  - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`)
41886d74e61SPeter Brune 
41986d74e61SPeter Brune   Level: intermediate
42086d74e61SPeter Brune 
421420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchGetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchPostCheck()`, `SNESLineSearchSetPreCheck()`
42286d74e61SPeter Brune @*/
423d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetPostCheck(SNESLineSearch linesearch, PetscErrorCode (**func)(SNESLineSearch, Vec, Vec, Vec, PetscBool *, PetscBool *, void *), void **ctx)
424d71ae5a4SJacob Faibussowitsch {
4259bd66eb0SPeter Brune   PetscFunctionBegin;
426f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
427f190f2fcSBarry Smith   if (func) *func = linesearch->ops->postcheck;
42886d74e61SPeter Brune   if (ctx) *ctx = linesearch->postcheckctx;
4293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
43086d74e61SPeter Brune }
43186d74e61SPeter Brune 
432f40b411bSPeter Brune /*@
433f1c6b773SPeter Brune   SNESLineSearchPreCheck - Prepares the line search for being applied.
434f40b411bSPeter Brune 
435c3339decSBarry Smith   Logically Collective
436f40b411bSPeter Brune 
437f40b411bSPeter Brune   Input Parameters:
4387b1df9c1SPeter Brune + linesearch - The linesearch instance.
4397b1df9c1SPeter Brune . X          - The current solution
4407b1df9c1SPeter Brune - Y          - The step direction
441f40b411bSPeter Brune 
4422fe279fdSBarry Smith   Output Parameter:
443420bcc1bSBarry Smith . changed - Indicator that the precheck routine has changed `Y`
444f40b411bSPeter Brune 
445f0b84518SBarry Smith   Level: advanced
446f40b411bSPeter Brune 
447f6dfbefdSBarry Smith   Note:
448420bcc1bSBarry Smith   This calls any function provided with `SNESLineSearchSetPreCheck()` and is called automatically inside the line search routines
449f6dfbefdSBarry Smith 
450420bcc1bSBarry Smith   Developer Note:
451420bcc1bSBarry Smith   The use of `PetscObjectGetState()` would eliminate the need for the `changed` argument to be provided
452420bcc1bSBarry Smith 
453420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`, `SNESLineSearchSetPostCheck()`,
454fe8e7dddSPierre Jolivet           `SNESLineSearchGetPostCheck()`
455f40b411bSPeter Brune @*/
456d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch, Vec X, Vec Y, PetscBool *changed)
457d71ae5a4SJacob Faibussowitsch {
458bf7f4e0aSPeter Brune   PetscFunctionBegin;
459bf7f4e0aSPeter Brune   *changed = PETSC_FALSE;
4606b2b7091SBarry Smith   if (linesearch->ops->precheck) {
461dbbe0bcdSBarry Smith     PetscUseTypeMethod(linesearch, precheck, X, Y, changed, linesearch->precheckctx);
46238bcdd5aSPeter Brune     PetscValidLogicalCollectiveBool(linesearch, *changed, 4);
463bf7f4e0aSPeter Brune   }
4643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
465bf7f4e0aSPeter Brune }
466bf7f4e0aSPeter Brune 
467f40b411bSPeter Brune /*@
468ef46b1a6SStefano Zampini   SNESLineSearchPostCheck - Hook to modify step direction or updated solution after a successful linesearch
469f40b411bSPeter Brune 
470c3339decSBarry Smith   Logically Collective
471f40b411bSPeter Brune 
472f40b411bSPeter Brune   Input Parameters:
4737b1df9c1SPeter Brune + linesearch - The line search context
4747b1df9c1SPeter Brune . X          - The last solution
4757b1df9c1SPeter Brune . Y          - The step direction
4766b095a85SStefano Zampini - W          - The updated solution, `W = X - lambda * Y` for some lambda
477f40b411bSPeter Brune 
478f40b411bSPeter Brune   Output Parameters:
4796b095a85SStefano Zampini + changed_Y - Indicator if the direction `Y` has been changed.
480420bcc1bSBarry Smith - changed_W - Indicator if the new candidate solution `W` has been changed.
481f40b411bSPeter Brune 
48220f4b53cSBarry Smith   Level: developer
48320f4b53cSBarry Smith 
484f6dfbefdSBarry Smith   Note:
485420bcc1bSBarry Smith   This calls any function provided with `SNESLineSearchSetPostCheck()` and is called automatically inside the line search routines
486f6dfbefdSBarry Smith 
487420bcc1bSBarry Smith   Developer Note:
488420bcc1bSBarry Smith   The use of `PetscObjectGetState()` would eliminate the need for the `changed_Y` and `changed_W` arguments to be provided
489420bcc1bSBarry Smith 
490420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESGetLineSearch()`, `SNESLineSearchPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPrecheck()`, `SNESLineSearchGetPrecheck()`
491f40b411bSPeter Brune @*/
492d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch, Vec X, Vec Y, Vec W, PetscBool *changed_Y, PetscBool *changed_W)
493d71ae5a4SJacob Faibussowitsch {
494bf7f4e0aSPeter Brune   PetscFunctionBegin;
495bf7f4e0aSPeter Brune   *changed_Y = PETSC_FALSE;
496bf7f4e0aSPeter Brune   *changed_W = PETSC_FALSE;
4976b2b7091SBarry Smith   if (linesearch->ops->postcheck) {
498dbbe0bcdSBarry Smith     PetscUseTypeMethod(linesearch, postcheck, X, Y, W, changed_Y, changed_W, linesearch->postcheckctx);
49938bcdd5aSPeter Brune     PetscValidLogicalCollectiveBool(linesearch, *changed_Y, 5);
50038bcdd5aSPeter Brune     PetscValidLogicalCollectiveBool(linesearch, *changed_W, 6);
50186d74e61SPeter Brune   }
5023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
50386d74e61SPeter Brune }
50486d74e61SPeter Brune 
50586d74e61SPeter Brune /*@C
50686d74e61SPeter Brune   SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration
50786d74e61SPeter Brune 
508c3339decSBarry Smith   Logically Collective
50986d74e61SPeter Brune 
5104165533cSJose E. Roman   Input Parameters:
511420bcc1bSBarry Smith + linesearch - the line search context
51286d74e61SPeter Brune . X          - base state for this step
513907376e6SBarry Smith - ctx        - context for this function
51486d74e61SPeter Brune 
51597bb3fdcSJose E. Roman   Input/Output Parameter:
51697bb3fdcSJose E. Roman . Y - correction, possibly modified
51797bb3fdcSJose E. Roman 
51897bb3fdcSJose E. Roman   Output Parameter:
519420bcc1bSBarry Smith . changed - flag indicating that `Y` was modified
52086d74e61SPeter Brune 
521420bcc1bSBarry Smith   Options Database Keys:
522cd7522eaSPeter Brune + -snes_linesearch_precheck_picard       - activate this routine
523cd7522eaSPeter Brune - -snes_linesearch_precheck_picard_angle - angle
52486d74e61SPeter Brune 
52586d74e61SPeter Brune   Level: advanced
52686d74e61SPeter Brune 
52786d74e61SPeter Brune   Notes:
528f6dfbefdSBarry Smith   This function should be passed to `SNESLineSearchSetPreCheck()`
52986d74e61SPeter Brune 
53086d74e61SPeter Brune   The justification for this method involves the linear convergence of a Picard iteration
53186d74e61SPeter Brune   so the Picard linearization should be provided in place of the "Jacobian". This correction
53286d74e61SPeter Brune   is generally not useful when using a Newton linearization.
53386d74e61SPeter Brune 
534e4094ef1SJacob Faibussowitsch   References:
535f6dfbefdSBarry Smith   . - * - Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.
53686d74e61SPeter Brune 
537420bcc1bSBarry Smith   Developer Note:
538420bcc1bSBarry Smith   The use of `PetscObjectGetState()` would eliminate the need for the `changed` argument to be provided
539420bcc1bSBarry Smith 
540420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESSetPicard()`, `SNESGetLineSearch()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`
54186d74e61SPeter Brune @*/
542d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch, Vec X, Vec Y, PetscBool *changed, void *ctx)
543d71ae5a4SJacob Faibussowitsch {
54486d74e61SPeter Brune   PetscReal   angle = *(PetscReal *)linesearch->precheckctx;
54586d74e61SPeter Brune   Vec         Ylast;
54686d74e61SPeter Brune   PetscScalar dot;
54786d74e61SPeter Brune   PetscInt    iter;
54886d74e61SPeter Brune   PetscReal   ynorm, ylastnorm, theta, angle_radians;
54986d74e61SPeter Brune   SNES        snes;
55086d74e61SPeter Brune 
55186d74e61SPeter Brune   PetscFunctionBegin;
5529566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchGetSNES(linesearch, &snes));
5539566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)snes, "SNESLineSearchPreCheckPicard_Ylast", (PetscObject *)&Ylast));
55486d74e61SPeter Brune   if (!Ylast) {
5559566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(Y, &Ylast));
5569566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompose((PetscObject)snes, "SNESLineSearchPreCheckPicard_Ylast", (PetscObject)Ylast));
5579566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)Ylast));
55886d74e61SPeter Brune   }
5599566063dSJacob Faibussowitsch   PetscCall(SNESGetIterationNumber(snes, &iter));
56086d74e61SPeter Brune   if (iter < 2) {
5619566063dSJacob Faibussowitsch     PetscCall(VecCopy(Y, Ylast));
56286d74e61SPeter Brune     *changed = PETSC_FALSE;
5633ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
56486d74e61SPeter Brune   }
56586d74e61SPeter Brune 
5669566063dSJacob Faibussowitsch   PetscCall(VecDot(Y, Ylast, &dot));
5679566063dSJacob Faibussowitsch   PetscCall(VecNorm(Y, NORM_2, &ynorm));
5689566063dSJacob Faibussowitsch   PetscCall(VecNorm(Ylast, NORM_2, &ylastnorm));
56986d74e61SPeter Brune   /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
570255453a1SBarry Smith   theta         = PetscAcosReal((PetscReal)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm), -1.0, 1.0));
57186d74e61SPeter Brune   angle_radians = angle * PETSC_PI / 180.;
57286d74e61SPeter Brune   if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
57386d74e61SPeter Brune     /* Modify the step Y */
57486d74e61SPeter Brune     PetscReal alpha, ydiffnorm;
5759566063dSJacob Faibussowitsch     PetscCall(VecAXPY(Ylast, -1.0, Y));
5769566063dSJacob Faibussowitsch     PetscCall(VecNorm(Ylast, NORM_2, &ydiffnorm));
577f85e2ce2SBarry Smith     alpha = (ydiffnorm > .001 * ylastnorm) ? ylastnorm / ydiffnorm : 1000.0;
5789566063dSJacob Faibussowitsch     PetscCall(VecCopy(Y, Ylast));
5799566063dSJacob Faibussowitsch     PetscCall(VecScale(Y, alpha));
5809566063dSJacob 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));
581a47ec85fSBarry Smith     *changed = PETSC_TRUE;
58286d74e61SPeter Brune   } else {
5839566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Angle %14.12e degrees exceeds threshold %14.12e, no correction applied\n", (double)(theta * 180. / PETSC_PI), (double)angle));
5849566063dSJacob Faibussowitsch     PetscCall(VecCopy(Y, Ylast));
58586d74e61SPeter Brune     *changed = PETSC_FALSE;
586bf7f4e0aSPeter Brune   }
5873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
588bf7f4e0aSPeter Brune }
589bf7f4e0aSPeter Brune 
590f40b411bSPeter Brune /*@
591cd7522eaSPeter Brune   SNESLineSearchApply - Computes the line-search update.
592f40b411bSPeter Brune 
593c3339decSBarry Smith   Collective
594f40b411bSPeter Brune 
5956b095a85SStefano Zampini   Input Parameter:
5966b095a85SStefano Zampini . linesearch - The line search context
597f40b411bSPeter Brune 
5986b867d5aSJose E. Roman   Input/Output Parameters:
5996b867d5aSJose E. Roman + X     - The current solution, on output the new solution
600420bcc1bSBarry Smith . F     - The current function value, on output the new function value at the solution value `X`
601*1bd63e3eSSatish Balay . fnorm - The current norm of `F`, on output the new norm of `F`
6026b095a85SStefano Zampini - Y     - The current search direction, on output the direction determined by the linesearch, i.e. Xnew = Xold - lambda*Y
603f40b411bSPeter Brune 
604cd7522eaSPeter Brune   Options Database Keys:
6050b00b554SBarry Smith + -snes_linesearch_type                - basic (or equivalently none), bt, l2, cp, nleqerr, shell
606dcf2fd19SBarry Smith . -snes_linesearch_monitor [:filename] - Print progress of line searches
6071fe24845SBarry Smith . -snes_linesearch_damping             - The linesearch damping parameter, default is 1.0 (no damping)
6081fe24845SBarry Smith . -snes_linesearch_norms               - Turn on/off the linesearch norms computation (SNESLineSearchSetComputeNorms())
6093c7d6663SPeter Brune . -snes_linesearch_keeplambda          - Keep the previous search length as the initial guess
6103c7d6663SPeter Brune - -snes_linesearch_max_it              - The number of iterations for iterative line searches
611cd7522eaSPeter Brune 
612e4094ef1SJacob Faibussowitsch   Level: intermediate
61320f4b53cSBarry Smith 
614cd7522eaSPeter Brune   Notes:
615f6dfbefdSBarry Smith   This is typically called from within a `SNESSolve()` implementation in order to
616f6dfbefdSBarry Smith   help with convergence of the nonlinear method.  Various `SNES` types use line searches
617cd7522eaSPeter Brune   in different ways, but the overarching theme is that a line search is used to determine
618cd7522eaSPeter Brune   an optimal damping parameter of a step at each iteration of the method.  Each
619f6dfbefdSBarry Smith   application of the line search may invoke `SNESComputeFunction()` several times, and
620cd7522eaSPeter Brune   therefore may be fairly expensive.
621cd7522eaSPeter Brune 
622*1bd63e3eSSatish Balay .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchCreate()`, `SNESLineSearchGetLambda()`, `SNESLineSearchPreCheck()`, `SNESLineSearchPostCheck()`, `SNESSolve()`, `SNESComputeFunction()`, `SNESLineSearchSetComputeNorms()`,
623db781477SPatrick Sanan           `SNESLineSearchType`, `SNESLineSearchSetType()`
624f40b411bSPeter Brune @*/
625d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal *fnorm, Vec Y)
626d71ae5a4SJacob Faibussowitsch {
627bf388a1fSBarry Smith   PetscFunctionBegin;
628f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
629bf7f4e0aSPeter Brune   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
630bf7f4e0aSPeter Brune   PetscValidHeaderSpecific(F, VEC_CLASSID, 3);
631064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(Y, VEC_CLASSID, 5);
632bf7f4e0aSPeter Brune 
633422a814eSBarry Smith   linesearch->result = SNES_LINESEARCH_SUCCEEDED;
634bf7f4e0aSPeter Brune 
635bf7f4e0aSPeter Brune   linesearch->vec_sol    = X;
636bf7f4e0aSPeter Brune   linesearch->vec_update = Y;
637bf7f4e0aSPeter Brune   linesearch->vec_func   = F;
638bf7f4e0aSPeter Brune 
6399566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchSetUp(linesearch));
640bf7f4e0aSPeter Brune 
641f5af7f23SKarl Rupp   if (!linesearch->keeplambda) linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
642bf7f4e0aSPeter Brune 
643f5af7f23SKarl Rupp   if (fnorm) linesearch->fnorm = *fnorm;
64448a46eb9SPierre Jolivet   else PetscCall(VecNorm(F, NORM_2, &linesearch->fnorm));
645bf7f4e0aSPeter Brune 
6469566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(SNESLINESEARCH_Apply, linesearch, X, F, Y));
647bf7f4e0aSPeter Brune 
648dbbe0bcdSBarry Smith   PetscUseTypeMethod(linesearch, apply);
649bf7f4e0aSPeter Brune 
6509566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(SNESLINESEARCH_Apply, linesearch, X, F, Y));
651bf7f4e0aSPeter Brune 
652f5af7f23SKarl Rupp   if (fnorm) *fnorm = linesearch->fnorm;
6533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
654bf7f4e0aSPeter Brune }
655bf7f4e0aSPeter Brune 
656f40b411bSPeter Brune /*@
657f1c6b773SPeter Brune   SNESLineSearchDestroy - Destroys the line search instance.
658f40b411bSPeter Brune 
659c3339decSBarry Smith   Collective
660f40b411bSPeter Brune 
6612fe279fdSBarry Smith   Input Parameter:
6628e557f58SPeter Brune . linesearch - The line search context
663f40b411bSPeter Brune 
66484238204SBarry Smith   Level: developer
665f40b411bSPeter Brune 
666420bcc1bSBarry Smith   Note:
667420bcc1bSBarry Smith   The line search in `SNES` is automatically called on `SNESDestroy()` so this call is rarely needed
668420bcc1bSBarry Smith 
669420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchCreate()`, `SNESLineSearchReset()`, `SNESDestroy()`
670f40b411bSPeter Brune @*/
671d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchDestroy(SNESLineSearch *linesearch)
672d71ae5a4SJacob Faibussowitsch {
673bf7f4e0aSPeter Brune   PetscFunctionBegin;
6743ba16761SJacob Faibussowitsch   if (!*linesearch) PetscFunctionReturn(PETSC_SUCCESS);
675f1c6b773SPeter Brune   PetscValidHeaderSpecific((*linesearch), SNESLINESEARCH_CLASSID, 1);
6769371c9d4SSatish Balay   if (--((PetscObject)(*linesearch))->refct > 0) {
6779371c9d4SSatish Balay     *linesearch = NULL;
6783ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6799371c9d4SSatish Balay   }
6809566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsViewOff((PetscObject)*linesearch));
6819566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchReset(*linesearch));
6823ba16761SJacob Faibussowitsch   PetscTryTypeMethod(*linesearch, destroy);
6839566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*linesearch)->monitor));
6849566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchMonitorCancel((*linesearch)));
6859566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(linesearch));
6863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
687bf7f4e0aSPeter Brune }
688bf7f4e0aSPeter Brune 
689f40b411bSPeter Brune /*@
690dcf2fd19SBarry Smith   SNESLineSearchSetDefaultMonitor - Turns on/off printing useful information and debugging output about the line search.
691bf7f4e0aSPeter Brune 
692c3339decSBarry Smith   Logically Collective
693f6dfbefdSBarry Smith 
694bf7f4e0aSPeter Brune   Input Parameters:
695dcf2fd19SBarry Smith + linesearch - the linesearch object
69620f4b53cSBarry Smith - viewer     - an `PETSCVIEWERASCII` `PetscViewer` or `NULL` to turn off monitor
697bf7f4e0aSPeter Brune 
698f6dfbefdSBarry Smith   Options Database Key:
699dcf2fd19SBarry Smith . -snes_linesearch_monitor [:filename] - enables the monitor
700bf7f4e0aSPeter Brune 
701bf7f4e0aSPeter Brune   Level: intermediate
702bf7f4e0aSPeter Brune 
703e4094ef1SJacob Faibussowitsch   Developer Notes:
704f6dfbefdSBarry Smith   This monitor is implemented differently than the other line search monitors that are set with
705f6dfbefdSBarry Smith   `SNESLineSearchMonitorSet()` since it is called in many locations of the line search routines to display aspects of the
706d12e167eSBarry Smith   line search that are not visible to the other monitors.
707dcf2fd19SBarry Smith 
708420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `PETSCVIEWERASCII`, `SNESGetLineSearch()`, `SNESLineSearchGetDefaultMonitor()`, `PetscViewer`, `SNESLineSearchSetMonitor()`,
709f6dfbefdSBarry Smith           `SNESLineSearchMonitorSetFromOptions()`
710bf7f4e0aSPeter Brune @*/
711d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetDefaultMonitor(SNESLineSearch linesearch, PetscViewer viewer)
712d71ae5a4SJacob Faibussowitsch {
713bf7f4e0aSPeter Brune   PetscFunctionBegin;
7149566063dSJacob Faibussowitsch   if (viewer) PetscCall(PetscObjectReference((PetscObject)viewer));
7159566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&linesearch->monitor));
716dcf2fd19SBarry Smith   linesearch->monitor = viewer;
7173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
718bf7f4e0aSPeter Brune }
719bf7f4e0aSPeter Brune 
720f40b411bSPeter Brune /*@
721420bcc1bSBarry Smith   SNESLineSearchGetDefaultMonitor - Gets the `PetscViewer` instance for the default line search monitor that is turned on with `SNESLineSearchSetDefaultMonitor()`
722f6dfbefdSBarry Smith 
723c3339decSBarry Smith   Logically Collective
7246a388c36SPeter Brune 
725f190f2fcSBarry Smith   Input Parameter:
726420bcc1bSBarry Smith . linesearch - the line search context
727f40b411bSPeter Brune 
728f190f2fcSBarry Smith   Output Parameter:
7298e557f58SPeter Brune . monitor - monitor context
730f40b411bSPeter Brune 
731f40b411bSPeter Brune   Level: intermediate
732f40b411bSPeter Brune 
733420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`, `SNESLineSearchSetDefaultMonitor()`, `PetscViewer`
734f40b411bSPeter Brune @*/
735d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetDefaultMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
736d71ae5a4SJacob Faibussowitsch {
7376a388c36SPeter Brune   PetscFunctionBegin;
738f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
7396a388c36SPeter Brune   *monitor = linesearch->monitor;
7403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7416a388c36SPeter Brune }
7426a388c36SPeter Brune 
743dcf2fd19SBarry Smith /*@C
744420bcc1bSBarry Smith   SNESLineSearchMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated in the options database
745dcf2fd19SBarry Smith 
746c3339decSBarry Smith   Collective
747dcf2fd19SBarry Smith 
748dcf2fd19SBarry Smith   Input Parameters:
749420bcc1bSBarry Smith + ls           - `SNESLineSearch` object to monitor
750420bcc1bSBarry Smith . name         - the monitor type
751dcf2fd19SBarry Smith . help         - message indicating what monitoring is done
752dcf2fd19SBarry Smith . manual       - manual page for the monitor
753dcf2fd19SBarry Smith . monitor      - the monitor function
754f6dfbefdSBarry 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`
755dcf2fd19SBarry Smith 
756420bcc1bSBarry Smith   Calling sequence of `monitor`:
757420bcc1bSBarry Smith + ls - `SNESLineSearch` object being monitored
758420bcc1bSBarry Smith - vf - a `PetscViewerAndFormat` struct that provides the `PetscViewer` and `PetscViewerFormat` being used
759dcf2fd19SBarry Smith 
760420bcc1bSBarry Smith   Calling sequence of `monitorsetup`:
761420bcc1bSBarry Smith + ls - `SNESLineSearch` object being monitored
762420bcc1bSBarry Smith - vf - a `PetscViewerAndFormat` struct that provides the `PetscViewer` and `PetscViewerFormat` being used
763420bcc1bSBarry Smith 
764420bcc1bSBarry Smith   Level: advanced
765420bcc1bSBarry Smith 
766420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchSetMonitor()`, `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
767db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
768e4094ef1SJacob Faibussowitsch           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
769db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
770c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
771db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
772db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
773dcf2fd19SBarry Smith @*/
774420bcc1bSBarry Smith PetscErrorCode SNESLineSearchMonitorSetFromOptions(SNESLineSearch ls, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(SNESLineSearch ls, PetscViewerAndFormat *vf), PetscErrorCode (*monitorsetup)(SNESLineSearch ls, PetscViewerAndFormat *vf))
775d71ae5a4SJacob Faibussowitsch {
776dcf2fd19SBarry Smith   PetscViewer       viewer;
777dcf2fd19SBarry Smith   PetscViewerFormat format;
778dcf2fd19SBarry Smith   PetscBool         flg;
779dcf2fd19SBarry Smith 
780dcf2fd19SBarry Smith   PetscFunctionBegin;
7819566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ls), ((PetscObject)ls)->options, ((PetscObject)ls)->prefix, name, &viewer, &format, &flg));
782dcf2fd19SBarry Smith   if (flg) {
783d12e167eSBarry Smith     PetscViewerAndFormat *vf;
7849566063dSJacob Faibussowitsch     PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf));
7859566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)viewer));
7861baa6e33SBarry Smith     if (monitorsetup) PetscCall((*monitorsetup)(ls, vf));
7879566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchMonitorSet(ls, (PetscErrorCode(*)(SNESLineSearch, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy));
788dcf2fd19SBarry Smith   }
7893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
790dcf2fd19SBarry Smith }
791dcf2fd19SBarry Smith 
792f40b411bSPeter Brune /*@
793f1c6b773SPeter Brune   SNESLineSearchSetFromOptions - Sets options for the line search
794f40b411bSPeter Brune 
795c3339decSBarry Smith   Logically Collective
796f6dfbefdSBarry Smith 
797f899ff85SJose E. Roman   Input Parameter:
798420bcc1bSBarry Smith . linesearch - a `SNESLineSearch` line search context
799f40b411bSPeter Brune 
800f40b411bSPeter Brune   Options Database Keys:
8010b00b554SBarry Smith + -snes_linesearch_type <type>                                      - basic (or equivalently none), bt, l2, cp, nleqerr, shell
8023c7d6663SPeter Brune . -snes_linesearch_order <order>                                    - 1, 2, 3.  Most types only support certain orders (bt supports 2 or 3)
803f6dfbefdSBarry Smith . -snes_linesearch_norms                                            - Turn on/off the linesearch norms for the basic linesearch typem (`SNESLineSearchSetComputeNorms()`)
80471eef1aeSPeter Brune . -snes_linesearch_minlambda                                        - The minimum step length
8051a9b3a06SPeter Brune . -snes_linesearch_maxstep                                          - The maximum step size
8061a9b3a06SPeter Brune . -snes_linesearch_rtol                                             - Relative tolerance for iterative line searches
8071a9b3a06SPeter Brune . -snes_linesearch_atol                                             - Absolute tolerance for iterative line searches
8081a9b3a06SPeter Brune . -snes_linesearch_ltol                                             - Change in lambda tolerance for iterative line searches
8091a9b3a06SPeter Brune . -snes_linesearch_max_it                                           - The number of iterations for iterative line searches
810dcf2fd19SBarry Smith . -snes_linesearch_monitor [:filename]                              - Print progress of line searches
811dcf2fd19SBarry Smith . -snes_linesearch_monitor_solution_update [viewer:filename:format] - view each update tried by line search routine
8128e557f58SPeter Brune . -snes_linesearch_damping                                          - The linesearch damping parameter
813cd7522eaSPeter Brune . -snes_linesearch_keeplambda                                       - Keep the previous search length as the initial guess.
8141a9b3a06SPeter Brune . -snes_linesearch_precheck_picard                                  - Use precheck that speeds up convergence of picard method
815d8d34be6SBarry Smith - -snes_linesearch_precheck_picard_angle                            - Angle used in Picard precheck method
816f40b411bSPeter Brune 
817f40b411bSPeter Brune   Level: intermediate
818f40b411bSPeter Brune 
819420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchCreate()`, `SNESLineSearchSetOrder()`, `SNESLineSearchSetType()`, `SNESLineSearchSetTolerances()`, `SNESLineSearchSetDamping()`, `SNESLineSearchPreCheckPicard()`,
820db781477SPatrick Sanan           `SNESLineSearchType`, `SNESLineSearchSetComputeNorms()`
821f40b411bSPeter Brune @*/
822d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch)
823d71ae5a4SJacob Faibussowitsch {
8241a4f838cSPeter Brune   const char *deft = SNESLINESEARCHBASIC;
825bf7f4e0aSPeter Brune   char        type[256];
826bf7f4e0aSPeter Brune   PetscBool   flg, set;
827dcf2fd19SBarry Smith   PetscViewer viewer;
828bf388a1fSBarry Smith 
829bf7f4e0aSPeter Brune   PetscFunctionBegin;
8309566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchRegisterAll());
831bf7f4e0aSPeter Brune 
832d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)linesearch);
833f5af7f23SKarl Rupp   if (((PetscObject)linesearch)->type_name) deft = ((PetscObject)linesearch)->type_name;
8349566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-snes_linesearch_type", "Linesearch type", "SNESLineSearchSetType", SNESLineSearchList, deft, type, 256, &flg));
835bf7f4e0aSPeter Brune   if (flg) {
8369566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetType(linesearch, type));
837bf7f4e0aSPeter Brune   } else if (!((PetscObject)linesearch)->type_name) {
8389566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetType(linesearch, deft));
839bf7f4e0aSPeter Brune   }
840bf7f4e0aSPeter Brune 
8419566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)linesearch), ((PetscObject)linesearch)->options, ((PetscObject)linesearch)->prefix, "-snes_linesearch_monitor", &viewer, NULL, &set));
842dcf2fd19SBarry Smith   if (set) {
8439566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetDefaultMonitor(linesearch, viewer));
8449566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
845dcf2fd19SBarry Smith   }
8469566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchMonitorSetFromOptions(linesearch, "-snes_linesearch_monitor_solution_update", "View correction at each iteration", "SNESLineSearchMonitorSolutionUpdate", SNESLineSearchMonitorSolutionUpdate, NULL));
847bf7f4e0aSPeter Brune 
8481a9b3a06SPeter Brune   /* tolerances */
8499566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_minlambda", "Minimum step length", "SNESLineSearchSetTolerances", linesearch->steptol, &linesearch->steptol, NULL));
8509566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_maxstep", "Maximum step size", "SNESLineSearchSetTolerances", linesearch->maxstep, &linesearch->maxstep, NULL));
8519566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_rtol", "Relative tolerance for iterative line search", "SNESLineSearchSetTolerances", linesearch->rtol, &linesearch->rtol, NULL));
8529566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_atol", "Absolute tolerance for iterative line search", "SNESLineSearchSetTolerances", linesearch->atol, &linesearch->atol, NULL));
8539566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_ltol", "Change in lambda tolerance for iterative line search", "SNESLineSearchSetTolerances", linesearch->ltol, &linesearch->ltol, NULL));
8549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_linesearch_max_it", "Maximum iterations for iterative line searches", "SNESLineSearchSetTolerances", linesearch->max_its, &linesearch->max_its, NULL));
8557a35526eSPeter Brune 
8561a9b3a06SPeter Brune   /* damping parameters */
8579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_linesearch_damping", "Line search damping and initial step guess", "SNESLineSearchSetDamping", linesearch->damping, &linesearch->damping, NULL));
8581a9b3a06SPeter Brune 
8599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_linesearch_keeplambda", "Use previous lambda as damping", "SNESLineSearchSetKeepLambda", linesearch->keeplambda, &linesearch->keeplambda, NULL));
8601a9b3a06SPeter Brune 
8611a9b3a06SPeter Brune   /* precheck */
8629566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_linesearch_precheck_picard", "Use a correction that sometimes improves convergence of Picard iteration", "SNESLineSearchPreCheckPicard", flg, &flg, &set));
8637a35526eSPeter Brune   if (set) {
8647a35526eSPeter Brune     if (flg) {
8657a35526eSPeter Brune       linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
866f5af7f23SKarl Rupp 
867d0609cedSBarry 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));
8689566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchSetPreCheck(linesearch, SNESLineSearchPreCheckPicard, &linesearch->precheck_picard_angle));
8697a35526eSPeter Brune     } else {
8709566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchSetPreCheck(linesearch, NULL, NULL));
8717a35526eSPeter Brune     }
8727a35526eSPeter Brune   }
8739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_linesearch_order", "Order of approximation used in the line search", "SNESLineSearchSetOrder", linesearch->order, &linesearch->order, NULL));
8749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_linesearch_norms", "Compute final norms in line search", "SNESLineSearchSetComputeNorms", linesearch->norms, &linesearch->norms, NULL));
8757a35526eSPeter Brune 
876dbbe0bcdSBarry Smith   PetscTryTypeMethod(linesearch, setfromoptions, PetscOptionsObject);
8775a9b6599SPeter Brune 
878dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)linesearch, PetscOptionsObject));
879d0609cedSBarry Smith   PetscOptionsEnd();
8803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
881bf7f4e0aSPeter Brune }
882bf7f4e0aSPeter Brune 
883f40b411bSPeter Brune /*@
884f190f2fcSBarry Smith   SNESLineSearchView - Prints useful information about the line search
885f40b411bSPeter Brune 
88620f4b53cSBarry Smith   Logically Collective
88720f4b53cSBarry Smith 
888f40b411bSPeter Brune   Input Parameters:
8892fe279fdSBarry Smith + linesearch - line search context
890420bcc1bSBarry Smith - viewer     - the `PetscViewer` to display the line search information to
891f40b411bSPeter Brune 
892f40b411bSPeter Brune   Level: intermediate
893f40b411bSPeter Brune 
894420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `PetscViewer`, `SNESLineSearchCreate()`
895f40b411bSPeter Brune @*/
896d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch, PetscViewer viewer)
897d71ae5a4SJacob Faibussowitsch {
8987f1410a3SPeter Brune   PetscBool iascii;
899bf388a1fSBarry Smith 
900bf7f4e0aSPeter Brune   PetscFunctionBegin;
9017f1410a3SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
90248a46eb9SPierre Jolivet   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)linesearch), &viewer));
9037f1410a3SPeter Brune   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
9047f1410a3SPeter Brune   PetscCheckSameComm(linesearch, 1, viewer, 2);
905f40b411bSPeter Brune 
9069566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
9077f1410a3SPeter Brune   if (iascii) {
9089566063dSJacob Faibussowitsch     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)linesearch, viewer));
9099566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
910dbbe0bcdSBarry Smith     PetscTryTypeMethod(linesearch, view, viewer);
9119566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
9129566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  maxstep=%e, minlambda=%e\n", (double)linesearch->maxstep, (double)linesearch->steptol));
9139566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  tolerances: relative=%e, absolute=%e, lambda=%e\n", (double)linesearch->rtol, (double)linesearch->atol, (double)linesearch->ltol));
91463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum iterations=%" PetscInt_FMT "\n", linesearch->max_its));
9156b2b7091SBarry Smith     if (linesearch->ops->precheck) {
9166b2b7091SBarry Smith       if (linesearch->ops->precheck == SNESLineSearchPreCheckPicard) {
91763a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  using precheck step to speed up Picard convergence\n"));
9187f1410a3SPeter Brune       } else {
91963a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  using user-defined precheck step\n"));
9207f1410a3SPeter Brune       }
9217f1410a3SPeter Brune     }
92248a46eb9SPierre Jolivet     if (linesearch->ops->postcheck) PetscCall(PetscViewerASCIIPrintf(viewer, "  using user-defined postcheck step\n"));
9237f1410a3SPeter Brune   }
9243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
925bf7f4e0aSPeter Brune }
926bf7f4e0aSPeter Brune 
927ea5d4fccSPeter Brune /*@C
928420bcc1bSBarry Smith   SNESLineSearchGetType - Gets the `SNESLinesearchType` of a `SNESLineSearch`
929a80ff896SJed Brown 
930c3339decSBarry Smith   Logically Collective
931a80ff896SJed Brown 
9322fe279fdSBarry Smith   Input Parameter:
933420bcc1bSBarry Smith . linesearch - the line search context
934a80ff896SJed Brown 
9352fe279fdSBarry Smith   Output Parameter:
9362fe279fdSBarry Smith . type - The type of line search, or `NULL` if not set
937a80ff896SJed Brown 
938a80ff896SJed Brown   Level: intermediate
939a80ff896SJed Brown 
940420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchType`, `SNESLineSearchCreate()`, `SNESLineSearchSetFromOptions()`, `SNESLineSearchSetType()`
941a80ff896SJed Brown @*/
942d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetType(SNESLineSearch linesearch, SNESLineSearchType *type)
943d71ae5a4SJacob Faibussowitsch {
944a80ff896SJed Brown   PetscFunctionBegin;
945a80ff896SJed Brown   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
9464f572ea9SToby Isaac   PetscAssertPointer(type, 2);
947a80ff896SJed Brown   *type = ((PetscObject)linesearch)->type_name;
9483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
949a80ff896SJed Brown }
950a80ff896SJed Brown 
951a80ff896SJed Brown /*@C
952420bcc1bSBarry Smith   SNESLineSearchSetType - Sets the `SNESLinesearchType` of a `SNESLineSearch`
953f40b411bSPeter Brune 
954c3339decSBarry Smith   Logically Collective
955f190f2fcSBarry Smith 
956f40b411bSPeter Brune   Input Parameters:
957420bcc1bSBarry Smith + linesearch - the line search context
958ceaaa498SBarry Smith - type       - The type of line search to be used, see `SNESLineSearchType`
9591fe24845SBarry Smith 
9603c7db156SBarry Smith   Options Database Key:
9610b00b554SBarry Smith . -snes_linesearch_type <type> - basic (or equivalently none), bt, l2, cp, nleqerr, shell
962cd7522eaSPeter Brune 
963f40b411bSPeter Brune   Level: intermediate
964f40b411bSPeter Brune 
965420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchType`, `SNESLineSearchCreate()`, `SNESLineSearchSetFromOptions()`, `SNESLineSearchGetType()`
966f40b411bSPeter Brune @*/
967d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, SNESLineSearchType type)
968d71ae5a4SJacob Faibussowitsch {
969bf7f4e0aSPeter Brune   PetscBool match;
9705f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(SNESLineSearch);
971bf7f4e0aSPeter Brune 
972bf7f4e0aSPeter Brune   PetscFunctionBegin;
973f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
9744f572ea9SToby Isaac   PetscAssertPointer(type, 2);
975bf7f4e0aSPeter Brune 
9769566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)linesearch, type, &match));
9773ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
978bf7f4e0aSPeter Brune 
9799566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(SNESLineSearchList, type, &r));
9806adde796SStefano Zampini   PetscCheck(r, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested Line Search type %s", type);
981bf7f4e0aSPeter Brune   /* Destroy the previous private line search context */
982bf7f4e0aSPeter Brune   if (linesearch->ops->destroy) {
9839566063dSJacob Faibussowitsch     PetscCall((*(linesearch)->ops->destroy)(linesearch));
9840298fd71SBarry Smith     linesearch->ops->destroy = NULL;
985bf7f4e0aSPeter Brune   }
986f1c6b773SPeter Brune   /* Reinitialize function pointers in SNESLineSearchOps structure */
9879e5d0892SLisandro Dalcin   linesearch->ops->apply          = NULL;
9889e5d0892SLisandro Dalcin   linesearch->ops->view           = NULL;
9899e5d0892SLisandro Dalcin   linesearch->ops->setfromoptions = NULL;
9909e5d0892SLisandro Dalcin   linesearch->ops->destroy        = NULL;
991bf7f4e0aSPeter Brune 
9929566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)linesearch, type));
9939566063dSJacob Faibussowitsch   PetscCall((*r)(linesearch));
9943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
995bf7f4e0aSPeter Brune }
996bf7f4e0aSPeter Brune 
997f40b411bSPeter Brune /*@
998f6dfbefdSBarry Smith   SNESLineSearchSetSNES - Sets the `SNES` for the linesearch for function evaluation.
999f40b411bSPeter Brune 
1000f40b411bSPeter Brune   Input Parameters:
1001420bcc1bSBarry Smith + linesearch - the line search context
1002420bcc1bSBarry Smith - snes       - The `SNES` instance
1003f40b411bSPeter Brune 
100478bcb3b5SPeter Brune   Level: developer
100578bcb3b5SPeter Brune 
1006f6dfbefdSBarry Smith   Note:
1007f190f2fcSBarry Smith   This happens automatically when the line search is obtained/created with
1008f6dfbefdSBarry Smith   `SNESGetLineSearch()`.  This routine is therefore mainly called within `SNES`
100978bcb3b5SPeter Brune   implementations.
1010f40b411bSPeter Brune 
1011420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchGetSNES()`, `SNESLineSearchSetVecs()`
1012f40b411bSPeter Brune @*/
1013d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes)
1014d71ae5a4SJacob Faibussowitsch {
1015bf7f4e0aSPeter Brune   PetscFunctionBegin;
1016f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1017bf7f4e0aSPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 2);
1018bf7f4e0aSPeter Brune   linesearch->snes = snes;
10193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1020bf7f4e0aSPeter Brune }
1021bf7f4e0aSPeter Brune 
1022f40b411bSPeter Brune /*@
1023f6dfbefdSBarry Smith   SNESLineSearchGetSNES - Gets the `SNES` instance associated with the line search.
1024f6dfbefdSBarry Smith 
1025f6dfbefdSBarry Smith   Not Collective
1026f40b411bSPeter Brune 
10272fe279fdSBarry Smith   Input Parameter:
1028420bcc1bSBarry Smith . linesearch - the line search context
1029f40b411bSPeter Brune 
10302fe279fdSBarry Smith   Output Parameter:
10312fe279fdSBarry Smith . snes - The `SNES` instance
1032f40b411bSPeter Brune 
10338141a3b9SPeter Brune   Level: developer
1034f40b411bSPeter Brune 
1035420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESType`, `SNESLineSearchSetVecs()`
1036f40b411bSPeter Brune @*/
1037d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes)
1038d71ae5a4SJacob Faibussowitsch {
1039bf7f4e0aSPeter Brune   PetscFunctionBegin;
1040f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
10414f572ea9SToby Isaac   PetscAssertPointer(snes, 2);
1042bf7f4e0aSPeter Brune   *snes = linesearch->snes;
10433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1044bf7f4e0aSPeter Brune }
1045bf7f4e0aSPeter Brune 
1046f40b411bSPeter Brune /*@
1047420bcc1bSBarry Smith   SNESLineSearchGetLambda - Gets the last line search steplength used
1048f40b411bSPeter Brune 
1049f6dfbefdSBarry Smith   Not Collective
1050f6dfbefdSBarry Smith 
10512fe279fdSBarry Smith   Input Parameter:
1052420bcc1bSBarry Smith . linesearch - the line search context
1053f40b411bSPeter Brune 
10542fe279fdSBarry Smith   Output Parameter:
1055f6dfbefdSBarry Smith . lambda - The last steplength computed during `SNESLineSearchApply()`
1056f40b411bSPeter Brune 
105778bcb3b5SPeter Brune   Level: advanced
105878bcb3b5SPeter Brune 
1059f6dfbefdSBarry Smith   Note:
10608e557f58SPeter Brune   This is useful in methods where the solver is ill-scaled and
106178bcb3b5SPeter Brune   requires some adaptive notion of the difference in scale between the
1062f6dfbefdSBarry Smith   solution and the function.  For instance, `SNESQN` may be scaled by the
106378bcb3b5SPeter Brune   line search lambda using the argument -snes_qn_scaling ls.
106478bcb3b5SPeter Brune 
1065420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchSetLambda()`, `SNESLineSearchGetDamping()`, `SNESLineSearchApply()`
1066f40b411bSPeter Brune @*/
1067d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetLambda(SNESLineSearch linesearch, PetscReal *lambda)
1068d71ae5a4SJacob Faibussowitsch {
10696a388c36SPeter Brune   PetscFunctionBegin;
1070f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
10714f572ea9SToby Isaac   PetscAssertPointer(lambda, 2);
10726a388c36SPeter Brune   *lambda = linesearch->lambda;
10733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10746a388c36SPeter Brune }
10756a388c36SPeter Brune 
1076f40b411bSPeter Brune /*@
1077f6dfbefdSBarry Smith   SNESLineSearchSetLambda - Sets the line search steplength
1078f40b411bSPeter Brune 
1079f40b411bSPeter Brune   Input Parameters:
10808e557f58SPeter Brune + linesearch - line search context
1081420bcc1bSBarry Smith - lambda     - The steplength to use
1082f40b411bSPeter Brune 
108320f4b53cSBarry Smith   Level: advanced
108420f4b53cSBarry Smith 
1085f6dfbefdSBarry Smith   Note:
1086f6dfbefdSBarry Smith   This routine is typically used within implementations of `SNESLineSearchApply()`
1087f6dfbefdSBarry Smith   to set the final steplength.  This routine (and `SNESLineSearchGetLambda()`) were
1088cd7522eaSPeter Brune   added in order to facilitate Quasi-Newton methods that use the previous steplength
1089cd7522eaSPeter Brune   as an inner scaling parameter.
1090cd7522eaSPeter Brune 
1091420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchGetLambda()`
1092f40b411bSPeter Brune @*/
1093d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
1094d71ae5a4SJacob Faibussowitsch {
10956a388c36SPeter Brune   PetscFunctionBegin;
1096f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
10976a388c36SPeter Brune   linesearch->lambda = lambda;
10983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10996a388c36SPeter Brune }
11006a388c36SPeter Brune 
1101f40b411bSPeter Brune /*@
1102ceaaa498SBarry Smith   SNESLineSearchGetTolerances - Gets the tolerances for the line search.
1103f40b411bSPeter Brune 
1104f6dfbefdSBarry Smith   Not Collective
1105f6dfbefdSBarry Smith 
1106f899ff85SJose E. Roman   Input Parameter:
1107420bcc1bSBarry Smith . linesearch - the line search context
1108f40b411bSPeter Brune 
1109f40b411bSPeter Brune   Output Parameters:
1110b13b64c2SBarry Smith + steptol - The minimum steplength
11116cc8e53bSPeter Brune . maxstep - The maximum steplength
1112516fe3c3SPeter Brune . rtol    - The relative tolerance for iterative line searches
1113516fe3c3SPeter Brune . atol    - The absolute tolerance for iterative line searches
1114516fe3c3SPeter Brune . ltol    - The change in lambda tolerance for iterative line searches
1115e4094ef1SJacob Faibussowitsch - max_its - The maximum number of iterations of the line search
1116f40b411bSPeter Brune 
111778bcb3b5SPeter Brune   Level: intermediate
111878bcb3b5SPeter Brune 
1119f6dfbefdSBarry Smith   Note:
112078bcb3b5SPeter Brune   Different line searches may implement these parameters slightly differently as
11213c7d6663SPeter Brune   the type requires.
1122516fe3c3SPeter Brune 
1123420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchSetTolerances()`
1124f40b411bSPeter Brune @*/
1125d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetTolerances(SNESLineSearch linesearch, PetscReal *steptol, PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
1126d71ae5a4SJacob Faibussowitsch {
11276a388c36SPeter Brune   PetscFunctionBegin;
1128f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1129516fe3c3SPeter Brune   if (steptol) {
11304f572ea9SToby Isaac     PetscAssertPointer(steptol, 2);
11316a388c36SPeter Brune     *steptol = linesearch->steptol;
1132516fe3c3SPeter Brune   }
1133516fe3c3SPeter Brune   if (maxstep) {
11344f572ea9SToby Isaac     PetscAssertPointer(maxstep, 3);
1135b13b64c2SBarry Smith     *maxstep = linesearch->maxstep;
1136516fe3c3SPeter Brune   }
1137516fe3c3SPeter Brune   if (rtol) {
11384f572ea9SToby Isaac     PetscAssertPointer(rtol, 4);
1139516fe3c3SPeter Brune     *rtol = linesearch->rtol;
1140516fe3c3SPeter Brune   }
1141516fe3c3SPeter Brune   if (atol) {
11424f572ea9SToby Isaac     PetscAssertPointer(atol, 5);
1143516fe3c3SPeter Brune     *atol = linesearch->atol;
1144516fe3c3SPeter Brune   }
1145516fe3c3SPeter Brune   if (ltol) {
11464f572ea9SToby Isaac     PetscAssertPointer(ltol, 6);
1147516fe3c3SPeter Brune     *ltol = linesearch->ltol;
1148516fe3c3SPeter Brune   }
1149516fe3c3SPeter Brune   if (max_its) {
11504f572ea9SToby Isaac     PetscAssertPointer(max_its, 7);
1151516fe3c3SPeter Brune     *max_its = linesearch->max_its;
1152516fe3c3SPeter Brune   }
11533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11546a388c36SPeter Brune }
11556a388c36SPeter Brune 
1156f40b411bSPeter Brune /*@
1157ceaaa498SBarry Smith   SNESLineSearchSetTolerances -  Sets the tolerances for the linesearch.
1158f40b411bSPeter Brune 
1159f6dfbefdSBarry Smith   Collective
1160f6dfbefdSBarry Smith 
1161f40b411bSPeter Brune   Input Parameters:
1162420bcc1bSBarry Smith + linesearch - the line search context
1163516fe3c3SPeter Brune . steptol    - The minimum steplength
11646cc8e53bSPeter Brune . maxstep    - The maximum steplength
1165516fe3c3SPeter Brune . rtol       - The relative tolerance for iterative line searches
1166516fe3c3SPeter Brune . atol       - The absolute tolerance for iterative line searches
1167516fe3c3SPeter Brune . ltol       - The change in lambda tolerance for iterative line searches
1168420bcc1bSBarry Smith - max_it     - The maximum number of iterations of the line search
1169420bcc1bSBarry Smith 
1170420bcc1bSBarry Smith   Options Database Keys:
1171420bcc1bSBarry Smith + -snes_linesearch_minlambda - The minimum step length
1172420bcc1bSBarry Smith . -snes_linesearch_maxstep   - The maximum step size
1173420bcc1bSBarry Smith . -snes_linesearch_rtol      - Relative tolerance for iterative line searches
1174420bcc1bSBarry Smith . -snes_linesearch_atol      - Absolute tolerance for iterative line searches
1175420bcc1bSBarry Smith . -snes_linesearch_ltol      - Change in lambda tolerance for iterative line searches
1176420bcc1bSBarry Smith - -snes_linesearch_max_it    - The number of iterations for iterative line searches
1177f40b411bSPeter Brune 
117820f4b53cSBarry Smith   Level: intermediate
117920f4b53cSBarry Smith 
1180f6dfbefdSBarry Smith   Note:
1181420bcc1bSBarry Smith   The user may choose to not set any of the tolerances using `PETSC_DEFAULT` in place of an argument.
1182f40b411bSPeter Brune 
1183420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchGetTolerances()`
1184f40b411bSPeter Brune @*/
1185420bcc1bSBarry Smith PetscErrorCode SNESLineSearchSetTolerances(SNESLineSearch linesearch, PetscReal steptol, PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_it)
1186d71ae5a4SJacob Faibussowitsch {
11876a388c36SPeter Brune   PetscFunctionBegin;
1188f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1189d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch, steptol, 2);
1190d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch, maxstep, 3);
1191d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch, rtol, 4);
1192d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch, atol, 5);
1193d3952184SSatish Balay   PetscValidLogicalCollectiveReal(linesearch, ltol, 6);
1194420bcc1bSBarry Smith   PetscValidLogicalCollectiveInt(linesearch, max_it, 7);
1195d3952184SSatish Balay 
119613bcc0bdSJacob Faibussowitsch   if (steptol != (PetscReal)PETSC_DEFAULT) {
11975f80ce2aSJacob Faibussowitsch     PetscCheck(steptol >= 0.0, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_ARG_OUTOFRANGE, "Minimum step length %14.12e must be non-negative", (double)steptol);
11986a388c36SPeter Brune     linesearch->steptol = steptol;
1199d3952184SSatish Balay   }
1200d3952184SSatish Balay 
120113bcc0bdSJacob Faibussowitsch   if (maxstep != (PetscReal)PETSC_DEFAULT) {
12025f80ce2aSJacob Faibussowitsch     PetscCheck(maxstep >= 0.0, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_ARG_OUTOFRANGE, "Maximum step length %14.12e must be non-negative", (double)maxstep);
1203516fe3c3SPeter Brune     linesearch->maxstep = maxstep;
1204d3952184SSatish Balay   }
1205d3952184SSatish Balay 
120613bcc0bdSJacob Faibussowitsch   if (rtol != (PetscReal)PETSC_DEFAULT) {
12072061ca32SJunchao 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);
1208516fe3c3SPeter Brune     linesearch->rtol = rtol;
1209d3952184SSatish Balay   }
1210d3952184SSatish Balay 
121113bcc0bdSJacob Faibussowitsch   if (atol != (PetscReal)PETSC_DEFAULT) {
12125f80ce2aSJacob Faibussowitsch     PetscCheck(atol >= 0.0, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_ARG_OUTOFRANGE, "Absolute tolerance %14.12e must be non-negative", (double)atol);
1213516fe3c3SPeter Brune     linesearch->atol = atol;
1214d3952184SSatish Balay   }
1215d3952184SSatish Balay 
121613bcc0bdSJacob Faibussowitsch   if (ltol != (PetscReal)PETSC_DEFAULT) {
12175f80ce2aSJacob Faibussowitsch     PetscCheck(ltol >= 0.0, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_ARG_OUTOFRANGE, "Lambda tolerance %14.12e must be non-negative", (double)ltol);
1218516fe3c3SPeter Brune     linesearch->ltol = ltol;
1219d3952184SSatish Balay   }
1220d3952184SSatish Balay 
1221420bcc1bSBarry Smith   if (max_it != PETSC_DEFAULT) {
1222420bcc1bSBarry Smith     PetscCheck(max_it >= 0, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of iterations %" PetscInt_FMT " must be non-negative", max_it);
1223420bcc1bSBarry Smith     linesearch->max_its = max_it;
1224d3952184SSatish Balay   }
12253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12266a388c36SPeter Brune }
12276a388c36SPeter Brune 
1228f40b411bSPeter Brune /*@
1229f1c6b773SPeter Brune   SNESLineSearchGetDamping - Gets the line search damping parameter.
1230f40b411bSPeter Brune 
12312fe279fdSBarry Smith   Input Parameter:
1232420bcc1bSBarry Smith . linesearch - the line search context
1233f40b411bSPeter Brune 
12342fe279fdSBarry Smith   Output Parameter:
12358e557f58SPeter Brune . damping - The damping parameter
1236f40b411bSPeter Brune 
123778bcb3b5SPeter Brune   Level: advanced
1238f40b411bSPeter Brune 
1239420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearchGetStepTolerance()`, `SNESQN`
1240f40b411bSPeter Brune @*/
1241d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetDamping(SNESLineSearch linesearch, PetscReal *damping)
1242d71ae5a4SJacob Faibussowitsch {
12436a388c36SPeter Brune   PetscFunctionBegin;
1244f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
12454f572ea9SToby Isaac   PetscAssertPointer(damping, 2);
12466a388c36SPeter Brune   *damping = linesearch->damping;
12473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12486a388c36SPeter Brune }
12496a388c36SPeter Brune 
1250f40b411bSPeter Brune /*@
1251fd292e60Sprj-   SNESLineSearchSetDamping - Sets the line search damping parameter.
1252f40b411bSPeter Brune 
1253f40b411bSPeter Brune   Input Parameters:
1254420bcc1bSBarry Smith + linesearch - the line search context
125503fd4120SBarry Smith - damping    - The damping parameter
1256f40b411bSPeter Brune 
1257f6dfbefdSBarry Smith   Options Database Key:
1258f6dfbefdSBarry Smith . -snes_linesearch_damping <damping> - the damping value
1259f6dfbefdSBarry Smith 
1260f40b411bSPeter Brune   Level: intermediate
1261f40b411bSPeter Brune 
1262f6dfbefdSBarry Smith   Note:
1263f6dfbefdSBarry Smith   The `SNESLINESEARCHNONE` line search merely takes the update step scaled by the damping parameter.
1264420bcc1bSBarry Smith   The use of the damping parameter in the `SNESLINESEARCHL2` and `SNESLINESEARCHCP` line searches is much more subtle;
126578bcb3b5SPeter Brune   it is used as a starting point in calculating the secant step. However, the eventual
1266420bcc1bSBarry Smith   step may be of greater length than the damping parameter.  In the `SNESLINESEARCHBT` line search it is
1267420bcc1bSBarry Smith   used as the maximum possible step length, as the `SNESLINESEARCHBT` line search only backtracks.
1268cd7522eaSPeter Brune 
1269420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchGetDamping()`
1270f40b411bSPeter Brune @*/
1271d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetDamping(SNESLineSearch linesearch, PetscReal damping)
1272d71ae5a4SJacob Faibussowitsch {
12736a388c36SPeter Brune   PetscFunctionBegin;
1274f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
12756a388c36SPeter Brune   linesearch->damping = damping;
12763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12776a388c36SPeter Brune }
12786a388c36SPeter Brune 
127959405d5eSPeter Brune /*@
128059405d5eSPeter Brune   SNESLineSearchGetOrder - Gets the line search approximation order.
128159405d5eSPeter Brune 
1282f6dfbefdSBarry Smith   Input Parameter:
1283420bcc1bSBarry Smith . linesearch - the line search context
128459405d5eSPeter Brune 
1285f6dfbefdSBarry Smith   Output Parameter:
12868e557f58SPeter Brune . order - The order
128759405d5eSPeter Brune 
128859405d5eSPeter Brune   Level: intermediate
128959405d5eSPeter Brune 
1290420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchSetOrder()`
129159405d5eSPeter Brune @*/
1292d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetOrder(SNESLineSearch linesearch, PetscInt *order)
1293d71ae5a4SJacob Faibussowitsch {
129459405d5eSPeter Brune   PetscFunctionBegin;
129559405d5eSPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
12964f572ea9SToby Isaac   PetscAssertPointer(order, 2);
129759405d5eSPeter Brune   *order = linesearch->order;
12983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
129959405d5eSPeter Brune }
130059405d5eSPeter Brune 
130159405d5eSPeter Brune /*@
13021f8196a2SJed Brown   SNESLineSearchSetOrder - Sets the maximum order of the polynomial fit used in the line search
130359405d5eSPeter Brune 
130459405d5eSPeter Brune   Input Parameters:
1305420bcc1bSBarry Smith + linesearch - the line search context
1306ceaaa498SBarry Smith - order      - The order
130759405d5eSPeter Brune 
130859405d5eSPeter Brune   Level: intermediate
130959405d5eSPeter Brune 
1310ceaaa498SBarry Smith   Values for `order`\:
1311f6dfbefdSBarry Smith +  1 or `SNES_LINESEARCH_ORDER_LINEAR` - linear order
1312f6dfbefdSBarry Smith .  2 or `SNES_LINESEARCH_ORDER_QUADRATIC` - quadratic order
1313f6dfbefdSBarry Smith -  3 or `SNES_LINESEARCH_ORDER_CUBIC` - cubic order
131478bcb3b5SPeter Brune 
1315420bcc1bSBarry Smith   Options Database Key:
1316420bcc1bSBarry Smith . -snes_linesearch_order <order> - 1, 2, 3.  Most types only support certain orders (`SNESLINESEARCHBT` supports 2 or 3)
1317420bcc1bSBarry Smith 
1318ceaaa498SBarry Smith   Note:
1319ceaaa498SBarry Smith   These orders are supported by `SNESLINESEARCHBT` and `SNESLINESEARCHCP`
132059405d5eSPeter Brune 
1321420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchGetOrder()`, `SNESLineSearchSetDamping()`
132259405d5eSPeter Brune @*/
1323d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetOrder(SNESLineSearch linesearch, PetscInt order)
1324d71ae5a4SJacob Faibussowitsch {
132559405d5eSPeter Brune   PetscFunctionBegin;
132659405d5eSPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
132759405d5eSPeter Brune   linesearch->order = order;
13283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
132959405d5eSPeter Brune }
133059405d5eSPeter Brune 
1331f40b411bSPeter Brune /*@
1332420bcc1bSBarry Smith   SNESLineSearchGetNorms - Gets the norms for the current solution `X`, the current update `Y`, and the current function value `F`.
1333f40b411bSPeter Brune 
1334f6dfbefdSBarry Smith   Not Collective
1335f6dfbefdSBarry Smith 
1336f899ff85SJose E. Roman   Input Parameter:
1337420bcc1bSBarry Smith . linesearch - the line search context
1338f40b411bSPeter Brune 
1339f40b411bSPeter Brune   Output Parameters:
1340f40b411bSPeter Brune + xnorm - The norm of the current solution
1341a68bbae5SBarry Smith . fnorm - The norm of the current function, this is the `norm(function(X))` where `X` is the current solution.
13426b095a85SStefano Zampini - ynorm - The norm of the current update (after scaling by the linesearch computed lambda)
1343f40b411bSPeter Brune 
134478bcb3b5SPeter Brune   Level: developer
1345f40b411bSPeter Brune 
1346420bcc1bSBarry Smith   Notes:
1347420bcc1bSBarry Smith   Some values may not be up-to-date at particular points in the code.
1348a68bbae5SBarry Smith 
1349a68bbae5SBarry Smith   This, in combination with `SNESLineSearchSetNorms()`, allow the line search and the `SNESSolve_XXX()` to share
1350a68bbae5SBarry Smith   computed values.
1351a68bbae5SBarry Smith 
1352420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchSetNorms()` `SNESLineSearchGetVecs()`
1353f40b411bSPeter Brune @*/
1354d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal *xnorm, PetscReal *fnorm, PetscReal *ynorm)
1355d71ae5a4SJacob Faibussowitsch {
1356bf7f4e0aSPeter Brune   PetscFunctionBegin;
1357f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1358f5af7f23SKarl Rupp   if (xnorm) *xnorm = linesearch->xnorm;
1359f5af7f23SKarl Rupp   if (fnorm) *fnorm = linesearch->fnorm;
1360f5af7f23SKarl Rupp   if (ynorm) *ynorm = linesearch->ynorm;
13613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1362bf7f4e0aSPeter Brune }
1363bf7f4e0aSPeter Brune 
1364f40b411bSPeter Brune /*@
1365*1bd63e3eSSatish Balay   SNESLineSearchSetNorms - Sets the computed norms for the current solution `X`, the current update `Y`, and the current function value `F`.
1366f40b411bSPeter Brune 
1367c3339decSBarry Smith   Collective
1368f6dfbefdSBarry Smith 
1369f40b411bSPeter Brune   Input Parameters:
1370420bcc1bSBarry Smith + linesearch - the line search context
1371f40b411bSPeter Brune . xnorm      - The norm of the current solution
1372a68bbae5SBarry Smith . fnorm      - The norm of the current function, this is the `norm(function(X))` where `X` is the current solution
13736b095a85SStefano Zampini - ynorm      - The norm of the current update (after scaling by the linesearch computed lambda)
1374f40b411bSPeter Brune 
1375f6dfbefdSBarry Smith   Level: developer
1376f40b411bSPeter Brune 
1377420bcc1bSBarry Smith   Note:
1378420bcc1bSBarry Smith   This is called by the line search routines to store the values they have just computed
1379420bcc1bSBarry Smith 
1380420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchGetNorms()`, `SNESLineSearchSetVecs()`
1381f40b411bSPeter Brune @*/
1382d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
1383d71ae5a4SJacob Faibussowitsch {
13846a388c36SPeter Brune   PetscFunctionBegin;
1385f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
13866a388c36SPeter Brune   linesearch->xnorm = xnorm;
13876a388c36SPeter Brune   linesearch->fnorm = fnorm;
13886a388c36SPeter Brune   linesearch->ynorm = ynorm;
13893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13906a388c36SPeter Brune }
13916a388c36SPeter Brune 
1392f40b411bSPeter Brune /*@
1393420bcc1bSBarry Smith   SNESLineSearchComputeNorms - Explicitly computes the norms of the current solution `X`, the current update `Y`, and the current function value `F`.
1394f40b411bSPeter Brune 
13952fe279fdSBarry Smith   Input Parameter:
1396420bcc1bSBarry Smith . linesearch - the line search context
1397f40b411bSPeter Brune 
139820f4b53cSBarry Smith   Options Database Key:
13998e557f58SPeter Brune . -snes_linesearch_norms - turn norm computation on or off
1400f40b411bSPeter Brune 
1401f40b411bSPeter Brune   Level: intermediate
1402f40b411bSPeter Brune 
1403420bcc1bSBarry Smith   Developer Note:
1404420bcc1bSBarry Smith   The options database key is misnamed. It should be -snes_linesearch_compute_norms
1405420bcc1bSBarry Smith 
1406420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchGetNorms`, `SNESLineSearchSetNorms()`, `SNESLineSearchSetComputeNorms()`
1407f40b411bSPeter Brune @*/
1408d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
1409d71ae5a4SJacob Faibussowitsch {
14109bd66eb0SPeter Brune   SNES snes;
1411bf388a1fSBarry Smith 
14126a388c36SPeter Brune   PetscFunctionBegin;
14136a388c36SPeter Brune   if (linesearch->norms) {
14149bd66eb0SPeter Brune     if (linesearch->ops->vinorm) {
14159566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchGetSNES(linesearch, &snes));
14169566063dSJacob Faibussowitsch       PetscCall(VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm));
14179566063dSJacob Faibussowitsch       PetscCall(VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm));
14189566063dSJacob Faibussowitsch       PetscCall((*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm));
14199bd66eb0SPeter Brune     } else {
14209566063dSJacob Faibussowitsch       PetscCall(VecNormBegin(linesearch->vec_func, NORM_2, &linesearch->fnorm));
14219566063dSJacob Faibussowitsch       PetscCall(VecNormBegin(linesearch->vec_sol, NORM_2, &linesearch->xnorm));
14229566063dSJacob Faibussowitsch       PetscCall(VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm));
14239566063dSJacob Faibussowitsch       PetscCall(VecNormEnd(linesearch->vec_func, NORM_2, &linesearch->fnorm));
14249566063dSJacob Faibussowitsch       PetscCall(VecNormEnd(linesearch->vec_sol, NORM_2, &linesearch->xnorm));
14259566063dSJacob Faibussowitsch       PetscCall(VecNormEnd(linesearch->vec_update, NORM_2, &linesearch->ynorm));
14266a388c36SPeter Brune     }
14279bd66eb0SPeter Brune   }
14283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14296a388c36SPeter Brune }
14306a388c36SPeter Brune 
14316f263ca3SPeter Brune /*@
14326f263ca3SPeter Brune   SNESLineSearchSetComputeNorms - Turns on or off the computation of final norms in the line search.
14336f263ca3SPeter Brune 
14346f263ca3SPeter Brune   Input Parameters:
1435420bcc1bSBarry Smith + linesearch - the line search context
143678bcb3b5SPeter Brune - flg        - indicates whether or not to compute norms
14376f263ca3SPeter Brune 
143820f4b53cSBarry Smith   Options Database Key:
1439420bcc1bSBarry Smith . -snes_linesearch_norms <true> - Turns on/off computation of the norms for basic (none) `SNESLINESEARCHBASIC` line search
14406f263ca3SPeter Brune 
144120f4b53cSBarry Smith   Level: intermediate
144220f4b53cSBarry Smith 
1443f6dfbefdSBarry Smith   Note:
1444f6dfbefdSBarry 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.
14456f263ca3SPeter Brune 
1446420bcc1bSBarry Smith   Developer Note:
1447420bcc1bSBarry Smith   The options database key is misnamed. It should be -snes_linesearch_compute_norms
1448420bcc1bSBarry Smith 
1449420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchGetNorms()`, `SNESLineSearchSetNorms()`, `SNESLineSearchComputeNorms()`, `SNESLINESEARCHBASIC`
14506f263ca3SPeter Brune @*/
1451d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetComputeNorms(SNESLineSearch linesearch, PetscBool flg)
1452d71ae5a4SJacob Faibussowitsch {
14536f263ca3SPeter Brune   PetscFunctionBegin;
14546f263ca3SPeter Brune   linesearch->norms = flg;
14553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14566f263ca3SPeter Brune }
14576f263ca3SPeter Brune 
1458f40b411bSPeter Brune /*@
1459f6dfbefdSBarry Smith   SNESLineSearchGetVecs - Gets the vectors from the `SNESLineSearch` context
1460f6dfbefdSBarry Smith 
14618f14a041SBarry Smith   Not Collective but the vectors are parallel
1462f40b411bSPeter Brune 
1463f899ff85SJose E. Roman   Input Parameter:
1464420bcc1bSBarry Smith . linesearch - the line search context
1465f40b411bSPeter Brune 
1466f40b411bSPeter Brune   Output Parameters:
14676232e825SPeter Brune + X - Solution vector
14686232e825SPeter Brune . F - Function vector
14696232e825SPeter Brune . Y - Search direction vector
14706232e825SPeter Brune . W - Solution work vector
14716232e825SPeter Brune - G - Function work vector
14726232e825SPeter Brune 
147320f4b53cSBarry Smith   Level: advanced
147420f4b53cSBarry Smith 
14757bba9028SPeter Brune   Notes:
147620f4b53cSBarry Smith   At the beginning of a line search application, `X` should contain a
147720f4b53cSBarry Smith   solution and the vector `F` the function computed at `X`.  At the end of the
147820f4b53cSBarry Smith   line search application, `X` should contain the new solution, and `F` the
14796232e825SPeter Brune   function evaluated at the new solution.
1480f40b411bSPeter Brune 
1481f6dfbefdSBarry Smith   These vectors are owned by the `SNESLineSearch` and should not be destroyed by the caller
14822a7a6963SBarry Smith 
1483420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchGetNorms()`, `SNESLineSearchSetVecs()`
1484f40b411bSPeter Brune @*/
1485d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch, Vec *X, Vec *F, Vec *Y, Vec *W, Vec *G)
1486d71ae5a4SJacob Faibussowitsch {
14876a388c36SPeter Brune   PetscFunctionBegin;
1488f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
14896a388c36SPeter Brune   if (X) {
14904f572ea9SToby Isaac     PetscAssertPointer(X, 2);
14916a388c36SPeter Brune     *X = linesearch->vec_sol;
14926a388c36SPeter Brune   }
14936a388c36SPeter Brune   if (F) {
14944f572ea9SToby Isaac     PetscAssertPointer(F, 3);
14956a388c36SPeter Brune     *F = linesearch->vec_func;
14966a388c36SPeter Brune   }
14976a388c36SPeter Brune   if (Y) {
14984f572ea9SToby Isaac     PetscAssertPointer(Y, 4);
14996a388c36SPeter Brune     *Y = linesearch->vec_update;
15006a388c36SPeter Brune   }
15016a388c36SPeter Brune   if (W) {
15024f572ea9SToby Isaac     PetscAssertPointer(W, 5);
15036a388c36SPeter Brune     *W = linesearch->vec_sol_new;
15046a388c36SPeter Brune   }
15056a388c36SPeter Brune   if (G) {
15064f572ea9SToby Isaac     PetscAssertPointer(G, 6);
15076a388c36SPeter Brune     *G = linesearch->vec_func_new;
15086a388c36SPeter Brune   }
15093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15106a388c36SPeter Brune }
15116a388c36SPeter Brune 
1512f40b411bSPeter Brune /*@
1513f6dfbefdSBarry Smith   SNESLineSearchSetVecs - Sets the vectors on the `SNESLineSearch` context
1514f6dfbefdSBarry Smith 
1515c3339decSBarry Smith   Logically Collective
1516f40b411bSPeter Brune 
1517f40b411bSPeter Brune   Input Parameters:
1518420bcc1bSBarry Smith + linesearch - the line search context
15196232e825SPeter Brune . X          - Solution vector
15206232e825SPeter Brune . F          - Function vector
15216232e825SPeter Brune . Y          - Search direction vector
15226232e825SPeter Brune . W          - Solution work vector
15236232e825SPeter Brune - G          - Function work vector
1524f40b411bSPeter Brune 
1525420bcc1bSBarry Smith   Level: developer
1526f40b411bSPeter Brune 
1527420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchSetNorms()`, `SNESLineSearchGetVecs()`
1528f40b411bSPeter Brune @*/
1529d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch, Vec X, Vec F, Vec Y, Vec W, Vec G)
1530d71ae5a4SJacob Faibussowitsch {
15316a388c36SPeter Brune   PetscFunctionBegin;
1532f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
15336a388c36SPeter Brune   if (X) {
15346a388c36SPeter Brune     PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
15356a388c36SPeter Brune     linesearch->vec_sol = X;
15366a388c36SPeter Brune   }
15376a388c36SPeter Brune   if (F) {
15386a388c36SPeter Brune     PetscValidHeaderSpecific(F, VEC_CLASSID, 3);
15396a388c36SPeter Brune     linesearch->vec_func = F;
15406a388c36SPeter Brune   }
15416a388c36SPeter Brune   if (Y) {
15426a388c36SPeter Brune     PetscValidHeaderSpecific(Y, VEC_CLASSID, 4);
15436a388c36SPeter Brune     linesearch->vec_update = Y;
15446a388c36SPeter Brune   }
15456a388c36SPeter Brune   if (W) {
15466a388c36SPeter Brune     PetscValidHeaderSpecific(W, VEC_CLASSID, 5);
15476a388c36SPeter Brune     linesearch->vec_sol_new = W;
15486a388c36SPeter Brune   }
15496a388c36SPeter Brune   if (G) {
15506a388c36SPeter Brune     PetscValidHeaderSpecific(G, VEC_CLASSID, 6);
15516a388c36SPeter Brune     linesearch->vec_func_new = G;
15526a388c36SPeter Brune   }
15533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15546a388c36SPeter Brune }
15556a388c36SPeter Brune 
1556e7058c64SPeter Brune /*@C
1557f1c6b773SPeter Brune   SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1558f6dfbefdSBarry Smith   `SNESLineSearch` options in the database.
1559e7058c64SPeter Brune 
1560c3339decSBarry Smith   Logically Collective
1561e7058c64SPeter Brune 
1562e7058c64SPeter Brune   Input Parameters:
1563f6dfbefdSBarry Smith + linesearch - the `SNESLineSearch` context
1564e7058c64SPeter Brune - prefix     - the prefix to prepend to all option names
1565e7058c64SPeter Brune 
156620f4b53cSBarry Smith   Level: advanced
156720f4b53cSBarry Smith 
1568f6dfbefdSBarry Smith   Note:
1569e7058c64SPeter Brune   A hyphen (-) must NOT be given at the beginning of the prefix name.
1570e7058c64SPeter Brune   The first character of all runtime options is AUTOMATICALLY the hyphen.
1571e7058c64SPeter Brune 
1572420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch()`, `SNESLineSearchSetFromOptions()`, `SNESGetOptionsPrefix()`
1573e7058c64SPeter Brune @*/
1574d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch, const char prefix[])
1575d71ae5a4SJacob Faibussowitsch {
1576e7058c64SPeter Brune   PetscFunctionBegin;
1577f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
15789566063dSJacob Faibussowitsch   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)linesearch, prefix));
15793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1580e7058c64SPeter Brune }
1581e7058c64SPeter Brune 
1582e7058c64SPeter Brune /*@C
1583f6dfbefdSBarry Smith   SNESLineSearchGetOptionsPrefix - Gets the prefix used for searching for all
1584f1c6b773SPeter Brune   SNESLineSearch options in the database.
1585e7058c64SPeter Brune 
1586e7058c64SPeter Brune   Not Collective
1587e7058c64SPeter Brune 
1588e7058c64SPeter Brune   Input Parameter:
1589f6dfbefdSBarry Smith . linesearch - the `SNESLineSearch` context
1590e7058c64SPeter Brune 
1591e7058c64SPeter Brune   Output Parameter:
1592e7058c64SPeter Brune . prefix - pointer to the prefix string used
1593e7058c64SPeter Brune 
1594e7058c64SPeter Brune   Level: advanced
1595e7058c64SPeter Brune 
1596e4094ef1SJacob Faibussowitsch   Fortran Notes:
159720f4b53cSBarry Smith   The user should pass in a string 'prefix' of
159820f4b53cSBarry Smith   sufficient length to hold the prefix.
159920f4b53cSBarry Smith 
1600420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESAppendOptionsPrefix()`
1601e7058c64SPeter Brune @*/
1602d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch, const char *prefix[])
1603d71ae5a4SJacob Faibussowitsch {
1604e7058c64SPeter Brune   PetscFunctionBegin;
1605f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
16069566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)linesearch, prefix));
16073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1608e7058c64SPeter Brune }
1609bf7f4e0aSPeter Brune 
16108d359177SBarry Smith /*@C
1611f6dfbefdSBarry Smith   SNESLineSearchSetWorkVecs - Sets work vectors for the line search.
1612f40b411bSPeter Brune 
1613d8d19677SJose E. Roman   Input Parameters:
1614f6dfbefdSBarry Smith + linesearch - the `SNESLineSearch` context
1615f40b411bSPeter Brune - nwork      - the number of work vectors
1616f40b411bSPeter Brune 
1617f40b411bSPeter Brune   Level: developer
1618f40b411bSPeter Brune 
1619420bcc1bSBarry Smith   Developer Note:
1620420bcc1bSBarry Smith   This is called from within the set up routines for each of the line search types `SNESLineSearchType`
1621420bcc1bSBarry Smith 
1622420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESSetWorkVecs()`
1623f40b411bSPeter Brune @*/
1624d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetWorkVecs(SNESLineSearch linesearch, PetscInt nwork)
1625d71ae5a4SJacob Faibussowitsch {
1626bf7f4e0aSPeter Brune   PetscFunctionBegin;
16270fdf79fbSJacob Faibussowitsch   PetscCheck(linesearch->vec_sol, PetscObjectComm((PetscObject)linesearch), PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
16289566063dSJacob Faibussowitsch   PetscCall(VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work));
16293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1630bf7f4e0aSPeter Brune }
1631bf7f4e0aSPeter Brune 
1632f40b411bSPeter Brune /*@
1633422a814eSBarry Smith   SNESLineSearchGetReason - Gets the success/failure status of the last line search application
1634f40b411bSPeter Brune 
16352fe279fdSBarry Smith   Input Parameter:
1636420bcc1bSBarry Smith . linesearch - the line search context
1637f40b411bSPeter Brune 
16382fe279fdSBarry Smith   Output Parameter:
1639422a814eSBarry Smith . result - The success or failure status
1640f40b411bSPeter Brune 
164120f4b53cSBarry Smith   Level: developer
164220f4b53cSBarry Smith 
1643f6dfbefdSBarry Smith   Note:
1644420bcc1bSBarry Smith   This is typically called after `SNESLineSearchApply()` in order to determine if the line search failed
1645420bcc1bSBarry Smith   (and set into the `SNES` convergence accordingly).
1646cd7522eaSPeter Brune 
1647420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchSetReason()`, `SNESLineSearchReason`
1648f40b411bSPeter Brune @*/
1649d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetReason(SNESLineSearch linesearch, SNESLineSearchReason *result)
1650d71ae5a4SJacob Faibussowitsch {
1651bf7f4e0aSPeter Brune   PetscFunctionBegin;
1652f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
16534f572ea9SToby Isaac   PetscAssertPointer(result, 2);
1654422a814eSBarry Smith   *result = linesearch->result;
16553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1656bf7f4e0aSPeter Brune }
1657bf7f4e0aSPeter Brune 
1658f40b411bSPeter Brune /*@
1659420bcc1bSBarry Smith   SNESLineSearchSetReason - Sets the success/failure status of the line search application
1660f40b411bSPeter Brune 
1661f40b411bSPeter Brune   Input Parameters:
1662420bcc1bSBarry Smith + linesearch - the line search context
1663422a814eSBarry Smith - result     - The success or failure status
1664f40b411bSPeter Brune 
166520f4b53cSBarry Smith   Level: developer
166620f4b53cSBarry Smith 
1667f6dfbefdSBarry Smith   Note:
1668420bcc1bSBarry Smith   This is typically called in a `SNESLineSearchType` implementation of `SNESLineSearchApply()` or a `SNESLINESEARCHSHELL` implementation to set
1669cd7522eaSPeter Brune   the success or failure of the line search method.
1670cd7522eaSPeter Brune 
1671420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchReason`, `SNESLineSearchGetSResult()`
1672f40b411bSPeter Brune @*/
1673d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetReason(SNESLineSearch linesearch, SNESLineSearchReason result)
1674d71ae5a4SJacob Faibussowitsch {
16756a388c36SPeter Brune   PetscFunctionBegin;
16765fd66863SKarl Rupp   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
1677422a814eSBarry Smith   linesearch->result = result;
16783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16796a388c36SPeter Brune }
16806a388c36SPeter Brune 
1681ceaaa498SBarry Smith // PetscClangLinter pragma disable: -fdoc-param-list-func-parameter-documentation
16829bd66eb0SPeter Brune /*@C
1683f1c6b773SPeter Brune   SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
16849bd66eb0SPeter Brune 
1685c3339decSBarry Smith   Logically Collective
1686f6dfbefdSBarry Smith 
16879bd66eb0SPeter Brune   Input Parameters:
1688ceaaa498SBarry Smith + linesearch  - the linesearch object
1689420bcc1bSBarry Smith . projectfunc - function for projecting the function to the bounds, see `SNESLineSearchSetVIFunctions` for calling sequence
1690420bcc1bSBarry Smith - normfunc    - function for computing the norm of an active set, see `SNESLineSearchSetVIFunctions ` for calling sequence
16919bd66eb0SPeter Brune 
1692f6dfbefdSBarry Smith   Level: advanced
16939bd66eb0SPeter Brune 
1694ceaaa498SBarry Smith   Notes:
169520f4b53cSBarry Smith   The VI solvers require projection of the solution to the feasible set.  `projectfunc` should implement this.
169620f4b53cSBarry Smith 
169720f4b53cSBarry Smith   The VI solvers require special evaluation of the function norm such that the norm is only calculated
169820f4b53cSBarry Smith   on the inactive set.  This should be implemented by `normfunc`.
169920f4b53cSBarry Smith 
1700420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchGetVIFunctions()`, `SNESLineSearchSetPostCheck()`, `SNESLineSearchSetPreCheck()`
17019bd66eb0SPeter Brune @*/
1702d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
1703d71ae5a4SJacob Faibussowitsch {
17049bd66eb0SPeter Brune   PetscFunctionBegin;
1705f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 1);
17069bd66eb0SPeter Brune   if (projectfunc) linesearch->ops->viproject = projectfunc;
17079bd66eb0SPeter Brune   if (normfunc) linesearch->ops->vinorm = normfunc;
17083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17099bd66eb0SPeter Brune }
17109bd66eb0SPeter Brune 
17119bd66eb0SPeter Brune /*@C
1712f1c6b773SPeter Brune   SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
17139bd66eb0SPeter Brune 
1714f6dfbefdSBarry Smith   Not Collective
1715f6dfbefdSBarry Smith 
1716f899ff85SJose E. Roman   Input Parameter:
1717f6dfbefdSBarry Smith . linesearch - the line search context, obtain with `SNESGetLineSearch()`
17189bd66eb0SPeter Brune 
17199bd66eb0SPeter Brune   Output Parameters:
17209bd66eb0SPeter Brune + projectfunc - function for projecting the function to the bounds
17219bd66eb0SPeter Brune - normfunc    - function for computing the norm of an active set
17229bd66eb0SPeter Brune 
1723f6dfbefdSBarry Smith   Level: advanced
17249bd66eb0SPeter Brune 
1725420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchSetVIFunctions()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchGetPreCheck()`
17269bd66eb0SPeter Brune @*/
1727d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
1728d71ae5a4SJacob Faibussowitsch {
17299bd66eb0SPeter Brune   PetscFunctionBegin;
17309bd66eb0SPeter Brune   if (projectfunc) *projectfunc = linesearch->ops->viproject;
17319bd66eb0SPeter Brune   if (normfunc) *normfunc = linesearch->ops->vinorm;
17323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17339bd66eb0SPeter Brune }
17349bd66eb0SPeter Brune 
1735bf7f4e0aSPeter Brune /*@C
1736420bcc1bSBarry Smith   SNESLineSearchRegister - register a line search type `SNESLineSearchType`
1737ceaaa498SBarry Smith 
1738ceaaa498SBarry Smith   Input Parameters:
1739420bcc1bSBarry Smith + sname    - name of the `SNESLineSearchType()`
1740ceaaa498SBarry Smith - function - the creation function for that type
1741ceaaa498SBarry Smith 
1742ceaaa498SBarry Smith   Calling sequence of `function`:
1743ceaaa498SBarry Smith . ls - the line search context
1744bf7f4e0aSPeter Brune 
1745bf7f4e0aSPeter Brune   Level: advanced
1746f6dfbefdSBarry Smith 
1747420bcc1bSBarry Smith .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESLineSearchType`, `SNESLineSearchSetType()`
1748bf7f4e0aSPeter Brune @*/
1749ceaaa498SBarry Smith PetscErrorCode SNESLineSearchRegister(const char sname[], PetscErrorCode (*function)(SNESLineSearch ls))
1750d71ae5a4SJacob Faibussowitsch {
1751bf7f4e0aSPeter Brune   PetscFunctionBegin;
17529566063dSJacob Faibussowitsch   PetscCall(SNESInitializePackage());
17539566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&SNESLineSearchList, sname, function));
17543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1755bf7f4e0aSPeter Brune }
1756