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) { 229566063dSJacob 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 */ 269566063dSJacob Faibussowitsch PetscCall(TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient)); 279566063dSJacob 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; 319566063dSJacob Faibussowitsch PetscCall(TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its)); 329566063dSJacob Faibussowitsch PetscCall(TaoMonitor(tao,tao->niter,f,gnorm,0.0,step)); 339566063dSJacob 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 */ 379566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, tao->stepdirection)); 389566063dSJacob 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) { 589566063dSJacob 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; 649566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->solution, cgP->X_old)); 659566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, cgP->G_old)); 669566063dSJacob 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 799566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, tao->stepdirection)); 809566063dSJacob Faibussowitsch PetscCall(VecScale(tao->stepdirection, -1.0)); 815e1affc2SSatish Balay } 825e1affc2SSatish Balay 835e1affc2SSatish Balay /* Search direction for improving point */ 849566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch,delta)); 859566063dSJacob Faibussowitsch PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status)); 869566063dSJacob 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; 939566063dSJacob Faibussowitsch PetscCall(VecCopy(cgP->X_old, tao->solution)); 949566063dSJacob 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 1069566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->gradient, tao->stepdirection)); 1079566063dSJacob Faibussowitsch PetscCall(VecScale(tao->stepdirection, -1.0)); 1085e1affc2SSatish Balay 1099566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch,delta)); 1109566063dSJacob Faibussowitsch PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status)); 1119566063dSJacob 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; 1179566063dSJacob Faibussowitsch PetscCall(VecCopy(cgP->X_old, tao->solution)); 1189566063dSJacob Faibussowitsch PetscCall(VecCopy(cgP->G_old, tao->gradient)); 1195e1affc2SSatish Balay delta = 1.0; 1209566063dSJacob Faibussowitsch PetscCall(VecCopy(tao->solution, tao->stepdirection)); 1219566063dSJacob Faibussowitsch PetscCall(VecScale(tao->stepdirection, -1.0)); 1225e1affc2SSatish Balay 1239566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch,delta)); 1249566063dSJacob Faibussowitsch PetscCall(TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status)); 1259566063dSJacob 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; 1309566063dSJacob Faibussowitsch PetscCall(VecCopy(cgP->X_old, tao->solution)); 1319566063dSJacob 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 */ 1399566063dSJacob 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++; 1459566063dSJacob Faibussowitsch PetscCall(TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its)); 1469566063dSJacob Faibussowitsch PetscCall(TaoMonitor(tao,tao->niter,f,gnorm,0.0,step)); 1479566063dSJacob 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 */ 1539566063dSJacob 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: 1739566063dSJacob Faibussowitsch PetscCall(VecDot(tao->gradient, tao->stepdirection, &gd)); 1749566063dSJacob 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: 1799566063dSJacob Faibussowitsch PetscCall(VecDot(tao->gradient, tao->stepdirection, &gd)); 1809566063dSJacob 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 */ 1919566063dSJacob 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; 2069566063dSJacob Faibussowitsch if (!tao->gradient) PetscCall(VecDuplicate(tao->solution,&tao->gradient)); 2079566063dSJacob Faibussowitsch if (!tao->stepdirection) PetscCall(VecDuplicate(tao->solution,&tao->stepdirection)); 2089566063dSJacob Faibussowitsch if (!cgP->X_old) PetscCall(VecDuplicate(tao->solution,&cgP->X_old)); 2099566063dSJacob 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) { 2199566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cgP->X_old)); 2209566063dSJacob Faibussowitsch PetscCall(VecDestroy(&cgP->G_old)); 2215e1affc2SSatish Balay } 2229566063dSJacob Faibussowitsch PetscCall(TaoLineSearchDestroy(&tao->linesearch)); 2239566063dSJacob 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; 2329566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetFromOptions(tao->linesearch)); 233*d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject,"Nonlinear Conjugate Gradient method for unconstrained optimization"); 2349566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-tao_cg_eta","restart tolerance", "", cgP->eta,&cgP->eta,NULL)); 2359566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-tao_cg_type","cg formula", "", CG_Table, CG_Types, CG_Table[cgP->cg_type], &cgP->cg_type,NULL)); 2369566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-tao_cg_delta_min","minimum delta value", "", cgP->delta_min,&cgP->delta_min,NULL)); 2379566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-tao_cg_delta_max","maximum delta value", "", cgP->delta_max,&cgP->delta_max,NULL)); 238*d0609cedSBarry Smith PetscOptionsHeadEnd(); 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; 2489566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 2495e1affc2SSatish Balay if (isascii) { 2509566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 2519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "CG Type: %s\n", CG_Table[cgP->cg_type])); 2529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Gradient steps: %D\n", cgP->ngradsteps)); 2539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Reset steps: %D\n", cgP->nresetsteps)); 2549566063dSJacob 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. */ 2999566063dSJacob Faibussowitsch PetscCall(TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch)); 3009566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1)); 3019566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetType(tao->linesearch, morethuente_type)); 3029566063dSJacob Faibussowitsch PetscCall(TaoLineSearchUseTaoRoutines(tao->linesearch, tao)); 3039566063dSJacob Faibussowitsch PetscCall(TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix)); 3045e1affc2SSatish Balay 3059566063dSJacob 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