xref: /petsc/src/tao/unconstrained/impls/cg/taocg.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
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 
13*9371c9d4SSatish Balay static PetscErrorCode TaoSolve_CG(Tao tao) {
145e1affc2SSatish Balay   TAO_CG                      *cgP       = (TAO_CG *)tao->data;
15e4cb33bbSBarry Smith   TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING;
165e1affc2SSatish Balay   PetscReal                    step      = 1.0, f, gnorm, gnorm2, delta, gd, ginner, beta;
175e1affc2SSatish Balay   PetscReal                    gd_old, gnorm2_old, f_old;
185e1affc2SSatish Balay 
195e1affc2SSatish Balay   PetscFunctionBegin;
20*9371c9d4SSatish Balay   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")); }
215e1affc2SSatish Balay 
225e1affc2SSatish Balay   /*  Check convergence criteria */
239566063dSJacob Faibussowitsch   PetscCall(TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient));
249566063dSJacob Faibussowitsch   PetscCall(VecNorm(tao->gradient, NORM_2, &gnorm));
253c859ba3SBarry Smith   PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm), PetscObjectComm((PetscObject)tao), PETSC_ERR_USER, "User provided compute function generated Inf or NaN");
265e1affc2SSatish Balay 
273ecd9318SAlp Dener   tao->reason = TAO_CONTINUE_ITERATING;
289566063dSJacob Faibussowitsch   PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its));
299566063dSJacob Faibussowitsch   PetscCall(TaoMonitor(tao, tao->niter, f, gnorm, 0.0, step));
30dbbe0bcdSBarry Smith   PetscUseTypeMethod(tao, convergencetest, tao->cnvP);
313ecd9318SAlp Dener   if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0);
325e1affc2SSatish Balay 
335e1affc2SSatish Balay   /*  Set initial direction to -gradient */
349566063dSJacob Faibussowitsch   PetscCall(VecCopy(tao->gradient, tao->stepdirection));
359566063dSJacob Faibussowitsch   PetscCall(VecScale(tao->stepdirection, -1.0));
365e1affc2SSatish Balay   gnorm2 = gnorm * gnorm;
375e1affc2SSatish Balay 
385e1affc2SSatish Balay   /*  Set initial scaling for the function */
395e1affc2SSatish Balay   if (f != 0.0) {
405e1affc2SSatish Balay     delta = 2.0 * PetscAbsScalar(f) / gnorm2;
415e1affc2SSatish Balay     delta = PetscMax(delta, cgP->delta_min);
425e1affc2SSatish Balay     delta = PetscMin(delta, cgP->delta_max);
435e1affc2SSatish Balay   } else {
445e1affc2SSatish Balay     delta = 2.0 / gnorm2;
455e1affc2SSatish Balay     delta = PetscMax(delta, cgP->delta_min);
465e1affc2SSatish Balay     delta = PetscMin(delta, cgP->delta_max);
475e1affc2SSatish Balay   }
485e1affc2SSatish Balay   /*  Set counter for gradient and reset steps */
495e1affc2SSatish Balay   cgP->ngradsteps  = 0;
505e1affc2SSatish Balay   cgP->nresetsteps = 0;
515e1affc2SSatish Balay 
525e1affc2SSatish Balay   while (1) {
53e1e80dc8SAlp Dener     /* Call general purpose update function */
54dbbe0bcdSBarry Smith     PetscTryTypeMethod(tao, update, tao->niter, tao->user_update);
55e1e80dc8SAlp Dener 
565e1affc2SSatish Balay     /*  Save the current gradient information */
575e1affc2SSatish Balay     f_old      = f;
585e1affc2SSatish Balay     gnorm2_old = gnorm2;
599566063dSJacob Faibussowitsch     PetscCall(VecCopy(tao->solution, cgP->X_old));
609566063dSJacob Faibussowitsch     PetscCall(VecCopy(tao->gradient, cgP->G_old));
619566063dSJacob Faibussowitsch     PetscCall(VecDot(tao->gradient, tao->stepdirection, &gd));
625e1affc2SSatish Balay     if ((gd >= 0) || PetscIsInfOrNanReal(gd)) {
635e1affc2SSatish Balay       ++cgP->ngradsteps;
645e1affc2SSatish Balay       if (f != 0.0) {
655e1affc2SSatish Balay         delta = 2.0 * PetscAbsScalar(f) / gnorm2;
665e1affc2SSatish Balay         delta = PetscMax(delta, cgP->delta_min);
675e1affc2SSatish Balay         delta = PetscMin(delta, cgP->delta_max);
685e1affc2SSatish Balay       } else {
695e1affc2SSatish Balay         delta = 2.0 / gnorm2;
705e1affc2SSatish Balay         delta = PetscMax(delta, cgP->delta_min);
715e1affc2SSatish Balay         delta = PetscMin(delta, cgP->delta_max);
725e1affc2SSatish Balay       }
735e1affc2SSatish Balay 
749566063dSJacob Faibussowitsch       PetscCall(VecCopy(tao->gradient, tao->stepdirection));
759566063dSJacob Faibussowitsch       PetscCall(VecScale(tao->stepdirection, -1.0));
765e1affc2SSatish Balay     }
775e1affc2SSatish Balay 
785e1affc2SSatish Balay     /*  Search direction for improving point */
799566063dSJacob Faibussowitsch     PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch, delta));
809566063dSJacob Faibussowitsch     PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status));
819566063dSJacob Faibussowitsch     PetscCall(TaoAddLineSearchCounts(tao));
8287f595a5SBarry Smith     if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) {
835e1affc2SSatish Balay       /*  Linesearch failed */
845e1affc2SSatish Balay       /*  Reset factors and use scaled gradient step */
855e1affc2SSatish Balay       ++cgP->nresetsteps;
865e1affc2SSatish Balay       f      = f_old;
875e1affc2SSatish Balay       gnorm2 = gnorm2_old;
889566063dSJacob Faibussowitsch       PetscCall(VecCopy(cgP->X_old, tao->solution));
899566063dSJacob Faibussowitsch       PetscCall(VecCopy(cgP->G_old, tao->gradient));
905e1affc2SSatish Balay 
915e1affc2SSatish Balay       if (f != 0.0) {
925e1affc2SSatish Balay         delta = 2.0 * PetscAbsScalar(f) / gnorm2;
935e1affc2SSatish Balay         delta = PetscMax(delta, cgP->delta_min);
945e1affc2SSatish Balay         delta = PetscMin(delta, cgP->delta_max);
955e1affc2SSatish Balay       } else {
965e1affc2SSatish Balay         delta = 2.0 / gnorm2;
975e1affc2SSatish Balay         delta = PetscMax(delta, cgP->delta_min);
985e1affc2SSatish Balay         delta = PetscMin(delta, cgP->delta_max);
995e1affc2SSatish Balay       }
1005e1affc2SSatish Balay 
1019566063dSJacob Faibussowitsch       PetscCall(VecCopy(tao->gradient, tao->stepdirection));
1029566063dSJacob Faibussowitsch       PetscCall(VecScale(tao->stepdirection, -1.0));
1035e1affc2SSatish Balay 
1049566063dSJacob Faibussowitsch       PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch, delta));
1059566063dSJacob Faibussowitsch       PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status));
1069566063dSJacob Faibussowitsch       PetscCall(TaoAddLineSearchCounts(tao));
1075e1affc2SSatish Balay 
10887f595a5SBarry Smith       if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) {
1095e1affc2SSatish Balay         /*  Linesearch failed again */
1105e1affc2SSatish Balay         /*  switch to unscaled gradient */
1115e1affc2SSatish Balay         f = f_old;
1129566063dSJacob Faibussowitsch         PetscCall(VecCopy(cgP->X_old, tao->solution));
1139566063dSJacob Faibussowitsch         PetscCall(VecCopy(cgP->G_old, tao->gradient));
1145e1affc2SSatish Balay         delta = 1.0;
1159566063dSJacob Faibussowitsch         PetscCall(VecCopy(tao->solution, tao->stepdirection));
1169566063dSJacob Faibussowitsch         PetscCall(VecScale(tao->stepdirection, -1.0));
1175e1affc2SSatish Balay 
1189566063dSJacob Faibussowitsch         PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch, delta));
1199566063dSJacob Faibussowitsch         PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status));
1209566063dSJacob Faibussowitsch         PetscCall(TaoAddLineSearchCounts(tao));
1218caf6e8cSBarry Smith         if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) {
1225e1affc2SSatish Balay           /*  Line search failed for last time -- give up */
1235e1affc2SSatish Balay           f = f_old;
1249566063dSJacob Faibussowitsch           PetscCall(VecCopy(cgP->X_old, tao->solution));
1259566063dSJacob Faibussowitsch           PetscCall(VecCopy(cgP->G_old, tao->gradient));
1265e1affc2SSatish Balay           step        = 0.0;
1275e1affc2SSatish Balay           tao->reason = TAO_DIVERGED_LS_FAILURE;
1285e1affc2SSatish Balay         }
1295e1affc2SSatish Balay       }
1305e1affc2SSatish Balay     }
1315e1affc2SSatish Balay 
1325e1affc2SSatish Balay     /*  Check for bad value */
1339566063dSJacob Faibussowitsch     PetscCall(VecNorm(tao->gradient, NORM_2, &gnorm));
1343c859ba3SBarry Smith     PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm), PetscObjectComm((PetscObject)tao), PETSC_ERR_USER, "User-provided compute function generated Inf or NaN");
1355e1affc2SSatish Balay 
1365e1affc2SSatish Balay     /*  Check for termination */
1375e1affc2SSatish Balay     gnorm2 = gnorm * gnorm;
1388931d482SJason Sarich     tao->niter++;
1399566063dSJacob Faibussowitsch     PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its));
1409566063dSJacob Faibussowitsch     PetscCall(TaoMonitor(tao, tao->niter, f, gnorm, 0.0, step));
141dbbe0bcdSBarry Smith     PetscUseTypeMethod(tao, convergencetest, tao->cnvP);
142*9371c9d4SSatish Balay     if (tao->reason != TAO_CONTINUE_ITERATING) { break; }
1435e1affc2SSatish Balay 
1445e1affc2SSatish Balay     /*  Check for restart condition */
1459566063dSJacob Faibussowitsch     PetscCall(VecDot(tao->gradient, cgP->G_old, &ginner));
1465e1affc2SSatish Balay     if (PetscAbsScalar(ginner) >= cgP->eta * gnorm2) {
147a5b23f4aSJose E. Roman       /*  Gradients far from orthogonal; use steepest descent direction */
1485e1affc2SSatish Balay       beta = 0.0;
1495e1affc2SSatish Balay     } else {
1505e1affc2SSatish Balay       /*  Gradients close to orthogonal; use conjugate gradient formula */
1515e1affc2SSatish Balay       switch (cgP->cg_type) {
152*9371c9d4SSatish Balay       case CG_FletcherReeves: beta = gnorm2 / gnorm2_old; break;
1535e1affc2SSatish Balay 
154*9371c9d4SSatish Balay       case CG_PolakRibiere: beta = (gnorm2 - ginner) / gnorm2_old; break;
1555e1affc2SSatish Balay 
156*9371c9d4SSatish Balay       case CG_PolakRibierePlus: beta = PetscMax((gnorm2 - ginner) / gnorm2_old, 0.0); break;
1575e1affc2SSatish Balay 
1585e1affc2SSatish Balay       case CG_HestenesStiefel:
1599566063dSJacob Faibussowitsch         PetscCall(VecDot(tao->gradient, tao->stepdirection, &gd));
1609566063dSJacob Faibussowitsch         PetscCall(VecDot(cgP->G_old, tao->stepdirection, &gd_old));
1615e1affc2SSatish Balay         beta = (gnorm2 - ginner) / (gd - gd_old);
1625e1affc2SSatish Balay         break;
1635e1affc2SSatish Balay 
1645e1affc2SSatish Balay       case CG_DaiYuan:
1659566063dSJacob Faibussowitsch         PetscCall(VecDot(tao->gradient, tao->stepdirection, &gd));
1669566063dSJacob Faibussowitsch         PetscCall(VecDot(cgP->G_old, tao->stepdirection, &gd_old));
1675e1affc2SSatish Balay         beta = gnorm2 / (gd - gd_old);
1685e1affc2SSatish Balay         break;
1695e1affc2SSatish Balay 
170*9371c9d4SSatish Balay       default: beta = 0.0; break;
1715e1affc2SSatish Balay       }
1725e1affc2SSatish Balay     }
1735e1affc2SSatish Balay 
1745e1affc2SSatish Balay     /*  Compute the direction d=-g + beta*d */
1759566063dSJacob Faibussowitsch     PetscCall(VecAXPBY(tao->stepdirection, -1.0, beta, tao->gradient));
1765e1affc2SSatish Balay 
1775e1affc2SSatish Balay     /*  update initial steplength choice */
1785e1affc2SSatish Balay     delta = 1.0;
1795e1affc2SSatish Balay     delta = PetscMax(delta, cgP->delta_min);
1805e1affc2SSatish Balay     delta = PetscMin(delta, cgP->delta_max);
1815e1affc2SSatish Balay   }
1825e1affc2SSatish Balay   PetscFunctionReturn(0);
1835e1affc2SSatish Balay }
1845e1affc2SSatish Balay 
185*9371c9d4SSatish Balay static PetscErrorCode TaoSetUp_CG(Tao tao) {
1865e1affc2SSatish Balay   TAO_CG *cgP = (TAO_CG *)tao->data;
1875e1affc2SSatish Balay 
1885e1affc2SSatish Balay   PetscFunctionBegin;
1899566063dSJacob Faibussowitsch   if (!tao->gradient) PetscCall(VecDuplicate(tao->solution, &tao->gradient));
1909566063dSJacob Faibussowitsch   if (!tao->stepdirection) PetscCall(VecDuplicate(tao->solution, &tao->stepdirection));
1919566063dSJacob Faibussowitsch   if (!cgP->X_old) PetscCall(VecDuplicate(tao->solution, &cgP->X_old));
1929566063dSJacob Faibussowitsch   if (!cgP->G_old) PetscCall(VecDuplicate(tao->gradient, &cgP->G_old));
1935e1affc2SSatish Balay   PetscFunctionReturn(0);
1945e1affc2SSatish Balay }
1955e1affc2SSatish Balay 
196*9371c9d4SSatish Balay static PetscErrorCode TaoDestroy_CG(Tao tao) {
1975e1affc2SSatish Balay   TAO_CG *cgP = (TAO_CG *)tao->data;
1985e1affc2SSatish Balay 
1995e1affc2SSatish Balay   PetscFunctionBegin;
2005e1affc2SSatish Balay   if (tao->setupcalled) {
2019566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&cgP->X_old));
2029566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&cgP->G_old));
2035e1affc2SSatish Balay   }
2049566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchDestroy(&tao->linesearch));
2059566063dSJacob Faibussowitsch   PetscCall(PetscFree(tao->data));
2065e1affc2SSatish Balay   PetscFunctionReturn(0);
2075e1affc2SSatish Balay }
2085e1affc2SSatish Balay 
209*9371c9d4SSatish Balay static PetscErrorCode TaoSetFromOptions_CG(Tao tao, PetscOptionItems *PetscOptionsObject) {
2105e1affc2SSatish Balay   TAO_CG *cgP = (TAO_CG *)tao->data;
2115e1affc2SSatish Balay 
2125e1affc2SSatish Balay   PetscFunctionBegin;
2139566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchSetFromOptions(tao->linesearch));
214d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "Nonlinear Conjugate Gradient method for unconstrained optimization");
2159566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_cg_eta", "restart tolerance", "", cgP->eta, &cgP->eta, NULL));
2169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-tao_cg_type", "cg formula", "", CG_Table, CG_Types, CG_Table[cgP->cg_type], &cgP->cg_type, NULL));
2179566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_cg_delta_min", "minimum delta value", "", cgP->delta_min, &cgP->delta_min, NULL));
2189566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_cg_delta_max", "maximum delta value", "", cgP->delta_max, &cgP->delta_max, NULL));
219d0609cedSBarry Smith   PetscOptionsHeadEnd();
2205e1affc2SSatish Balay   PetscFunctionReturn(0);
2215e1affc2SSatish Balay }
2225e1affc2SSatish Balay 
223*9371c9d4SSatish Balay static PetscErrorCode TaoView_CG(Tao tao, PetscViewer viewer) {
2245e1affc2SSatish Balay   PetscBool isascii;
2255e1affc2SSatish Balay   TAO_CG   *cgP = (TAO_CG *)tao->data;
2265e1affc2SSatish Balay 
2275e1affc2SSatish Balay   PetscFunctionBegin;
2289566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2295e1affc2SSatish Balay   if (isascii) {
2309566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
2319566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "CG Type: %s\n", CG_Table[cgP->cg_type]));
23263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Gradient steps: %" PetscInt_FMT "\n", cgP->ngradsteps));
23363a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Reset steps: %" PetscInt_FMT "\n", cgP->nresetsteps));
2349566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
2355e1affc2SSatish Balay   }
2365e1affc2SSatish Balay   PetscFunctionReturn(0);
2375e1affc2SSatish Balay }
2384aa34175SJason Sarich 
2394aa34175SJason Sarich /*MC
2404aa34175SJason Sarich      TAOCG -   Nonlinear conjugate gradient method is an extension of the
2414aa34175SJason Sarich nonlinear conjugate gradient solver for nonlinear optimization.
2424aa34175SJason Sarich 
2434aa34175SJason Sarich    Options Database Keys:
2444aa34175SJason Sarich +      -tao_cg_eta <r> - restart tolerance
2454aa34175SJason Sarich .      -tao_cg_type <taocg_type> - cg formula
2464aa34175SJason Sarich .      -tao_cg_delta_min <r> - minimum delta value
2474aa34175SJason Sarich -      -tao_cg_delta_max <r> - maximum delta value
2484aa34175SJason Sarich 
2494aa34175SJason Sarich   Notes:
2504aa34175SJason Sarich      CG formulas are:
2514aa34175SJason Sarich          "fr" - Fletcher-Reeves
2524aa34175SJason Sarich          "pr" - Polak-Ribiere
2534aa34175SJason Sarich          "prp" - Polak-Ribiere-Plus
2544aa34175SJason Sarich          "hs" - Hestenes-Steifel
2554aa34175SJason Sarich          "dy" - Dai-Yuan
2561eb8069cSJason Sarich   Level: beginner
2574aa34175SJason Sarich M*/
2585e1affc2SSatish Balay 
259*9371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode TaoCreate_CG(Tao tao) {
2605e1affc2SSatish Balay   TAO_CG     *cgP;
2618caf6e8cSBarry Smith   const char *morethuente_type = TAOLINESEARCHMT;
26287f595a5SBarry Smith 
2635e1affc2SSatish Balay   PetscFunctionBegin;
2645e1affc2SSatish Balay   tao->ops->setup          = TaoSetUp_CG;
2655e1affc2SSatish Balay   tao->ops->solve          = TaoSolve_CG;
2665e1affc2SSatish Balay   tao->ops->view           = TaoView_CG;
2675e1affc2SSatish Balay   tao->ops->setfromoptions = TaoSetFromOptions_CG;
2685e1affc2SSatish Balay   tao->ops->destroy        = TaoDestroy_CG;
2695e1affc2SSatish Balay 
2706552cf8aSJason Sarich   /* Override default settings (unless already changed) */
2716552cf8aSJason Sarich   if (!tao->max_it_changed) tao->max_it = 2000;
2726552cf8aSJason Sarich   if (!tao->max_funcs_changed) tao->max_funcs = 4000;
2735e1affc2SSatish Balay 
2745e1affc2SSatish Balay   /*  Note: nondefault values should be used for nonlinear conjugate gradient  */
2755e1affc2SSatish Balay   /*  method.  In particular, gtol should be less that 0.5; the value used in  */
2765e1affc2SSatish Balay   /*  Nocedal and Wright is 0.10.  We use the default values for the  */
2775e1affc2SSatish Balay   /*  linesearch because it seems to work better. */
2789566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch));
2799566063dSJacob Faibussowitsch   PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1));
2809566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchSetType(tao->linesearch, morethuente_type));
2819566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchUseTaoRoutines(tao->linesearch, tao));
2829566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchSetOptionsPrefix(tao->linesearch, tao->hdr.prefix));
2835e1affc2SSatish Balay 
2849566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(tao, &cgP));
2855e1affc2SSatish Balay   tao->data      = (void *)cgP;
2865e1affc2SSatish Balay   cgP->eta       = 0.1;
2875e1affc2SSatish Balay   cgP->delta_min = 1e-7;
2885e1affc2SSatish Balay   cgP->delta_max = 100;
2895e1affc2SSatish Balay   cgP->cg_type   = CG_PolakRibierePlus;
2905e1affc2SSatish Balay   PetscFunctionReturn(0);
2915e1affc2SSatish Balay }
292