xref: /petsc/src/snes/linesearch/interface/linesearch.c (revision 7a35526ea7663f00cb6ea7142638f9b11e38a849)
19e764e56SPeter Brune #include <private/linesearchimpl.h> /*I "petscsnes.h" I*/
2bf7f4e0aSPeter Brune 
3f1c6b773SPeter Brune PetscBool  SNESLineSearchRegisterAllCalled = PETSC_FALSE;
4f1c6b773SPeter Brune PetscFList SNESLineSearchList              = PETSC_NULL;
5bf7f4e0aSPeter Brune 
6f1c6b773SPeter Brune PetscClassId   SNESLINESEARCH_CLASSID;
7f1c6b773SPeter Brune PetscLogEvent  SNESLineSearch_Apply;
8bf7f4e0aSPeter Brune 
9bf7f4e0aSPeter Brune #undef __FUNCT__
10f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchCreate"
11f40b411bSPeter Brune /*@
12f1c6b773SPeter Brune    SNESLineSearchCreate - Creates the line search.
13f40b411bSPeter Brune 
14f40b411bSPeter Brune    Collective on LineSearch
15f40b411bSPeter Brune 
16f40b411bSPeter Brune    Input Parameters:
17f40b411bSPeter Brune .  comm - MPI communicator for the line search
18f40b411bSPeter Brune 
19f40b411bSPeter Brune    Output Parameters:
20f40b411bSPeter Brune .  outlinesearch - the line search instance.
21f40b411bSPeter Brune 
22f40b411bSPeter Brune    Level: Beginner
23f40b411bSPeter Brune 
24f40b411bSPeter Brune    .keywords: LineSearch, Create
25f40b411bSPeter Brune 
26f40b411bSPeter Brune    .seealso: LineSearchDestroy()
27f40b411bSPeter Brune @*/
28f40b411bSPeter Brune 
29f1c6b773SPeter Brune PetscErrorCode SNESLineSearchCreate(MPI_Comm comm, SNESLineSearch *outlinesearch) {
30bf7f4e0aSPeter Brune   PetscErrorCode      ierr;
31f1c6b773SPeter Brune   SNESLineSearch     linesearch;
32bf7f4e0aSPeter Brune   PetscFunctionBegin;
33ea5d4fccSPeter Brune   PetscValidPointer(outlinesearch,2);
34ea5d4fccSPeter Brune   *outlinesearch = PETSC_NULL;
35f1c6b773SPeter Brune   ierr = PetscHeaderCreate(linesearch,_p_LineSearch,struct _LineSearchOps,SNESLINESEARCH_CLASSID, 0,
36f1c6b773SPeter Brune                            "SNESLineSearch","Line-search method","SNESLineSearch",comm,SNESLineSearchDestroy,SNESLineSearchView);CHKERRQ(ierr);
37bf7f4e0aSPeter Brune 
38bf7f4e0aSPeter Brune   linesearch->ops->precheckstep = PETSC_NULL;
39bf7f4e0aSPeter Brune   linesearch->ops->postcheckstep = PETSC_NULL;
40bf7f4e0aSPeter Brune 
419bd66eb0SPeter Brune   linesearch->vec_sol_new   = PETSC_NULL;
429bd66eb0SPeter Brune   linesearch->vec_func_new  = PETSC_NULL;
439bd66eb0SPeter Brune   linesearch->vec_sol       = PETSC_NULL;
449bd66eb0SPeter Brune   linesearch->vec_func      = PETSC_NULL;
459bd66eb0SPeter Brune   linesearch->vec_update    = PETSC_NULL;
469bd66eb0SPeter Brune 
47bf7f4e0aSPeter Brune   linesearch->lambda        = 1.0;
48bf7f4e0aSPeter Brune   linesearch->fnorm         = 1.0;
49bf7f4e0aSPeter Brune   linesearch->ynorm         = 1.0;
50bf7f4e0aSPeter Brune   linesearch->xnorm         = 1.0;
51bf7f4e0aSPeter Brune   linesearch->success       = PETSC_TRUE;
52bf7f4e0aSPeter Brune   linesearch->norms         = PETSC_TRUE;
53bf7f4e0aSPeter Brune   linesearch->keeplambda    = PETSC_FALSE;
54bf7f4e0aSPeter Brune   linesearch->damping       = 1.0;
55bf7f4e0aSPeter Brune   linesearch->maxstep       = 1e8;
56bf7f4e0aSPeter Brune   linesearch->steptol       = 1e-12;
57516fe3c3SPeter Brune   linesearch->rtol          = 1e-8;
58516fe3c3SPeter Brune   linesearch->atol          = 1e-15;
59516fe3c3SPeter Brune   linesearch->ltol          = 1e-8;
60bf7f4e0aSPeter Brune   linesearch->precheckctx   = PETSC_NULL;
61bf7f4e0aSPeter Brune   linesearch->postcheckctx  = PETSC_NULL;
62516fe3c3SPeter Brune   linesearch->max_its       = 3;
63bf7f4e0aSPeter Brune   linesearch->setupcalled   = PETSC_FALSE;
64bf7f4e0aSPeter Brune   *outlinesearch            = linesearch;
65bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
66bf7f4e0aSPeter Brune }
67bf7f4e0aSPeter Brune 
68bf7f4e0aSPeter Brune #undef __FUNCT__
69f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetUp"
70f40b411bSPeter Brune /*@
71f1c6b773SPeter Brune    SNESLineSearchSetUp - Prepares the line search for being applied.
72f40b411bSPeter Brune 
73f40b411bSPeter Brune    Collective on LineSearch
74f40b411bSPeter Brune 
75f40b411bSPeter Brune    Input Parameters:
76f40b411bSPeter Brune .  linesearch - The LineSearch instance.
77f40b411bSPeter Brune 
78f40b411bSPeter Brune    Level: Intermediate
79f40b411bSPeter Brune 
80f1c6b773SPeter Brune    .keywords: SNESLineSearch, SetUp
81f40b411bSPeter Brune 
82f1c6b773SPeter Brune    .seealso: SNESLineSearchReset()
83f40b411bSPeter Brune @*/
84f40b411bSPeter Brune 
85f1c6b773SPeter Brune PetscErrorCode SNESLineSearchSetUp(SNESLineSearch linesearch) {
86bf7f4e0aSPeter Brune   PetscErrorCode ierr;
87bf7f4e0aSPeter Brune   PetscFunctionBegin;
88bf7f4e0aSPeter Brune   if (!((PetscObject)linesearch)->type_name) {
89f1c6b773SPeter Brune     ierr = SNESLineSearchSetType(linesearch,SNES_LINESEARCH_BASIC);CHKERRQ(ierr);
90bf7f4e0aSPeter Brune   }
91bf7f4e0aSPeter Brune   if (!linesearch->setupcalled) {
929bd66eb0SPeter Brune     if (!linesearch->vec_sol_new) {
93bf7f4e0aSPeter Brune       ierr = VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);CHKERRQ(ierr);
949bd66eb0SPeter Brune     }
959bd66eb0SPeter Brune     if (!linesearch->vec_func_new) {
969bd66eb0SPeter Brune       ierr = VecDuplicate(linesearch->vec_sol, &linesearch->vec_func_new);CHKERRQ(ierr);
979bd66eb0SPeter Brune     }
98bf7f4e0aSPeter Brune     if (linesearch->ops->setup) {
99bf7f4e0aSPeter Brune       ierr = (*linesearch->ops->setup)(linesearch);CHKERRQ(ierr);
100bf7f4e0aSPeter Brune     }
101bf7f4e0aSPeter Brune     linesearch->lambda = linesearch->damping;
102bf7f4e0aSPeter Brune     linesearch->setupcalled = PETSC_TRUE;
103bf7f4e0aSPeter Brune   }
104bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
105bf7f4e0aSPeter Brune }
106bf7f4e0aSPeter Brune 
107bf7f4e0aSPeter Brune #undef __FUNCT__
108f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchReset"
109f40b411bSPeter Brune 
110f40b411bSPeter Brune /*@
111f1c6b773SPeter Brune    SNESLineSearchReset - Tears down the structures required for application
112f40b411bSPeter Brune 
113f1c6b773SPeter Brune    Collective on SNESLineSearch
114f40b411bSPeter Brune 
115f40b411bSPeter Brune    Input Parameters:
116f40b411bSPeter Brune .  linesearch - The LineSearch instance.
117f40b411bSPeter Brune 
118f40b411bSPeter Brune    Level: Intermediate
119f40b411bSPeter Brune 
120f1c6b773SPeter Brune    .keywords: SNESLineSearch, Create
121f40b411bSPeter Brune 
122f1c6b773SPeter Brune    .seealso: SNESLineSearchSetUp()
123f40b411bSPeter Brune @*/
124f40b411bSPeter Brune 
125f1c6b773SPeter Brune PetscErrorCode SNESLineSearchReset(SNESLineSearch linesearch) {
126bf7f4e0aSPeter Brune   PetscErrorCode ierr;
127bf7f4e0aSPeter Brune   PetscFunctionBegin;
128bf7f4e0aSPeter Brune   if (linesearch->ops->reset) {
129bf7f4e0aSPeter Brune     (*linesearch->ops->reset)(linesearch);
130bf7f4e0aSPeter Brune   }
131bf7f4e0aSPeter Brune   ierr = VecDestroy(&linesearch->vec_sol_new);CHKERRQ(ierr);
132bf7f4e0aSPeter Brune   ierr = VecDestroy(&linesearch->vec_func_new);CHKERRQ(ierr);
133bf7f4e0aSPeter Brune 
134bf7f4e0aSPeter Brune   ierr = VecDestroyVecs(linesearch->nwork, &linesearch->work);CHKERRQ(ierr);
135bf7f4e0aSPeter Brune   linesearch->nwork = 0;
136bf7f4e0aSPeter Brune   linesearch->setupcalled = PETSC_FALSE;
137bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
138bf7f4e0aSPeter Brune }
139bf7f4e0aSPeter Brune 
14086d74e61SPeter Brune 
14186d74e61SPeter Brune #undef __FUNCT__
142f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetPreCheck"
14386d74e61SPeter Brune /*@C
144f1c6b773SPeter Brune    SNESLineSearchSetPreCheck - Sets a pre-check function for the line search routine.
14586d74e61SPeter Brune 
146f1c6b773SPeter Brune    Logically Collective on SNESLineSearch
14786d74e61SPeter Brune 
14886d74e61SPeter Brune    Input Parameters:
149f1c6b773SPeter Brune +  linesearch - the SNESLineSearch context
15086d74e61SPeter Brune .  func       - [optional] function evaluation routine
15186d74e61SPeter Brune -  ctx        - [optional] user-defined context for private data for the
15286d74e61SPeter Brune                 function evaluation routine (may be PETSC_NULL)
15386d74e61SPeter Brune 
15486d74e61SPeter Brune    Calling sequence of func:
155f1c6b773SPeter Brune $    func (SNESLineSearch snes,Vec x,Vec y, PetscBool *changed);
15686d74e61SPeter Brune 
15786d74e61SPeter Brune +  x - solution vector
15886d74e61SPeter Brune .  y - search direction vector
15986d74e61SPeter Brune -  changed - flag to indicate the precheck changed something.
16086d74e61SPeter Brune 
16186d74e61SPeter Brune    Level: intermediate
16286d74e61SPeter Brune 
16386d74e61SPeter Brune .keywords: set, linesearch, pre-check
16486d74e61SPeter Brune 
165f1c6b773SPeter Brune .seealso: SNESLineSearchSetPostCheck()
16686d74e61SPeter Brune @*/
167f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchSetPreCheck(SNESLineSearch linesearch, SNESLineSearchPreCheckFunc func,void *ctx)
16886d74e61SPeter Brune {
1699bd66eb0SPeter Brune   PetscFunctionBegin;
170f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
17186d74e61SPeter Brune   if (func) linesearch->ops->precheckstep = func;
17286d74e61SPeter Brune   if (ctx) linesearch->precheckctx = ctx;
17386d74e61SPeter Brune   PetscFunctionReturn(0);
17486d74e61SPeter Brune }
17586d74e61SPeter Brune 
17686d74e61SPeter Brune 
17786d74e61SPeter Brune #undef __FUNCT__
178f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchGetPreCheck"
17986d74e61SPeter Brune /*@C
180f1c6b773SPeter Brune    SNESLineSearchSetPreCheck - Sets a pre-check function for the line search routine.
18186d74e61SPeter Brune 
18286d74e61SPeter Brune    Input Parameters:
183f1c6b773SPeter Brune .  linesearch - the SNESLineSearch context
18486d74e61SPeter Brune 
18586d74e61SPeter Brune    Output Parameters:
18686d74e61SPeter Brune +  func       - [optional] function evaluation routine
18786d74e61SPeter Brune -  ctx        - [optional] user-defined context for private data for the
18886d74e61SPeter Brune                 function evaluation routine (may be PETSC_NULL)
18986d74e61SPeter Brune 
19086d74e61SPeter Brune    Level: intermediate
19186d74e61SPeter Brune 
19286d74e61SPeter Brune .keywords: get, linesearch, pre-check
19386d74e61SPeter Brune 
194f1c6b773SPeter Brune .seealso: SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck()
19586d74e61SPeter Brune @*/
196f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetPreCheck(SNESLineSearch linesearch, SNESLineSearchPreCheckFunc *func,void **ctx)
19786d74e61SPeter Brune {
1989bd66eb0SPeter Brune   PetscFunctionBegin;
199f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
20086d74e61SPeter Brune   if (func) *func = linesearch->ops->precheckstep;
20186d74e61SPeter Brune   if (ctx) *ctx = linesearch->precheckctx;
20286d74e61SPeter Brune   PetscFunctionReturn(0);
20386d74e61SPeter Brune }
20486d74e61SPeter Brune 
20586d74e61SPeter Brune 
20686d74e61SPeter Brune #undef __FUNCT__
207f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetPostCheck"
20886d74e61SPeter Brune /*@C
209f1c6b773SPeter Brune    SNESLineSearchSetPostCheck - Sets a post-check function for the line search routine.
21086d74e61SPeter Brune 
211f1c6b773SPeter Brune    Logically Collective on SNESLineSearch
21286d74e61SPeter Brune 
21386d74e61SPeter Brune    Input Parameters:
214f1c6b773SPeter Brune +  linesearch - the SNESLineSearch context
21586d74e61SPeter Brune .  func       - [optional] function evaluation routine
21686d74e61SPeter Brune -  ctx        - [optional] user-defined context for private data for the
21786d74e61SPeter Brune                 function evaluation routine (may be PETSC_NULL)
21886d74e61SPeter Brune 
21986d74e61SPeter Brune    Calling sequence of func:
220f1c6b773SPeter Brune $    func (SNESLineSearch linesearch,Vec x, Vec w, Vec y, PetscBool *changed_w, *changed_y);
22186d74e61SPeter Brune 
22286d74e61SPeter Brune +  x - old solution vector
22386d74e61SPeter Brune .  y - search direction vector
22486d74e61SPeter Brune .  w - new solution vector
22586d74e61SPeter Brune .  changed_y - indicates that the line search changed y.
22686d74e61SPeter Brune .  changed_w - indicates that the line search changed w.
22786d74e61SPeter Brune 
22886d74e61SPeter Brune    Level: intermediate
22986d74e61SPeter Brune 
23086d74e61SPeter Brune .keywords: set, linesearch, post-check
23186d74e61SPeter Brune 
232f1c6b773SPeter Brune .seealso: SNESLineSearchSetPreCheck()
23386d74e61SPeter Brune @*/
234f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchSetPostCheck(SNESLineSearch linesearch, SNESLineSearchPostCheckFunc func,void *ctx)
23586d74e61SPeter Brune {
23686d74e61SPeter Brune   PetscFunctionBegin;
237f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
23886d74e61SPeter Brune   if (func) linesearch->ops->postcheckstep = func;
23986d74e61SPeter Brune   if (ctx) linesearch->postcheckctx = ctx;
24086d74e61SPeter Brune   PetscFunctionReturn(0);
24186d74e61SPeter Brune }
24286d74e61SPeter Brune 
24386d74e61SPeter Brune 
24486d74e61SPeter Brune #undef __FUNCT__
245f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchGetPostCheck"
24686d74e61SPeter Brune /*@C
247f1c6b773SPeter Brune    SNESLineSearchGetPostCheck - Gets the post-check function for the line search routine.
24886d74e61SPeter Brune 
24986d74e61SPeter Brune    Input Parameters:
250f1c6b773SPeter Brune .  linesearch - the SNESLineSearch context
25186d74e61SPeter Brune 
25286d74e61SPeter Brune    Output Parameters:
25386d74e61SPeter Brune +  func       - [optional] function evaluation routine
25486d74e61SPeter Brune -  ctx        - [optional] user-defined context for private data for the
25586d74e61SPeter Brune                 function evaluation routine (may be PETSC_NULL)
25686d74e61SPeter Brune 
25786d74e61SPeter Brune    Level: intermediate
25886d74e61SPeter Brune 
25986d74e61SPeter Brune .keywords: get, linesearch, post-check
26086d74e61SPeter Brune 
261f1c6b773SPeter Brune .seealso: SNESLineSearchGetPreCheck(), SNESLineSearchSetPostCheck()
26286d74e61SPeter Brune @*/
263f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetPostCheck(SNESLineSearch linesearch, SNESLineSearchPostCheckFunc *func,void **ctx)
26486d74e61SPeter Brune {
2659bd66eb0SPeter Brune   PetscFunctionBegin;
266f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
26786d74e61SPeter Brune   if (func) *func = linesearch->ops->postcheckstep;
26886d74e61SPeter Brune   if (ctx) *ctx = linesearch->postcheckctx;
26986d74e61SPeter Brune   PetscFunctionReturn(0);
27086d74e61SPeter Brune }
27186d74e61SPeter Brune 
27286d74e61SPeter Brune 
273bf7f4e0aSPeter Brune #undef __FUNCT__
274f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchPreCheck"
275f40b411bSPeter Brune /*@
276f1c6b773SPeter Brune    SNESLineSearchPreCheck - Prepares the line search for being applied.
277f40b411bSPeter Brune 
278f1c6b773SPeter Brune    Collective on SNESLineSearch
279f40b411bSPeter Brune 
280f40b411bSPeter Brune    Input Parameters:
281f40b411bSPeter Brune .  linesearch - The linesearch instance.
282f40b411bSPeter Brune 
283f40b411bSPeter Brune    Output Parameters:
284f40b411bSPeter Brune .  changed - Indicator if the pre-check has changed anything.
285f40b411bSPeter Brune 
286f40b411bSPeter Brune    Level: Beginner
287f40b411bSPeter Brune 
288f1c6b773SPeter Brune    .keywords: SNESLineSearch, Create
289f40b411bSPeter Brune 
290f1c6b773SPeter Brune    .seealso: SNESLineSearchPostCheck()
291f40b411bSPeter Brune @*/
292f1c6b773SPeter Brune PetscErrorCode SNESLineSearchPreCheck(SNESLineSearch linesearch, PetscBool * changed)
293bf7f4e0aSPeter Brune {
294bf7f4e0aSPeter Brune   PetscErrorCode ierr;
295bf7f4e0aSPeter Brune   PetscFunctionBegin;
296bf7f4e0aSPeter Brune   *changed = PETSC_FALSE;
297bf7f4e0aSPeter Brune   if (linesearch->ops->precheckstep) {
298c87759e9SPeter Brune     ierr = (*linesearch->ops->precheckstep)(linesearch, linesearch->vec_sol, linesearch->vec_update, changed, linesearch->precheckctx);CHKERRQ(ierr);
299bf7f4e0aSPeter Brune   }
300bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
301bf7f4e0aSPeter Brune }
302bf7f4e0aSPeter Brune 
303bf7f4e0aSPeter Brune #undef __FUNCT__
304f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchPostCheck"
305f40b411bSPeter Brune /*@
306f1c6b773SPeter Brune    SNESLineSearchPostCheck - Prepares the line search for being applied.
307f40b411bSPeter Brune 
308f1c6b773SPeter Brune    Collective on SNESLineSearch
309f40b411bSPeter Brune 
310f40b411bSPeter Brune    Input Parameters:
311f40b411bSPeter Brune .  linesearch - The linesearch instance.
312f40b411bSPeter Brune 
313f40b411bSPeter Brune    Output Parameters:
31468fb48e8SJed Brown +  changed_Y - Indicator if the direction has been changed.
31568fb48e8SJed Brown -  changed_W - Indicator if the solution has been changed.
316f40b411bSPeter Brune 
317f40b411bSPeter Brune    Level: Intermediate
318f40b411bSPeter Brune 
319f1c6b773SPeter Brune    .keywords: SNESLineSearch, Create
320f40b411bSPeter Brune 
321f1c6b773SPeter Brune    .seealso: SNESLineSearchPreCheck()
322f40b411bSPeter Brune @*/
323f1c6b773SPeter Brune PetscErrorCode SNESLineSearchPostCheck(SNESLineSearch linesearch, PetscBool * changed_Y, PetscBool * changed_W)
324bf7f4e0aSPeter Brune {
325bf7f4e0aSPeter Brune   PetscErrorCode ierr;
326bf7f4e0aSPeter Brune   PetscFunctionBegin;
327bf7f4e0aSPeter Brune   *changed_Y = PETSC_FALSE;
328bf7f4e0aSPeter Brune   *changed_W = PETSC_FALSE;
329bf7f4e0aSPeter Brune   if (linesearch->ops->postcheckstep) {
330c87759e9SPeter Brune     ierr = (*linesearch->ops->postcheckstep)(linesearch, linesearch->vec_sol, linesearch->vec_update, linesearch->vec_sol_new, changed_Y, changed_W, linesearch->postcheckctx);CHKERRQ(ierr);
33186d74e61SPeter Brune   }
33286d74e61SPeter Brune   PetscFunctionReturn(0);
33386d74e61SPeter Brune }
33486d74e61SPeter Brune 
33586d74e61SPeter Brune 
33686d74e61SPeter Brune #undef __FUNCT__
337f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchPreCheckPicard"
33886d74e61SPeter Brune /*@C
33986d74e61SPeter Brune    SNESLineSearchPreCheckPicard - Implements a correction that is sometimes useful to improve the convergence rate of Picard iteration
34086d74e61SPeter Brune 
34186d74e61SPeter Brune    Logically Collective
34286d74e61SPeter Brune 
34386d74e61SPeter Brune    Input Arguments:
34486d74e61SPeter Brune +  linesearch - linesearch context
34586d74e61SPeter Brune .  X - base state for this step
34686d74e61SPeter Brune .  Y - initial correction
34786d74e61SPeter Brune 
34886d74e61SPeter Brune    Output Arguments:
34986d74e61SPeter Brune +  Y - correction, possibly modified
35086d74e61SPeter Brune -  changed - flag indicating that Y was modified
35186d74e61SPeter Brune 
35286d74e61SPeter Brune    Options Database Key:
35386d74e61SPeter Brune +  -snes_ls_precheck_picard - activate this routine
35486d74e61SPeter Brune -  -snes_ls_precheck_picard_angle - angle
35586d74e61SPeter Brune 
35686d74e61SPeter Brune    Level: advanced
35786d74e61SPeter Brune 
35886d74e61SPeter Brune    Notes:
35986d74e61SPeter Brune    This function should be passed to SNESLineSearchSetPreCheck()
36086d74e61SPeter Brune 
36186d74e61SPeter Brune    The justification for this method involves the linear convergence of a Picard iteration
36286d74e61SPeter Brune    so the Picard linearization should be provided in place of the "Jacobian". This correction
36386d74e61SPeter Brune    is generally not useful when using a Newton linearization.
36486d74e61SPeter Brune 
36586d74e61SPeter Brune    Reference:
36686d74e61SPeter Brune    Hindmarsh and Payne (1996) Time step limits for stable solutions of the ice sheet equation, Annals of Glaciology.
36786d74e61SPeter Brune 
36886d74e61SPeter Brune .seealso: SNESLineSearchSetPreCheck()
36986d74e61SPeter Brune @*/
370f1c6b773SPeter Brune PetscErrorCode SNESLineSearchPreCheckPicard(SNESLineSearch linesearch,Vec X,Vec Y,PetscBool *changed,void *ctx)
37186d74e61SPeter Brune {
37286d74e61SPeter Brune   PetscErrorCode ierr;
37386d74e61SPeter Brune   PetscReal      angle = *(PetscReal*)linesearch->precheckctx;
37486d74e61SPeter Brune   Vec            Ylast;
37586d74e61SPeter Brune   PetscScalar    dot;
376c87759e9SPeter Brune 
37786d74e61SPeter Brune   PetscInt       iter;
37886d74e61SPeter Brune   PetscReal      ynorm,ylastnorm,theta,angle_radians;
37986d74e61SPeter Brune   SNES           snes;
38086d74e61SPeter Brune 
38186d74e61SPeter Brune   PetscFunctionBegin;
382f1c6b773SPeter Brune   ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr);
38386d74e61SPeter Brune   ierr = PetscObjectQuery((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject*)&Ylast);CHKERRQ(ierr);
38486d74e61SPeter Brune   if (!Ylast) {
38586d74e61SPeter Brune     ierr = VecDuplicate(Y,&Ylast);CHKERRQ(ierr);
38686d74e61SPeter Brune     ierr = PetscObjectCompose((PetscObject)snes,"SNESLineSearchPreCheckPicard_Ylast",(PetscObject)Ylast);CHKERRQ(ierr);
38786d74e61SPeter Brune     ierr = PetscObjectDereference((PetscObject)Ylast);CHKERRQ(ierr);
38886d74e61SPeter Brune   }
38986d74e61SPeter Brune   ierr = SNESGetIterationNumber(snes,&iter);CHKERRQ(ierr);
39086d74e61SPeter Brune   if (iter < 2) {
39186d74e61SPeter Brune     ierr = VecCopy(Y,Ylast);CHKERRQ(ierr);
39286d74e61SPeter Brune     *changed = PETSC_FALSE;
39386d74e61SPeter Brune     PetscFunctionReturn(0);
39486d74e61SPeter Brune   }
39586d74e61SPeter Brune 
39686d74e61SPeter Brune   ierr = VecDot(Y,Ylast,&dot);CHKERRQ(ierr);
39786d74e61SPeter Brune   ierr = VecNorm(Y,NORM_2,&ynorm);CHKERRQ(ierr);
39886d74e61SPeter Brune   ierr = VecNorm(Ylast,NORM_2,&ylastnorm);CHKERRQ(ierr);
39986d74e61SPeter Brune   /* Compute the angle between the vectors Y and Ylast, clip to keep inside the domain of acos() */
40086d74e61SPeter Brune   theta = acos((double)PetscClipInterval(PetscAbsScalar(dot) / (ynorm * ylastnorm),-1.0,1.0));
40186d74e61SPeter Brune   angle_radians = angle * PETSC_PI / 180.;
40286d74e61SPeter Brune   if (PetscAbsReal(theta) < angle_radians || PetscAbsReal(theta - PETSC_PI) < angle_radians) {
40386d74e61SPeter Brune     /* Modify the step Y */
40486d74e61SPeter Brune     PetscReal alpha,ydiffnorm;
40586d74e61SPeter Brune     ierr = VecAXPY(Ylast,-1.0,Y);CHKERRQ(ierr);
40686d74e61SPeter Brune     ierr = VecNorm(Ylast,NORM_2,&ydiffnorm);CHKERRQ(ierr);
40786d74e61SPeter Brune     alpha = ylastnorm / ydiffnorm;
40886d74e61SPeter Brune     ierr = VecCopy(Y,Ylast);CHKERRQ(ierr);
40986d74e61SPeter Brune     ierr = VecScale(Y,alpha);CHKERRQ(ierr);
41086d74e61SPeter Brune     ierr = PetscInfo3(snes,"Angle %G degrees less than threshold %G, corrected step by alpha=%G\n",theta*180./PETSC_PI,angle,alpha);CHKERRQ(ierr);
41186d74e61SPeter Brune   } else {
41286d74e61SPeter Brune     ierr = PetscInfo2(snes,"Angle %G degrees exceeds threshold %G, no correction applied\n",theta*180./PETSC_PI,angle);CHKERRQ(ierr);
41386d74e61SPeter Brune     ierr = VecCopy(Y,Ylast);CHKERRQ(ierr);
41486d74e61SPeter Brune     *changed = PETSC_FALSE;
415bf7f4e0aSPeter Brune   }
416bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
417bf7f4e0aSPeter Brune }
418bf7f4e0aSPeter Brune 
419bf7f4e0aSPeter Brune #undef __FUNCT__
420f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchApply"
421f40b411bSPeter Brune /*@
422f1c6b773SPeter Brune    SNESLineSearchApply - Computes the line-search update
423f40b411bSPeter Brune 
424f1c6b773SPeter Brune    Collective on SNESLineSearch
425f40b411bSPeter Brune 
426f40b411bSPeter Brune    Input Parameters:
427f40b411bSPeter Brune +  linesearch - The linesearch instance.
428f40b411bSPeter Brune .  X - The current solution.
429f40b411bSPeter Brune .  F - The current function.
430f40b411bSPeter Brune .  fnorm - The current norm.
431f40b411bSPeter Brune .  Y - The search direction.
432f40b411bSPeter Brune 
433f40b411bSPeter Brune    Output Parameters:
434f40b411bSPeter Brune +  X - The new solution.
435f40b411bSPeter Brune .  F - The new function.
436f40b411bSPeter Brune -  fnorm - The new function norm.
437f40b411bSPeter Brune 
438f40b411bSPeter Brune    Level: Intermediate
439f40b411bSPeter Brune 
440f1c6b773SPeter Brune    .keywords: SNESLineSearch, Create
441f40b411bSPeter Brune 
442f1c6b773SPeter Brune    .seealso: SNESLineSearchCreate(), SNESLineSearchPreCheck(), SNESLineSearchPostCheck()
443f40b411bSPeter Brune @*/
444f1c6b773SPeter Brune PetscErrorCode SNESLineSearchApply(SNESLineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y) {
445bf7f4e0aSPeter Brune   PetscErrorCode ierr;
446bf7f4e0aSPeter Brune   PetscFunctionBegin;
447bf7f4e0aSPeter Brune 
448bf7f4e0aSPeter Brune   /* check the pointers */
449f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
450bf7f4e0aSPeter Brune   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
451bf7f4e0aSPeter Brune   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
452bf7f4e0aSPeter Brune   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
453bf7f4e0aSPeter Brune 
454bf7f4e0aSPeter Brune   linesearch->success = PETSC_TRUE;
455bf7f4e0aSPeter Brune 
456bf7f4e0aSPeter Brune   linesearch->vec_sol = X;
457bf7f4e0aSPeter Brune   linesearch->vec_update = Y;
458bf7f4e0aSPeter Brune   linesearch->vec_func = F;
459bf7f4e0aSPeter Brune 
460f1c6b773SPeter Brune   ierr = SNESLineSearchSetUp(linesearch);CHKERRQ(ierr);
461bf7f4e0aSPeter Brune 
462bf7f4e0aSPeter Brune   if (!linesearch->keeplambda)
463bf7f4e0aSPeter Brune     linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
464bf7f4e0aSPeter Brune 
465bf7f4e0aSPeter Brune   if (fnorm) {
466bf7f4e0aSPeter Brune     linesearch->fnorm = *fnorm;
467bf7f4e0aSPeter Brune   } else {
468bf7f4e0aSPeter Brune     ierr = VecNorm(F, NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
469bf7f4e0aSPeter Brune   }
470bf7f4e0aSPeter Brune 
471f1c6b773SPeter Brune   ierr = PetscLogEventBegin(SNESLineSearch_Apply,linesearch,X,F,Y);CHKERRQ(ierr);
472bf7f4e0aSPeter Brune 
473bf7f4e0aSPeter Brune   ierr = (*linesearch->ops->apply)(linesearch);CHKERRQ(ierr);
474bf7f4e0aSPeter Brune 
475f1c6b773SPeter Brune   ierr = PetscLogEventEnd(SNESLineSearch_Apply,linesearch,X,F,Y);CHKERRQ(ierr);
476bf7f4e0aSPeter Brune 
477bf7f4e0aSPeter Brune   if (fnorm)
478bf7f4e0aSPeter Brune     *fnorm = linesearch->fnorm;
479bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
480bf7f4e0aSPeter Brune }
481bf7f4e0aSPeter Brune 
482bf7f4e0aSPeter Brune #undef __FUNCT__
483f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchDestroy"
484f40b411bSPeter Brune /*@
485f1c6b773SPeter Brune    SNESLineSearchDestroy - Destroys the line search instance.
486f40b411bSPeter Brune 
487f1c6b773SPeter Brune    Collective on SNESLineSearch
488f40b411bSPeter Brune 
489f40b411bSPeter Brune    Input Parameters:
490f40b411bSPeter Brune .  linesearch - The linesearch instance.
491f40b411bSPeter Brune 
492f40b411bSPeter Brune    Level: Intermediate
493f40b411bSPeter Brune 
494f1c6b773SPeter Brune    .keywords: SNESLineSearch, Create
495f40b411bSPeter Brune 
496f1c6b773SPeter Brune    .seealso: SNESLineSearchCreate(), SNESLineSearchReset()
497f40b411bSPeter Brune @*/
498f1c6b773SPeter Brune PetscErrorCode SNESLineSearchDestroy(SNESLineSearch * linesearch) {
499bf7f4e0aSPeter Brune   PetscErrorCode ierr;
500bf7f4e0aSPeter Brune   PetscFunctionBegin;
501bf7f4e0aSPeter Brune   if (!*linesearch) PetscFunctionReturn(0);
502f1c6b773SPeter Brune   PetscValidHeaderSpecific((*linesearch),SNESLINESEARCH_CLASSID,1);
503bf7f4e0aSPeter Brune   if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; PetscFunctionReturn(0);}
504bf7f4e0aSPeter Brune   ierr = PetscObjectDepublish((*linesearch));CHKERRQ(ierr);
505f1c6b773SPeter Brune   ierr = SNESLineSearchReset(*linesearch);
506bf7f4e0aSPeter Brune   if ((*linesearch)->ops->destroy) {
507bf7f4e0aSPeter Brune     (*linesearch)->ops->destroy(*linesearch);
508bf7f4e0aSPeter Brune   }
509bf7f4e0aSPeter Brune   ierr = PetscViewerDestroy(&(*linesearch)->monitor);CHKERRQ(ierr);
510e7058c64SPeter Brune   ierr = PetscHeaderDestroy(linesearch);CHKERRQ(ierr);
511bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
512bf7f4e0aSPeter Brune }
513bf7f4e0aSPeter Brune 
514bf7f4e0aSPeter Brune #undef __FUNCT__
515f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetMonitor"
516f40b411bSPeter Brune /*@
517f1c6b773SPeter Brune    SNESLineSearchSetMonitor - Turns on/off printing useful things about the line search.
518bf7f4e0aSPeter Brune 
519bf7f4e0aSPeter Brune    Input Parameters:
520bf7f4e0aSPeter Brune +  snes - nonlinear context obtained from SNESCreate()
521bf7f4e0aSPeter Brune -  flg - PETSC_TRUE to monitor the line search
522bf7f4e0aSPeter Brune 
523bf7f4e0aSPeter Brune    Logically Collective on SNES
524bf7f4e0aSPeter Brune 
525bf7f4e0aSPeter Brune    Options Database:
526f40b411bSPeter Brune .   -linesearch_monitor - enables the monitor.
527bf7f4e0aSPeter Brune 
528bf7f4e0aSPeter Brune    Level: intermediate
529bf7f4e0aSPeter Brune 
530bf7f4e0aSPeter Brune 
531f1c6b773SPeter Brune .seealso: SNESLineSearchGetMonitor()
532bf7f4e0aSPeter Brune @*/
533f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchSetMonitor(SNESLineSearch linesearch, PetscBool flg)
534bf7f4e0aSPeter Brune {
535bf7f4e0aSPeter Brune 
536bf7f4e0aSPeter Brune   PetscErrorCode ierr;
537bf7f4e0aSPeter Brune   PetscFunctionBegin;
538bf7f4e0aSPeter Brune   if (flg && !linesearch->monitor) {
539bf7f4e0aSPeter Brune     ierr = PetscViewerASCIIOpen(((PetscObject)linesearch)->comm,"stdout",&linesearch->monitor);CHKERRQ(ierr);
540bf7f4e0aSPeter Brune   } else if (!flg && linesearch->monitor) {
541bf7f4e0aSPeter Brune     ierr = PetscViewerDestroy(&linesearch->monitor);CHKERRQ(ierr);
542bf7f4e0aSPeter Brune   }
543bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
544bf7f4e0aSPeter Brune }
545bf7f4e0aSPeter Brune 
546bf7f4e0aSPeter Brune #undef __FUNCT__
547f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchGetMonitor"
548f40b411bSPeter Brune /*@
549f1c6b773SPeter Brune    SNESLineSearchGetMonitor - Gets the monitor instance for the line search
5506a388c36SPeter Brune 
551f40b411bSPeter Brune    Input Parameters:
552f40b411bSPeter Brune .  linesearch - linesearch context.
553f40b411bSPeter Brune 
554f40b411bSPeter Brune    Input Parameters:
555f40b411bSPeter Brune .  monitor - monitor context.
556f40b411bSPeter Brune 
557f40b411bSPeter Brune    Logically Collective on SNES
558f40b411bSPeter Brune 
559f40b411bSPeter Brune 
560f40b411bSPeter Brune    Options Database Keys:
561f40b411bSPeter Brune .   -linesearch_monitor - enables the monitor.
562f40b411bSPeter Brune 
563f40b411bSPeter Brune    Level: intermediate
564f40b411bSPeter Brune 
565f40b411bSPeter Brune 
566f1c6b773SPeter Brune .seealso: SNESLineSearchSetMonitor()
567f40b411bSPeter Brune @*/
568f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetMonitor(SNESLineSearch linesearch, PetscViewer *monitor)
5696a388c36SPeter Brune {
5706a388c36SPeter Brune 
5716a388c36SPeter Brune   PetscFunctionBegin;
572f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
5736a388c36SPeter Brune   if (monitor) {
5746a388c36SPeter Brune     PetscValidPointer(monitor, 2);
5756a388c36SPeter Brune     *monitor = linesearch->monitor;
5766a388c36SPeter Brune   }
5776a388c36SPeter Brune   PetscFunctionReturn(0);
5786a388c36SPeter Brune }
5796a388c36SPeter Brune 
5806a388c36SPeter Brune #undef __FUNCT__
581f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetFromOptions"
582f40b411bSPeter Brune /*@
583f1c6b773SPeter Brune    SNESLineSearchSetFromOptions - Sets options for the line search
584f40b411bSPeter Brune 
585f40b411bSPeter Brune    Input Parameters:
586f40b411bSPeter Brune .  linesearch - linesearch context.
587f40b411bSPeter Brune 
588f40b411bSPeter Brune    Options Database Keys:
589f40b411bSPeter Brune + -linesearch_type - The Line search method
590f40b411bSPeter Brune . -linesearch_monitor - Print progress of line searches
591f40b411bSPeter Brune . -linesearch_damping - The linesearch damping parameter.
592f40b411bSPeter Brune . -linesearch_norms   - Turn on/off the linesearch norms
593f40b411bSPeter Brune . -linesearch_keeplambda - Keep the previous search length as the initial guess.
594f40b411bSPeter Brune - -linesearch_max_it - The number of iterations for iterative line searches.
595f40b411bSPeter Brune 
596f1c6b773SPeter Brune    Logically Collective on SNESLineSearch
597f40b411bSPeter Brune 
598f40b411bSPeter Brune    Level: intermediate
599f40b411bSPeter Brune 
600f40b411bSPeter Brune 
601f1c6b773SPeter Brune .seealso: SNESLineSearchCreate()
602f40b411bSPeter Brune @*/
603f1c6b773SPeter Brune PetscErrorCode SNESLineSearchSetFromOptions(SNESLineSearch linesearch) {
604bf7f4e0aSPeter Brune   PetscErrorCode ierr;
605f1c6b773SPeter Brune   const char     *deft = SNES_LINESEARCH_BASIC;
606bf7f4e0aSPeter Brune   char           type[256];
607bf7f4e0aSPeter Brune   PetscBool      flg, set;
608bf7f4e0aSPeter Brune   PetscFunctionBegin;
609f1c6b773SPeter Brune   if (!SNESLineSearchRegisterAllCalled) {ierr = SNESLineSearchRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
610bf7f4e0aSPeter Brune 
611bf7f4e0aSPeter Brune   ierr = PetscObjectOptionsBegin((PetscObject)linesearch);CHKERRQ(ierr);
612bf7f4e0aSPeter Brune   if (((PetscObject)linesearch)->type_name) {
613bf7f4e0aSPeter Brune     deft = ((PetscObject)linesearch)->type_name;
614bf7f4e0aSPeter Brune   }
615*7a35526eSPeter Brune   ierr = PetscOptionsList("-snes_linesearch_type","Line-search method","SNESLineSearchSetType",SNESLineSearchList,deft,type,256,&flg);CHKERRQ(ierr);
616bf7f4e0aSPeter Brune   if (flg) {
617f1c6b773SPeter Brune     ierr = SNESLineSearchSetType(linesearch,type);CHKERRQ(ierr);
618bf7f4e0aSPeter Brune   } else if (!((PetscObject)linesearch)->type_name) {
619f1c6b773SPeter Brune     ierr = SNESLineSearchSetType(linesearch,deft);CHKERRQ(ierr);
620bf7f4e0aSPeter Brune   }
621bf7f4e0aSPeter Brune   if (linesearch->ops->setfromoptions) {
622bf7f4e0aSPeter Brune     (*linesearch->ops->setfromoptions)(linesearch);CHKERRQ(ierr);
623bf7f4e0aSPeter Brune   }
624bf7f4e0aSPeter Brune 
625*7a35526eSPeter Brune   ierr = PetscOptionsBool("-snes_linesearch_monitor","Print progress of line searches","SNESSNESLineSearchSetMonitor",
626bf7f4e0aSPeter Brune                           linesearch->monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
627f1c6b773SPeter Brune   if (set) {ierr = SNESLineSearchSetMonitor(linesearch,flg);CHKERRQ(ierr);}
628bf7f4e0aSPeter Brune 
629*7a35526eSPeter Brune   ierr = PetscOptionsReal("-snes_linesearch_damping","Line search damping and initial step guess","SNESLineSearchSetDamping",linesearch->damping,&linesearch->damping,0);CHKERRQ(ierr);
630*7a35526eSPeter Brune   ierr = PetscOptionsReal("-snes_linesearch_rtol","Tolerance for iterative line search","SNESLineSearchSetRTolerance",linesearch->rtol,&linesearch->rtol,0);CHKERRQ(ierr);
631*7a35526eSPeter Brune   ierr = PetscOptionsBool("-snes_linesearch_norms","Compute final norms in line search","SNESLineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,0);CHKERRQ(ierr);
632*7a35526eSPeter Brune   ierr = PetscOptionsBool("-snes_linesearch_keeplambda","Use previous lambda as damping","SNESLineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,0);CHKERRQ(ierr);
633*7a35526eSPeter Brune   ierr = PetscOptionsInt("-snes_linesearch_max_it","Maximum iterations for iterative line searches","",linesearch->max_its,&linesearch->max_its,0);CHKERRQ(ierr);
634*7a35526eSPeter Brune 
635*7a35526eSPeter Brune   ierr = PetscOptionsBool("-snes_linesearch_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr);
636*7a35526eSPeter Brune   if (set) {
637*7a35526eSPeter Brune     if (flg) {
638*7a35526eSPeter Brune       linesearch->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
639*7a35526eSPeter Brune       ierr = PetscOptionsReal("-snes_linesearch_precheck_picard_angle","Maximum angle at which to activate the correction",
640*7a35526eSPeter Brune                               "none",linesearch->precheck_picard_angle,&linesearch->precheck_picard_angle,PETSC_NULL);CHKERRQ(ierr);
641*7a35526eSPeter Brune       ierr = SNESLineSearchSetPreCheck(linesearch,SNESLineSearchPreCheckPicard,&linesearch->precheck_picard_angle);CHKERRQ(ierr);
642*7a35526eSPeter Brune     } else {
643*7a35526eSPeter Brune       ierr = SNESLineSearchSetPreCheck(linesearch,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
644*7a35526eSPeter Brune     }
645*7a35526eSPeter Brune   }
646*7a35526eSPeter Brune 
647bf7f4e0aSPeter Brune   ierr = PetscObjectProcessOptionsHandlers((PetscObject)linesearch);CHKERRQ(ierr);
648bf7f4e0aSPeter Brune   ierr = PetscOptionsEnd();CHKERRQ(ierr);
649bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
650bf7f4e0aSPeter Brune }
651bf7f4e0aSPeter Brune 
652bf7f4e0aSPeter Brune #undef __FUNCT__
653f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchView"
654f40b411bSPeter Brune /*@
655f1c6b773SPeter Brune    SNESLineSearchView - Views useful information for the line search.
656f40b411bSPeter Brune 
657f40b411bSPeter Brune    Input Parameters:
658f40b411bSPeter Brune .  linesearch - linesearch context.
659f40b411bSPeter Brune 
660f1c6b773SPeter Brune    Logically Collective on SNESLineSearch
661f40b411bSPeter Brune 
662f40b411bSPeter Brune    Level: intermediate
663f40b411bSPeter Brune 
664f40b411bSPeter Brune 
665f1c6b773SPeter Brune .seealso: SNESLineSearchCreate()
666f40b411bSPeter Brune @*/
667f1c6b773SPeter Brune PetscErrorCode SNESLineSearchView(SNESLineSearch linesearch) {
668bf7f4e0aSPeter Brune   PetscFunctionBegin;
669f40b411bSPeter Brune 
670bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
671bf7f4e0aSPeter Brune }
672bf7f4e0aSPeter Brune 
673bf7f4e0aSPeter Brune #undef __FUNCT__
674f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetType"
675ea5d4fccSPeter Brune /*@C
676f1c6b773SPeter Brune    SNESLineSearchSetType - Sets the linesearch type
677f40b411bSPeter Brune 
678f40b411bSPeter Brune    Input Parameters:
679f40b411bSPeter Brune +  linesearch - linesearch context.
680f40b411bSPeter Brune -  type - The type of line search to be used
681f40b411bSPeter Brune 
682f1c6b773SPeter Brune    Logically Collective on SNESLineSearch
683f40b411bSPeter Brune 
684f40b411bSPeter Brune    Level: intermediate
685f40b411bSPeter Brune 
686f40b411bSPeter Brune 
687f1c6b773SPeter Brune .seealso: SNESLineSearchCreate()
688f40b411bSPeter Brune @*/
689f1c6b773SPeter Brune PetscErrorCode SNESLineSearchSetType(SNESLineSearch linesearch, const SNESLineSearchType type)
690bf7f4e0aSPeter Brune {
691bf7f4e0aSPeter Brune 
692f1c6b773SPeter Brune   PetscErrorCode ierr,(*r)(SNESLineSearch);
693bf7f4e0aSPeter Brune   PetscBool      match;
694bf7f4e0aSPeter Brune 
695bf7f4e0aSPeter Brune   PetscFunctionBegin;
696f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
697bf7f4e0aSPeter Brune   PetscValidCharPointer(type,2);
698bf7f4e0aSPeter Brune 
699bf7f4e0aSPeter Brune   ierr = PetscTypeCompare((PetscObject)linesearch,type,&match);CHKERRQ(ierr);
700bf7f4e0aSPeter Brune   if (match) PetscFunctionReturn(0);
701bf7f4e0aSPeter Brune 
702f1c6b773SPeter Brune   ierr =  PetscFListFind(SNESLineSearchList,((PetscObject)linesearch)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
703bf7f4e0aSPeter Brune   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
704bf7f4e0aSPeter Brune   /* Destroy the previous private linesearch context */
705bf7f4e0aSPeter Brune   if (linesearch->ops->destroy) {
706bf7f4e0aSPeter Brune     ierr = (*(linesearch)->ops->destroy)(linesearch);CHKERRQ(ierr);
707bf7f4e0aSPeter Brune     linesearch->ops->destroy = PETSC_NULL;
708bf7f4e0aSPeter Brune   }
709f1c6b773SPeter Brune   /* Reinitialize function pointers in SNESLineSearchOps structure */
710bf7f4e0aSPeter Brune   linesearch->ops->apply          = 0;
711bf7f4e0aSPeter Brune   linesearch->ops->view           = 0;
712bf7f4e0aSPeter Brune   linesearch->ops->setfromoptions = 0;
713bf7f4e0aSPeter Brune   linesearch->ops->destroy        = 0;
714bf7f4e0aSPeter Brune 
715bf7f4e0aSPeter Brune   ierr = PetscObjectChangeTypeName((PetscObject)linesearch,type);CHKERRQ(ierr);
716bf7f4e0aSPeter Brune   ierr = (*r)(linesearch);CHKERRQ(ierr);
717bf7f4e0aSPeter Brune #if defined(PETSC_HAVE_AMS)
718bf7f4e0aSPeter Brune   if (PetscAMSPublishAll) {
719bf7f4e0aSPeter Brune     ierr = PetscObjectAMSPublish((PetscObject)linesearch);CHKERRQ(ierr);
720bf7f4e0aSPeter Brune   }
721bf7f4e0aSPeter Brune #endif
722bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
723bf7f4e0aSPeter Brune }
724bf7f4e0aSPeter Brune 
725bf7f4e0aSPeter Brune #undef __FUNCT__
726f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetSNES"
727f40b411bSPeter Brune /*@
728f1c6b773SPeter Brune    SNESLineSearchSetSNES - Sets the SNES for the linesearch for function evaluation
729f40b411bSPeter Brune 
730f40b411bSPeter Brune    Input Parameters:
731f40b411bSPeter Brune +  linesearch - linesearch context.
732f40b411bSPeter Brune -  snes - The snes instance
733f40b411bSPeter Brune 
734f40b411bSPeter Brune    Level: intermediate
735f40b411bSPeter Brune 
736f40b411bSPeter Brune 
737f1c6b773SPeter Brune .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs()
738f40b411bSPeter Brune @*/
739f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchSetSNES(SNESLineSearch linesearch, SNES snes){
740bf7f4e0aSPeter Brune   PetscFunctionBegin;
741f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
742bf7f4e0aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
743bf7f4e0aSPeter Brune   linesearch->snes = snes;
744bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
745bf7f4e0aSPeter Brune }
746bf7f4e0aSPeter Brune 
747bf7f4e0aSPeter Brune #undef __FUNCT__
748f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchGetSNES"
749f40b411bSPeter Brune /*@
750f1c6b773SPeter Brune    SNESLineSearchGetSNES - Gets the SNES for the linesearch for function evaluation
751f40b411bSPeter Brune 
752f40b411bSPeter Brune    Input Parameters:
753f40b411bSPeter Brune .  linesearch - linesearch context.
754f40b411bSPeter Brune 
755f40b411bSPeter Brune    Output Parameters:
756f40b411bSPeter Brune .  snes - The snes instance
757f40b411bSPeter Brune 
758f40b411bSPeter Brune    Level: intermediate
759f40b411bSPeter Brune 
760f1c6b773SPeter Brune .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs()
761f40b411bSPeter Brune @*/
762f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetSNES(SNESLineSearch linesearch, SNES *snes){
763bf7f4e0aSPeter Brune   PetscFunctionBegin;
764f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
7656a388c36SPeter Brune   PetscValidPointer(snes, 2);
766bf7f4e0aSPeter Brune   *snes = linesearch->snes;
767bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
768bf7f4e0aSPeter Brune }
769bf7f4e0aSPeter Brune 
7706a388c36SPeter Brune #undef __FUNCT__
771f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchGetLambda"
772f40b411bSPeter Brune /*@
773f1c6b773SPeter Brune    SNESLineSearchGetLambda - Gets the last linesearch steplength discovered.
774f40b411bSPeter Brune 
775f40b411bSPeter Brune    Input Parameters:
776f40b411bSPeter Brune .  linesearch - linesearch context.
777f40b411bSPeter Brune 
778f40b411bSPeter Brune    Output Parameters:
779f40b411bSPeter Brune .  lambda - The last steplength.
780f40b411bSPeter Brune 
781f40b411bSPeter Brune    Level: intermediate
782f40b411bSPeter Brune 
783f1c6b773SPeter Brune .seealso: SNESLineSearchGetSNES(), SNESLineSearchSetVecs()
784f40b411bSPeter Brune @*/
785f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetLambda(SNESLineSearch linesearch,PetscReal *lambda)
7866a388c36SPeter Brune {
7876a388c36SPeter Brune   PetscFunctionBegin;
788f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
7896a388c36SPeter Brune   PetscValidPointer(lambda, 2);
7906a388c36SPeter Brune   *lambda = linesearch->lambda;
7916a388c36SPeter Brune   PetscFunctionReturn(0);
7926a388c36SPeter Brune }
7936a388c36SPeter Brune 
7946a388c36SPeter Brune #undef __FUNCT__
795f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetLambda"
796f40b411bSPeter Brune /*@
797f1c6b773SPeter Brune    SNESLineSearchSetLambda - Sets the linesearch steplength.
798f40b411bSPeter Brune 
799f40b411bSPeter Brune    Input Parameters:
800f40b411bSPeter Brune +  linesearch - linesearch context.
801f40b411bSPeter Brune -  lambda - The last steplength.
802f40b411bSPeter Brune 
803f40b411bSPeter Brune    Level: intermediate
804f40b411bSPeter Brune 
805f1c6b773SPeter Brune .seealso: SNESLineSearchGetLambda()
806f40b411bSPeter Brune @*/
807f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchSetLambda(SNESLineSearch linesearch, PetscReal lambda)
8086a388c36SPeter Brune {
8096a388c36SPeter Brune   PetscFunctionBegin;
810f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
8116a388c36SPeter Brune   linesearch->lambda = lambda;
8126a388c36SPeter Brune   PetscFunctionReturn(0);
8136a388c36SPeter Brune }
8146a388c36SPeter Brune 
8156a388c36SPeter Brune #undef  __FUNCT__
816f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchGetTolerances"
817f40b411bSPeter Brune /*@
818f1c6b773SPeter Brune    SNESLineSearchGetTolerances - Gets the tolerances for the method
819f40b411bSPeter Brune 
820f40b411bSPeter Brune    Input Parameters:
821f40b411bSPeter Brune .  linesearch - linesearch context.
822f40b411bSPeter Brune 
823f40b411bSPeter Brune    Output Parameters:
824516fe3c3SPeter Brune +  steptol - The minimum steplength
825516fe3c3SPeter Brune .  rtol    - The relative tolerance for iterative line searches
826516fe3c3SPeter Brune .  atol    - The absolute tolerance for iterative line searches
827516fe3c3SPeter Brune .  ltol    - The change in lambda tolerance for iterative line searches
828516fe3c3SPeter Brune -  max_it  - The maximum number of iterations of the line search
829f40b411bSPeter Brune 
830f40b411bSPeter Brune 
831516fe3c3SPeter Brune    Level: advanced
832516fe3c3SPeter Brune 
833f1c6b773SPeter Brune .seealso: SNESLineSearchSetTolerances()
834f40b411bSPeter Brune @*/
835f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetTolerances(SNESLineSearch linesearch,PetscReal *steptol,PetscReal *maxstep, PetscReal *rtol, PetscReal *atol, PetscReal *ltol, PetscInt *max_its)
8366a388c36SPeter Brune {
8376a388c36SPeter Brune   PetscFunctionBegin;
838f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
839516fe3c3SPeter Brune   if (steptol) {
8406a388c36SPeter Brune     PetscValidPointer(steptol, 2);
8416a388c36SPeter Brune     *steptol = linesearch->steptol;
842516fe3c3SPeter Brune   }
843516fe3c3SPeter Brune   if (maxstep) {
844516fe3c3SPeter Brune     PetscValidPointer(maxstep, 3);
845516fe3c3SPeter Brune     *maxstep = linesearch->maxstep;
846516fe3c3SPeter Brune   }
847516fe3c3SPeter Brune   if (rtol) {
848516fe3c3SPeter Brune     PetscValidPointer(rtol, 4);
849516fe3c3SPeter Brune     *rtol = linesearch->rtol;
850516fe3c3SPeter Brune   }
851516fe3c3SPeter Brune   if (atol) {
852516fe3c3SPeter Brune     PetscValidPointer(atol, 5);
853516fe3c3SPeter Brune     *atol = linesearch->atol;
854516fe3c3SPeter Brune   }
855516fe3c3SPeter Brune   if (ltol) {
856516fe3c3SPeter Brune     PetscValidPointer(ltol, 6);
857516fe3c3SPeter Brune     *ltol = linesearch->ltol;
858516fe3c3SPeter Brune   }
859516fe3c3SPeter Brune   if (max_its) {
860516fe3c3SPeter Brune     PetscValidPointer(max_its, 7);
861516fe3c3SPeter Brune     *max_its = linesearch->max_its;
862516fe3c3SPeter Brune   }
8636a388c36SPeter Brune   PetscFunctionReturn(0);
8646a388c36SPeter Brune }
8656a388c36SPeter Brune 
8666a388c36SPeter Brune #undef  __FUNCT__
867f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetTolerances"
868f40b411bSPeter Brune /*@
869f1c6b773SPeter Brune    SNESLineSearchSetTolerances - Sets the tolerances for the method
870f40b411bSPeter Brune 
871f40b411bSPeter Brune    Input Parameters:
872516fe3c3SPeter Brune +  linesearch - linesearch context.
873516fe3c3SPeter Brune .  steptol - The minimum steplength
874516fe3c3SPeter Brune .  rtol    - The relative tolerance for iterative line searches
875516fe3c3SPeter Brune .  atol    - The absolute tolerance for iterative line searches
876516fe3c3SPeter Brune .  ltol    - The change in lambda tolerance for iterative line searches
877516fe3c3SPeter Brune -  max_it  - The maximum number of iterations of the line search
878f40b411bSPeter Brune 
879f40b411bSPeter Brune 
880516fe3c3SPeter Brune    Level: advanced
881516fe3c3SPeter Brune 
882f1c6b773SPeter Brune .seealso: SNESLineSearchGetTolerances()
883f40b411bSPeter Brune @*/
884f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchSetTolerances(SNESLineSearch linesearch,PetscReal steptol,PetscReal maxstep, PetscReal rtol, PetscReal atol, PetscReal ltol, PetscInt max_its)
8856a388c36SPeter Brune {
8866a388c36SPeter Brune   PetscFunctionBegin;
887f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
8886a388c36SPeter Brune   linesearch->steptol = steptol;
889516fe3c3SPeter Brune   linesearch->maxstep = maxstep;
890516fe3c3SPeter Brune   linesearch->rtol = rtol;
891516fe3c3SPeter Brune   linesearch->atol = atol;
892516fe3c3SPeter Brune   linesearch->ltol = ltol;
893516fe3c3SPeter Brune   linesearch->max_its = max_its;
8946a388c36SPeter Brune   PetscFunctionReturn(0);
8956a388c36SPeter Brune }
8966a388c36SPeter Brune 
897516fe3c3SPeter Brune 
8986a388c36SPeter Brune #undef __FUNCT__
899f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchGetDamping"
900f40b411bSPeter Brune /*@
901f1c6b773SPeter Brune    SNESLineSearchGetDamping - Gets the line search damping parameter.
902f40b411bSPeter Brune 
903f40b411bSPeter Brune    Input Parameters:
904f40b411bSPeter Brune .  linesearch - linesearch context.
905f40b411bSPeter Brune 
906f40b411bSPeter Brune    Output Parameters:
907f40b411bSPeter Brune .  damping - The damping parameter.
908f40b411bSPeter Brune 
909f40b411bSPeter Brune    Level: intermediate
910f40b411bSPeter Brune 
911f1c6b773SPeter Brune .seealso: SNESLineSearchGetStepTolerance()
912f40b411bSPeter Brune @*/
913f40b411bSPeter Brune 
914f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetDamping(SNESLineSearch linesearch,PetscReal *damping)
9156a388c36SPeter Brune {
9166a388c36SPeter Brune   PetscFunctionBegin;
917f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
9186a388c36SPeter Brune   PetscValidPointer(damping, 2);
9196a388c36SPeter Brune   *damping = linesearch->damping;
9206a388c36SPeter Brune   PetscFunctionReturn(0);
9216a388c36SPeter Brune }
9226a388c36SPeter Brune 
9236a388c36SPeter Brune #undef __FUNCT__
924f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetDamping"
925f40b411bSPeter Brune /*@
926f1c6b773SPeter Brune    SNESLineSearchSetDamping - Sets the line search damping paramter.
927f40b411bSPeter Brune 
928f40b411bSPeter Brune    Input Parameters:
929f40b411bSPeter Brune .  linesearch - linesearch context.
930f40b411bSPeter Brune .  damping - The damping parameter.
931f40b411bSPeter Brune 
932f40b411bSPeter Brune    Level: intermediate
933f40b411bSPeter Brune 
934f1c6b773SPeter Brune .seealso: SNESLineSearchGetDamping()
935f40b411bSPeter Brune @*/
936f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchSetDamping(SNESLineSearch linesearch,PetscReal damping)
9376a388c36SPeter Brune {
9386a388c36SPeter Brune   PetscFunctionBegin;
939f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
9406a388c36SPeter Brune   linesearch->damping = damping;
9416a388c36SPeter Brune   PetscFunctionReturn(0);
9426a388c36SPeter Brune }
9436a388c36SPeter Brune 
9446a388c36SPeter Brune #undef __FUNCT__
945f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchGetNorms"
946f40b411bSPeter Brune /*@
947f1c6b773SPeter Brune    SNESLineSearchGetNorms - Gets the norms for for X, Y, and F.
948f40b411bSPeter Brune 
949f40b411bSPeter Brune    Input Parameters:
950f40b411bSPeter Brune .  linesearch - linesearch context.
951f40b411bSPeter Brune 
952f40b411bSPeter Brune    Output Parameters:
953f40b411bSPeter Brune +  xnorm - The norm of the current solution
954f40b411bSPeter Brune .  fnorm - The norm of the current function
955f40b411bSPeter Brune -  ynorm - The norm of the current update
956f40b411bSPeter Brune 
957f40b411bSPeter Brune    Level: intermediate
958f40b411bSPeter Brune 
959f1c6b773SPeter Brune .seealso: SNESLineSearchSetNorms() SNESLineSearchGetVecs()
960f40b411bSPeter Brune @*/
961f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetNorms(SNESLineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
962bf7f4e0aSPeter Brune {
963bf7f4e0aSPeter Brune   PetscFunctionBegin;
964f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
965bf7f4e0aSPeter Brune   if (xnorm) {
966bf7f4e0aSPeter Brune     *xnorm = linesearch->xnorm;
967bf7f4e0aSPeter Brune   }
968bf7f4e0aSPeter Brune   if (fnorm) {
969bf7f4e0aSPeter Brune     *fnorm = linesearch->fnorm;
970bf7f4e0aSPeter Brune   }
971bf7f4e0aSPeter Brune   if (ynorm) {
972bf7f4e0aSPeter Brune     *ynorm = linesearch->ynorm;
973bf7f4e0aSPeter Brune   }
974bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
975bf7f4e0aSPeter Brune }
976bf7f4e0aSPeter Brune 
977e7058c64SPeter Brune #undef __FUNCT__
978f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetNorms"
979f40b411bSPeter Brune /*@
980f1c6b773SPeter Brune    SNESLineSearchSetNorms - Gets the computed norms for for X, Y, and F.
981f40b411bSPeter Brune 
982f40b411bSPeter Brune    Input Parameters:
983f40b411bSPeter Brune +  linesearch - linesearch context.
984f40b411bSPeter Brune .  xnorm - The norm of the current solution
985f40b411bSPeter Brune .  fnorm - The norm of the current function
986f40b411bSPeter Brune -  ynorm - The norm of the current update
987f40b411bSPeter Brune 
988f40b411bSPeter Brune    Level: intermediate
989f40b411bSPeter Brune 
990f1c6b773SPeter Brune .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
991f40b411bSPeter Brune @*/
992f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchSetNorms(SNESLineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
9936a388c36SPeter Brune {
9946a388c36SPeter Brune   PetscFunctionBegin;
995f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
9966a388c36SPeter Brune   linesearch->xnorm = xnorm;
9976a388c36SPeter Brune   linesearch->fnorm = fnorm;
9986a388c36SPeter Brune   linesearch->ynorm = ynorm;
9996a388c36SPeter Brune   PetscFunctionReturn(0);
10006a388c36SPeter Brune }
10016a388c36SPeter Brune 
10026a388c36SPeter Brune #undef __FUNCT__
1003f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchComputeNorms"
1004f40b411bSPeter Brune /*@
1005f1c6b773SPeter Brune    SNESLineSearchComputeNorms - Computes the norms of X, F, and Y.
1006f40b411bSPeter Brune 
1007f40b411bSPeter Brune    Input Parameters:
1008f40b411bSPeter Brune .  linesearch - linesearch context.
1009f40b411bSPeter Brune 
1010f40b411bSPeter Brune    Options Database Keys:
1011f40b411bSPeter Brune .   -linesearch_norms - turn norm computation on or off.
1012f40b411bSPeter Brune 
1013f40b411bSPeter Brune    Level: intermediate
1014f40b411bSPeter Brune 
1015f1c6b773SPeter Brune .seealso: SNESLineSearchGetNorms, SNESLineSearchSetNorms()
1016f40b411bSPeter Brune @*/
1017f1c6b773SPeter Brune PetscErrorCode SNESLineSearchComputeNorms(SNESLineSearch linesearch)
10186a388c36SPeter Brune {
10196a388c36SPeter Brune   PetscErrorCode ierr;
10209bd66eb0SPeter Brune   SNES snes;
10216a388c36SPeter Brune   PetscFunctionBegin;
10226a388c36SPeter Brune   if (linesearch->norms) {
10239bd66eb0SPeter Brune     if (linesearch->ops->vinorm) {
1024f1c6b773SPeter Brune       ierr = SNESLineSearchGetSNES(linesearch, &snes);CHKERRQ(ierr);
10259bd66eb0SPeter Brune       ierr = VecNorm(linesearch->vec_sol, NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
10269bd66eb0SPeter Brune       ierr = VecNorm(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
10279bd66eb0SPeter Brune       ierr = (*linesearch->ops->vinorm)(snes, linesearch->vec_func, linesearch->vec_sol, &linesearch->fnorm);CHKERRQ(ierr);
10289bd66eb0SPeter Brune     } else {
10296a388c36SPeter Brune       ierr = VecNormBegin(linesearch->vec_func,   NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
10306a388c36SPeter Brune       ierr = VecNormBegin(linesearch->vec_sol,    NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
10316a388c36SPeter Brune       ierr = VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
10326a388c36SPeter Brune       ierr = VecNormEnd(linesearch->vec_func,     NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
10336a388c36SPeter Brune       ierr = VecNormEnd(linesearch->vec_sol,      NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
10346a388c36SPeter Brune       ierr = VecNormEnd(linesearch->vec_update,   NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
10356a388c36SPeter Brune     }
10369bd66eb0SPeter Brune   }
10376a388c36SPeter Brune   PetscFunctionReturn(0);
10386a388c36SPeter Brune }
10396a388c36SPeter Brune 
10406a388c36SPeter Brune #undef __FUNCT__
1041f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchGetVecs"
1042f40b411bSPeter Brune /*@
1043f1c6b773SPeter Brune    SNESLineSearchGetVecs - Gets the vectors from the SNESLineSearch context
1044f40b411bSPeter Brune 
1045f40b411bSPeter Brune    Input Parameters:
1046f40b411bSPeter Brune .  linesearch - linesearch context.
1047f40b411bSPeter Brune 
1048f40b411bSPeter Brune    Output Parameters:
1049f40b411bSPeter Brune +  X - The old solution
1050f40b411bSPeter Brune .  F - The old function
1051f40b411bSPeter Brune .  Y - The search direction
1052f40b411bSPeter Brune .  W - The new solution
1053f40b411bSPeter Brune -  G - The new function
1054f40b411bSPeter Brune 
1055f40b411bSPeter Brune    Level: intermediate
1056f40b411bSPeter Brune 
1057f1c6b773SPeter Brune .seealso: SNESLineSearchGetNorms(), SNESLineSearchSetVecs()
1058f40b411bSPeter Brune @*/
1059f1c6b773SPeter Brune PetscErrorCode SNESLineSearchGetVecs(SNESLineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G) {
10606a388c36SPeter Brune   PetscFunctionBegin;
1061f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
10626a388c36SPeter Brune   if (X) {
10636a388c36SPeter Brune     PetscValidPointer(X, 2);
10646a388c36SPeter Brune     *X = linesearch->vec_sol;
10656a388c36SPeter Brune   }
10666a388c36SPeter Brune   if (F) {
10676a388c36SPeter Brune     PetscValidPointer(F, 3);
10686a388c36SPeter Brune     *F = linesearch->vec_func;
10696a388c36SPeter Brune   }
10706a388c36SPeter Brune   if (Y) {
10716a388c36SPeter Brune     PetscValidPointer(Y, 4);
10726a388c36SPeter Brune     *Y = linesearch->vec_update;
10736a388c36SPeter Brune   }
10746a388c36SPeter Brune   if (W) {
10756a388c36SPeter Brune     PetscValidPointer(W, 5);
10766a388c36SPeter Brune     *W = linesearch->vec_sol_new;
10776a388c36SPeter Brune   }
10786a388c36SPeter Brune   if (G) {
10796a388c36SPeter Brune     PetscValidPointer(G, 6);
10806a388c36SPeter Brune     *G = linesearch->vec_func_new;
10816a388c36SPeter Brune   }
10826a388c36SPeter Brune 
10836a388c36SPeter Brune   PetscFunctionReturn(0);
10846a388c36SPeter Brune }
10856a388c36SPeter Brune 
10866a388c36SPeter Brune #undef __FUNCT__
1087f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetVecs"
1088f40b411bSPeter Brune /*@
1089f1c6b773SPeter Brune    SNESLineSearchSetVecs - Sets the vectors on the SNESLineSearch context
1090f40b411bSPeter Brune 
1091f40b411bSPeter Brune    Input Parameters:
1092f40b411bSPeter Brune +  linesearch - linesearch context.
1093f40b411bSPeter Brune .  X - The old solution
1094f40b411bSPeter Brune .  F - The old function
1095f40b411bSPeter Brune .  Y - The search direction
1096f40b411bSPeter Brune .  W - The new solution
1097f40b411bSPeter Brune -  G - The new function
1098f40b411bSPeter Brune 
1099f40b411bSPeter Brune    Level: intermediate
1100f40b411bSPeter Brune 
1101f1c6b773SPeter Brune .seealso: SNESLineSearchSetNorms(), SNESLineSearchGetVecs()
1102f40b411bSPeter Brune @*/
1103f1c6b773SPeter Brune PetscErrorCode SNESLineSearchSetVecs(SNESLineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G) {
11046a388c36SPeter Brune   PetscFunctionBegin;
1105f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
11066a388c36SPeter Brune   if (X) {
11076a388c36SPeter Brune     PetscValidHeaderSpecific(X,VEC_CLASSID,2);
11086a388c36SPeter Brune     linesearch->vec_sol = X;
11096a388c36SPeter Brune   }
11106a388c36SPeter Brune   if (F) {
11116a388c36SPeter Brune     PetscValidHeaderSpecific(F,VEC_CLASSID,3);
11126a388c36SPeter Brune     linesearch->vec_func = F;
11136a388c36SPeter Brune   }
11146a388c36SPeter Brune   if (Y) {
11156a388c36SPeter Brune     PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
11166a388c36SPeter Brune     linesearch->vec_update = Y;
11176a388c36SPeter Brune   }
11186a388c36SPeter Brune   if (W) {
11196a388c36SPeter Brune     PetscValidHeaderSpecific(W,VEC_CLASSID,5);
11206a388c36SPeter Brune     linesearch->vec_sol_new = W;
11216a388c36SPeter Brune   }
11226a388c36SPeter Brune   if (G) {
11236a388c36SPeter Brune     PetscValidHeaderSpecific(G,VEC_CLASSID,6);
11246a388c36SPeter Brune     linesearch->vec_func_new = G;
11256a388c36SPeter Brune   }
11266a388c36SPeter Brune 
11276a388c36SPeter Brune   PetscFunctionReturn(0);
11286a388c36SPeter Brune }
11296a388c36SPeter Brune 
11306a388c36SPeter Brune #undef __FUNCT__
1131f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchAppendOptionsPrefix"
1132e7058c64SPeter Brune /*@C
1133f1c6b773SPeter Brune    SNESLineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
1134e7058c64SPeter Brune    SNES options in the database.
1135e7058c64SPeter Brune 
1136e7058c64SPeter Brune    Logically Collective on SNES
1137e7058c64SPeter Brune 
1138e7058c64SPeter Brune    Input Parameters:
1139e7058c64SPeter Brune +  snes - the SNES context
1140e7058c64SPeter Brune -  prefix - the prefix to prepend to all option names
1141e7058c64SPeter Brune 
1142e7058c64SPeter Brune    Notes:
1143e7058c64SPeter Brune    A hyphen (-) must NOT be given at the beginning of the prefix name.
1144e7058c64SPeter Brune    The first character of all runtime options is AUTOMATICALLY the hyphen.
1145e7058c64SPeter Brune 
1146e7058c64SPeter Brune    Level: advanced
1147e7058c64SPeter Brune 
1148f1c6b773SPeter Brune .keywords: SNESLineSearch, append, options, prefix, database
1149e7058c64SPeter Brune 
1150e7058c64SPeter Brune .seealso: SNESGetOptionsPrefix()
1151e7058c64SPeter Brune @*/
1152f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchAppendOptionsPrefix(SNESLineSearch linesearch,const char prefix[])
1153e7058c64SPeter Brune {
1154e7058c64SPeter Brune   PetscErrorCode ierr;
1155e7058c64SPeter Brune 
1156e7058c64SPeter Brune   PetscFunctionBegin;
1157f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1158e7058c64SPeter Brune   ierr = PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr);
1159e7058c64SPeter Brune   PetscFunctionReturn(0);
1160e7058c64SPeter Brune }
1161e7058c64SPeter Brune 
1162e7058c64SPeter Brune #undef __FUNCT__
1163f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchGetOptionsPrefix"
1164e7058c64SPeter Brune /*@C
1165f1c6b773SPeter Brune    SNESLineSearchGetOptionsPrefix - Sets the prefix used for searching for all
1166f1c6b773SPeter Brune    SNESLineSearch options in the database.
1167e7058c64SPeter Brune 
1168e7058c64SPeter Brune    Not Collective
1169e7058c64SPeter Brune 
1170e7058c64SPeter Brune    Input Parameter:
1171e7058c64SPeter Brune .  snes - the SNES context
1172e7058c64SPeter Brune 
1173e7058c64SPeter Brune    Output Parameter:
1174e7058c64SPeter Brune .  prefix - pointer to the prefix string used
1175e7058c64SPeter Brune 
1176e7058c64SPeter Brune    Notes: On the fortran side, the user should pass in a string 'prefix' of
1177e7058c64SPeter Brune    sufficient length to hold the prefix.
1178e7058c64SPeter Brune 
1179e7058c64SPeter Brune    Level: advanced
1180e7058c64SPeter Brune 
1181f1c6b773SPeter Brune .keywords: SNESLineSearch, get, options, prefix, database
1182e7058c64SPeter Brune 
1183e7058c64SPeter Brune .seealso: SNESAppendOptionsPrefix()
1184e7058c64SPeter Brune @*/
1185f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetOptionsPrefix(SNESLineSearch linesearch,const char *prefix[])
1186e7058c64SPeter Brune {
1187e7058c64SPeter Brune   PetscErrorCode ierr;
1188e7058c64SPeter Brune 
1189e7058c64SPeter Brune   PetscFunctionBegin;
1190f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
1191e7058c64SPeter Brune   ierr = PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr);
1192e7058c64SPeter Brune   PetscFunctionReturn(0);
1193e7058c64SPeter Brune }
1194bf7f4e0aSPeter Brune 
1195bf7f4e0aSPeter Brune #undef __FUNCT__
1196f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchGetWork"
1197f40b411bSPeter Brune /*@
1198f1c6b773SPeter Brune    SNESLineSearchGetWork - Gets work vectors for the line search.
1199f40b411bSPeter Brune 
1200f40b411bSPeter Brune    Input Parameter:
1201f1c6b773SPeter Brune +  linesearch - the SNESLineSearch context
1202f40b411bSPeter Brune -  nwork - the number of work vectors
1203f40b411bSPeter Brune 
1204f40b411bSPeter Brune    Level: developer
1205f40b411bSPeter Brune 
1206f1c6b773SPeter Brune .keywords: SNESLineSearch, work, vector
1207f40b411bSPeter Brune 
1208f40b411bSPeter Brune .seealso: SNESDefaultGetWork()
1209f40b411bSPeter Brune @*/
1210f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetWork(SNESLineSearch linesearch, PetscInt nwork)
1211bf7f4e0aSPeter Brune {
1212bf7f4e0aSPeter Brune   PetscErrorCode ierr;
1213bf7f4e0aSPeter Brune   PetscFunctionBegin;
1214bf7f4e0aSPeter Brune   if (linesearch->vec_sol) {
1215bf7f4e0aSPeter Brune     ierr = VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);CHKERRQ(ierr);
1216bf7f4e0aSPeter Brune   } else {
1217bf7f4e0aSPeter Brune     SETERRQ(((PetscObject)linesearch)->comm, PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1218bf7f4e0aSPeter Brune   }
1219bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
1220bf7f4e0aSPeter Brune }
1221bf7f4e0aSPeter Brune 
12226a388c36SPeter Brune 
1223bf7f4e0aSPeter Brune #undef __FUNCT__
1224f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchGetSuccess"
1225f40b411bSPeter Brune /*@
1226f1c6b773SPeter Brune    SNESLineSearchGetSuccess - Gets the success/failure status of the last line search application
1227f40b411bSPeter Brune 
1228f40b411bSPeter Brune    Input Parameters:
1229f40b411bSPeter Brune .  linesearch - linesearch context.
1230f40b411bSPeter Brune 
1231f40b411bSPeter Brune    Output Parameters:
1232f40b411bSPeter Brune .  success - The success or failure status.
1233f40b411bSPeter Brune 
1234f40b411bSPeter Brune    Level: intermediate
1235f40b411bSPeter Brune 
1236f1c6b773SPeter Brune .seealso: SNESLineSearchSetSuccess()
1237f40b411bSPeter Brune @*/
1238f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchGetSuccess(SNESLineSearch linesearch, PetscBool *success)
1239bf7f4e0aSPeter Brune {
1240bf7f4e0aSPeter Brune   PetscFunctionBegin;
1241f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
12426a388c36SPeter Brune   PetscValidPointer(success, 2);
1243bf7f4e0aSPeter Brune   if (success) {
1244bf7f4e0aSPeter Brune     *success = linesearch->success;
1245bf7f4e0aSPeter Brune   }
1246bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
1247bf7f4e0aSPeter Brune }
1248bf7f4e0aSPeter Brune 
1249bf7f4e0aSPeter Brune #undef __FUNCT__
1250f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetSuccess"
1251f40b411bSPeter Brune /*@
1252f1c6b773SPeter Brune    SNESLineSearchSetSuccess - Sets the success/failure status of the last line search application
1253f40b411bSPeter Brune 
1254f40b411bSPeter Brune    Input Parameters:
1255f40b411bSPeter Brune +  linesearch - linesearch context.
1256f40b411bSPeter Brune -  success - The success or failure status.
1257f40b411bSPeter Brune 
1258f40b411bSPeter Brune    Level: intermediate
1259f40b411bSPeter Brune 
1260f1c6b773SPeter Brune .seealso: SNESLineSearchGetSuccess()
1261f40b411bSPeter Brune @*/
1262f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchSetSuccess(SNESLineSearch linesearch, PetscBool success)
12636a388c36SPeter Brune {
1264f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
12656a388c36SPeter Brune   PetscFunctionBegin;
12666a388c36SPeter Brune   linesearch->success = success;
12676a388c36SPeter Brune   PetscFunctionReturn(0);
12686a388c36SPeter Brune }
12696a388c36SPeter Brune 
12706a388c36SPeter Brune #undef __FUNCT__
1271f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchSetVIFunctions"
12729bd66eb0SPeter Brune /*@C
1273f1c6b773SPeter Brune    SNESLineSearchSetVIFunctions - Sets VI-specific functions for line search computation.
12749bd66eb0SPeter Brune 
12759bd66eb0SPeter Brune    Input Parameters:
12769bd66eb0SPeter Brune +  snes - nonlinear context obtained from SNESCreate()
12779bd66eb0SPeter Brune .  projectfunc - function for projecting the function to the bounds
12789bd66eb0SPeter Brune -  normfunc - function for computing the norm of an active set
12799bd66eb0SPeter Brune 
12809bd66eb0SPeter Brune    Logically Collective on SNES
12819bd66eb0SPeter Brune 
12829bd66eb0SPeter Brune    Calling sequence of projectfunc:
12839bd66eb0SPeter Brune .vb
12849bd66eb0SPeter Brune    projectfunc (SNES snes, Vec X)
12859bd66eb0SPeter Brune .ve
12869bd66eb0SPeter Brune 
12879bd66eb0SPeter Brune     Input parameters for projectfunc:
12889bd66eb0SPeter Brune +   snes - nonlinear context
12899bd66eb0SPeter Brune -   X - current solution
12909bd66eb0SPeter Brune 
12919bd66eb0SPeter Brune     Output parameters for func:
12929bd66eb0SPeter Brune .   X - Projected solution
12939bd66eb0SPeter Brune 
12949bd66eb0SPeter Brune    Calling sequence of normfunc:
12959bd66eb0SPeter Brune .vb
12969bd66eb0SPeter Brune    projectfunc (SNES snes, Vec X, Vec F, PetscScalar * fnorm)
12979bd66eb0SPeter Brune .ve
12989bd66eb0SPeter Brune 
12999bd66eb0SPeter Brune     Input parameters for projectfunc:
13009bd66eb0SPeter Brune +   snes - nonlinear context
13019bd66eb0SPeter Brune .   X - current solution
13029bd66eb0SPeter Brune -   F - current residual
13039bd66eb0SPeter Brune 
13049bd66eb0SPeter Brune     Output parameters for func:
13059bd66eb0SPeter Brune .   fnorm - VI-specific norm of the function
13069bd66eb0SPeter Brune 
13079bd66eb0SPeter Brune 
13089bd66eb0SPeter Brune     Level: developer
13099bd66eb0SPeter Brune 
13109bd66eb0SPeter Brune .keywords: SNES, line search, VI, nonlinear, set, line search
13119bd66eb0SPeter Brune 
1312f1c6b773SPeter Brune .seealso: SNESLineSearchGetVIFunctions(), SNESLineSearchSetPostCheck(), SNESLineSearchSetPreCheck()
13139bd66eb0SPeter Brune @*/
1314f1c6b773SPeter Brune extern PetscErrorCode SNESLineSearchSetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc projectfunc, SNESLineSearchVINormFunc normfunc)
13159bd66eb0SPeter Brune {
13169bd66eb0SPeter Brune   PetscFunctionBegin;
1317f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch,SNESLINESEARCH_CLASSID,1);
13189bd66eb0SPeter Brune   if (projectfunc) linesearch->ops->viproject = projectfunc;
13199bd66eb0SPeter Brune   if (normfunc) linesearch->ops->vinorm = normfunc;
13209bd66eb0SPeter Brune   PetscFunctionReturn(0);
13219bd66eb0SPeter Brune }
13229bd66eb0SPeter Brune 
13239bd66eb0SPeter Brune #undef __FUNCT__
1324f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchGetVIFunctions"
13259bd66eb0SPeter Brune /*@C
1326f1c6b773SPeter Brune    SNESLineSearchGetVIFunctions - Sets VI-specific functions for line search computation.
13279bd66eb0SPeter Brune 
13289bd66eb0SPeter Brune    Input Parameters:
13299bd66eb0SPeter Brune .  snes - nonlinear context obtained from SNESCreate()
13309bd66eb0SPeter Brune 
13319bd66eb0SPeter Brune    Output Parameters:
13329bd66eb0SPeter Brune +  projectfunc - function for projecting the function to the bounds
13339bd66eb0SPeter Brune -  normfunc - function for computing the norm of an active set
13349bd66eb0SPeter Brune 
13359bd66eb0SPeter Brune    Logically Collective on SNES
13369bd66eb0SPeter Brune 
13379bd66eb0SPeter Brune     Level: developer
13389bd66eb0SPeter Brune 
13399bd66eb0SPeter Brune .keywords: SNES, line search, VI, nonlinear, get, line search
13409bd66eb0SPeter Brune 
1341f1c6b773SPeter Brune .seealso: SNESLineSearchSetVIFunctions(), SNESLineSearchGetPostCheck(), SNESLineSearchGetPreCheck()
13429bd66eb0SPeter Brune @*/
1343f1c6b773SPeter Brune extern PetscErrorCode SNESLineSearchGetVIFunctions(SNESLineSearch linesearch, SNESLineSearchVIProjectFunc *projectfunc, SNESLineSearchVINormFunc *normfunc)
13449bd66eb0SPeter Brune {
13459bd66eb0SPeter Brune   PetscFunctionBegin;
13469bd66eb0SPeter Brune   if (projectfunc) *projectfunc = linesearch->ops->viproject;
13479bd66eb0SPeter Brune   if (normfunc) *normfunc = linesearch->ops->vinorm;
13489bd66eb0SPeter Brune   PetscFunctionReturn(0);
13499bd66eb0SPeter Brune }
13509bd66eb0SPeter Brune 
13519bd66eb0SPeter Brune #undef __FUNCT__
1352f1c6b773SPeter Brune #define __FUNCT__ "SNESLineSearchRegister"
1353bf7f4e0aSPeter Brune /*@C
1354f1c6b773SPeter Brune   SNESLineSearchRegister - See SNESLineSearchRegisterDynamic()
1355bf7f4e0aSPeter Brune 
1356bf7f4e0aSPeter Brune   Level: advanced
1357bf7f4e0aSPeter Brune @*/
1358f1c6b773SPeter Brune PetscErrorCode  SNESLineSearchRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNESLineSearch))
1359bf7f4e0aSPeter Brune {
1360bf7f4e0aSPeter Brune   char           fullname[PETSC_MAX_PATH_LEN];
1361bf7f4e0aSPeter Brune   PetscErrorCode ierr;
1362bf7f4e0aSPeter Brune 
1363bf7f4e0aSPeter Brune   PetscFunctionBegin;
1364bf7f4e0aSPeter Brune   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
1365f1c6b773SPeter Brune   ierr = PetscFListAdd(&SNESLineSearchList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
1366bf7f4e0aSPeter Brune   PetscFunctionReturn(0);
1367bf7f4e0aSPeter Brune }
1368