xref: /petsc/src/tao/unconstrained/impls/cg/taocg.c (revision 9566063d113dddea24716c546802770db7481bc0)
1ba92ff59SBarry Smith #include <petsctaolinesearch.h>
2aaa7dc30SBarry Smith #include <../src/tao/unconstrained/impls/cg/taocg.h>
35e1affc2SSatish Balay 
45e1affc2SSatish Balay #define CG_FletcherReeves       0
55e1affc2SSatish Balay #define CG_PolakRibiere         1
65e1affc2SSatish Balay #define CG_PolakRibierePlus     2
75e1affc2SSatish Balay #define CG_HestenesStiefel      3
85e1affc2SSatish Balay #define CG_DaiYuan              4
95e1affc2SSatish Balay #define CG_Types                5
105e1affc2SSatish Balay 
1187f595a5SBarry Smith static const char *CG_Table[64] = {"fr", "pr", "prp", "hs", "dy"};
125e1affc2SSatish Balay 
13441846f8SBarry Smith static PetscErrorCode TaoSolve_CG(Tao tao)
145e1affc2SSatish Balay {
155e1affc2SSatish Balay   TAO_CG                       *cgP = (TAO_CG*)tao->data;
16e4cb33bbSBarry Smith   TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING;
175e1affc2SSatish Balay   PetscReal                    step=1.0,f,gnorm,gnorm2,delta,gd,ginner,beta;
185e1affc2SSatish Balay   PetscReal                    gd_old,gnorm2_old,f_old;
195e1affc2SSatish Balay 
205e1affc2SSatish Balay   PetscFunctionBegin;
215e1affc2SSatish Balay   if (tao->XL || tao->XU || tao->ops->computebounds) {
22*9566063dSJacob Faibussowitsch     PetscCall(PetscInfo(tao,"WARNING: Variable bounds have been set but will be ignored by cg algorithm\n"));
235e1affc2SSatish Balay   }
245e1affc2SSatish Balay 
255e1affc2SSatish Balay   /*  Check convergence criteria */
26*9566063dSJacob Faibussowitsch   PetscCall(TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient));
27*9566063dSJacob Faibussowitsch   PetscCall(VecNorm(tao->gradient,NORM_2,&gnorm));
283c859ba3SBarry Smith   PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm),PetscObjectComm((PetscObject)tao),PETSC_ERR_USER, "User provided compute function generated Inf or NaN");
295e1affc2SSatish Balay 
303ecd9318SAlp Dener   tao->reason = TAO_CONTINUE_ITERATING;
31*9566063dSJacob Faibussowitsch   PetscCall(TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its));
32*9566063dSJacob Faibussowitsch   PetscCall(TaoMonitor(tao,tao->niter,f,gnorm,0.0,step));
33*9566063dSJacob Faibussowitsch   PetscCall((*tao->ops->convergencetest)(tao,tao->cnvP));
343ecd9318SAlp Dener   if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0);
355e1affc2SSatish Balay 
365e1affc2SSatish Balay   /*  Set initial direction to -gradient */
37*9566063dSJacob Faibussowitsch   PetscCall(VecCopy(tao->gradient, tao->stepdirection));
38*9566063dSJacob Faibussowitsch   PetscCall(VecScale(tao->stepdirection, -1.0));
395e1affc2SSatish Balay   gnorm2 = gnorm*gnorm;
405e1affc2SSatish Balay 
415e1affc2SSatish Balay   /*  Set initial scaling for the function */
425e1affc2SSatish Balay   if (f != 0.0) {
435e1affc2SSatish Balay     delta = 2.0*PetscAbsScalar(f) / gnorm2;
445e1affc2SSatish Balay     delta = PetscMax(delta,cgP->delta_min);
455e1affc2SSatish Balay     delta = PetscMin(delta,cgP->delta_max);
465e1affc2SSatish Balay   } else {
475e1affc2SSatish Balay     delta = 2.0 / gnorm2;
485e1affc2SSatish Balay     delta = PetscMax(delta,cgP->delta_min);
495e1affc2SSatish Balay     delta = PetscMin(delta,cgP->delta_max);
505e1affc2SSatish Balay   }
515e1affc2SSatish Balay   /*  Set counter for gradient and reset steps */
525e1affc2SSatish Balay   cgP->ngradsteps = 0;
535e1affc2SSatish Balay   cgP->nresetsteps = 0;
545e1affc2SSatish Balay 
555e1affc2SSatish Balay   while (1) {
56e1e80dc8SAlp Dener     /* Call general purpose update function */
57e1e80dc8SAlp Dener     if (tao->ops->update) {
58*9566063dSJacob Faibussowitsch       PetscCall((*tao->ops->update)(tao, tao->niter, tao->user_update));
59e1e80dc8SAlp Dener     }
60e1e80dc8SAlp Dener 
615e1affc2SSatish Balay     /*  Save the current gradient information */
625e1affc2SSatish Balay     f_old = f;
635e1affc2SSatish Balay     gnorm2_old = gnorm2;
64*9566063dSJacob Faibussowitsch     PetscCall(VecCopy(tao->solution, cgP->X_old));
65*9566063dSJacob Faibussowitsch     PetscCall(VecCopy(tao->gradient, cgP->G_old));
66*9566063dSJacob Faibussowitsch     PetscCall(VecDot(tao->gradient, tao->stepdirection, &gd));
675e1affc2SSatish Balay     if ((gd >= 0) || PetscIsInfOrNanReal(gd)) {
685e1affc2SSatish Balay       ++cgP->ngradsteps;
695e1affc2SSatish Balay       if (f != 0.0) {
705e1affc2SSatish Balay         delta = 2.0*PetscAbsScalar(f) / gnorm2;
715e1affc2SSatish Balay         delta = PetscMax(delta,cgP->delta_min);
725e1affc2SSatish Balay         delta = PetscMin(delta,cgP->delta_max);
735e1affc2SSatish Balay       } else {
745e1affc2SSatish Balay         delta = 2.0 / gnorm2;
755e1affc2SSatish Balay         delta = PetscMax(delta,cgP->delta_min);
765e1affc2SSatish Balay         delta = PetscMin(delta,cgP->delta_max);
775e1affc2SSatish Balay       }
785e1affc2SSatish Balay 
79*9566063dSJacob Faibussowitsch       PetscCall(VecCopy(tao->gradient, tao->stepdirection));
80*9566063dSJacob Faibussowitsch       PetscCall(VecScale(tao->stepdirection, -1.0));
815e1affc2SSatish Balay     }
825e1affc2SSatish Balay 
835e1affc2SSatish Balay     /*  Search direction for improving point */
84*9566063dSJacob Faibussowitsch     PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch,delta));
85*9566063dSJacob Faibussowitsch     PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status));
86*9566063dSJacob Faibussowitsch     PetscCall(TaoAddLineSearchCounts(tao));
8787f595a5SBarry Smith     if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) {
885e1affc2SSatish Balay       /*  Linesearch failed */
895e1affc2SSatish Balay       /*  Reset factors and use scaled gradient step */
905e1affc2SSatish Balay       ++cgP->nresetsteps;
915e1affc2SSatish Balay       f = f_old;
925e1affc2SSatish Balay       gnorm2 = gnorm2_old;
93*9566063dSJacob Faibussowitsch       PetscCall(VecCopy(cgP->X_old, tao->solution));
94*9566063dSJacob Faibussowitsch       PetscCall(VecCopy(cgP->G_old, tao->gradient));
955e1affc2SSatish Balay 
965e1affc2SSatish Balay       if (f != 0.0) {
975e1affc2SSatish Balay         delta = 2.0*PetscAbsScalar(f) / gnorm2;
985e1affc2SSatish Balay         delta = PetscMax(delta,cgP->delta_min);
995e1affc2SSatish Balay         delta = PetscMin(delta,cgP->delta_max);
1005e1affc2SSatish Balay       } else {
1015e1affc2SSatish Balay         delta = 2.0 / gnorm2;
1025e1affc2SSatish Balay         delta = PetscMax(delta,cgP->delta_min);
1035e1affc2SSatish Balay         delta = PetscMin(delta,cgP->delta_max);
1045e1affc2SSatish Balay       }
1055e1affc2SSatish Balay 
106*9566063dSJacob Faibussowitsch       PetscCall(VecCopy(tao->gradient, tao->stepdirection));
107*9566063dSJacob Faibussowitsch       PetscCall(VecScale(tao->stepdirection, -1.0));
1085e1affc2SSatish Balay 
109*9566063dSJacob Faibussowitsch       PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch,delta));
110*9566063dSJacob Faibussowitsch       PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status));
111*9566063dSJacob Faibussowitsch       PetscCall(TaoAddLineSearchCounts(tao));
1125e1affc2SSatish Balay 
11387f595a5SBarry Smith       if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) {
1145e1affc2SSatish Balay         /*  Linesearch failed again */
1155e1affc2SSatish Balay         /*  switch to unscaled gradient */
1165e1affc2SSatish Balay         f = f_old;
117*9566063dSJacob Faibussowitsch         PetscCall(VecCopy(cgP->X_old, tao->solution));
118*9566063dSJacob Faibussowitsch         PetscCall(VecCopy(cgP->G_old, tao->gradient));
1195e1affc2SSatish Balay         delta = 1.0;
120*9566063dSJacob Faibussowitsch         PetscCall(VecCopy(tao->solution, tao->stepdirection));
121*9566063dSJacob Faibussowitsch         PetscCall(VecScale(tao->stepdirection, -1.0));
1225e1affc2SSatish Balay 
123*9566063dSJacob Faibussowitsch         PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch,delta));
124*9566063dSJacob Faibussowitsch         PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status));
125*9566063dSJacob Faibussowitsch         PetscCall(TaoAddLineSearchCounts(tao));
1268caf6e8cSBarry Smith         if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) {
1275e1affc2SSatish Balay 
1285e1affc2SSatish Balay           /*  Line search failed for last time -- give up */
1295e1affc2SSatish Balay           f = f_old;
130*9566063dSJacob Faibussowitsch           PetscCall(VecCopy(cgP->X_old, tao->solution));
131*9566063dSJacob Faibussowitsch           PetscCall(VecCopy(cgP->G_old, tao->gradient));
1325e1affc2SSatish Balay           step = 0.0;
1335e1affc2SSatish Balay           tao->reason = TAO_DIVERGED_LS_FAILURE;
1345e1affc2SSatish Balay         }
1355e1affc2SSatish Balay       }
1365e1affc2SSatish Balay     }
1375e1affc2SSatish Balay 
1385e1affc2SSatish Balay     /*  Check for bad value */
139*9566063dSJacob Faibussowitsch     PetscCall(VecNorm(tao->gradient,NORM_2,&gnorm));
1403c859ba3SBarry Smith     PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm),PetscObjectComm((PetscObject)tao),PETSC_ERR_USER,"User-provided compute function generated Inf or NaN");
1415e1affc2SSatish Balay 
1425e1affc2SSatish Balay     /*  Check for termination */
1435e1affc2SSatish Balay     gnorm2 =gnorm * gnorm;
1448931d482SJason Sarich     tao->niter++;
145*9566063dSJacob Faibussowitsch     PetscCall(TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its));
146*9566063dSJacob Faibussowitsch     PetscCall(TaoMonitor(tao,tao->niter,f,gnorm,0.0,step));
147*9566063dSJacob Faibussowitsch     PetscCall((*tao->ops->convergencetest)(tao,tao->cnvP));
1483ecd9318SAlp Dener     if (tao->reason != TAO_CONTINUE_ITERATING) {
1495e1affc2SSatish Balay       break;
1505e1affc2SSatish Balay     }
1515e1affc2SSatish Balay 
1525e1affc2SSatish Balay     /*  Check for restart condition */
153*9566063dSJacob Faibussowitsch     PetscCall(VecDot(tao->gradient, cgP->G_old, &ginner));
1545e1affc2SSatish Balay     if (PetscAbsScalar(ginner) >= cgP->eta * gnorm2) {
155a5b23f4aSJose E. Roman       /*  Gradients far from orthogonal; use steepest descent direction */
1565e1affc2SSatish Balay       beta = 0.0;
1575e1affc2SSatish Balay     } else {
1585e1affc2SSatish Balay       /*  Gradients close to orthogonal; use conjugate gradient formula */
1595e1affc2SSatish Balay       switch (cgP->cg_type) {
1605e1affc2SSatish Balay       case CG_FletcherReeves:
1615e1affc2SSatish Balay         beta = gnorm2 / gnorm2_old;
1625e1affc2SSatish Balay         break;
1635e1affc2SSatish Balay 
1645e1affc2SSatish Balay       case CG_PolakRibiere:
1655e1affc2SSatish Balay         beta = (gnorm2 - ginner) / gnorm2_old;
1665e1affc2SSatish Balay         break;
1675e1affc2SSatish Balay 
1685e1affc2SSatish Balay       case CG_PolakRibierePlus:
1695e1affc2SSatish Balay         beta = PetscMax((gnorm2-ginner)/gnorm2_old, 0.0);
1705e1affc2SSatish Balay         break;
1715e1affc2SSatish Balay 
1725e1affc2SSatish Balay       case CG_HestenesStiefel:
173*9566063dSJacob Faibussowitsch         PetscCall(VecDot(tao->gradient, tao->stepdirection, &gd));
174*9566063dSJacob Faibussowitsch         PetscCall(VecDot(cgP->G_old, tao->stepdirection, &gd_old));
1755e1affc2SSatish Balay         beta = (gnorm2 - ginner) / (gd - gd_old);
1765e1affc2SSatish Balay         break;
1775e1affc2SSatish Balay 
1785e1affc2SSatish Balay       case CG_DaiYuan:
179*9566063dSJacob Faibussowitsch         PetscCall(VecDot(tao->gradient, tao->stepdirection, &gd));
180*9566063dSJacob Faibussowitsch         PetscCall(VecDot(cgP->G_old, tao->stepdirection, &gd_old));
1815e1affc2SSatish Balay         beta = gnorm2 / (gd - gd_old);
1825e1affc2SSatish Balay         break;
1835e1affc2SSatish Balay 
1845e1affc2SSatish Balay       default:
1855e1affc2SSatish Balay         beta = 0.0;
1865e1affc2SSatish Balay         break;
1875e1affc2SSatish Balay       }
1885e1affc2SSatish Balay     }
1895e1affc2SSatish Balay 
1905e1affc2SSatish Balay     /*  Compute the direction d=-g + beta*d */
191*9566063dSJacob Faibussowitsch     PetscCall(VecAXPBY(tao->stepdirection, -1.0, beta, tao->gradient));
1925e1affc2SSatish Balay 
1935e1affc2SSatish Balay     /*  update initial steplength choice */
1945e1affc2SSatish Balay     delta = 1.0;
1955e1affc2SSatish Balay     delta = PetscMax(delta, cgP->delta_min);
1965e1affc2SSatish Balay     delta = PetscMin(delta, cgP->delta_max);
1975e1affc2SSatish Balay   }
1985e1affc2SSatish Balay   PetscFunctionReturn(0);
1995e1affc2SSatish Balay }
2005e1affc2SSatish Balay 
201441846f8SBarry Smith static PetscErrorCode TaoSetUp_CG(Tao tao)
2025e1affc2SSatish Balay {
2035e1affc2SSatish Balay   TAO_CG         *cgP = (TAO_CG*)tao->data;
2045e1affc2SSatish Balay 
2055e1affc2SSatish Balay   PetscFunctionBegin;
206*9566063dSJacob Faibussowitsch   if (!tao->gradient) PetscCall(VecDuplicate(tao->solution,&tao->gradient));
207*9566063dSJacob Faibussowitsch   if (!tao->stepdirection) PetscCall(VecDuplicate(tao->solution,&tao->stepdirection));
208*9566063dSJacob Faibussowitsch   if (!cgP->X_old) PetscCall(VecDuplicate(tao->solution,&cgP->X_old));
209*9566063dSJacob Faibussowitsch   if (!cgP->G_old) PetscCall(VecDuplicate(tao->gradient,&cgP->G_old));
2105e1affc2SSatish Balay   PetscFunctionReturn(0);
2115e1affc2SSatish Balay }
2125e1affc2SSatish Balay 
213441846f8SBarry Smith static PetscErrorCode TaoDestroy_CG(Tao tao)
2145e1affc2SSatish Balay {
2155e1affc2SSatish Balay   TAO_CG         *cgP = (TAO_CG*) tao->data;
2165e1affc2SSatish Balay 
2175e1affc2SSatish Balay   PetscFunctionBegin;
2185e1affc2SSatish Balay   if (tao->setupcalled) {
219*9566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&cgP->X_old));
220*9566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&cgP->G_old));
2215e1affc2SSatish Balay   }
222*9566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchDestroy(&tao->linesearch));
223*9566063dSJacob Faibussowitsch   PetscCall(PetscFree(tao->data));
2245e1affc2SSatish Balay   PetscFunctionReturn(0);
2255e1affc2SSatish Balay }
2265e1affc2SSatish Balay 
2274416b707SBarry Smith static PetscErrorCode TaoSetFromOptions_CG(PetscOptionItems *PetscOptionsObject,Tao tao)
2285e1affc2SSatish Balay {
2295e1affc2SSatish Balay   TAO_CG         *cgP = (TAO_CG*)tao->data;
2305e1affc2SSatish Balay 
2315e1affc2SSatish Balay   PetscFunctionBegin;
232*9566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchSetFromOptions(tao->linesearch));
233*9566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHead(PetscOptionsObject,"Nonlinear Conjugate Gradient method for unconstrained optimization"));
234*9566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_cg_eta","restart tolerance", "", cgP->eta,&cgP->eta,NULL));
235*9566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-tao_cg_type","cg formula", "", CG_Table, CG_Types, CG_Table[cgP->cg_type], &cgP->cg_type,NULL));
236*9566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_cg_delta_min","minimum delta value", "", cgP->delta_min,&cgP->delta_min,NULL));
237*9566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_cg_delta_max","maximum delta value", "", cgP->delta_max,&cgP->delta_max,NULL));
238*9566063dSJacob Faibussowitsch   PetscCall(PetscOptionsTail());
2395e1affc2SSatish Balay   PetscFunctionReturn(0);
2405e1affc2SSatish Balay }
2415e1affc2SSatish Balay 
242441846f8SBarry Smith static PetscErrorCode TaoView_CG(Tao tao, PetscViewer viewer)
2435e1affc2SSatish Balay {
2445e1affc2SSatish Balay   PetscBool      isascii;
2455e1affc2SSatish Balay   TAO_CG         *cgP = (TAO_CG*)tao->data;
2465e1affc2SSatish Balay 
2475e1affc2SSatish Balay   PetscFunctionBegin;
248*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2495e1affc2SSatish Balay   if (isascii) {
250*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
251*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "CG Type: %s\n", CG_Table[cgP->cg_type]));
252*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Gradient steps: %D\n", cgP->ngradsteps));
253*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Reset steps: %D\n", cgP->nresetsteps));
254*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
2555e1affc2SSatish Balay   }
2565e1affc2SSatish Balay   PetscFunctionReturn(0);
2575e1affc2SSatish Balay }
2584aa34175SJason Sarich 
2594aa34175SJason Sarich /*MC
2604aa34175SJason Sarich      TAOCG -   Nonlinear conjugate gradient method is an extension of the
2614aa34175SJason Sarich nonlinear conjugate gradient solver for nonlinear optimization.
2624aa34175SJason Sarich 
2634aa34175SJason Sarich    Options Database Keys:
2644aa34175SJason Sarich +      -tao_cg_eta <r> - restart tolerance
2654aa34175SJason Sarich .      -tao_cg_type <taocg_type> - cg formula
2664aa34175SJason Sarich .      -tao_cg_delta_min <r> - minimum delta value
2674aa34175SJason Sarich -      -tao_cg_delta_max <r> - maximum delta value
2684aa34175SJason Sarich 
2694aa34175SJason Sarich   Notes:
2704aa34175SJason Sarich      CG formulas are:
2714aa34175SJason Sarich          "fr" - Fletcher-Reeves
2724aa34175SJason Sarich          "pr" - Polak-Ribiere
2734aa34175SJason Sarich          "prp" - Polak-Ribiere-Plus
2744aa34175SJason Sarich          "hs" - Hestenes-Steifel
2754aa34175SJason Sarich          "dy" - Dai-Yuan
2761eb8069cSJason Sarich   Level: beginner
2774aa34175SJason Sarich M*/
2785e1affc2SSatish Balay 
279728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoCreate_CG(Tao tao)
2805e1affc2SSatish Balay {
2815e1affc2SSatish Balay   TAO_CG         *cgP;
2828caf6e8cSBarry Smith   const char     *morethuente_type = TAOLINESEARCHMT;
28387f595a5SBarry Smith 
2845e1affc2SSatish Balay   PetscFunctionBegin;
2855e1affc2SSatish Balay   tao->ops->setup = TaoSetUp_CG;
2865e1affc2SSatish Balay   tao->ops->solve = TaoSolve_CG;
2875e1affc2SSatish Balay   tao->ops->view = TaoView_CG;
2885e1affc2SSatish Balay   tao->ops->setfromoptions = TaoSetFromOptions_CG;
2895e1affc2SSatish Balay   tao->ops->destroy = TaoDestroy_CG;
2905e1affc2SSatish Balay 
2916552cf8aSJason Sarich   /* Override default settings (unless already changed) */
2926552cf8aSJason Sarich   if (!tao->max_it_changed) tao->max_it = 2000;
2936552cf8aSJason Sarich   if (!tao->max_funcs_changed) tao->max_funcs = 4000;
2945e1affc2SSatish Balay 
2955e1affc2SSatish Balay   /*  Note: nondefault values should be used for nonlinear conjugate gradient  */
2965e1affc2SSatish Balay   /*  method.  In particular, gtol should be less that 0.5; the value used in  */
2975e1affc2SSatish Balay   /*  Nocedal and Wright is 0.10.  We use the default values for the  */
2985e1affc2SSatish Balay   /*  linesearch because it seems to work better. */
299*9566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch));
300*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1));
301*9566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchSetType(tao->linesearch, morethuente_type));
302*9566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchUseTaoRoutines(tao->linesearch, tao));
303*9566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix));
3045e1affc2SSatish Balay 
305*9566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(tao,&cgP));
3065e1affc2SSatish Balay   tao->data = (void*)cgP;
3075e1affc2SSatish Balay   cgP->eta = 0.1;
3085e1affc2SSatish Balay   cgP->delta_min = 1e-7;
3095e1affc2SSatish Balay   cgP->delta_max = 100;
3105e1affc2SSatish Balay   cgP->cg_type = CG_PolakRibierePlus;
3115e1affc2SSatish Balay   PetscFunctionReturn(0);
3125e1affc2SSatish Balay }
313