xref: /petsc/src/snes/linesearch/interface/linesearch.c (revision 0ebbf5cd9a3c2c6e80db03c16b7e9d3cb0ce5fc5)
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 /*@
12    LineSearchCreate - Creates the line search.
13 
14    Collective on LineSearch
15 
16    Input Parameters:
17 .  comm - MPI communicator for the line search
18 
19    Output Parameters:
20 .  outlinesearch - the line search instance.
21 
22    Level: Beginner
23 
24    .keywords: LineSearch, Create
25 
26    .seealso: LineSearchDestroy()
27 @*/
28 
29 PetscErrorCode LineSearchCreate(MPI_Comm comm, LineSearch * outlinesearch) {
30   PetscErrorCode ierr;
31   LineSearch     linesearch;
32   PetscFunctionBegin;
33   ierr = PetscHeaderCreate(linesearch, _p_LineSearch,struct _LineSearchOps,LineSearch_CLASSID, 0,
34                            "LineSearch","Line-search method","LineSearch",comm,LineSearchDestroy,LineSearchView);CHKERRQ(ierr);
35 
36   linesearch->ops->precheckstep = PETSC_NULL;
37   linesearch->ops->postcheckstep = PETSC_NULL;
38 
39   linesearch->lambda        = 1.0;
40   linesearch->fnorm         = 1.0;
41   linesearch->ynorm         = 1.0;
42   linesearch->xnorm         = 1.0;
43   linesearch->success       = PETSC_TRUE;
44   linesearch->norms         = PETSC_TRUE;
45   linesearch->keeplambda    = PETSC_FALSE;
46   linesearch->damping       = 1.0;
47   linesearch->maxstep       = 1e8;
48   linesearch->steptol       = 1e-12;
49   linesearch->precheckctx   = PETSC_NULL;
50   linesearch->postcheckctx  = PETSC_NULL;
51   linesearch->max_its       = 1;
52   linesearch->setupcalled   = PETSC_FALSE;
53   *outlinesearch            = linesearch;
54   PetscFunctionReturn(0);
55 }
56 
57 #undef __FUNCT__
58 #define __FUNCT__ "LineSearchSetUp"
59 /*@
60    LineSearchSetUp - Prepares the line search for being applied.
61 
62    Collective on LineSearch
63 
64    Input Parameters:
65 .  linesearch - The LineSearch instance.
66 
67    Level: Intermediate
68 
69    .keywords: LineSearch, SetUp
70 
71    .seealso: LineSearchReset()
72 @*/
73 
74 PetscErrorCode LineSearchSetUp(LineSearch linesearch) {
75   PetscErrorCode ierr;
76   PetscFunctionBegin;
77 
78   if (!((PetscObject)linesearch)->type_name) {
79     ierr = LineSearchSetType(linesearch,LINESEARCHBASIC);CHKERRQ(ierr);
80   }
81 
82   if (!linesearch->setupcalled) {
83     ierr = VecDuplicate(linesearch->vec_sol, &linesearch->vec_sol_new);CHKERRQ(ierr);
84     ierr = VecDuplicate(linesearch->vec_func, &linesearch->vec_func_new);CHKERRQ(ierr);
85     if (linesearch->ops->setup) {
86       ierr = (*linesearch->ops->setup)(linesearch);CHKERRQ(ierr);
87     }
88     linesearch->lambda = linesearch->damping;
89     linesearch->setupcalled = PETSC_TRUE;
90   }
91   PetscFunctionReturn(0);
92 }
93 
94 #undef __FUNCT__
95 #define __FUNCT__ "LineSearchReset"
96 
97 /*@
98    LineSearchReset - Tears down the structures required for application
99 
100    Collective on LineSearch
101 
102    Input Parameters:
103 .  linesearch - The LineSearch instance.
104 
105    Level: Intermediate
106 
107    .keywords: LineSearch, Create
108 
109    .seealso: LineSearchSetUp()
110 @*/
111 
112 PetscErrorCode LineSearchReset(LineSearch linesearch) {
113   PetscErrorCode ierr;
114   PetscFunctionBegin;
115   if (linesearch->ops->reset) {
116     (*linesearch->ops->reset)(linesearch);
117   }
118   ierr = VecDestroy(&linesearch->vec_sol_new);CHKERRQ(ierr);
119   ierr = VecDestroy(&linesearch->vec_func_new);CHKERRQ(ierr);
120 
121   ierr = VecDestroyVecs(linesearch->nwork, &linesearch->work);CHKERRQ(ierr);
122   linesearch->nwork = 0;
123   linesearch->setupcalled = PETSC_FALSE;
124   PetscFunctionReturn(0);
125 }
126 
127 #undef __FUNCT__
128 #define __FUNCT__ "LineSearchPreCheck"
129 /*@
130    LineSearchPreCheck - Prepares the line search for being applied.
131 
132    Collective on LineSearch
133 
134    Input Parameters:
135 .  linesearch - The linesearch instance.
136 
137    Output Parameters:
138 .  changed - Indicator if the pre-check has changed anything.
139 
140    Level: Beginner
141 
142    .keywords: LineSearch, Create
143 
144    .seealso: LineSearchPostCheck()
145 @*/
146 PetscErrorCode LineSearchPreCheck(LineSearch linesearch, PetscBool * changed)
147 {
148   PetscErrorCode ierr;
149   PetscFunctionBegin;
150   *changed = PETSC_FALSE;
151   if (linesearch->ops->precheckstep) {
152     ierr = (*linesearch->ops->precheckstep)(linesearch, linesearch->vec_sol, linesearch->vec_update, changed);CHKERRQ(ierr);
153   }
154   PetscFunctionReturn(0);
155 }
156 
157 #undef __FUNCT__
158 #define __FUNCT__ "LineSearchPostCheck"
159 /*@
160    LineSearchPostCheck - Prepares the line search for being applied.
161 
162    Collective on LineSearch
163 
164    Input Parameters:
165 .  linesearch - The linesearch instance.
166 
167    Output Parameters:
168 +  changed_W - Indicator if the solution has been changed.
169 -  changed_Y - Indicator if the direction has been changed.
170 
171    Level: Intermediate
172 
173    .keywords: LineSearch, Create
174 
175    .seealso: LineSearchPreCheck()
176 @*/
177 PetscErrorCode LineSearchPostCheck(LineSearch linesearch, PetscBool * changed_W, PetscBool * changed_Y)
178 {
179   PetscErrorCode ierr;
180   PetscFunctionBegin;
181   *changed_Y = PETSC_FALSE;
182   *changed_W = PETSC_FALSE;
183   if (linesearch->ops->postcheckstep) {
184     ierr = (*linesearch->ops->postcheckstep)(linesearch, linesearch->vec_sol, linesearch->vec_sol_new, linesearch->vec_update, changed_W, changed_Y);CHKERRQ(ierr);
185   }
186   PetscFunctionReturn(0);
187 }
188 
189 #undef __FUNCT__
190 #define __FUNCT__ "LineSearchApply"
191 /*@
192    LineSearchApply - Computes the line-search update
193 
194    Collective on LineSearch
195 
196    Input Parameters:
197 +  linesearch - The linesearch instance.
198 .  X - The current solution.
199 .  F - The current function.
200 .  fnorm - The current norm.
201 .  Y - The search direction.
202 
203    Output Parameters:
204 +  X - The new solution.
205 .  F - The new function.
206 -  fnorm - The new function norm.
207 
208    Level: Intermediate
209 
210    .keywords: LineSearch, Create
211 
212    .seealso: LineSearchCreate(), LineSearchPreCheck(), LineSearchPostCheck()
213 @*/
214 PetscErrorCode LineSearchApply(LineSearch linesearch, Vec X, Vec F, PetscReal * fnorm, Vec Y) {
215   PetscErrorCode ierr;
216   PetscFunctionBegin;
217 
218   /* check the pointers */
219   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
220   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
221   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
222   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
223 
224   linesearch->success = PETSC_TRUE;
225 
226   linesearch->vec_sol = X;
227   linesearch->vec_update = Y;
228   linesearch->vec_func = F;
229 
230   ierr = LineSearchSetUp(linesearch);CHKERRQ(ierr);
231 
232   if (!linesearch->keeplambda)
233     linesearch->lambda = linesearch->damping; /* set the initial guess to lambda */
234 
235   if (fnorm) {
236     linesearch->fnorm = *fnorm;
237   } else {
238     ierr = VecNorm(F, NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
239   }
240 
241   ierr = PetscLogEventBegin(LineSearch_Apply,linesearch,X,F,Y);CHKERRQ(ierr);
242 
243   ierr = (*linesearch->ops->apply)(linesearch);CHKERRQ(ierr);
244 
245   ierr = PetscLogEventEnd(LineSearch_Apply,linesearch,X,F,Y);CHKERRQ(ierr);
246 
247   if (fnorm)
248     *fnorm = linesearch->fnorm;
249   PetscFunctionReturn(0);
250 }
251 
252 #undef __FUNCT__
253 #define __FUNCT__ "LineSearchDestroy"
254 /*@
255    LineSearchDestroy - Destroys the line search instance.
256 
257    Collective on LineSearch
258 
259    Input Parameters:
260 .  linesearch - The linesearch instance.
261 
262    Level: Intermediate
263 
264    .keywords: LineSearch, Create
265 
266    .seealso: LineSearchCreate(), LineSearchReset()
267 @*/
268 PetscErrorCode LineSearchDestroy(LineSearch * linesearch) {
269   PetscErrorCode ierr;
270   PetscFunctionBegin;
271   if (!*linesearch) PetscFunctionReturn(0);
272   PetscValidHeaderSpecific((*linesearch),LineSearch_CLASSID,1);
273   if (--((PetscObject)(*linesearch))->refct > 0) {*linesearch = 0; PetscFunctionReturn(0);}
274   ierr = PetscObjectDepublish((*linesearch));CHKERRQ(ierr);
275   ierr = LineSearchReset(*linesearch);
276   if ((*linesearch)->ops->destroy) {
277     (*linesearch)->ops->destroy(*linesearch);
278   }
279   ierr = PetscViewerDestroy(&(*linesearch)->monitor);CHKERRQ(ierr);
280   ierr = PetscHeaderDestroy(linesearch);CHKERRQ(ierr);
281   PetscFunctionReturn(0);
282 }
283 
284 #undef __FUNCT__
285 #define __FUNCT__ "LineSearchSetMonitor"
286 /*@
287    LineSearchSetMonitor - Turns on/off printing useful things about the line search.
288 
289    Input Parameters:
290 +  snes - nonlinear context obtained from SNESCreate()
291 -  flg - PETSC_TRUE to monitor the line search
292 
293    Logically Collective on SNES
294 
295    Options Database:
296 .   -linesearch_monitor - enables the monitor.
297 
298    Level: intermediate
299 
300 
301 .seealso: LineSearchGetMonitor()
302 @*/
303 PetscErrorCode  LineSearchSetMonitor(LineSearch linesearch, PetscBool flg)
304 {
305 
306   PetscErrorCode ierr;
307   PetscFunctionBegin;
308   if (flg && !linesearch->monitor) {
309     ierr = PetscViewerASCIIOpen(((PetscObject)linesearch)->comm,"stdout",&linesearch->monitor);CHKERRQ(ierr);
310   } else if (!flg && linesearch->monitor) {
311     ierr = PetscViewerDestroy(&linesearch->monitor);CHKERRQ(ierr);
312   }
313   PetscFunctionReturn(0);
314 }
315 
316 #undef __FUNCT__
317 #define __FUNCT__ "LineSearchGetMonitor"
318 /*@
319    LineSearchGetMonitor - Gets the monitor instance for the line search
320 
321    Input Parameters:
322 .  linesearch - linesearch context.
323 
324    Input Parameters:
325 .  monitor - monitor context.
326 
327    Logically Collective on SNES
328 
329 
330    Options Database Keys:
331 .   -linesearch_monitor - enables the monitor.
332 
333    Level: intermediate
334 
335 
336 .seealso: LineSearchSetMonitor()
337 @*/
338 PetscErrorCode  LineSearchGetMonitor(LineSearch linesearch, PetscViewer *monitor)
339 {
340 
341   PetscFunctionBegin;
342   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
343   if (monitor) {
344     PetscValidPointer(monitor, 2);
345     *monitor = linesearch->monitor;
346   }
347   PetscFunctionReturn(0);
348 }
349 
350 #undef __FUNCT__
351 #define __FUNCT__ "LineSearchSetFromOptions"
352 /*@
353    LineSearchSetFromOptions - Sets options for the line search
354 
355    Input Parameters:
356 .  linesearch - linesearch context.
357 
358    Options Database Keys:
359 + -linesearch_type - The Line search method
360 . -linesearch_monitor - Print progress of line searches
361 . -linesearch_damping - The linesearch damping parameter.
362 . -linesearch_norms   - Turn on/off the linesearch norms
363 . -linesearch_keeplambda - Keep the previous search length as the initial guess.
364 - -linesearch_max_it - The number of iterations for iterative line searches.
365 
366    Logically Collective on LineSearch
367 
368    Level: intermediate
369 
370 
371 .seealso: LineSearchCreate()
372 @*/
373 PetscErrorCode LineSearchSetFromOptions(LineSearch linesearch) {
374   PetscErrorCode ierr;
375   const char     *deft = LINESEARCHBASIC;
376   char           type[256];
377   PetscBool      flg, set;
378   PetscFunctionBegin;
379   if (!LineSearchRegisterAllCalled) {ierr = LineSearchRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
380 
381   ierr = PetscObjectOptionsBegin((PetscObject)linesearch);CHKERRQ(ierr);
382   if (((PetscObject)linesearch)->type_name) {
383     deft = ((PetscObject)linesearch)->type_name;
384   }
385   ierr = PetscOptionsList("-linesearch_type","Line-search method","LineSearchSetType",LineSearchList,deft,type,256,&flg);CHKERRQ(ierr);
386   if (flg) {
387     ierr = LineSearchSetType(linesearch,type);CHKERRQ(ierr);
388   } else if (!((PetscObject)linesearch)->type_name) {
389     ierr = LineSearchSetType(linesearch,deft);CHKERRQ(ierr);
390   }
391   if (linesearch->ops->setfromoptions) {
392     (*linesearch->ops->setfromoptions)(linesearch);CHKERRQ(ierr);
393   }
394 
395   ierr = PetscOptionsBool("-linesearch_monitor","Print progress of line searches","SNESLineSearchSetMonitor",
396                           linesearch->monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
397   if (set) {ierr = LineSearchSetMonitor(linesearch,flg);CHKERRQ(ierr);}
398 
399   ierr = PetscOptionsReal("-linesearch_damping","Line search damping and initial step guess","LineSearchSetDamping",linesearch->damping,&linesearch->damping,0);CHKERRQ(ierr);
400   ierr = PetscOptionsBool("-linesearch_norms","Compute final norms in line search","LineSearchSetComputeNorms",linesearch->norms,&linesearch->norms,0);CHKERRQ(ierr);
401   ierr = PetscOptionsBool("-linesearch_keeplambda","Use previous lambda as damping","LineSearchSetKeepLambda",linesearch->keeplambda,&linesearch->keeplambda,0);CHKERRQ(ierr);
402   ierr = PetscOptionsInt("-linesearch_max_it","Maximum iterations for iterative line searches","",linesearch->max_its,&linesearch->max_its,0);CHKERRQ(ierr);
403   ierr = PetscObjectProcessOptionsHandlers((PetscObject)linesearch);CHKERRQ(ierr);
404   ierr = PetscOptionsEnd();CHKERRQ(ierr);
405   PetscFunctionReturn(0);
406 }
407 
408 #undef __FUNCT__
409 #define __FUNCT__ "LineSearchView"
410 /*@
411    LineSearchView - Views useful information for the line search.
412 
413    Input Parameters:
414 .  linesearch - linesearch context.
415 
416    Logically Collective on LineSearch
417 
418    Level: intermediate
419 
420 
421 .seealso: LineSearchCreate()
422 @*/
423 PetscErrorCode LineSearchView(LineSearch linesearch) {
424   PetscFunctionBegin;
425 
426   PetscFunctionReturn(0);
427 }
428 
429 #undef __FUNCT__
430 #define __FUNCT__ "LineSearchSetType"
431 /*@
432    LineSearchSetType - Sets the linesearch type
433 
434    Input Parameters:
435 +  linesearch - linesearch context.
436 -  type - The type of line search to be used
437 
438    Logically Collective on LineSearch
439 
440    Level: intermediate
441 
442 
443 .seealso: LineSearchCreate()
444 @*/
445 PetscErrorCode LineSearchSetType(LineSearch linesearch, const LineSearchType type)
446 {
447 
448   PetscErrorCode ierr,(*r)(LineSearch);
449   PetscBool      match;
450 
451   PetscFunctionBegin;
452   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
453   PetscValidCharPointer(type,2);
454 
455   ierr = PetscTypeCompare((PetscObject)linesearch,type,&match);CHKERRQ(ierr);
456   if (match) PetscFunctionReturn(0);
457 
458   ierr =  PetscFListFind(LineSearchList,((PetscObject)linesearch)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
459   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Line Search type %s",type);
460   /* Destroy the previous private linesearch context */
461   if (linesearch->ops->destroy) {
462     ierr = (*(linesearch)->ops->destroy)(linesearch);CHKERRQ(ierr);
463     linesearch->ops->destroy = PETSC_NULL;
464   }
465   /* Reinitialize function pointers in LineSearchOps structure */
466   linesearch->ops->apply          = 0;
467   linesearch->ops->view           = 0;
468   linesearch->ops->setfromoptions = 0;
469   linesearch->ops->destroy        = 0;
470 
471   ierr = PetscObjectChangeTypeName((PetscObject)linesearch,type);CHKERRQ(ierr);
472   ierr = (*r)(linesearch);CHKERRQ(ierr);
473 #if defined(PETSC_HAVE_AMS)
474   if (PetscAMSPublishAll) {
475     ierr = PetscObjectAMSPublish((PetscObject)linesearch);CHKERRQ(ierr);
476   }
477 #endif
478   PetscFunctionReturn(0);
479 }
480 
481 #undef __FUNCT__
482 #define __FUNCT__ "LineSearchSetSNES"
483 /*@
484    LineSearchSetSNES - Sets the SNES for the linesearch for function evaluation
485 
486    Input Parameters:
487 +  linesearch - linesearch context.
488 -  snes - The snes instance
489 
490    Level: intermediate
491 
492 
493 .seealso: LineSearchGetSNES(), LineSearchSetVecs()
494 @*/
495 PetscErrorCode  LineSearchSetSNES(LineSearch linesearch, SNES snes){
496   PetscFunctionBegin;
497   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
498   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
499   linesearch->snes = snes;
500   PetscFunctionReturn(0);
501 }
502 
503 #undef __FUNCT__
504 #define __FUNCT__ "LineSearchGetSNES"
505 /*@
506    LineSearchGetSNES - Gets the SNES for the linesearch for function evaluation
507 
508    Input Parameters:
509 .  linesearch - linesearch context.
510 
511    Output Parameters:
512 .  snes - The snes instance
513 
514    Level: intermediate
515 
516 .seealso: LineSearchGetSNES(), LineSearchSetVecs()
517 @*/
518 PetscErrorCode  LineSearchGetSNES(LineSearch linesearch, SNES *snes){
519   PetscFunctionBegin;
520   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
521   PetscValidPointer(snes, 2);
522   *snes = linesearch->snes;
523   PetscFunctionReturn(0);
524 }
525 
526 #undef __FUNCT__
527 #define __FUNCT__ "LineSearchGetLambda"
528 /*@
529    LineSearchGetLambda - Gets the last linesearch steplength discovered.
530 
531    Input Parameters:
532 .  linesearch - linesearch context.
533 
534    Output Parameters:
535 .  lambda - The last steplength.
536 
537    Level: intermediate
538 
539 .seealso: LineSearchGetSNES(), LineSearchSetVecs()
540 @*/
541 PetscErrorCode  LineSearchGetLambda(LineSearch linesearch,PetscReal *lambda)
542 {
543   PetscFunctionBegin;
544   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
545   PetscValidPointer(lambda, 2);
546   *lambda = linesearch->lambda;
547   PetscFunctionReturn(0);
548 }
549 
550 #undef __FUNCT__
551 #define __FUNCT__ "LineSearchSetLambda"
552 /*@
553    LineSearchSetLambda - Sets the linesearch steplength.
554 
555    Input Parameters:
556 +  linesearch - linesearch context.
557 -  lambda - The last steplength.
558 
559    Level: intermediate
560 
561 .seealso: LineSearchGetLambda()
562 @*/
563 PetscErrorCode  LineSearchSetLambda(LineSearch linesearch, PetscReal lambda)
564 {
565   PetscFunctionBegin;
566   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
567   linesearch->lambda = lambda;
568   PetscFunctionReturn(0);
569 }
570 
571 #undef __FUNCT__
572 #define __FUNCT__ "LineSearchGetStepTolerance"
573 /*@
574    LineSearchGetStepTolerance - Gets the line search step tolerance.
575 
576    Input Parameters:
577 .  linesearch - linesearch context.
578 
579    Output Parameters:
580 .  steptol - The last steplength.
581 
582    Level: intermediate
583 
584 .seealso: LineSearchSetStepTolerance()
585 @*/
586 PetscErrorCode  LineSearchGetStepTolerance(LineSearch linesearch ,PetscReal *steptol)
587 {
588   PetscFunctionBegin;
589   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
590   PetscValidPointer(steptol, 2);
591   *steptol = linesearch->steptol;
592   PetscFunctionReturn(0);
593 }
594 
595 #undef __FUNCT__
596 #define __FUNCT__ "LineSearchSetStepTolerance"
597 /*@
598    LineSearchSetStepTolerance - Gets the line search step tolerance.
599 
600    Input Parameters:
601 .  linesearch - linesearch context.
602 .  steptol - The last steplength.
603 
604    Level: intermediate
605 
606 .seealso: LineSearchGetStepTolerance()
607 @*/
608 PetscErrorCode  LineSearchSetStepTolerance(LineSearch linesearch,PetscReal steptol)
609 {
610   PetscFunctionBegin;
611   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
612   linesearch->steptol = steptol;
613   PetscFunctionReturn(0);
614 }
615 
616 #undef __FUNCT__
617 #define __FUNCT__ "LineSearchGetDamping"
618 /*@
619    LineSearchGetDamping - Gets the line search damping paramter.
620 
621    Input Parameters:
622 .  linesearch - linesearch context.
623 
624    Output Parameters:
625 .  damping - The damping parameter.
626 
627    Level: intermediate
628 
629 .seealso: LineSearchGetStepTolerance()
630 @*/
631 
632 PetscErrorCode  LineSearchGetDamping(LineSearch linesearch,PetscReal *damping)
633 {
634   PetscFunctionBegin;
635   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
636   PetscValidPointer(damping, 2);
637   *damping = linesearch->damping;
638   PetscFunctionReturn(0);
639 }
640 
641 #undef __FUNCT__
642 #define __FUNCT__ "LineSearchSetDamping"
643 /*@
644    LineSearchSetDamping - Sets the line search damping paramter.
645 
646    Input Parameters:
647 .  linesearch - linesearch context.
648 .  damping - The damping parameter.
649 
650    Level: intermediate
651 
652 .seealso: LineSearchGetDamping()
653 @*/
654 PetscErrorCode  LineSearchSetDamping(LineSearch linesearch,PetscReal damping)
655 {
656   PetscFunctionBegin;
657   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
658   linesearch->damping = damping;
659   PetscFunctionReturn(0);
660 }
661 
662 #undef __FUNCT__
663 #define __FUNCT__ "LineSearchGetMaxStep"
664 /*@
665    LineSearchGetMaxStep - Gets the maximum allowable step size for the line search.
666 
667    Input Parameters:
668 .  linesearch - linesearch context.
669 
670    Output Parameters:
671 .  maxstep - The maximum step.
672 
673    Level: intermediate
674 
675 .seealso: LineSearchSetMaxStep()
676 @*/
677 PetscErrorCode  LineSearchGetMaxStep(LineSearch linesearch,PetscReal* maxstep)
678 {
679   PetscFunctionBegin;
680   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
681   PetscValidPointer(maxstep, 2);
682   *maxstep = linesearch->maxstep;
683   PetscFunctionReturn(0);
684 }
685 
686 #undef __FUNCT__
687 #define __FUNCT__ "LineSearchSetMaxStep"
688 /*@
689    LineSearchSetMaxStep - Sets the maximum allowable step size for the line search.
690 
691    Input Parameters:
692 .  linesearch - linesearch context.
693 .  maxstep - The maximum step.
694 
695    Level: intermediate
696 
697 .seealso: LineSearchGetStepTolerance()
698 @*/
699 PetscErrorCode  LineSearchSetMaxStep(LineSearch linesearch, PetscReal maxstep)
700 {
701   PetscFunctionBegin;
702   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
703   linesearch->maxstep = maxstep;
704   PetscFunctionReturn(0);
705 }
706 
707 #undef __FUNCT__
708 #define __FUNCT__ "LineSearchGetMaxIts"
709 /*@
710    LineSearchGetMaxIts - Gets the maximum iterations for iterative line searches.
711 
712    Input Parameters:
713 .  linesearch - linesearch context.
714 
715    Output Parameters:
716 .  max_its - The maximum number of iterations.
717 
718    Level: intermediate
719 
720 .seealso: LineSearchSetMaxIts()
721 @*/
722 PetscErrorCode LineSearchGetMaxIts(LineSearch linesearch, PetscInt * max_its)
723 {
724   PetscFunctionBegin;
725   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
726   PetscValidPointer(max_its, 2);
727   *max_its = linesearch->max_its;
728   PetscFunctionReturn(0);
729 }
730 
731 #undef __FUNCT__
732 #define __FUNCT__ "LineSearchSetMaxIts"
733 /*@
734    LineSearchSetMaxIts - Sets the maximum iterations for iterative line searches.
735 
736    Input Parameters:
737 .  linesearch - linesearch context.
738 .  max_its - The maximum number of iterations.
739 
740    Level: intermediate
741 
742 .seealso: LineSearchGetMaxIts()
743 @*/
744 PetscErrorCode LineSearchSetMaxIts(LineSearch linesearch, PetscInt max_its)
745 {
746   PetscFunctionBegin;
747   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
748   linesearch->max_its = max_its;
749   PetscFunctionReturn(0);
750 }
751 
752 #undef __FUNCT__
753 #define __FUNCT__ "LineSearchGetNorms"
754 /*@
755    LineSearchGetNorms - Gets the norms for for X, Y, and F.
756 
757    Input Parameters:
758 .  linesearch - linesearch context.
759 
760    Output Parameters:
761 +  xnorm - The norm of the current solution
762 .  fnorm - The norm of the current function
763 -  ynorm - The norm of the current update
764 
765    Level: intermediate
766 
767 .seealso: LineSearchSetNorms() LineSearchGetVecs()
768 @*/
769 PetscErrorCode  LineSearchGetNorms(LineSearch linesearch, PetscReal * xnorm, PetscReal * fnorm, PetscReal * ynorm)
770 {
771   PetscFunctionBegin;
772   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
773   if (xnorm) {
774     *xnorm = linesearch->xnorm;
775   }
776   if (fnorm) {
777     *fnorm = linesearch->fnorm;
778   }
779   if (ynorm) {
780     *ynorm = linesearch->ynorm;
781   }
782   PetscFunctionReturn(0);
783 }
784 
785 #undef __FUNCT__
786 #define __FUNCT__ "LineSearchSetNorms"
787 /*@
788    LineSearchSetNorms - Gets the computed norms for for X, Y, and F.
789 
790    Input Parameters:
791 +  linesearch - linesearch context.
792 .  xnorm - The norm of the current solution
793 .  fnorm - The norm of the current function
794 -  ynorm - The norm of the current update
795 
796    Level: intermediate
797 
798 .seealso: LineSearchGetNorms(), LineSearchSetVecs()
799 @*/
800 PetscErrorCode  LineSearchSetNorms(LineSearch linesearch, PetscReal xnorm, PetscReal fnorm, PetscReal ynorm)
801 {
802   PetscFunctionBegin;
803   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
804   if (xnorm) {
805     linesearch->xnorm = xnorm;
806   }
807   if (fnorm) {
808     linesearch->fnorm = fnorm;
809   }
810   if (ynorm) {
811     linesearch->ynorm = ynorm;
812   }
813   PetscFunctionReturn(0);
814 }
815 
816 #undef __FUNCT__
817 #define __FUNCT__ "LineSearchComputeNorms"
818 /*@
819    LineSearchComputeNorms - Computes the norms of X, F, and Y.
820 
821    Input Parameters:
822 .  linesearch - linesearch context.
823 
824    Options Database Keys:
825 .   -linesearch_norms - turn norm computation on or off.
826 
827    Level: intermediate
828 
829 .seealso: LineSearchGetNorms, LineSearchSetNorms()
830 @*/
831 PetscErrorCode LineSearchComputeNorms(LineSearch linesearch)
832 {
833   PetscErrorCode ierr;
834   PetscFunctionBegin;
835   if (linesearch->norms) {
836     ierr = VecNormBegin(linesearch->vec_func,   NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
837     ierr = VecNormBegin(linesearch->vec_sol,    NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
838     ierr = VecNormBegin(linesearch->vec_update, NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
839     ierr = VecNormEnd(linesearch->vec_func,     NORM_2, &linesearch->fnorm);CHKERRQ(ierr);
840     ierr = VecNormEnd(linesearch->vec_sol,      NORM_2, &linesearch->xnorm);CHKERRQ(ierr);
841     ierr = VecNormEnd(linesearch->vec_update,   NORM_2, &linesearch->ynorm);CHKERRQ(ierr);
842   }
843   PetscFunctionReturn(0);
844 }
845 
846 #undef __FUNCT__
847 #define __FUNCT__ "LineSearchGetVecs"
848 /*@
849    LineSearchGetVecs - Gets the vectors from the LineSearch context
850 
851    Input Parameters:
852 .  linesearch - linesearch context.
853 
854    Output Parameters:
855 +  X - The old solution
856 .  F - The old function
857 .  Y - The search direction
858 .  W - The new solution
859 -  G - The new function
860 
861    Level: intermediate
862 
863 .seealso: LineSearchGetNorms(), LineSearchSetVecs()
864 @*/
865 PetscErrorCode LineSearchGetVecs(LineSearch linesearch,Vec *X,Vec *F, Vec *Y,Vec *W,Vec *G) {
866   PetscFunctionBegin;
867   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
868   if (X) {
869     PetscValidPointer(X, 2);
870     *X = linesearch->vec_sol;
871   }
872   if (F) {
873     PetscValidPointer(F, 3);
874     *F = linesearch->vec_func;
875   }
876   if (Y) {
877     PetscValidPointer(Y, 4);
878     *Y = linesearch->vec_update;
879   }
880   if (W) {
881     PetscValidPointer(W, 5);
882     *W = linesearch->vec_sol_new;
883   }
884   if (G) {
885     PetscValidPointer(G, 6);
886     *G = linesearch->vec_func_new;
887   }
888 
889   PetscFunctionReturn(0);
890 }
891 
892 #undef __FUNCT__
893 #define __FUNCT__ "LineSearchSetVecs"
894 /*@
895    LineSearchSetVecs - Sets the vectors on the LineSearch context
896 
897    Input Parameters:
898 +  linesearch - linesearch context.
899 .  X - The old solution
900 .  F - The old function
901 .  Y - The search direction
902 .  W - The new solution
903 -  G - The new function
904 
905    Level: intermediate
906 
907 .seealso: LineSearchSetNorms(), LineSearchGetVecs()
908 @*/
909 PetscErrorCode LineSearchSetVecs(LineSearch linesearch,Vec X,Vec F,Vec Y,Vec W, Vec G) {
910   PetscFunctionBegin;
911   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
912   if (X) {
913     PetscValidHeaderSpecific(X,VEC_CLASSID,2);
914     linesearch->vec_sol = X;
915   }
916   if (F) {
917     PetscValidHeaderSpecific(F,VEC_CLASSID,3);
918     linesearch->vec_func = F;
919   }
920   if (Y) {
921     PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
922     linesearch->vec_update = Y;
923   }
924   if (W) {
925     PetscValidHeaderSpecific(W,VEC_CLASSID,5);
926     linesearch->vec_sol_new = W;
927   }
928   if (G) {
929     PetscValidHeaderSpecific(G,VEC_CLASSID,6);
930     linesearch->vec_func_new = G;
931   }
932 
933   PetscFunctionReturn(0);
934 }
935 
936 #undef __FUNCT__
937 #define __FUNCT__ "LineSearchAppendOptionsPrefix"
938 /*@C
939    LineSearchAppendOptionsPrefix - Appends to the prefix used for searching for all
940    SNES options in the database.
941 
942    Logically Collective on SNES
943 
944    Input Parameters:
945 +  snes - the SNES context
946 -  prefix - the prefix to prepend to all option names
947 
948    Notes:
949    A hyphen (-) must NOT be given at the beginning of the prefix name.
950    The first character of all runtime options is AUTOMATICALLY the hyphen.
951 
952    Level: advanced
953 
954 .keywords: LineSearch, append, options, prefix, database
955 
956 .seealso: SNESGetOptionsPrefix()
957 @*/
958 PetscErrorCode  LineSearchAppendOptionsPrefix(LineSearch linesearch,const char prefix[])
959 {
960   PetscErrorCode ierr;
961 
962   PetscFunctionBegin;
963   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
964   ierr = PetscObjectAppendOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr);
965   PetscFunctionReturn(0);
966 }
967 
968 #undef __FUNCT__
969 #define __FUNCT__ "LineSearchGetOptionsPrefix"
970 /*@C
971    LineSearchGetOptionsPrefix - Sets the prefix used for searching for all
972    LineSearch options in the database.
973 
974    Not Collective
975 
976    Input Parameter:
977 .  snes - the SNES context
978 
979    Output Parameter:
980 .  prefix - pointer to the prefix string used
981 
982    Notes: On the fortran side, the user should pass in a string 'prefix' of
983    sufficient length to hold the prefix.
984 
985    Level: advanced
986 
987 .keywords: LineSearch, get, options, prefix, database
988 
989 .seealso: SNESAppendOptionsPrefix()
990 @*/
991 PetscErrorCode  LineSearchGetOptionsPrefix(LineSearch linesearch,const char *prefix[])
992 {
993   PetscErrorCode ierr;
994 
995   PetscFunctionBegin;
996   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
997   ierr = PetscObjectGetOptionsPrefix((PetscObject)linesearch,prefix);CHKERRQ(ierr);
998   PetscFunctionReturn(0);
999 }
1000 
1001 #undef __FUNCT__
1002 #define __FUNCT__ "LineSearchGetWork"
1003 /*@
1004    LineSearchGetWork - Gets work vectors for the line search.
1005 
1006    Input Parameter:
1007 +  linesearch - the LineSearch context
1008 -  nwork - the number of work vectors
1009 
1010    Level: developer
1011 
1012 .keywords: LineSearch, work, vector
1013 
1014 .seealso: SNESDefaultGetWork()
1015 @*/
1016 PetscErrorCode  LineSearchGetWork(LineSearch linesearch, PetscInt nwork)
1017 {
1018   PetscErrorCode ierr;
1019   PetscFunctionBegin;
1020   if (linesearch->vec_sol) {
1021     ierr = VecDuplicateVecs(linesearch->vec_sol, nwork, &linesearch->work);CHKERRQ(ierr);
1022   } else {
1023     SETERRQ(((PetscObject)linesearch)->comm, PETSC_ERR_USER, "Cannot get linesearch work-vectors without setting a solution vec!");
1024   }
1025   PetscFunctionReturn(0);
1026 }
1027 
1028 
1029 #undef __FUNCT__
1030 #define __FUNCT__ "LineSearchGetSuccess"
1031 /*@
1032    LineSearchGetSuccess - Gets the success/failure status of the last line search application
1033 
1034    Input Parameters:
1035 .  linesearch - linesearch context.
1036 
1037    Output Parameters:
1038 .  success - The success or failure status.
1039 
1040    Level: intermediate
1041 
1042 .seealso: LineSearchSetSuccess()
1043 @*/
1044 PetscErrorCode  LineSearchGetSuccess(LineSearch linesearch, PetscBool *success)
1045 {
1046   PetscFunctionBegin;
1047   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
1048   PetscValidPointer(success, 2);
1049   if (success) {
1050     *success = linesearch->success;
1051   }
1052   PetscFunctionReturn(0);
1053 }
1054 
1055 #undef __FUNCT__
1056 #define __FUNCT__ "LineSearchSetSuccess"
1057 /*@
1058    LineSearchSetSuccess - Sets the success/failure status of the last line search application
1059 
1060    Input Parameters:
1061 +  linesearch - linesearch context.
1062 -  success - The success or failure status.
1063 
1064    Level: intermediate
1065 
1066 .seealso: LineSearchGetSuccess()
1067 @*/
1068 PetscErrorCode  LineSearchSetSuccess(LineSearch linesearch, PetscBool success)
1069 {
1070   PetscValidHeaderSpecific(linesearch,LineSearch_CLASSID,1);
1071   PetscFunctionBegin;
1072   linesearch->success = success;
1073   PetscFunctionReturn(0);
1074 }
1075 
1076 #undef __FUNCT__
1077 #define __FUNCT__ "LineSearchRegister"
1078 /*@C
1079   LineSearchRegister - See LineSearchRegisterDynamic()
1080 
1081   Level: advanced
1082 @*/
1083 PetscErrorCode  LineSearchRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(LineSearch))
1084 {
1085   char           fullname[PETSC_MAX_PATH_LEN];
1086   PetscErrorCode ierr;
1087 
1088   PetscFunctionBegin;
1089   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
1090   ierr = PetscFListAdd(&LineSearchList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
1091   PetscFunctionReturn(0);
1092 }
1093