xref: /petsc/src/tao/unconstrained/impls/cg/taocg.c (revision 6552cf8a047ee1037a00972883c152ad7688e3b4)
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 
135e1affc2SSatish Balay  #undef __FUNCT__
145e1affc2SSatish Balay  #define __FUNCT__ "TaoSolve_CG"
15441846f8SBarry Smith  static PetscErrorCode TaoSolve_CG(Tao tao)
165e1affc2SSatish Balay  {
175e1affc2SSatish Balay    TAO_CG                       *cgP = (TAO_CG*)tao->data;
185e1affc2SSatish Balay    PetscErrorCode               ierr;
19e4cb33bbSBarry Smith    TaoConvergedReason           reason = TAO_CONTINUE_ITERATING;
20e4cb33bbSBarry Smith    TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING;
215e1affc2SSatish Balay    PetscReal                    step=1.0,f,gnorm,gnorm2,delta,gd,ginner,beta;
225e1affc2SSatish Balay    PetscReal                    gd_old,gnorm2_old,f_old;
235e1affc2SSatish Balay 
245e1affc2SSatish Balay    PetscFunctionBegin;
255e1affc2SSatish Balay    if (tao->XL || tao->XU || tao->ops->computebounds) {
265e1affc2SSatish Balay      ierr = PetscPrintf(((PetscObject)tao)->comm,"WARNING: Variable bounds have been set but will be ignored by cg algorithm\n");CHKERRQ(ierr);
275e1affc2SSatish Balay    }
285e1affc2SSatish Balay 
295e1affc2SSatish Balay    /*  Check convergence criteria */
305e1affc2SSatish Balay    ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient);CHKERRQ(ierr);
315e1affc2SSatish Balay    ierr = VecNorm(tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr);
3287f595a5SBarry Smith    if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN");
335e1affc2SSatish Balay 
348931d482SJason Sarich    ierr = TaoMonitor(tao, tao->niter, f, gnorm, 0.0, step, &reason);CHKERRQ(ierr);
3587f595a5SBarry Smith    if (reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0);
365e1affc2SSatish Balay 
375e1affc2SSatish Balay    /*  Set initial direction to -gradient */
385e1affc2SSatish Balay    ierr = VecCopy(tao->gradient, tao->stepdirection);CHKERRQ(ierr);
395e1affc2SSatish Balay    ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr);
405e1affc2SSatish Balay    gnorm2 = gnorm*gnorm;
415e1affc2SSatish Balay 
425e1affc2SSatish Balay    /*  Set initial scaling for the function */
435e1affc2SSatish Balay    if (f != 0.0) {
445e1affc2SSatish Balay      delta = 2.0*PetscAbsScalar(f) / gnorm2;
455e1affc2SSatish Balay      delta = PetscMax(delta,cgP->delta_min);
465e1affc2SSatish Balay      delta = PetscMin(delta,cgP->delta_max);
475e1affc2SSatish Balay    } else {
485e1affc2SSatish Balay      delta = 2.0 / gnorm2;
495e1affc2SSatish Balay      delta = PetscMax(delta,cgP->delta_min);
505e1affc2SSatish Balay      delta = PetscMin(delta,cgP->delta_max);
515e1affc2SSatish Balay    }
525e1affc2SSatish Balay    /*  Set counter for gradient and reset steps */
535e1affc2SSatish Balay    cgP->ngradsteps = 0;
545e1affc2SSatish Balay    cgP->nresetsteps = 0;
555e1affc2SSatish Balay 
565e1affc2SSatish Balay    while (1) {
575e1affc2SSatish Balay      /*  Save the current gradient information */
585e1affc2SSatish Balay      f_old = f;
595e1affc2SSatish Balay      gnorm2_old = gnorm2;
605e1affc2SSatish Balay      ierr = VecCopy(tao->solution, cgP->X_old);CHKERRQ(ierr);
615e1affc2SSatish Balay      ierr = VecCopy(tao->gradient, cgP->G_old);CHKERRQ(ierr);
625e1affc2SSatish Balay      ierr = VecDot(tao->gradient, tao->stepdirection, &gd);CHKERRQ(ierr);
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 
755e1affc2SSatish Balay        ierr = VecCopy(tao->gradient, tao->stepdirection);CHKERRQ(ierr);
765e1affc2SSatish Balay        ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr);
775e1affc2SSatish Balay      }
785e1affc2SSatish Balay 
795e1affc2SSatish Balay      /*  Search direction for improving point */
80302440fdSBarry Smith      ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,delta);CHKERRQ(ierr);
815e1affc2SSatish Balay      ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status);CHKERRQ(ierr);
825e1affc2SSatish Balay      ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr);
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;
895e1affc2SSatish Balay        ierr = VecCopy(cgP->X_old, tao->solution);CHKERRQ(ierr);
905e1affc2SSatish Balay        ierr = VecCopy(cgP->G_old, tao->gradient);CHKERRQ(ierr);
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 
1025e1affc2SSatish Balay        ierr = VecCopy(tao->gradient, tao->stepdirection);CHKERRQ(ierr);
1035e1affc2SSatish Balay        ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr);
1045e1affc2SSatish Balay 
105302440fdSBarry Smith        ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,delta);CHKERRQ(ierr);
1065e1affc2SSatish Balay        ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status);CHKERRQ(ierr);
1075e1affc2SSatish Balay        ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr);
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;
1135e1affc2SSatish Balay          gnorm2 = gnorm2_old;
1145e1affc2SSatish Balay          ierr = VecCopy(cgP->X_old, tao->solution);CHKERRQ(ierr);
1155e1affc2SSatish Balay          ierr = VecCopy(cgP->G_old, tao->gradient);CHKERRQ(ierr);
1165e1affc2SSatish Balay          delta = 1.0;
1175e1affc2SSatish Balay          ierr = VecCopy(tao->solution, tao->stepdirection);CHKERRQ(ierr);
1185e1affc2SSatish Balay          ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr);
1195e1affc2SSatish Balay 
120302440fdSBarry Smith          ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,delta);CHKERRQ(ierr);
1215e1affc2SSatish Balay          ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, tao->stepdirection, &step, &ls_status);CHKERRQ(ierr);
1225e1affc2SSatish Balay          ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr);
1238caf6e8cSBarry Smith          if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) {
1245e1affc2SSatish Balay 
1255e1affc2SSatish Balay            /*  Line search failed for last time -- give up */
1265e1affc2SSatish Balay            f = f_old;
1275e1affc2SSatish Balay            gnorm2 = gnorm2_old;
1285e1affc2SSatish Balay            ierr = VecCopy(cgP->X_old, tao->solution);CHKERRQ(ierr);
1295e1affc2SSatish Balay            ierr = VecCopy(cgP->G_old, tao->gradient);CHKERRQ(ierr);
1305e1affc2SSatish Balay            step = 0.0;
1315e1affc2SSatish Balay            reason = TAO_DIVERGED_LS_FAILURE;
1325e1affc2SSatish Balay            tao->reason = TAO_DIVERGED_LS_FAILURE;
1335e1affc2SSatish Balay          }
1345e1affc2SSatish Balay        }
1355e1affc2SSatish Balay      }
1365e1affc2SSatish Balay 
1375e1affc2SSatish Balay      /*  Check for bad value */
1385e1affc2SSatish Balay      ierr = VecNorm(tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr);
13987f595a5SBarry Smith      if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1,"User-provided compute function generated Inf or NaN");
1405e1affc2SSatish Balay 
1415e1affc2SSatish Balay      /*  Check for termination */
1425e1affc2SSatish Balay      gnorm2 =gnorm * gnorm;
1438931d482SJason Sarich      tao->niter++;
1448931d482SJason Sarich      ierr = TaoMonitor(tao, tao->niter, f, gnorm, 0.0, step, &reason);CHKERRQ(ierr);
1455e1affc2SSatish Balay      if (reason != TAO_CONTINUE_ITERATING) {
1465e1affc2SSatish Balay        break;
1475e1affc2SSatish Balay      }
1485e1affc2SSatish Balay 
1495e1affc2SSatish Balay      /*  Check for restart condition */
1505e1affc2SSatish Balay      ierr = VecDot(tao->gradient, cgP->G_old, &ginner);CHKERRQ(ierr);
1515e1affc2SSatish Balay      if (PetscAbsScalar(ginner) >= cgP->eta * gnorm2) {
1525e1affc2SSatish Balay        /*  Gradients far from orthognal; use steepest descent direction */
1535e1affc2SSatish Balay        beta = 0.0;
1545e1affc2SSatish Balay      } else {
1555e1affc2SSatish Balay        /*  Gradients close to orthogonal; use conjugate gradient formula */
1565e1affc2SSatish Balay        switch (cgP->cg_type) {
1575e1affc2SSatish Balay        case CG_FletcherReeves:
1585e1affc2SSatish Balay          beta = gnorm2 / gnorm2_old;
1595e1affc2SSatish Balay          break;
1605e1affc2SSatish Balay 
1615e1affc2SSatish Balay        case CG_PolakRibiere:
1625e1affc2SSatish Balay          beta = (gnorm2 - ginner) / gnorm2_old;
1635e1affc2SSatish Balay          break;
1645e1affc2SSatish Balay 
1655e1affc2SSatish Balay        case CG_PolakRibierePlus:
1665e1affc2SSatish Balay          beta = PetscMax((gnorm2-ginner)/gnorm2_old, 0.0);
1675e1affc2SSatish Balay          break;
1685e1affc2SSatish Balay 
1695e1affc2SSatish Balay        case CG_HestenesStiefel:
1705e1affc2SSatish Balay          ierr = VecDot(tao->gradient, tao->stepdirection, &gd);CHKERRQ(ierr);
1715e1affc2SSatish Balay          ierr = VecDot(cgP->G_old, tao->stepdirection, &gd_old);CHKERRQ(ierr);
1725e1affc2SSatish Balay          beta = (gnorm2 - ginner) / (gd - gd_old);
1735e1affc2SSatish Balay          break;
1745e1affc2SSatish Balay 
1755e1affc2SSatish Balay        case CG_DaiYuan:
1765e1affc2SSatish Balay          ierr = VecDot(tao->gradient, tao->stepdirection, &gd);CHKERRQ(ierr);
1775e1affc2SSatish Balay          ierr = VecDot(cgP->G_old, tao->stepdirection, &gd_old);CHKERRQ(ierr);
1785e1affc2SSatish Balay          beta = gnorm2 / (gd - gd_old);
1795e1affc2SSatish Balay          break;
1805e1affc2SSatish Balay 
1815e1affc2SSatish Balay        default:
1825e1affc2SSatish Balay          beta = 0.0;
1835e1affc2SSatish Balay          break;
1845e1affc2SSatish Balay        }
1855e1affc2SSatish Balay      }
1865e1affc2SSatish Balay 
1875e1affc2SSatish Balay      /*  Compute the direction d=-g + beta*d */
1885e1affc2SSatish Balay      ierr = VecAXPBY(tao->stepdirection, -1.0, beta, tao->gradient);CHKERRQ(ierr);
1895e1affc2SSatish Balay 
1905e1affc2SSatish Balay      /*  update initial steplength choice */
1915e1affc2SSatish Balay      delta = 1.0;
1925e1affc2SSatish Balay      delta = PetscMax(delta, cgP->delta_min);
1935e1affc2SSatish Balay      delta = PetscMin(delta, cgP->delta_max);
1945e1affc2SSatish Balay    }
1955e1affc2SSatish Balay    PetscFunctionReturn(0);
1965e1affc2SSatish Balay  }
1975e1affc2SSatish Balay 
1985e1affc2SSatish Balay  #undef __FUNCT__
1995e1affc2SSatish Balay  #define __FUNCT__ "TaoSetUp_CG"
200441846f8SBarry Smith  static PetscErrorCode TaoSetUp_CG(Tao tao)
2015e1affc2SSatish Balay  {
2025e1affc2SSatish Balay    TAO_CG         *cgP = (TAO_CG*)tao->data;
2035e1affc2SSatish Balay    PetscErrorCode ierr;
2045e1affc2SSatish Balay 
2055e1affc2SSatish Balay    PetscFunctionBegin;
2065e1affc2SSatish Balay    if (!tao->gradient) {ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr);}
2075e1affc2SSatish Balay    if (!tao->stepdirection) {ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr); }
2085e1affc2SSatish Balay    if (!cgP->X_old) {ierr = VecDuplicate(tao->solution,&cgP->X_old);CHKERRQ(ierr);}
2095e1affc2SSatish Balay    if (!cgP->G_old) {ierr = VecDuplicate(tao->gradient,&cgP->G_old);CHKERRQ(ierr); }
2105e1affc2SSatish Balay     PetscFunctionReturn(0);
2115e1affc2SSatish Balay  }
2125e1affc2SSatish Balay 
2135e1affc2SSatish Balay  #undef __FUNCT__
2145e1affc2SSatish Balay  #define __FUNCT__ "TaoDestroy_CG"
215441846f8SBarry Smith  static PetscErrorCode TaoDestroy_CG(Tao tao)
2165e1affc2SSatish Balay  {
2175e1affc2SSatish Balay    TAO_CG         *cgP = (TAO_CG*) tao->data;
2185e1affc2SSatish Balay    PetscErrorCode ierr;
2195e1affc2SSatish Balay 
2205e1affc2SSatish Balay    PetscFunctionBegin;
2215e1affc2SSatish Balay    if (tao->setupcalled) {
2225e1affc2SSatish Balay      ierr = VecDestroy(&cgP->X_old);CHKERRQ(ierr);
2235e1affc2SSatish Balay      ierr = VecDestroy(&cgP->G_old);CHKERRQ(ierr);
2245e1affc2SSatish Balay    }
2255e1affc2SSatish Balay    ierr = TaoLineSearchDestroy(&tao->linesearch);CHKERRQ(ierr);
2265e1affc2SSatish Balay    ierr = PetscFree(tao->data);CHKERRQ(ierr);
2275e1affc2SSatish Balay    PetscFunctionReturn(0);
2285e1affc2SSatish Balay  }
2295e1affc2SSatish Balay 
2305e1affc2SSatish Balay  #undef __FUNCT__
2315e1affc2SSatish Balay  #define __FUNCT__ "TaoSetFromOptions_CG"
2328c34d3f5SBarry Smith static PetscErrorCode TaoSetFromOptions_CG(PetscOptions *PetscOptionsObject,Tao tao)
2335e1affc2SSatish Balay  {
2345e1affc2SSatish Balay     TAO_CG         *cgP = (TAO_CG*)tao->data;
2355e1affc2SSatish Balay     PetscErrorCode ierr;
2365e1affc2SSatish Balay 
2375e1affc2SSatish Balay     PetscFunctionBegin;
2385e1affc2SSatish Balay     ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr);
2391a1499c8SBarry Smith     ierr = PetscOptionsHead(PetscOptionsObject,"Nonlinear Conjugate Gradient method for unconstrained optimization");CHKERRQ(ierr);
24094ae4db5SBarry Smith     ierr = PetscOptionsReal("-tao_cg_eta","restart tolerance", "", cgP->eta,&cgP->eta,NULL);CHKERRQ(ierr);
24194ae4db5SBarry Smith     ierr = PetscOptionsEList("-tao_cg_type","cg formula", "", CG_Table, CG_Types, CG_Table[cgP->cg_type], &cgP->cg_type,NULL);CHKERRQ(ierr);
24294ae4db5SBarry Smith     ierr = PetscOptionsReal("-tao_cg_delta_min","minimum delta value", "", cgP->delta_min,&cgP->delta_min,NULL);CHKERRQ(ierr);
24394ae4db5SBarry Smith     ierr = PetscOptionsReal("-tao_cg_delta_max","maximum delta value", "", cgP->delta_max,&cgP->delta_max,NULL);CHKERRQ(ierr);
2445e1affc2SSatish Balay    ierr = PetscOptionsTail();CHKERRQ(ierr);
2455e1affc2SSatish Balay    PetscFunctionReturn(0);
2465e1affc2SSatish Balay }
2475e1affc2SSatish Balay 
2485e1affc2SSatish Balay #undef __FUNCT__
2495e1affc2SSatish Balay #define __FUNCT__ "TaoView_CG"
250441846f8SBarry Smith static PetscErrorCode TaoView_CG(Tao tao, PetscViewer viewer)
2515e1affc2SSatish Balay {
2525e1affc2SSatish Balay   PetscBool      isascii;
2535e1affc2SSatish Balay   TAO_CG         *cgP = (TAO_CG*)tao->data;
2545e1affc2SSatish Balay   PetscErrorCode ierr;
2555e1affc2SSatish Balay 
2565e1affc2SSatish Balay   PetscFunctionBegin;
2575e1affc2SSatish Balay   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr);
2585e1affc2SSatish Balay   if (isascii) {
2595e1affc2SSatish Balay     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2605e1affc2SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer, "CG Type: %s\n", CG_Table[cgP->cg_type]);CHKERRQ(ierr);
2615e1affc2SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer, "Gradient steps: %D\n", cgP->ngradsteps);CHKERRQ(ierr);
2625e1affc2SSatish Balay     ierr= PetscViewerASCIIPrintf(viewer, "Reset steps: %D\n", cgP->nresetsteps);CHKERRQ(ierr);
2635e1affc2SSatish Balay     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2645e1affc2SSatish Balay   }
2655e1affc2SSatish Balay   PetscFunctionReturn(0);
2665e1affc2SSatish Balay }
2674aa34175SJason Sarich 
2684aa34175SJason Sarich /*MC
2694aa34175SJason Sarich      TAOCG -   Nonlinear conjugate gradient method is an extension of the
2704aa34175SJason Sarich nonlinear conjugate gradient solver for nonlinear optimization.
2714aa34175SJason Sarich 
2724aa34175SJason Sarich    Options Database Keys:
2734aa34175SJason Sarich +      -tao_cg_eta <r> - restart tolerance
2744aa34175SJason Sarich .      -tao_cg_type <taocg_type> - cg formula
2754aa34175SJason Sarich .      -tao_cg_delta_min <r> - minimum delta value
2764aa34175SJason Sarich -      -tao_cg_delta_max <r> - maximum delta value
2774aa34175SJason Sarich 
2784aa34175SJason Sarich   Notes:
2794aa34175SJason Sarich      CG formulas are:
2804aa34175SJason Sarich          "fr" - Fletcher-Reeves
2814aa34175SJason Sarich          "pr" - Polak-Ribiere
2824aa34175SJason Sarich          "prp" - Polak-Ribiere-Plus
2834aa34175SJason Sarich          "hs" - Hestenes-Steifel
2844aa34175SJason Sarich          "dy" - Dai-Yuan
2851eb8069cSJason Sarich   Level: beginner
2864aa34175SJason Sarich M*/
2875e1affc2SSatish Balay 
2885e1affc2SSatish Balay 
2895e1affc2SSatish Balay #undef __FUNCT__
2905e1affc2SSatish Balay #define __FUNCT__ "TaoCreate_CG"
291728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoCreate_CG(Tao tao)
2925e1affc2SSatish Balay {
2935e1affc2SSatish Balay   TAO_CG         *cgP;
2948caf6e8cSBarry Smith   const char     *morethuente_type = TAOLINESEARCHMT;
2955e1affc2SSatish Balay   PetscErrorCode ierr;
29687f595a5SBarry Smith 
2975e1affc2SSatish Balay   PetscFunctionBegin;
2985e1affc2SSatish Balay   tao->ops->setup = TaoSetUp_CG;
2995e1affc2SSatish Balay   tao->ops->solve = TaoSolve_CG;
3005e1affc2SSatish Balay   tao->ops->view = TaoView_CG;
3015e1affc2SSatish Balay   tao->ops->setfromoptions = TaoSetFromOptions_CG;
3025e1affc2SSatish Balay   tao->ops->destroy = TaoDestroy_CG;
3035e1affc2SSatish Balay 
304*6552cf8aSJason Sarich   /* Override default settings (unless already changed) */
305*6552cf8aSJason Sarich   if (!tao->max_it_changed) tao->max_it = 2000;
306*6552cf8aSJason Sarich   if (!tao->max_funcs_changed) tao->max_funcs = 4000;
307*6552cf8aSJason Sarich   if (!tao->fatol_changed) tao->fatol = 1e-4;
308*6552cf8aSJason Sarich   if (!tao->frtol_changed) tao->frtol = 1e-4;
3095e1affc2SSatish Balay 
3105e1affc2SSatish Balay   /*  Note: nondefault values should be used for nonlinear conjugate gradient  */
3115e1affc2SSatish Balay   /*  method.  In particular, gtol should be less that 0.5; the value used in  */
3125e1affc2SSatish Balay   /*  Nocedal and Wright is 0.10.  We use the default values for the  */
3135e1affc2SSatish Balay   /*  linesearch because it seems to work better. */
3145e1affc2SSatish Balay   ierr = TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch);CHKERRQ(ierr);
3155e1affc2SSatish Balay   ierr = TaoLineSearchSetType(tao->linesearch, morethuente_type);CHKERRQ(ierr);
316441846f8SBarry Smith   ierr = TaoLineSearchUseTaoRoutines(tao->linesearch, tao);CHKERRQ(ierr);
3175d527766SPatrick Farrell   ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr);
3185e1affc2SSatish Balay 
3195e1affc2SSatish Balay   ierr = PetscNewLog(tao,&cgP);CHKERRQ(ierr);
3205e1affc2SSatish Balay   tao->data = (void*)cgP;
3215e1affc2SSatish Balay   cgP->eta = 0.1;
3225e1affc2SSatish Balay   cgP->delta_min = 1e-7;
3235e1affc2SSatish Balay   cgP->delta_max = 100;
3245e1affc2SSatish Balay   cgP->cg_type = CG_PolakRibierePlus;
3255e1affc2SSatish Balay   PetscFunctionReturn(0);
3265e1affc2SSatish Balay }
327