xref: /petsc/src/snes/linesearch/interface/linesearch.c (revision 6a388c361ff2893f4363aecae9e02aa0b4e91a18)
1 #include <private/linesearchimpl.h> /*I "petsclinesearch.h" I*/
2 
3 PetscBool  LineSearchRegisterAllCalled = PETSC_FALSE;
4 PetscFList LineSearchList              = PETSC_NULL;
5 
6 PetscClassId   LineSearch_CLASSID;
7 PetscLogEvent  LineSearch_Apply;
8 
9 #undef __FUNCT__
10 #define __FUNCT__ "LineSearchCreate"
11 PetscErrorCode LineSearchCreate(MPI_Comm comm, LineSearch * outlinesearch) {
12   PetscErrorCode ierr;
13   LineSearch     linesearch;
14   PetscFunctionBegin;
15   ierr = PetscHeaderCreate(linesearch, _p_LineSearch,struct _LineSearchOps,LineSearch_CLASSID, 0,
16                            "LineSearch","Line-search method","LineSearch",comm,LineSearchDestroy,LineSearchView);CHKERRQ(ierr);
17 
18   linesearch->ops->precheckstep = PETSC_NULL;
19   linesearch->ops->postcheckstep = PETSC_NULL;
20 
21   linesearch->lambda        = 1.0;
22   linesearch->fnorm         = 1.0;
23   linesearch->ynorm         = 1.0;
24   linesearch->xnorm         = 1.0;
25   linesearch->success       = PETSC_TRUE;
26   linesearch->norms         = PETSC_TRUE;
27   linesearch->keeplambda    = PETSC_FALSE;
28   linesearch->damping       = 1.0;
29   linesearch->maxstep       = 1e8;
30   linesearch->steptol       = 1e-12;
31   linesearch->precheckctx   = PETSC_NULL;
32   linesearch->postcheckctx  = PETSC_NULL;
33   linesearch->max_its       = 1;
34   linesearch->setupcalled   = PETSC_FALSE;
35   *outlinesearch            = linesearch;
36   PetscFunctionReturn(0);
37 }
38 
39 #undef __FUNCT__
40 #define __FUNCT__ "LineSearchSetUp"
41 PetscErrorCode LineSearchSetUp(LineSearch linesearch) {
42   PetscErrorCode ierr;
43   PetscFunctionBegin;
44 
45   if (!((PetscObject)linesearch)->type_name) {
46     ierr = LineSearchSetType(linesearch,LINESEARCHBASIC);CHKERRQ(ierr);
47   }
48 
49   if (!linesearch->setupcalled) {
50     ierr = VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);CHKERRQ(ierr);
51     ierr = VecDuplicate(linesearch->vec_func, &linesearch->vec_func_new);CHKERRQ(ierr);
52     if (linesearch->ops->setup) {
53       ierr = (*linesearch->ops->setup)(linesearch);CHKERRQ(ierr);
54     }
55     linesearch->lambda = linesearch->damping;
56     linesearch->setupcalled = PETSC_TRUE;
57   }
58   PetscFunctionReturn(0);
59 }
60 
61 #undef __FUNCT__
62 #define __FUNCT__ "LineSearchReset"
63 PetscErrorCode LineSearchReset(LineSearch linesearch) {
64   PetscErrorCode ierr;
65   PetscFunctionBegin;
66   if (linesearch->ops->reset) {
67     (*linesearch->ops->reset)(linesearch);
68   }
69   ierr = VecDestroy(&linesearch->vec_sol_new);CHKERRQ(ierr);
70   ierr = VecDestroy(&linesearch->vec_func_new);CHKERRQ(ierr);
71 
72   ierr = VecDestroyVecs(linesearch->nwork, &linesearch->work);CHKERRQ(ierr);
73   linesearch->nwork = 0;
74   linesearch->setupcalled = PETSC_FALSE;
75   PetscFunctionReturn(0);
76 }
77 
78 #undef __FUNCT__
79 #define __FUNCT__ "LineSearchPreCheck"
80 PetscErrorCode LineSearchPreCheck(LineSearch linesearch, PetscBool * changed)
81 {
82   PetscErrorCode ierr;
83   PetscFunctionBegin;
84   *changed = PETSC_FALSE;
85   if (linesearch->ops->precheckstep) {
86     ierr = (*linesearch->ops->precheckstep)(linesearch, linesearch->vec_sol, linesearch->vec_update, changed);CHKERRQ(ierr);
87   }
88   PetscFunctionReturn(0);
89 }
90 
91 #undef __FUNCT__
92 #define __FUNCT__ "LineSearchPostCheck"
93 PetscErrorCode LineSearchPostCheck(LineSearch linesearch, PetscBool * changed_W, PetscBool * changed_Y)
94 {
95   PetscErrorCode ierr;
96   PetscFunctionBegin;
97   *changed_Y = PETSC_FALSE;
98   *changed_W = PETSC_FALSE;
99   if (linesearch->ops->postcheckstep) {
100     ierr = (*linesearch->ops->postcheckstep)(linesearch, linesearch->vec_sol, linesearch->vec_sol_new, linesearch->vec_update, changed_W, changed_Y);CHKERRQ(ierr);
101   }
102   PetscFunctionReturn(0);
103 }
104 
105 #undef __FUNCT__
106 #define __FUNCT__ "LineSearchApply"
107 PetscErrorCode LineSearchApply(LineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y) {
108   PetscErrorCode ierr;
109   PetscFunctionBegin;
110 
111   /* check the pointers */
112   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
113   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
114   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
115   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
116 
117   linesearch->success = PETSC_TRUE;
118 
119   linesearch->vec_sol = X;
120   linesearch->vec_update = Y;
121   linesearch->vec_func = F;
122 
123   ierr = LineSearchSetUp(linesearch);CHKERRQ(ierr);
124 
125   if (!linesearch->keeplambda)
126     linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
127 
128   if (fnorm) {
129     linesearch->fnorm = *fnorm;
130   } else {
131     ierr = VecNorm(F, NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
132   }
133 
134   ierr = PetscLogEventBegin(LineSearch_Apply,linesearch,X,F,Y);CHKERRQ(ierr);
135 
136   ierr = (*linesearch->ops->apply)(linesearch);CHKERRQ(ierr);
137 
138   ierr = PetscLogEventEnd(LineSearch_Apply,linesearch,X,F,Y);CHKERRQ(ierr);
139 
140   if (fnorm)
141     *fnorm = linesearch->fnorm;
142   PetscFunctionReturn(0);
143 }
144 
145 #undef __FUNCT__
146 #define __FUNCT__ "LineSearchDestroy"
147 PetscErrorCode LineSearchDestroy(LineSearch * linesearch) {
148   PetscErrorCode ierr;
149   PetscFunctionBegin;
150   if (!*linesearch) PetscFunctionReturn(0);
151   PetscValidHeaderSpecific((*linesearch),LineSearch_CLASSID,1);
152   if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; PetscFunctionReturn(0);}
153   ierr = PetscObjectDepublish((*linesearch));CHKERRQ(ierr);
154   ierr = LineSearchReset(*linesearch);
155   if ((*linesearch)->ops->destroy) {
156     (*linesearch)->ops->destroy(*linesearch);
157   }
158   ierr = PetscViewerDestroy(&(*linesearch)->monitor);CHKERRQ(ierr);
159   ierr = PetscHeaderDestroy(linesearch);CHKERRQ(ierr);
160   PetscFunctionReturn(0);
161 }
162 
163 #undef __FUNCT__
164 #define __FUNCT__ "LineSearchSetMonitor"
165 /*@C
166    SNESLineSearchSetMonitor - Prints information about the progress or lack of progress of the line search
167 
168    Input Parameters:
169 +  snes - nonlinear context obtained from SNESCreate()
170 -  flg - PETSC_TRUE to monitor the line search
171 
172    Logically Collective on SNES
173 
174    Options Database:
175 .   -snes_ls_monitor
176 
177    Level: intermediate
178 
179 
180 .seealso: SNESLineSearchSet(), SNESLineSearchSetPostCheck(), SNESSetUpdate()
181 @*/
182 PetscErrorCode  LineSearchSetMonitor(LineSearch linesearch,PetscBool flg)
183 {
184 
185   PetscErrorCode ierr;
186   PetscFunctionBegin;
187   if (flg && !linesearch->monitor) {
188     ierr = PetscViewerASCIIOpen(((PetscObject)linesearch)->comm,"stdout",&linesearch->monitor);CHKERRQ(ierr);
189   } else if (!flg && linesearch->monitor) {
190     ierr = PetscViewerDestroy(&linesearch->monitor);CHKERRQ(ierr);
191   }
192   PetscFunctionReturn(0);
193 }
194 
195 #undef __FUNCT__
196 #define __FUNCT__ "LineSearchGetMonitor"
197 
198 PetscErrorCode  LineSearchGetMonitor(LineSearch linesearch, PetscViewer *monitor)
199 {
200 
201   PetscFunctionBegin;
202   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
203   if (monitor) {
204     PetscValidPointer(monitor, 2);
205     *monitor = linesearch->monitor;
206   }
207   PetscFunctionReturn(0);
208 }
209 
210 #undef __FUNCT__
211 #define __FUNCT__ "LineSearchSetFromOptions"
212 PetscErrorCode LineSearchSetFromOptions(LineSearch linesearch) {
213   PetscErrorCode ierr;
214   const char     *deft = LINESEARCHBASIC;
215   char           type[256];
216   PetscBool      flg, set;
217   PetscFunctionBegin;
218   if (!LineSearchRegisterAllCalled) {ierr = LineSearchRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
219 
220   ierr = PetscObjectOptionsBegin((PetscObject)linesearch);CHKERRQ(ierr);
221   if (((PetscObject)linesearch)->type_name) {
222     deft = ((PetscObject)linesearch)->type_name;
223   }
224   ierr = PetscOptionsList("-linesearch_type","Line-search method","LineSearchSetType",LineSearchList,deft,type,256,&flg);CHKERRQ(ierr);
225   if (flg) {
226     ierr = LineSearchSetType(linesearch,type);CHKERRQ(ierr);
227   } else if (!((PetscObject)linesearch)->type_name) {
228     ierr = LineSearchSetType(linesearch,deft);CHKERRQ(ierr);
229   }
230   if (linesearch->ops->setfromoptions) {
231     (*linesearch->ops->setfromoptions)(linesearch);CHKERRQ(ierr);
232   }
233 
234   ierr = PetscOptionsBool("-linesearch_monitor","Print progress of line searches","SNESLineSearchSetMonitor",
235                           linesearch->monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
236   if (set) {ierr = LineSearchSetMonitor(linesearch,flg);CHKERRQ(ierr);}
237 
238   ierr = PetscOptionsReal("-linesearch_damping","Line search damping and initial step guess","LineSearchSetDamping",linesearch->damping,&linesearch->damping,0);CHKERRQ(ierr);
239   ierr = PetscOptionsBool("-linesearch_norms","Compute final norms in line search","LineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,0);CHKERRQ(ierr);
240   ierr = PetscOptionsBool("-linesearch_keeplambda","Use previous lambda as damping","LineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,0);CHKERRQ(ierr);
241   ierr = PetscOptionsInt("-linesearch_max_it","Maximum iterations for iterative line searches","",linesearch->max_its,&linesearch->max_its,0);CHKERRQ(ierr);
242   ierr = PetscObjectProcessOptionsHandlers((PetscObject)linesearch);CHKERRQ(ierr);
243   ierr = PetscOptionsEnd();CHKERRQ(ierr);
244   PetscFunctionReturn(0);
245 }
246 
247 #undef __FUNCT__
248 #define __FUNCT__ "LineSearchView"
249 PetscErrorCode LineSearchView(LineSearch linesearch) {
250   PetscFunctionBegin;
251   PetscFunctionReturn(0);
252 }
253 
254 #undef __FUNCT__
255 #define __FUNCT__ "LineSearchSetType"
256 PetscErrorCode LineSearchSetType(LineSearch linesearch, const LineSearchType type)
257 {
258 
259   PetscErrorCode ierr,(*r)(LineSearch);
260   PetscBool      match;
261 
262   PetscFunctionBegin;
263   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
264   PetscValidCharPointer(type,2);
265 
266   ierr = PetscTypeCompare((PetscObject)linesearch,type,&match);CHKERRQ(ierr);
267   if (match) PetscFunctionReturn(0);
268 
269   ierr =  PetscFListFind(LineSearchList,((PetscObject)linesearch)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
270   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
271   /* Destroy the previous private linesearch context */
272   if (linesearch->ops->destroy) {
273     ierr = (*(linesearch)->ops->destroy)(linesearch);CHKERRQ(ierr);
274     linesearch->ops->destroy = PETSC_NULL;
275   }
276   /* Reinitialize function pointers in LineSearchOps structure */
277   linesearch->ops->apply          = 0;
278   linesearch->ops->view           = 0;
279   linesearch->ops->setfromoptions = 0;
280   linesearch->ops->destroy        = 0;
281 
282   ierr = PetscObjectChangeTypeName((PetscObject)linesearch,type);CHKERRQ(ierr);
283   ierr = (*r)(linesearch);CHKERRQ(ierr);
284 #if defined(PETSC_HAVE_AMS)
285   if (PetscAMSPublishAll) {
286     ierr = PetscObjectAMSPublish((PetscObject)linesearch);CHKERRQ(ierr);
287   }
288 #endif
289   PetscFunctionReturn(0);
290 }
291 
292 #undef __FUNCT__
293 #define __FUNCT__ "LineSearchSetSNES"
294 PetscErrorCode  LineSearchSetSNES(LineSearch linesearch, SNES snes){
295   PetscFunctionBegin;
296   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
297   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
298   linesearch->snes = snes;
299   PetscFunctionReturn(0);
300 }
301 
302 #undef __FUNCT__
303 #define __FUNCT__ "LineSearchGetSNES"
304 PetscErrorCode  LineSearchGetSNES(LineSearch linesearch, SNES *snes){
305   PetscFunctionBegin;
306   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
307   PetscValidPointer(snes, 2);
308   *snes = linesearch->snes;
309   PetscFunctionReturn(0);
310 }
311 
312 #undef __FUNCT__
313 #define __FUNCT__ "LineSearchGetLambda"
314 PetscErrorCode  LineSearchGetLambda(LineSearch linesearch,PetscReal *lambda)
315 {
316   PetscFunctionBegin;
317   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
318   PetscValidPointer(lambda, 2);
319   *lambda = linesearch->lambda;
320   PetscFunctionReturn(0);
321 }
322 
323 #undef __FUNCT__
324 #define __FUNCT__ "LineSearchSetLambda"
325 PetscErrorCode  LineSearchSetLambda(LineSearch linesearch, PetscReal lambda)
326 {
327   PetscFunctionBegin;
328   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
329   linesearch->lambda = lambda;
330   PetscFunctionReturn(0);
331 }
332 
333 #undef __FUNCT__
334 #define __FUNCT__ "LineSearchGetStepTolerance"
335 PetscErrorCode  LineSearchGetStepTolerance(LineSearch linesearch ,PetscReal *steptol)
336 {
337   PetscFunctionBegin;
338   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
339   PetscValidPointer(steptol, 2);
340   *steptol = linesearch->steptol;
341   PetscFunctionReturn(0);
342 }
343 
344 #undef __FUNCT__
345 #define __FUNCT__ "LineSearchSetStepTolerance"
346 PetscErrorCode  LineSearchSetStepTolerance(LineSearch linesearch,PetscReal steptol)
347 {
348   PetscFunctionBegin;
349   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
350   linesearch->steptol = steptol;
351   PetscFunctionReturn(0);
352 }
353 
354 #undef __FUNCT__
355 #define __FUNCT__ "LineSearchGetDamping"
356 extern PetscErrorCode  LineSearchGetDamping(LineSearch linesearch,PetscReal *damping)
357 {
358   PetscFunctionBegin;
359   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
360   PetscValidPointer(damping, 2);
361   *damping = linesearch->damping;
362   PetscFunctionReturn(0);
363 }
364 
365 #undef __FUNCT__
366 #define __FUNCT__ "LineSearchSetDamping"
367 extern PetscErrorCode  LineSearchSetDamping(LineSearch linesearch,PetscReal damping)
368 {
369   PetscFunctionBegin;
370   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
371   linesearch->damping = damping;
372   PetscFunctionReturn(0);
373 }
374 
375 #undef __FUNCT__
376 #define __FUNCT__ "LineSearchGetMaxStep"
377 extern PetscErrorCode  LineSearchGetMaxStep(LineSearch linesearch,PetscReal* maxstep)
378 {
379   PetscFunctionBegin;
380   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
381   PetscValidPointer(maxstep, 2);
382   *maxstep = linesearch->maxstep;
383   PetscFunctionReturn(0);
384 }
385 
386 #undef __FUNCT__
387 #define __FUNCT__ "LineSearchSetMaxStep"
388 extern PetscErrorCode  LineSearchSetMaxStep(LineSearch linesearch, PetscReal maxstep)
389 {
390   PetscFunctionBegin;
391   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
392   linesearch->maxstep = maxstep;
393   PetscFunctionReturn(0);
394 }
395 
396 #undef __FUNCT__
397 #define __FUNCT__ "LineSearchGetMaxIts"
398 PetscErrorCode LineSearchGetMaxIts(LineSearch linesearch, PetscInt * max_its)
399 {
400   PetscFunctionBegin;
401   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
402   PetscValidPointer(max_its, 2);
403   *max_its = linesearch->max_its;
404   PetscFunctionReturn(0);
405 }
406 
407 #undef __FUNCT__
408 #define __FUNCT__ "LineSearchSetMaxIts"
409 PetscErrorCode LineSearchSetMaxIts(LineSearch linesearch, PetscInt max_its)
410 {
411   PetscFunctionBegin;
412   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
413   linesearch->max_its = max_its;
414   PetscFunctionReturn(0);
415 }
416 
417 #undef __FUNCT__
418 #define __FUNCT__ "LineSearchGetNorms"
419 PetscErrorCode  LineSearchGetNorms(LineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
420 {
421   PetscFunctionBegin;
422   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
423   if (xnorm) {
424     *xnorm = linesearch->xnorm;
425   }
426   if (fnorm) {
427     *fnorm = linesearch->fnorm;
428   }
429   if (ynorm) {
430     *ynorm = linesearch->ynorm;
431   }
432   PetscFunctionReturn(0);
433 }
434 
435 #undef __FUNCT__
436 #define __FUNCT__ "LineSearchSetNorms"
437 PetscErrorCode  LineSearchSetNorms(LineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
438 {
439   PetscFunctionBegin;
440   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
441   if (xnorm) {
442     linesearch->xnorm = xnorm;
443   }
444   if (fnorm) {
445     linesearch->fnorm = fnorm;
446   }
447   if (ynorm) {
448     linesearch->ynorm = ynorm;
449   }
450   PetscFunctionReturn(0);
451 }
452 
453 #undef __FUNCT__
454 #define __FUNCT__ "LineSearchComputeNorms"
455 PetscErrorCode LineSearchComputeNorms(LineSearch linesearch)
456 {
457   PetscErrorCode ierr;
458   PetscFunctionBegin;
459   if (linesearch->norms) {
460     ierr = VecNormBegin(linesearch->vec_func,   NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
461     ierr = VecNormBegin(linesearch->vec_sol,    NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
462     ierr = VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
463     ierr = VecNormEnd(linesearch->vec_func,     NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
464     ierr = VecNormEnd(linesearch->vec_sol,      NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
465     ierr = VecNormEnd(linesearch->vec_update,   NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
466   }
467   PetscFunctionReturn(0);
468 }
469 
470 #undef __FUNCT__
471 #define __FUNCT__ "LineSearchGetVecs"
472 PetscErrorCode LineSearchGetVecs(LineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G) {
473   PetscFunctionBegin;
474   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
475   if (X) {
476     PetscValidPointer(X, 2);
477     *X = linesearch->vec_sol;
478   }
479   if (F) {
480     PetscValidPointer(F, 3);
481     *F = linesearch->vec_func;
482   }
483   if (Y) {
484     PetscValidPointer(Y, 4);
485     *Y = linesearch->vec_update;
486   }
487   if (W) {
488     PetscValidPointer(W, 5);
489     *W = linesearch->vec_sol_new;
490   }
491   if (G) {
492     PetscValidPointer(G, 6);
493     *G = linesearch->vec_func_new;
494   }
495 
496   PetscFunctionReturn(0);
497 }
498 
499 #undef __FUNCT__
500 #define __FUNCT__ "LineSearchSetVecs"
501 PetscErrorCode LineSearchSetVecs(LineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G) {
502   PetscFunctionBegin;
503   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
504   if (X) {
505     PetscValidHeaderSpecific(X,VEC_CLASSID,2);
506     linesearch->vec_sol = X;
507   }
508   if (F) {
509     PetscValidHeaderSpecific(F,VEC_CLASSID,3);
510     linesearch->vec_func = F;
511   }
512   if (Y) {
513     PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
514     linesearch->vec_update = Y;
515   }
516   if (W) {
517     PetscValidHeaderSpecific(W,VEC_CLASSID,5);
518     linesearch->vec_sol_new = W;
519   }
520   if (G) {
521     PetscValidHeaderSpecific(G,VEC_CLASSID,6);
522     linesearch->vec_func_new = G;
523   }
524 
525   PetscFunctionReturn(0);
526 }
527 
528 #undef __FUNCT__
529 #define __FUNCT__ "LineSearchAppendOptionsPrefix"
530 /*@C
531    LineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
532    SNES options in the database.
533 
534    Logically Collective on SNES
535 
536    Input Parameters:
537 +  snes - the SNES context
538 -  prefix - the prefix to prepend to all option names
539 
540    Notes:
541    A hyphen (-) must NOT be given at the beginning of the prefix name.
542    The first character of all runtime options is AUTOMATICALLY the hyphen.
543 
544    Level: advanced
545 
546 .keywords: SNES, append, options, prefix, database
547 
548 .seealso: SNESGetOptionsPrefix()
549 @*/
550 PetscErrorCode  LineSearchAppendOptionsPrefix(LineSearch linesearch,const char prefix[])
551 {
552   PetscErrorCode ierr;
553 
554   PetscFunctionBegin;
555   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
556   ierr = PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr);
557   PetscFunctionReturn(0);
558 }
559 
560 #undef __FUNCT__
561 #define __FUNCT__ "LineSearchGetOptionsPrefix"
562 /*@C
563    LineSearchGetOptionsPrefix - Sets the prefix used for searching for all
564    SNES options in the database.
565 
566    Not Collective
567 
568    Input Parameter:
569 .  snes - the SNES context
570 
571    Output Parameter:
572 .  prefix - pointer to the prefix string used
573 
574    Notes: On the fortran side, the user should pass in a string 'prefix' of
575    sufficient length to hold the prefix.
576 
577    Level: advanced
578 
579 .keywords: SNES, get, options, prefix, database
580 
581 .seealso: SNESAppendOptionsPrefix()
582 @*/
583 PetscErrorCode  LineSearchGetOptionsPrefix(LineSearch linesearch,const char *prefix[])
584 {
585   PetscErrorCode ierr;
586 
587   PetscFunctionBegin;
588   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
589   ierr = PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr);
590   PetscFunctionReturn(0);
591 }
592 
593 #undef __FUNCT__
594 #define __FUNCT__ "LineSearchGetWork"
595 PetscErrorCode  LineSearchGetWork(LineSearch linesearch, PetscInt nwork)
596 {
597   PetscErrorCode ierr;
598   PetscFunctionBegin;
599   if (linesearch->vec_sol) {
600     ierr = VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);CHKERRQ(ierr);
601   } else {
602     SETERRQ(((PetscObject)linesearch)->comm, PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
603   }
604   PetscFunctionReturn(0);
605 }
606 
607 
608 #undef __FUNCT__
609 #define __FUNCT__ "LineSearchGetSuccess"
610 PetscErrorCode  LineSearchGetSuccess(LineSearch linesearch, PetscBool *success)
611 {
612   PetscFunctionBegin;
613   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
614   PetscValidPointer(success, 2);
615   if (success) {
616     *success = linesearch->success;
617   }
618   PetscFunctionReturn(0);
619 }
620 
621 #undef __FUNCT__
622 #define __FUNCT__ "LineSearchSetSuccess"
623 PetscErrorCode  LineSearchSetSuccess(LineSearch linesearch, PetscBool success)
624 {
625   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
626   PetscFunctionBegin;
627   linesearch->success = success;
628   PetscFunctionReturn(0);
629 }
630 
631 #undef __FUNCT__
632 #define __FUNCT__ "LineSearchRegister"
633 /*@C
634   LineSearchRegister - See LineSearchRegisterDynamic()
635 
636   Level: advanced
637 @*/
638 PetscErrorCode  LineSearchRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(LineSearch))
639 {
640   char           fullname[PETSC_MAX_PATH_LEN];
641   PetscErrorCode ierr;
642 
643   PetscFunctionBegin;
644   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
645   ierr = PetscFListAdd(&LineSearchList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
646   PetscFunctionReturn(0);
647 }
648