xref: /petsc/src/tao/unconstrained/impls/cg/taocg.c (revision 3ba1676111f5c958fe6c2729b46ca4d523958bb3)
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 
13d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoSolve_CG(Tao tao)
14d71ae5a4SJacob Faibussowitsch {
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;
2148a46eb9SPierre Jolivet   if (tao->XL || tao->XU || tao->ops->computebounds) PetscCall(PetscInfo(tao, "WARNING: Variable bounds have been set but will be ignored by cg algorithm\n"));
225e1affc2SSatish Balay 
235e1affc2SSatish Balay   /*  Check convergence criteria */
249566063dSJacob Faibussowitsch   PetscCall(TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient));
259566063dSJacob Faibussowitsch   PetscCall(VecNorm(tao->gradient, NORM_2, &gnorm));
263c859ba3SBarry Smith   PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm), PetscObjectComm((PetscObject)tao), PETSC_ERR_USER, "User provided compute function generated Inf or NaN");
275e1affc2SSatish Balay 
283ecd9318SAlp Dener   tao->reason = TAO_CONTINUE_ITERATING;
299566063dSJacob Faibussowitsch   PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its));
309566063dSJacob Faibussowitsch   PetscCall(TaoMonitor(tao, tao->niter, f, gnorm, 0.0, step));
31dbbe0bcdSBarry Smith   PetscUseTypeMethod(tao, convergencetest, tao->cnvP);
32*3ba16761SJacob Faibussowitsch   if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(PETSC_SUCCESS);
335e1affc2SSatish Balay 
345e1affc2SSatish Balay   /*  Set initial direction to -gradient */
359566063dSJacob Faibussowitsch   PetscCall(VecCopy(tao->gradient, tao->stepdirection));
369566063dSJacob Faibussowitsch   PetscCall(VecScale(tao->stepdirection, -1.0));
375e1affc2SSatish Balay   gnorm2 = gnorm * gnorm;
385e1affc2SSatish Balay 
395e1affc2SSatish Balay   /*  Set initial scaling for the function */
405e1affc2SSatish Balay   if (f != 0.0) {
415e1affc2SSatish Balay     delta = 2.0 * PetscAbsScalar(f) / gnorm2;
425e1affc2SSatish Balay     delta = PetscMax(delta, cgP->delta_min);
435e1affc2SSatish Balay     delta = PetscMin(delta, cgP->delta_max);
445e1affc2SSatish Balay   } else {
455e1affc2SSatish Balay     delta = 2.0 / gnorm2;
465e1affc2SSatish Balay     delta = PetscMax(delta, cgP->delta_min);
475e1affc2SSatish Balay     delta = PetscMin(delta, cgP->delta_max);
485e1affc2SSatish Balay   }
495e1affc2SSatish Balay   /*  Set counter for gradient and reset steps */
505e1affc2SSatish Balay   cgP->ngradsteps  = 0;
515e1affc2SSatish Balay   cgP->nresetsteps = 0;
525e1affc2SSatish Balay 
535e1affc2SSatish Balay   while (1) {
54e1e80dc8SAlp Dener     /* Call general purpose update function */
55dbbe0bcdSBarry Smith     PetscTryTypeMethod(tao, update, tao->niter, tao->user_update);
56e1e80dc8SAlp Dener 
575e1affc2SSatish Balay     /*  Save the current gradient information */
585e1affc2SSatish Balay     f_old      = f;
595e1affc2SSatish Balay     gnorm2_old = gnorm2;
609566063dSJacob Faibussowitsch     PetscCall(VecCopy(tao->solution, cgP->X_old));
619566063dSJacob Faibussowitsch     PetscCall(VecCopy(tao->gradient, cgP->G_old));
629566063dSJacob Faibussowitsch     PetscCall(VecDot(tao->gradient, tao->stepdirection, &gd));
635e1affc2SSatish Balay     if ((gd >= 0) || PetscIsInfOrNanReal(gd)) {
645e1affc2SSatish Balay       ++cgP->ngradsteps;
655e1affc2SSatish Balay       if (f != 0.0) {
665e1affc2SSatish Balay         delta = 2.0 * PetscAbsScalar(f) / gnorm2;
675e1affc2SSatish Balay         delta = PetscMax(delta, cgP->delta_min);
685e1affc2SSatish Balay         delta = PetscMin(delta, cgP->delta_max);
695e1affc2SSatish Balay       } else {
705e1affc2SSatish Balay         delta = 2.0 / gnorm2;
715e1affc2SSatish Balay         delta = PetscMax(delta, cgP->delta_min);
725e1affc2SSatish Balay         delta = PetscMin(delta, cgP->delta_max);
735e1affc2SSatish Balay       }
745e1affc2SSatish Balay 
759566063dSJacob Faibussowitsch       PetscCall(VecCopy(tao->gradient, tao->stepdirection));
769566063dSJacob Faibussowitsch       PetscCall(VecScale(tao->stepdirection, -1.0));
775e1affc2SSatish Balay     }
785e1affc2SSatish Balay 
795e1affc2SSatish Balay     /*  Search direction for improving point */
809566063dSJacob Faibussowitsch     PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch, delta));
819566063dSJacob Faibussowitsch     PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status));
829566063dSJacob Faibussowitsch     PetscCall(TaoAddLineSearchCounts(tao));
8387f595a5SBarry Smith     if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) {
845e1affc2SSatish Balay       /*  Linesearch failed */
855e1affc2SSatish Balay       /*  Reset factors and use scaled gradient step */
865e1affc2SSatish Balay       ++cgP->nresetsteps;
875e1affc2SSatish Balay       f      = f_old;
885e1affc2SSatish Balay       gnorm2 = gnorm2_old;
899566063dSJacob Faibussowitsch       PetscCall(VecCopy(cgP->X_old, tao->solution));
909566063dSJacob Faibussowitsch       PetscCall(VecCopy(cgP->G_old, tao->gradient));
915e1affc2SSatish Balay 
925e1affc2SSatish Balay       if (f != 0.0) {
935e1affc2SSatish Balay         delta = 2.0 * PetscAbsScalar(f) / gnorm2;
945e1affc2SSatish Balay         delta = PetscMax(delta, cgP->delta_min);
955e1affc2SSatish Balay         delta = PetscMin(delta, cgP->delta_max);
965e1affc2SSatish Balay       } else {
975e1affc2SSatish Balay         delta = 2.0 / gnorm2;
985e1affc2SSatish Balay         delta = PetscMax(delta, cgP->delta_min);
995e1affc2SSatish Balay         delta = PetscMin(delta, cgP->delta_max);
1005e1affc2SSatish Balay       }
1015e1affc2SSatish Balay 
1029566063dSJacob Faibussowitsch       PetscCall(VecCopy(tao->gradient, tao->stepdirection));
1039566063dSJacob Faibussowitsch       PetscCall(VecScale(tao->stepdirection, -1.0));
1045e1affc2SSatish Balay 
1059566063dSJacob Faibussowitsch       PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch, delta));
1069566063dSJacob Faibussowitsch       PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status));
1079566063dSJacob Faibussowitsch       PetscCall(TaoAddLineSearchCounts(tao));
1085e1affc2SSatish Balay 
10987f595a5SBarry Smith       if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) {
1105e1affc2SSatish Balay         /*  Linesearch failed again */
1115e1affc2SSatish Balay         /*  switch to unscaled gradient */
1125e1affc2SSatish Balay         f = f_old;
1139566063dSJacob Faibussowitsch         PetscCall(VecCopy(cgP->X_old, tao->solution));
1149566063dSJacob Faibussowitsch         PetscCall(VecCopy(cgP->G_old, tao->gradient));
1155e1affc2SSatish Balay         delta = 1.0;
1169566063dSJacob Faibussowitsch         PetscCall(VecCopy(tao->solution, tao->stepdirection));
1179566063dSJacob Faibussowitsch         PetscCall(VecScale(tao->stepdirection, -1.0));
1185e1affc2SSatish Balay 
1199566063dSJacob Faibussowitsch         PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch, delta));
1209566063dSJacob Faibussowitsch         PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status));
1219566063dSJacob Faibussowitsch         PetscCall(TaoAddLineSearchCounts(tao));
1228caf6e8cSBarry Smith         if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) {
1235e1affc2SSatish Balay           /*  Line search failed for last time -- give up */
1245e1affc2SSatish Balay           f = f_old;
1259566063dSJacob Faibussowitsch           PetscCall(VecCopy(cgP->X_old, tao->solution));
1269566063dSJacob Faibussowitsch           PetscCall(VecCopy(cgP->G_old, tao->gradient));
1275e1affc2SSatish Balay           step        = 0.0;
1285e1affc2SSatish Balay           tao->reason = TAO_DIVERGED_LS_FAILURE;
1295e1affc2SSatish Balay         }
1305e1affc2SSatish Balay       }
1315e1affc2SSatish Balay     }
1325e1affc2SSatish Balay 
1335e1affc2SSatish Balay     /*  Check for bad value */
1349566063dSJacob Faibussowitsch     PetscCall(VecNorm(tao->gradient, NORM_2, &gnorm));
1353c859ba3SBarry Smith     PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm), PetscObjectComm((PetscObject)tao), PETSC_ERR_USER, "User-provided compute function generated Inf or NaN");
1365e1affc2SSatish Balay 
1375e1affc2SSatish Balay     /*  Check for termination */
1385e1affc2SSatish Balay     gnorm2 = gnorm * gnorm;
1398931d482SJason Sarich     tao->niter++;
1409566063dSJacob Faibussowitsch     PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its));
1419566063dSJacob Faibussowitsch     PetscCall(TaoMonitor(tao, tao->niter, f, gnorm, 0.0, step));
142dbbe0bcdSBarry Smith     PetscUseTypeMethod(tao, convergencetest, tao->cnvP);
143ad540459SPierre Jolivet     if (tao->reason != TAO_CONTINUE_ITERATING) break;
1445e1affc2SSatish Balay 
1455e1affc2SSatish Balay     /*  Check for restart condition */
1469566063dSJacob Faibussowitsch     PetscCall(VecDot(tao->gradient, cgP->G_old, &ginner));
1475e1affc2SSatish Balay     if (PetscAbsScalar(ginner) >= cgP->eta * gnorm2) {
148a5b23f4aSJose E. Roman       /*  Gradients far from orthogonal; use steepest descent direction */
1495e1affc2SSatish Balay       beta = 0.0;
1505e1affc2SSatish Balay     } else {
1515e1affc2SSatish Balay       /*  Gradients close to orthogonal; use conjugate gradient formula */
1525e1affc2SSatish Balay       switch (cgP->cg_type) {
153d71ae5a4SJacob Faibussowitsch       case CG_FletcherReeves:
154d71ae5a4SJacob Faibussowitsch         beta = gnorm2 / gnorm2_old;
155d71ae5a4SJacob Faibussowitsch         break;
1565e1affc2SSatish Balay 
157d71ae5a4SJacob Faibussowitsch       case CG_PolakRibiere:
158d71ae5a4SJacob Faibussowitsch         beta = (gnorm2 - ginner) / gnorm2_old;
159d71ae5a4SJacob Faibussowitsch         break;
1605e1affc2SSatish Balay 
161d71ae5a4SJacob Faibussowitsch       case CG_PolakRibierePlus:
162d71ae5a4SJacob Faibussowitsch         beta = PetscMax((gnorm2 - ginner) / gnorm2_old, 0.0);
163d71ae5a4SJacob Faibussowitsch         break;
1645e1affc2SSatish Balay 
1655e1affc2SSatish Balay       case CG_HestenesStiefel:
1669566063dSJacob Faibussowitsch         PetscCall(VecDot(tao->gradient, tao->stepdirection, &gd));
1679566063dSJacob Faibussowitsch         PetscCall(VecDot(cgP->G_old, tao->stepdirection, &gd_old));
1685e1affc2SSatish Balay         beta = (gnorm2 - ginner) / (gd - gd_old);
1695e1affc2SSatish Balay         break;
1705e1affc2SSatish Balay 
1715e1affc2SSatish Balay       case CG_DaiYuan:
1729566063dSJacob Faibussowitsch         PetscCall(VecDot(tao->gradient, tao->stepdirection, &gd));
1739566063dSJacob Faibussowitsch         PetscCall(VecDot(cgP->G_old, tao->stepdirection, &gd_old));
1745e1affc2SSatish Balay         beta = gnorm2 / (gd - gd_old);
1755e1affc2SSatish Balay         break;
1765e1affc2SSatish Balay 
177d71ae5a4SJacob Faibussowitsch       default:
178d71ae5a4SJacob Faibussowitsch         beta = 0.0;
179d71ae5a4SJacob Faibussowitsch         break;
1805e1affc2SSatish Balay       }
1815e1affc2SSatish Balay     }
1825e1affc2SSatish Balay 
1835e1affc2SSatish Balay     /*  Compute the direction d=-g + beta*d */
1849566063dSJacob Faibussowitsch     PetscCall(VecAXPBY(tao->stepdirection, -1.0, beta, tao->gradient));
1855e1affc2SSatish Balay 
1865e1affc2SSatish Balay     /*  update initial steplength choice */
1875e1affc2SSatish Balay     delta = 1.0;
1885e1affc2SSatish Balay     delta = PetscMax(delta, cgP->delta_min);
1895e1affc2SSatish Balay     delta = PetscMin(delta, cgP->delta_max);
1905e1affc2SSatish Balay   }
191*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1925e1affc2SSatish Balay }
1935e1affc2SSatish Balay 
194d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoSetUp_CG(Tao tao)
195d71ae5a4SJacob Faibussowitsch {
1965e1affc2SSatish Balay   TAO_CG *cgP = (TAO_CG *)tao->data;
1975e1affc2SSatish Balay 
1985e1affc2SSatish Balay   PetscFunctionBegin;
1999566063dSJacob Faibussowitsch   if (!tao->gradient) PetscCall(VecDuplicate(tao->solution, &tao->gradient));
2009566063dSJacob Faibussowitsch   if (!tao->stepdirection) PetscCall(VecDuplicate(tao->solution, &tao->stepdirection));
2019566063dSJacob Faibussowitsch   if (!cgP->X_old) PetscCall(VecDuplicate(tao->solution, &cgP->X_old));
2029566063dSJacob Faibussowitsch   if (!cgP->G_old) PetscCall(VecDuplicate(tao->gradient, &cgP->G_old));
203*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2045e1affc2SSatish Balay }
2055e1affc2SSatish Balay 
206d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoDestroy_CG(Tao tao)
207d71ae5a4SJacob Faibussowitsch {
2085e1affc2SSatish Balay   TAO_CG *cgP = (TAO_CG *)tao->data;
2095e1affc2SSatish Balay 
2105e1affc2SSatish Balay   PetscFunctionBegin;
2115e1affc2SSatish Balay   if (tao->setupcalled) {
2129566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&cgP->X_old));
2139566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&cgP->G_old));
2145e1affc2SSatish Balay   }
2159566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchDestroy(&tao->linesearch));
2169566063dSJacob Faibussowitsch   PetscCall(PetscFree(tao->data));
217*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2185e1affc2SSatish Balay }
2195e1affc2SSatish Balay 
220d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoSetFromOptions_CG(Tao tao, PetscOptionItems *PetscOptionsObject)
221d71ae5a4SJacob Faibussowitsch {
2225e1affc2SSatish Balay   TAO_CG *cgP = (TAO_CG *)tao->data;
2235e1affc2SSatish Balay 
2245e1affc2SSatish Balay   PetscFunctionBegin;
2259566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchSetFromOptions(tao->linesearch));
226d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "Nonlinear Conjugate Gradient method for unconstrained optimization");
2279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_cg_eta", "restart tolerance", "", cgP->eta, &cgP->eta, NULL));
2289566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-tao_cg_type", "cg formula", "", CG_Table, CG_Types, CG_Table[cgP->cg_type], &cgP->cg_type, NULL));
2299566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_cg_delta_min", "minimum delta value", "", cgP->delta_min, &cgP->delta_min, NULL));
2309566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_cg_delta_max", "maximum delta value", "", cgP->delta_max, &cgP->delta_max, NULL));
231d0609cedSBarry Smith   PetscOptionsHeadEnd();
232*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2335e1affc2SSatish Balay }
2345e1affc2SSatish Balay 
235d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoView_CG(Tao tao, PetscViewer viewer)
236d71ae5a4SJacob Faibussowitsch {
2375e1affc2SSatish Balay   PetscBool isascii;
2385e1affc2SSatish Balay   TAO_CG   *cgP = (TAO_CG *)tao->data;
2395e1affc2SSatish Balay 
2405e1affc2SSatish Balay   PetscFunctionBegin;
2419566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2425e1affc2SSatish Balay   if (isascii) {
2439566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
2449566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "CG Type: %s\n", CG_Table[cgP->cg_type]));
24563a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Gradient steps: %" PetscInt_FMT "\n", cgP->ngradsteps));
24663a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Reset steps: %" PetscInt_FMT "\n", cgP->nresetsteps));
2479566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
2485e1affc2SSatish Balay   }
249*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2505e1affc2SSatish Balay }
2514aa34175SJason Sarich 
2524aa34175SJason Sarich /*MC
2534aa34175SJason Sarich      TAOCG -   Nonlinear conjugate gradient method is an extension of the
2544aa34175SJason Sarich nonlinear conjugate gradient solver for nonlinear optimization.
2554aa34175SJason Sarich 
2564aa34175SJason Sarich    Options Database Keys:
2574aa34175SJason Sarich +      -tao_cg_eta <r> - restart tolerance
2584aa34175SJason Sarich .      -tao_cg_type <taocg_type> - cg formula
2594aa34175SJason Sarich .      -tao_cg_delta_min <r> - minimum delta value
2604aa34175SJason Sarich -      -tao_cg_delta_max <r> - maximum delta value
2614aa34175SJason Sarich 
2624aa34175SJason Sarich   Notes:
2634aa34175SJason Sarich      CG formulas are:
2644aa34175SJason Sarich          "fr" - Fletcher-Reeves
2654aa34175SJason Sarich          "pr" - Polak-Ribiere
2664aa34175SJason Sarich          "prp" - Polak-Ribiere-Plus
2674aa34175SJason Sarich          "hs" - Hestenes-Steifel
2684aa34175SJason Sarich          "dy" - Dai-Yuan
2691eb8069cSJason Sarich   Level: beginner
2704aa34175SJason Sarich M*/
2715e1affc2SSatish Balay 
272d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TaoCreate_CG(Tao tao)
273d71ae5a4SJacob Faibussowitsch {
2745e1affc2SSatish Balay   TAO_CG     *cgP;
2758caf6e8cSBarry Smith   const char *morethuente_type = TAOLINESEARCHMT;
27687f595a5SBarry Smith 
2775e1affc2SSatish Balay   PetscFunctionBegin;
2785e1affc2SSatish Balay   tao->ops->setup          = TaoSetUp_CG;
2795e1affc2SSatish Balay   tao->ops->solve          = TaoSolve_CG;
2805e1affc2SSatish Balay   tao->ops->view           = TaoView_CG;
2815e1affc2SSatish Balay   tao->ops->setfromoptions = TaoSetFromOptions_CG;
2825e1affc2SSatish Balay   tao->ops->destroy        = TaoDestroy_CG;
2835e1affc2SSatish Balay 
2846552cf8aSJason Sarich   /* Override default settings (unless already changed) */
2856552cf8aSJason Sarich   if (!tao->max_it_changed) tao->max_it = 2000;
2866552cf8aSJason Sarich   if (!tao->max_funcs_changed) tao->max_funcs = 4000;
2875e1affc2SSatish Balay 
2885e1affc2SSatish Balay   /*  Note: nondefault values should be used for nonlinear conjugate gradient  */
2895e1affc2SSatish Balay   /*  method.  In particular, gtol should be less that 0.5; the value used in  */
2905e1affc2SSatish Balay   /*  Nocedal and Wright is 0.10.  We use the default values for the  */
2915e1affc2SSatish Balay   /*  linesearch because it seems to work better. */
2929566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch));
2939566063dSJacob Faibussowitsch   PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1));
2949566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchSetType(tao->linesearch, morethuente_type));
2959566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchUseTaoRoutines(tao->linesearch, tao));
2969566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchSetOptionsPrefix(tao->linesearch, tao->hdr.prefix));
2975e1affc2SSatish Balay 
2984dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&cgP));
2995e1affc2SSatish Balay   tao->data      = (void *)cgP;
3005e1affc2SSatish Balay   cgP->eta       = 0.1;
3015e1affc2SSatish Balay   cgP->delta_min = 1e-7;
3025e1affc2SSatish Balay   cgP->delta_max = 100;
3035e1affc2SSatish Balay   cgP->cg_type   = CG_PolakRibierePlus;
304*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3055e1affc2SSatish Balay }
306