Actual source code: taosolver.c
petsc-3.15.0 2021-03-30
Report Typos and Errors

      1: #define TAO_DLL

      3: #include <petsc/private/taoimpl.h>

      5: PetscBool TaoRegisterAllCalled = PETSC_FALSE;
      6: PetscFunctionList TaoList = NULL;

      8: PetscClassId TAO_CLASSID;

     10: PetscLogEvent TAO_Solve;
     11: PetscLogEvent TAO_ObjectiveEval;
     12: PetscLogEvent TAO_GradientEval;
     13: PetscLogEvent TAO_ObjGradEval;
     14: PetscLogEvent TAO_HessianEval;
     15: PetscLogEvent TAO_JacobianEval;
     16: PetscLogEvent TAO_ConstraintsEval;

     18: const char *TaoSubSetTypes[] = {"subvec","mask","matrixfree","TaoSubSetType","TAO_SUBSET_",NULL};

     20: struct _n_TaoMonitorDrawCtx {
     21:   PetscViewer viewer;
     22:   PetscInt    howoften;  /* when > 0 uses iteration % howoften, when negative only final solution plotted */
     23: };

     25: /*@
     26:   TaoCreate - Creates a TAO solver

     28:   Collective

     30:   Input Parameter:
     31: . comm - MPI communicator

     33:   Output Parameter:
     34: . newtao - the new Tao context

     36:   Available methods include:
     37: +    nls - Newton's method with line search for unconstrained minimization
     38: .    ntr - Newton's method with trust region for unconstrained minimization
     39: .    ntl - Newton's method with trust region, line search for unconstrained minimization
     40: .    lmvm - Limited memory variable metric method for unconstrained minimization
     41: .    cg - Nonlinear conjugate gradient method for unconstrained minimization
     42: .    nm - Nelder-Mead algorithm for derivate-free unconstrained minimization
     43: .    tron - Newton Trust Region method for bound constrained minimization
     44: .    gpcg - Newton Trust Region method for quadratic bound constrained minimization
     45: .    blmvm - Limited memory variable metric method for bound constrained minimization
     46: .    lcl - Linearly constrained Lagrangian method for pde-constrained minimization
     47: -    pounders - Model-based algorithm for nonlinear least squares

     49:    Options Database Keys:
     50: .   -tao_type - select which method TAO should use

     52:    Level: beginner

     54: .seealso: TaoSolve(), TaoDestroy()
     55: @*/
     56: PetscErrorCode TaoCreate(MPI_Comm comm, Tao *newtao)
     57: {
     59:   Tao            tao;

     63:   *newtao = NULL;

     65:   TaoInitializePackage();
     66:   TaoLineSearchInitializePackage();

     68:   PetscHeaderCreate(tao,TAO_CLASSID,"Tao","Optimization solver","Tao",comm,TaoDestroy,TaoView);
     69:   tao->ops->computeobjective = NULL;
     70:   tao->ops->computeobjectiveandgradient = NULL;
     71:   tao->ops->computegradient = NULL;
     72:   tao->ops->computehessian = NULL;
     73:   tao->ops->computeresidual = NULL;
     74:   tao->ops->computeresidualjacobian = NULL;
     75:   tao->ops->computeconstraints = NULL;
     76:   tao->ops->computejacobian = NULL;
     77:   tao->ops->computejacobianequality = NULL;
     78:   tao->ops->computejacobianinequality = NULL;
     79:   tao->ops->computeequalityconstraints = NULL;
     80:   tao->ops->computeinequalityconstraints = NULL;
     81:   tao->ops->convergencetest = TaoDefaultConvergenceTest;
     82:   tao->ops->convergencedestroy = NULL;
     83:   tao->ops->computedual = NULL;
     84:   tao->ops->setup = NULL;
     85:   tao->ops->solve = NULL;
     86:   tao->ops->view = NULL;
     87:   tao->ops->setfromoptions = NULL;
     88:   tao->ops->destroy = NULL;

     90:   tao->solution=NULL;
     91:   tao->gradient=NULL;
     92:   tao->ls_res = NULL;
     93:   tao->ls_jac = NULL;
     94:   tao->constraints=NULL;
     95:   tao->constraints_equality=NULL;
     96:   tao->constraints_inequality=NULL;
     97:   tao->res_weights_v=NULL;
     98:   tao->res_weights_w=NULL;
     99:   tao->stepdirection=NULL;
    100:   tao->niter=0;
    101:   tao->ntotalits=0;
    102:   tao->XL = NULL;
    103:   tao->XU = NULL;
    104:   tao->IL = NULL;
    105:   tao->IU = NULL;
    106:   tao->DI = NULL;
    107:   tao->DE = NULL;
    108:   tao->gradient_norm = NULL;
    109:   tao->gradient_norm_tmp = NULL;
    110:   tao->hessian = NULL;
    111:   tao->hessian_pre = NULL;
    112:   tao->jacobian = NULL;
    113:   tao->jacobian_pre = NULL;
    114:   tao->jacobian_state = NULL;
    115:   tao->jacobian_state_pre = NULL;
    116:   tao->jacobian_state_inv = NULL;
    117:   tao->jacobian_design = NULL;
    118:   tao->jacobian_design_pre = NULL;
    119:   tao->jacobian_equality = NULL;
    120:   tao->jacobian_equality_pre = NULL;
    121:   tao->jacobian_inequality = NULL;
    122:   tao->jacobian_inequality_pre = NULL;
    123:   tao->state_is = NULL;
    124:   tao->design_is = NULL;

    126:   tao->max_it     = 10000;
    127:   tao->max_funcs   = 10000;
    128: #if defined(PETSC_USE_REAL_SINGLE)
    129:   tao->gatol       = 1e-5;
    130:   tao->grtol       = 1e-5;
    131:   tao->crtol       = 1e-5;
    132:   tao->catol       = 1e-5;
    133: #else
    134:   tao->gatol       = 1e-8;
    135:   tao->grtol       = 1e-8;
    136:   tao->crtol       = 1e-8;
    137:   tao->catol       = 1e-8;
    138: #endif
    139:   tao->gttol       = 0.0;
    140:   tao->steptol     = 0.0;
    141:   tao->trust0      = PETSC_INFINITY;
    142:   tao->fmin        = PETSC_NINFINITY;
    143:   tao->hist_malloc = PETSC_FALSE;
    144:   tao->hist_reset = PETSC_TRUE;
    145:   tao->hist_max = 0;
    146:   tao->hist_len = 0;
    147:   tao->hist_obj = NULL;
    148:   tao->hist_resid = NULL;
    149:   tao->hist_cnorm = NULL;
    150:   tao->hist_lits = NULL;

    152:   tao->numbermonitors=0;
    153:   tao->viewsolution=PETSC_FALSE;
    154:   tao->viewhessian=PETSC_FALSE;
    155:   tao->viewgradient=PETSC_FALSE;
    156:   tao->viewjacobian=PETSC_FALSE;
    157:   tao->viewconstraints = PETSC_FALSE;

    159:   tao->bounded = PETSC_FALSE;
    160:   tao->constrained = PETSC_FALSE;
    161:   tao->eq_constrained = PETSC_FALSE;
    162:   tao->ineq_constrained = PETSC_FALSE;
    163:   tao->ineq_doublesided = PETSC_FALSE;

    165:   tao->recycle = PETSC_FALSE;

    167:   tao->header_printed = PETSC_FALSE;

    169:   /* These flags prevents algorithms from overriding user options */
    170:   tao->max_it_changed   =PETSC_FALSE;
    171:   tao->max_funcs_changed=PETSC_FALSE;
    172:   tao->gatol_changed    =PETSC_FALSE;
    173:   tao->grtol_changed    =PETSC_FALSE;
    174:   tao->gttol_changed    =PETSC_FALSE;
    175:   tao->steptol_changed  =PETSC_FALSE;
    176:   tao->trust0_changed   =PETSC_FALSE;
    177:   tao->fmin_changed     =PETSC_FALSE;
    178:   tao->catol_changed    =PETSC_FALSE;
    179:   tao->crtol_changed    =PETSC_FALSE;
    180:   TaoResetStatistics(tao);
    181:   *newtao = tao;
    182:   return(0);
    183: }

    185: /*@
    186:   TaoSolve - Solves an optimization problem min F(x) s.t. l <= x <= u

    188:   Collective on Tao

    190:   Input Parameters:
    191: . tao - the Tao context

    193:   Notes:
    194:   The user must set up the Tao with calls to TaoSetInitialVector(),
    195:   TaoSetObjectiveRoutine(),
    196:   TaoSetGradientRoutine(), and (if using 2nd order method) TaoSetHessianRoutine().

    198:   You should call TaoGetConvergedReason() or run with -tao_converged_reason to determine if the optimization algorithm actually succeeded or
    199:   why it failed.

    201:   Level: beginner

    203: .seealso: TaoCreate(), TaoSetObjectiveRoutine(), TaoSetGradientRoutine(), TaoSetHessianRoutine(), TaoGetConvergedReason()
    204:  @*/
    205: PetscErrorCode TaoSolve(Tao tao)
    206: {
    207:   PetscErrorCode   ierr;
    208:   static PetscBool set = PETSC_FALSE;

    212:   PetscCitationsRegister("@TechReport{tao-user-ref,\n"
    213:                                 "title   = {Toolkit for Advanced Optimization (TAO) Users Manual},\n"
    214:                                 "author  = {Todd Munson and Jason Sarich and Stefan Wild and Steve Benson and Lois Curfman McInnes},\n"
    215:                                 "Institution = {Argonne National Laboratory},\n"
    216:                                 "Year   = 2014,\n"
    217:                                 "Number = {ANL/MCS-TM-322 - Revision 3.5},\n"
    218:                                 "url    = {https://www.mcs.anl.gov/research/projects/tao/}\n}\n",&set);
    219:   tao->header_printed = PETSC_FALSE;
    220:   TaoSetUp(tao);
    221:   TaoResetStatistics(tao);
    222:   if (tao->linesearch) {
    223:     TaoLineSearchReset(tao->linesearch);
    224:   }

    226:   PetscLogEventBegin(TAO_Solve,tao,0,0,0);
    227:   if (tao->ops->solve){ (*tao->ops->solve)(tao); }
    228:   PetscLogEventEnd(TAO_Solve,tao,0,0,0);

    230:   VecViewFromOptions(tao->solution,(PetscObject)tao,"-tao_view_solution");

    232:   tao->ntotalits += tao->niter;
    233:   TaoViewFromOptions(tao,NULL,"-tao_view");

    235:   if (tao->printreason) {
    236:     if (tao->reason > 0) {
    237:       PetscPrintf(((PetscObject)tao)->comm,"TAO solve converged due to %s iterations %D\n",TaoConvergedReasons[tao->reason],tao->niter);
    238:     } else {
    239:       PetscPrintf(((PetscObject)tao)->comm,"TAO solve did not converge due to %s iteration %D\n",TaoConvergedReasons[tao->reason],tao->niter);
    240:     }
    241:   }
    242:   return(0);
    243: }

    245: /*@
    246:   TaoSetUp - Sets up the internal data structures for the later use
    247:   of a Tao solver

    249:   Collective on tao

    251:   Input Parameters:
    252: . tao - the TAO context

    254:   Notes:
    255:   The user will not need to explicitly call TaoSetUp(), as it will
    256:   automatically be called in TaoSolve().  However, if the user
    257:   desires to call it explicitly, it should come after TaoCreate()
    258:   and any TaoSetSomething() routines, but before TaoSolve().

    260:   Level: advanced

    262: .seealso: TaoCreate(), TaoSolve()
    263: @*/
    264: PetscErrorCode TaoSetUp(Tao tao)
    265: {

    270:   if (tao->setupcalled) return(0);

    272:   if (!tao->solution) SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetInitialVector");
    273:   if (tao->ops->setup) {
    274:     (*tao->ops->setup)(tao);
    275:   }
    276:   tao->setupcalled = PETSC_TRUE;
    277:   return(0);
    278: }

    280: /*@C
    281:   TaoDestroy - Destroys the TAO context that was created with
    282:   TaoCreate()

    284:   Collective on Tao

    286:   Input Parameter:
    287: . tao - the Tao context

    289:   Level: beginner

    291: .seealso: TaoCreate(), TaoSolve()
    292: @*/
    293: PetscErrorCode TaoDestroy(Tao *tao)
    294: {

    298:   if (!*tao) return(0);
    300:   if (--((PetscObject)*tao)->refct > 0) {*tao = NULL;return(0);}

    302:   if ((*tao)->ops->destroy) {
    303:     (*((*tao))->ops->destroy)(*tao);
    304:   }
    305:   KSPDestroy(&(*tao)->ksp);
    306:   TaoLineSearchDestroy(&(*tao)->linesearch);

    308:   if ((*tao)->ops->convergencedestroy) {
    309:     (*(*tao)->ops->convergencedestroy)((*tao)->cnvP);
    310:     if ((*tao)->jacobian_state_inv) {
    311:       MatDestroy(&(*tao)->jacobian_state_inv);
    312:     }
    313:   }
    314:   VecDestroy(&(*tao)->solution);
    315:   VecDestroy(&(*tao)->gradient);
    316:   VecDestroy(&(*tao)->ls_res);

    318:   if ((*tao)->gradient_norm) {
    319:     PetscObjectDereference((PetscObject)(*tao)->gradient_norm);
    320:     VecDestroy(&(*tao)->gradient_norm_tmp);
    321:   }

    323:   VecDestroy(&(*tao)->XL);
    324:   VecDestroy(&(*tao)->XU);
    325:   VecDestroy(&(*tao)->IL);
    326:   VecDestroy(&(*tao)->IU);
    327:   VecDestroy(&(*tao)->DE);
    328:   VecDestroy(&(*tao)->DI);
    329:   VecDestroy(&(*tao)->constraints_equality);
    330:   VecDestroy(&(*tao)->constraints_inequality);
    331:   VecDestroy(&(*tao)->stepdirection);
    332:   MatDestroy(&(*tao)->hessian_pre);
    333:   MatDestroy(&(*tao)->hessian);
    334:   MatDestroy(&(*tao)->ls_jac);
    335:   MatDestroy(&(*tao)->ls_jac_pre);
    336:   MatDestroy(&(*tao)->jacobian_pre);
    337:   MatDestroy(&(*tao)->jacobian);
    338:   MatDestroy(&(*tao)->jacobian_state_pre);
    339:   MatDestroy(&(*tao)->jacobian_state);
    340:   MatDestroy(&(*tao)->jacobian_state_inv);
    341:   MatDestroy(&(*tao)->jacobian_design);
    342:   MatDestroy(&(*tao)->jacobian_equality);
    343:   MatDestroy(&(*tao)->jacobian_equality_pre);
    344:   MatDestroy(&(*tao)->jacobian_inequality);
    345:   MatDestroy(&(*tao)->jacobian_inequality_pre);
    346:   ISDestroy(&(*tao)->state_is);
    347:   ISDestroy(&(*tao)->design_is);
    348:   VecDestroy(&(*tao)->res_weights_v);
    349:   TaoCancelMonitors(*tao);
    350:   if ((*tao)->hist_malloc) {
    351:     PetscFree4((*tao)->hist_obj,(*tao)->hist_resid,(*tao)->hist_cnorm,(*tao)->hist_lits);
    352:   }
    353:   if ((*tao)->res_weights_n) {
    354:     PetscFree((*tao)->res_weights_rows);
    355:     PetscFree((*tao)->res_weights_cols);
    356:     PetscFree((*tao)->res_weights_w);
    357:   }
    358:   PetscHeaderDestroy(tao);
    359:   return(0);
    360: }

    362: /*@
    363:   TaoSetFromOptions - Sets various Tao parameters from user
    364:   options.

    366:   Collective on Tao

    368:   Input Paremeter:
    369: . tao - the Tao solver context

    371:   options Database Keys:
    372: + -tao_type <type> - The algorithm that TAO uses (lmvm, nls, etc.)
    373: . -tao_gatol <gatol> - absolute error tolerance for ||gradient||
    374: . -tao_grtol <grtol> - relative error tolerance for ||gradient||
    375: . -tao_gttol <gttol> - reduction of ||gradient|| relative to initial gradient
    376: . -tao_max_it <max> - sets maximum number of iterations
    377: . -tao_max_funcs <max> - sets maximum number of function evaluations
    378: . -tao_fmin <fmin> - stop if function value reaches fmin
    379: . -tao_steptol <tol> - stop if trust region radius less than <tol>
    380: . -tao_trust0 <t> - initial trust region radius
    381: . -tao_monitor - prints function value and residual at each iteration
    382: . -tao_smonitor - same as tao_monitor, but truncates very small values
    383: . -tao_cmonitor - prints function value, residual, and constraint norm at each iteration
    384: . -tao_view_solution - prints solution vector at each iteration
    385: . -tao_view_ls_residual - prints least-squares residual vector at each iteration
    386: . -tao_view_step - prints step direction vector at each iteration
    387: . -tao_view_gradient - prints gradient vector at each iteration
    388: . -tao_draw_solution - graphically view solution vector at each iteration
    389: . -tao_draw_step - graphically view step vector at each iteration
    390: . -tao_draw_gradient - graphically view gradient at each iteration
    391: . -tao_fd_gradient - use gradient computed with finite differences
    392: . -tao_fd_hessian - use hessian computed with finite differences
    393: . -tao_mf_hessian - use matrix-free hessian computed with finite differences
    394: . -tao_cancelmonitors - cancels all monitors (except those set with command line)
    395: . -tao_view - prints information about the Tao after solving
    396: - -tao_converged_reason - prints the reason TAO stopped iterating

    398:   Notes:
    399:   To see all options, run your program with the -help option or consult the
    400:   user's manual. Should be called after TaoCreate() but before TaoSolve()

    402:   Level: beginner
    403: @*/
    404: PetscErrorCode TaoSetFromOptions(Tao tao)
    405: {
    407:   TaoType        default_type = TAOLMVM;
    408:   char           type[256], monfilename[PETSC_MAX_PATH_LEN];
    409:   PetscViewer    monviewer;
    410:   PetscBool      flg;
    411:   MPI_Comm       comm;

    415:   PetscObjectGetComm((PetscObject)tao,&comm);

    417:   /* So no warnings are given about unused options */
    418:   PetscOptionsHasName(((PetscObject)tao)->options,((PetscObject)tao)->prefix,"-tao_ls_type",&flg);

    420:   PetscObjectOptionsBegin((PetscObject)tao);
    421:   {
    422:     TaoRegisterAll();
    423:     if (((PetscObject)tao)->type_name) {
    424:       default_type = ((PetscObject)tao)->type_name;
    425:     }
    426:     /* Check for type from options */
    427:     PetscOptionsFList("-tao_type","Tao Solver type","TaoSetType",TaoList,default_type,type,256,&flg);
    428:     if (flg) {
    429:       TaoSetType(tao,type);
    430:     } else if (!((PetscObject)tao)->type_name) {
    431:       TaoSetType(tao,default_type);
    432:     }

    434:     PetscOptionsReal("-tao_catol","Stop if constraints violations within","TaoSetConstraintTolerances",tao->catol,&tao->catol,&flg);
    435:     if (flg) tao->catol_changed=PETSC_TRUE;
    436:     PetscOptionsReal("-tao_crtol","Stop if relative contraint violations within","TaoSetConstraintTolerances",tao->crtol,&tao->crtol,&flg);
    437:     if (flg) tao->crtol_changed=PETSC_TRUE;
    438:     PetscOptionsReal("-tao_gatol","Stop if norm of gradient less than","TaoSetTolerances",tao->gatol,&tao->gatol,&flg);
    439:     if (flg) tao->gatol_changed=PETSC_TRUE;
    440:     PetscOptionsReal("-tao_grtol","Stop if norm of gradient divided by the function value is less than","TaoSetTolerances",tao->grtol,&tao->grtol,&flg);
    441:     if (flg) tao->grtol_changed=PETSC_TRUE;
    442:     PetscOptionsReal("-tao_gttol","Stop if the norm of the gradient is less than the norm of the initial gradient times tol","TaoSetTolerances",tao->gttol,&tao->gttol,&flg);
    443:     if (flg) tao->gttol_changed=PETSC_TRUE;
    444:     PetscOptionsInt("-tao_max_it","Stop if iteration number exceeds","TaoSetMaximumIterations",tao->max_it,&tao->max_it,&flg);
    445:     if (flg) tao->max_it_changed=PETSC_TRUE;
    446:     PetscOptionsInt("-tao_max_funcs","Stop if number of function evaluations exceeds","TaoSetMaximumFunctionEvaluations",tao->max_funcs,&tao->max_funcs,&flg);
    447:     if (flg) tao->max_funcs_changed=PETSC_TRUE;
    448:     PetscOptionsReal("-tao_fmin","Stop if function less than","TaoSetFunctionLowerBound",tao->fmin,&tao->fmin,&flg);
    449:     if (flg) tao->fmin_changed=PETSC_TRUE;
    450:     PetscOptionsReal("-tao_steptol","Stop if step size or trust region radius less than","",tao->steptol,&tao->steptol,&flg);
    451:     if (flg) tao->steptol_changed=PETSC_TRUE;
    452:     PetscOptionsReal("-tao_trust0","Initial trust region radius","TaoSetTrustRegionRadius",tao->trust0,&tao->trust0,&flg);
    453:     if (flg) tao->trust0_changed=PETSC_TRUE;
    454:     PetscOptionsString("-tao_view_solution","view solution vector after each evaluation","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg);
    455:     if (flg) {
    456:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    457:       TaoSetMonitor(tao,TaoSolutionMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    458:     }

    460:     PetscOptionsBool("-tao_converged_reason","Print reason for TAO converged","TaoSolve",tao->printreason,&tao->printreason,NULL);
    461:     PetscOptionsString("-tao_view_gradient","view gradient vector after each evaluation","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg);
    462:     if (flg) {
    463:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    464:       TaoSetMonitor(tao,TaoGradientMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    465:     }

    467:     PetscOptionsString("-tao_view_stepdirection","view step direction vector after each iteration","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg);
    468:     if (flg) {
    469:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    470:       TaoSetMonitor(tao,TaoStepDirectionMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    471:     }

    473:     PetscOptionsString("-tao_view_residual","view least-squares residual vector after each evaluation","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg);
    474:     if (flg) {
    475:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    476:       TaoSetMonitor(tao,TaoResidualMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    477:     }

    479:     PetscOptionsString("-tao_monitor","Use the default convergence monitor","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg);
    480:     if (flg) {
    481:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    482:       TaoSetMonitor(tao,TaoMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    483:     }

    485:     PetscOptionsString("-tao_gmonitor","Use the convergence monitor with extra globalization info","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg);
    486:     if (flg) {
    487:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    488:       TaoSetMonitor(tao,TaoDefaultGMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    489:     }

    491:     PetscOptionsString("-tao_smonitor","Use the short convergence monitor","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg);
    492:     if (flg) {
    493:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    494:       TaoSetMonitor(tao,TaoDefaultSMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    495:     }

    497:     PetscOptionsString("-tao_cmonitor","Use the default convergence monitor with constraint norm","TaoSetMonitor","stdout",monfilename,sizeof(monfilename),&flg);
    498:     if (flg) {
    499:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    500:       TaoSetMonitor(tao,TaoDefaultCMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    501:     }

    504:     flg = PETSC_FALSE;
    505:     PetscOptionsBool("-tao_cancelmonitors","cancel all monitors and call any registered destroy routines","TaoCancelMonitors",flg,&flg,NULL);
    506:     if (flg) {TaoCancelMonitors(tao);}

    508:     flg = PETSC_FALSE;
    509:     PetscOptionsBool("-tao_draw_solution","Plot solution vector at each iteration","TaoSetMonitor",flg,&flg,NULL);
    510:     if (flg) {
    511:       TaoMonitorDrawCtx drawctx;
    512:       PetscInt          howoften = 1;
    513:       TaoMonitorDrawCtxCreate(PetscObjectComm((PetscObject)tao),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&drawctx);
    514:       TaoSetMonitor(tao,TaoDrawSolutionMonitor,drawctx,(PetscErrorCode (*)(void**))TaoMonitorDrawCtxDestroy);
    515:     }

    517:     flg = PETSC_FALSE;
    518:     PetscOptionsBool("-tao_draw_step","plots step direction at each iteration","TaoSetMonitor",flg,&flg,NULL);
    519:     if (flg) {
    520:       TaoSetMonitor(tao,TaoDrawStepMonitor,NULL,NULL);
    521:     }

    523:     flg = PETSC_FALSE;
    524:     PetscOptionsBool("-tao_draw_gradient","plots gradient at each iteration","TaoSetMonitor",flg,&flg,NULL);
    525:     if (flg) {
    526:       TaoMonitorDrawCtx drawctx;
    527:       PetscInt          howoften = 1;
    528:       TaoMonitorDrawCtxCreate(PetscObjectComm((PetscObject)tao),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&drawctx);
    529:       TaoSetMonitor(tao,TaoDrawGradientMonitor,drawctx,(PetscErrorCode (*)(void**))TaoMonitorDrawCtxDestroy);
    530:     }
    531:     flg = PETSC_FALSE;
    532:     PetscOptionsBool("-tao_fd_gradient","compute gradient using finite differences","TaoDefaultComputeGradient",flg,&flg,NULL);
    533:     if (flg) {
    534:       TaoSetGradientRoutine(tao,TaoDefaultComputeGradient,NULL);
    535:     }
    536:     flg = PETSC_FALSE;
    537:     PetscOptionsBool("-tao_fd_hessian","compute hessian using finite differences","TaoDefaultComputeHessian",flg,&flg,NULL);
    538:     if (flg) {
    539:       Mat H;

    541:       MatCreate(PetscObjectComm((PetscObject)tao),&H);
    542:       MatSetType(H,MATAIJ);
    543:       TaoSetHessianRoutine(tao,H,H,TaoDefaultComputeHessian,NULL);
    544:       MatDestroy(&H);
    545:     }
    546:     flg = PETSC_FALSE;
    547:     PetscOptionsBool("-tao_mf_hessian","compute matrix-free hessian using finite differences","TaoDefaultComputeHessianMFFD",flg,&flg,NULL);
    548:     if (flg) {
    549:       Mat H;

    551:       MatCreate(PetscObjectComm((PetscObject)tao),&H);
    552:       TaoSetHessianRoutine(tao,H,H,TaoDefaultComputeHessianMFFD,NULL);
    553:       MatDestroy(&H);
    554:     }
    555:     flg = PETSC_FALSE;
    556:     PetscOptionsBool("-tao_recycle_history","enable recycling/re-using information from the previous TaoSolve() call for some algorithms","TaoSetRecycleHistory",flg,&flg,NULL);
    557:     if (flg) {
    558:       TaoSetRecycleHistory(tao, PETSC_TRUE);
    559:     }
    560:     PetscOptionsEnum("-tao_subset_type","subset type","",TaoSubSetTypes,(PetscEnum)tao->subset_type,(PetscEnum*)&tao->subset_type,NULL);

    562:     if (tao->ops->setfromoptions) {
    563:       (*tao->ops->setfromoptions)(PetscOptionsObject,tao);
    564:     }
    565:   }
    566:   PetscOptionsEnd();
    567:   return(0);
    568: }

    570: /*@C
    571:    TaoViewFromOptions - View from Options

    573:    Collective on Tao

    575:    Input Parameters:
    576: +  A - the  Tao context
    577: .  obj - Optional object
    578: -  name - command line option

    580:    Level: intermediate
    581: .seealso:  Tao, TaoView, PetscObjectViewFromOptions(), TaoCreate()
    582: @*/
    583: PetscErrorCode  TaoViewFromOptions(Tao A,PetscObject obj,const char name[])
    584: {

    589:   PetscObjectViewFromOptions((PetscObject)A,obj,name);
    590:   return(0);
    591: }

    593: /*@C
    594:   TaoView - Prints information about the Tao

    596:   Collective on Tao

    598:   InputParameters:
    599: + tao - the Tao context
    600: - viewer - visualization context

    602:   Options Database Key:
    603: . -tao_view - Calls TaoView() at the end of TaoSolve()

    605:   Notes:
    606:   The available visualization contexts include
    607: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    608: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    609:          output where only the first processor opens
    610:          the file.  All other processors send their
    611:          data to the first processor to print.

    613:   Level: beginner

    615: .seealso: PetscViewerASCIIOpen()
    616: @*/
    617: PetscErrorCode TaoView(Tao tao, PetscViewer viewer)
    618: {
    619:   PetscErrorCode      ierr;
    620:   PetscBool           isascii,isstring;
    621:   TaoType             type;

    625:   if (!viewer) {
    626:     PetscViewerASCIIGetStdout(((PetscObject)tao)->comm,&viewer);
    627:   }

    631:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    632:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
    633:   if (isascii) {
    634:     PetscObjectPrintClassNamePrefixType((PetscObject)tao,viewer);

    636:     if (tao->ops->view) {
    637:       PetscViewerASCIIPushTab(viewer);
    638:       (*tao->ops->view)(tao,viewer);
    639:       PetscViewerASCIIPopTab(viewer);
    640:     }
    641:     if (tao->linesearch) {
    642:       PetscViewerASCIIPushTab(viewer);
    643:       TaoLineSearchView(tao->linesearch,viewer);
    644:       PetscViewerASCIIPopTab(viewer);
    645:     }
    646:     if (tao->ksp) {
    647:       PetscViewerASCIIPushTab(viewer);
    648:       KSPView(tao->ksp,viewer);
    649:       PetscViewerASCIIPrintf(viewer,"total KSP iterations: %D\n",tao->ksp_tot_its);
    650:       PetscViewerASCIIPopTab(viewer);
    651:     }

    653:     PetscViewerASCIIPushTab(viewer);

    655:     if (tao->XL || tao->XU) {
    656:       PetscViewerASCIIPrintf(viewer,"Active Set subset type: %s\n",TaoSubSetTypes[tao->subset_type]);
    657:     }

    659:     PetscViewerASCIIPrintf(viewer,"convergence tolerances: gatol=%g,",(double)tao->gatol);
    660:     PetscViewerASCIIPrintf(viewer," steptol=%g,",(double)tao->steptol);
    661:     PetscViewerASCIIPrintf(viewer," gttol=%g\n",(double)tao->gttol);
    662:     PetscViewerASCIIPrintf(viewer,"Residual in Function/Gradient:=%g\n",(double)tao->residual);

    664:     if (tao->constrained){
    665:       ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances:");
    666:       ierr=PetscViewerASCIIPrintf(viewer," catol=%g,",(double)tao->catol);
    667:       ierr=PetscViewerASCIIPrintf(viewer," crtol=%g\n",(double)tao->crtol);
    668:       PetscViewerASCIIPrintf(viewer,"Residual in Constraints:=%g\n",(double)tao->cnorm);
    669:     }

    671:     if (tao->trust < tao->steptol){
    672:       ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances: steptol=%g\n",(double)tao->steptol);
    673:       ierr=PetscViewerASCIIPrintf(viewer,"Final trust region radius:=%g\n",(double)tao->trust);
    674:     }

    676:     if (tao->fmin>-1.e25){
    677:       ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances: function minimum=%g\n",(double)tao->fmin);
    678:     }
    679:     PetscViewerASCIIPrintf(viewer,"Objective value=%g\n",(double)tao->fc);

    681:     PetscViewerASCIIPrintf(viewer,"total number of iterations=%D,          ",tao->niter);
    682:     PetscViewerASCIIPrintf(viewer,"              (max: %D)\n",tao->max_it);

    684:     if (tao->nfuncs>0){
    685:       PetscViewerASCIIPrintf(viewer,"total number of function evaluations=%D,",tao->nfuncs);
    686:       PetscViewerASCIIPrintf(viewer,"                max: %D\n",tao->max_funcs);
    687:     }
    688:     if (tao->ngrads>0){
    689:       PetscViewerASCIIPrintf(viewer,"total number of gradient evaluations=%D,",tao->ngrads);
    690:       PetscViewerASCIIPrintf(viewer,"                max: %D\n",tao->max_funcs);
    691:     }
    692:     if (tao->nfuncgrads>0){
    693:       PetscViewerASCIIPrintf(viewer,"total number of function/gradient evaluations=%D,",tao->nfuncgrads);
    694:       PetscViewerASCIIPrintf(viewer,"    (max: %D)\n",tao->max_funcs);
    695:     }
    696:     if (tao->nhess>0){
    697:       PetscViewerASCIIPrintf(viewer,"total number of Hessian evaluations=%D\n",tao->nhess);
    698:     }
    699:     /*  if (tao->linear_its>0){
    700:      PetscViewerASCIIPrintf(viewer,"  total Krylov method iterations=%D\n",tao->linear_its);
    701:      }*/
    702:     if (tao->nconstraints>0){
    703:       PetscViewerASCIIPrintf(viewer,"total number of constraint function evaluations=%D\n",tao->nconstraints);
    704:     }
    705:     if (tao->njac>0){
    706:       PetscViewerASCIIPrintf(viewer,"total number of Jacobian evaluations=%D\n",tao->njac);
    707:     }

    709:     if (tao->reason>0){
    710:       PetscViewerASCIIPrintf(viewer,    "Solution converged: ");
    711:       switch (tao->reason) {
    712:       case TAO_CONVERGED_GATOL:
    713:         PetscViewerASCIIPrintf(viewer," ||g(X)|| <= gatol\n");
    714:         break;
    715:       case TAO_CONVERGED_GRTOL:
    716:         PetscViewerASCIIPrintf(viewer," ||g(X)||/|f(X)| <= grtol\n");
    717:         break;
    718:       case TAO_CONVERGED_GTTOL:
    719:         PetscViewerASCIIPrintf(viewer," ||g(X)||/||g(X0)|| <= gttol\n");
    720:         break;
    721:       case TAO_CONVERGED_STEPTOL:
    722:         PetscViewerASCIIPrintf(viewer," Steptol -- step size small\n");
    723:         break;
    724:       case TAO_CONVERGED_MINF:
    725:         PetscViewerASCIIPrintf(viewer," Minf --  f < fmin\n");
    726:         break;
    727:       case TAO_CONVERGED_USER:
    728:         PetscViewerASCIIPrintf(viewer," User Terminated\n");
    729:         break;
    730:       default:
    731:         PetscViewerASCIIPrintf(viewer,"\n");
    732:         break;
    733:       }

    735:     } else {
    736:       PetscViewerASCIIPrintf(viewer,"Solver terminated: %d",tao->reason);
    737:       switch (tao->reason) {
    738:       case TAO_DIVERGED_MAXITS:
    739:         PetscViewerASCIIPrintf(viewer," Maximum Iterations\n");
    740:         break;
    741:       case TAO_DIVERGED_NAN:
    742:         PetscViewerASCIIPrintf(viewer," NAN or Inf encountered\n");
    743:         break;
    744:       case TAO_DIVERGED_MAXFCN:
    745:         PetscViewerASCIIPrintf(viewer," Maximum Function Evaluations\n");
    746:         break;
    747:       case TAO_DIVERGED_LS_FAILURE:
    748:         PetscViewerASCIIPrintf(viewer," Line Search Failure\n");
    749:         break;
    750:       case TAO_DIVERGED_TR_REDUCTION:
    751:         PetscViewerASCIIPrintf(viewer," Trust Region too small\n");
    752:         break;
    753:       case TAO_DIVERGED_USER:
    754:         PetscViewerASCIIPrintf(viewer," User Terminated\n");
    755:         break;
    756:       default:
    757:         PetscViewerASCIIPrintf(viewer,"\n");
    758:         break;
    759:       }
    760:     }
    761:     PetscViewerASCIIPopTab(viewer);
    762:   } else if (isstring) {
    763:     TaoGetType(tao,&type);
    764:     PetscViewerStringSPrintf(viewer," %-3.3s",type);
    765:   }
    766:   return(0);
    767: }

    769: /*@
    770:   TaoSetRecycleHistory - Sets the boolean flag to enable/disable re-using
    771:   iterate information from the previous TaoSolve(). This feature is disabled by
    772:   default.

    774:   For conjugate gradient methods (BNCG), this re-uses the latest search direction
    775:   from the previous TaoSolve() call when computing the first search direction in a
    776:   new solution. By default, CG methods set the first search direction to the
    777:   negative gradient.

    779:   For quasi-Newton family of methods (BQNLS, BQNKLS, BQNKTR, BQNKTL), this re-uses
    780:   the accumulated quasi-Newton Hessian approximation from the previous TaoSolve()
    781:   call. By default, QN family of methods reset the initial Hessian approximation to
    782:   the identity matrix.

    784:   For any other algorithm, this setting has no effect.

    786:   Logically collective on Tao

    788:   Input Parameters:
    789: + tao - the Tao context
    790: - recycle - boolean flag

    792:   Options Database Keys:
    793: . -tao_recycle_history

    795:   Level: intermediate

    797: .seealso: TaoSetRecycleHistory(), TAOBNCG, TAOBQNLS, TAOBQNKLS, TAOBQNKTR, TAOBQNKTL

    799: @*/
    800: PetscErrorCode TaoSetRecycleHistory(Tao tao, PetscBool recycle)
    801: {
    804:   tao->recycle = recycle;
    805:   return(0);
    806: }

    808: /*@
    809:   TaoGetRecycleHistory - Retrieve the boolean flag for re-using iterate information
    810:   from the previous TaoSolve(). This feature is disabled by default.

    812:   Logically collective on Tao

    814:   Input Parameters:
    815: , tao - the Tao context

    817:   Output Parameters:
    818: , recycle - boolean flag

    820:   Options Database Keys:
    821: . -tao_recycle_history

    823:   Level: intermediate

    825: .seealso: TaoGetRecycleHistory(), TAOBNCG, TAOBQNLS, TAOBQNKLS, TAOBQNKTR, TAOBQNKTL

    827: @*/
    828: PetscErrorCode TaoGetRecycleHistory(Tao tao, PetscBool *recycle)
    829: {
    832:   *recycle = tao->recycle;
    833:   return(0);
    834: }

    836: /*@
    837:   TaoSetTolerances - Sets parameters used in TAO convergence tests

    839:   Logically collective on Tao

    841:   Input Parameters:
    842: + tao - the Tao context
    843: . gatol - stop if norm of gradient is less than this
    844: . grtol - stop if relative norm of gradient is less than this
    845: - gttol - stop if norm of gradient is reduced by this factor

    847:   Options Database Keys:
    848: + -tao_gatol <gatol> - Sets gatol
    849: . -tao_grtol <grtol> - Sets grtol
    850: - -tao_gttol <gttol> - Sets gttol

    852:   Stopping Criteria:
    853: $ ||g(X)||                            <= gatol
    854: $ ||g(X)|| / |f(X)|                   <= grtol
    855: $ ||g(X)|| / ||g(X0)||                <= gttol

    857:   Notes:
    858:   Use PETSC_DEFAULT to leave one or more tolerances unchanged.

    860:   Level: beginner

    862: .seealso: TaoGetTolerances()

    864: @*/
    865: PetscErrorCode TaoSetTolerances(Tao tao, PetscReal gatol, PetscReal grtol, PetscReal gttol)
    866: {

    872:   if (gatol != PETSC_DEFAULT) {
    873:     if (gatol<0) {
    874:       PetscInfo(tao,"Tried to set negative gatol -- ignored.\n");
    875:     } else {
    876:       tao->gatol = PetscMax(0,gatol);
    877:       tao->gatol_changed=PETSC_TRUE;
    878:     }
    879:   }

    881:   if (grtol != PETSC_DEFAULT) {
    882:     if (grtol<0) {
    883:       PetscInfo(tao,"Tried to set negative grtol -- ignored.\n");
    884:     } else {
    885:       tao->grtol = PetscMax(0,grtol);
    886:       tao->grtol_changed=PETSC_TRUE;
    887:     }
    888:   }

    890:   if (gttol != PETSC_DEFAULT) {
    891:     if (gttol<0) {
    892:       PetscInfo(tao,"Tried to set negative gttol -- ignored.\n");
    893:     } else {
    894:       tao->gttol = PetscMax(0,gttol);
    895:       tao->gttol_changed=PETSC_TRUE;
    896:     }
    897:   }
    898:   return(0);
    899: }

    901: /*@
    902:   TaoSetConstraintTolerances - Sets constraint tolerance parameters used in TAO  convergence tests

    904:   Logically collective on Tao

    906:   Input Parameters:
    907: + tao - the Tao context
    908: . catol - absolute constraint tolerance, constraint norm must be less than catol for used for gatol convergence criteria
    909: - crtol - relative contraint tolerance, constraint norm must be less than crtol for used for gatol, gttol convergence criteria

    911:   Options Database Keys:
    912: + -tao_catol <catol> - Sets catol
    913: - -tao_crtol <crtol> - Sets crtol

    915:   Notes:
    916:   Use PETSC_DEFAULT to leave any tolerance unchanged.

    918:   Level: intermediate

    920: .seealso: TaoGetTolerances(), TaoGetConstraintTolerances(), TaoSetTolerances()

    922: @*/
    923: PetscErrorCode TaoSetConstraintTolerances(Tao tao, PetscReal catol, PetscReal crtol)
    924: {

    930:   if (catol != PETSC_DEFAULT) {
    931:     if (catol<0) {
    932:       PetscInfo(tao,"Tried to set negative catol -- ignored.\n");
    933:     } else {
    934:       tao->catol = PetscMax(0,catol);
    935:       tao->catol_changed=PETSC_TRUE;
    936:     }
    937:   }

    939:   if (crtol != PETSC_DEFAULT) {
    940:     if (crtol<0) {
    941:       PetscInfo(tao,"Tried to set negative crtol -- ignored.\n");
    942:     } else {
    943:       tao->crtol = PetscMax(0,crtol);
    944:       tao->crtol_changed=PETSC_TRUE;
    945:     }
    946:   }
    947:   return(0);
    948: }

    950: /*@
    951:   TaoGetConstraintTolerances - Gets constraint tolerance parameters used in TAO  convergence tests

    953:   Not ollective

    955:   Input Parameter:
    956: . tao - the Tao context

    958:   Output Parameter:
    959: + catol - absolute constraint tolerance, constraint norm must be less than catol for used for gatol convergence criteria
    960: - crtol - relative contraint tolerance, constraint norm must be less than crtol for used for gatol, gttol convergence criteria

    962:   Level: intermediate

    964: .seealso: TaoGetTolerances(), TaoSetTolerances(), TaoSetConstraintTolerances()

    966: @*/
    967: PetscErrorCode TaoGetConstraintTolerances(Tao tao, PetscReal *catol, PetscReal *crtol)
    968: {
    971:   if (catol) *catol = tao->catol;
    972:   if (crtol) *crtol = tao->crtol;
    973:   return(0);
    974: }

    976: /*@
    977:    TaoSetFunctionLowerBound - Sets a bound on the solution objective value.
    978:    When an approximate solution with an objective value below this number
    979:    has been found, the solver will terminate.

    981:    Logically Collective on Tao

    983:    Input Parameters:
    984: +  tao - the Tao solver context
    985: -  fmin - the tolerance

    987:    Options Database Keys:
    988: .    -tao_fmin <fmin> - sets the minimum function value

    990:    Level: intermediate

    992: .seealso: TaoSetTolerances()
    993: @*/
    994: PetscErrorCode TaoSetFunctionLowerBound(Tao tao,PetscReal fmin)
    995: {
    998:   tao->fmin = fmin;
    999:   tao->fmin_changed=PETSC_TRUE;
    1000:   return(0);
    1001: }

    1003: /*@
    1004:    TaoGetFunctionLowerBound - Gets the bound on the solution objective value.
    1005:    When an approximate solution with an objective value below this number
    1006:    has been found, the solver will terminate.

    1008:    Not collective on Tao

    1010:    Input Parameters:
    1011: .  tao - the Tao solver context

    1013:    OutputParameters:
    1014: .  fmin - the minimum function value

    1016:    Level: intermediate

    1018: .seealso: TaoSetFunctionLowerBound()
    1019: @*/
    1020: PetscErrorCode TaoGetFunctionLowerBound(Tao tao,PetscReal *fmin)
    1021: {
    1024:   *fmin = tao->fmin;
    1025:   return(0);
    1026: }

    1028: /*@
    1029:    TaoSetMaximumFunctionEvaluations - Sets a maximum number of
    1030:    function evaluations.

    1032:    Logically Collective on Tao

    1034:    Input Parameters:
    1035: +  tao - the Tao solver context
    1036: -  nfcn - the maximum number of function evaluations (>=0)

    1038:    Options Database Keys:
    1039: .    -tao_max_funcs <nfcn> - sets the maximum number of function evaluations

    1041:    Level: intermediate

    1043: .seealso: TaoSetTolerances(), TaoSetMaximumIterations()
    1044: @*/

    1046: PetscErrorCode TaoSetMaximumFunctionEvaluations(Tao tao,PetscInt nfcn)
    1047: {
    1050:   tao->max_funcs = PetscMax(0,nfcn);
    1051:   tao->max_funcs_changed=PETSC_TRUE;
    1052:   return(0);
    1053: }

    1055: /*@
    1056:    TaoGetMaximumFunctionEvaluations - Sets a maximum number of
    1057:    function evaluations.

    1059:    Not Collective

    1061:    Input Parameters:
    1062: .  tao - the Tao solver context

    1064:    Output Parameters:
    1065: .  nfcn - the maximum number of function evaluations

    1067:    Level: intermediate

    1069: .seealso: TaoSetMaximumFunctionEvaluations(), TaoGetMaximumIterations()
    1070: @*/

    1072: PetscErrorCode TaoGetMaximumFunctionEvaluations(Tao tao,PetscInt *nfcn)
    1073: {
    1076:   *nfcn = tao->max_funcs;
    1077:   return(0);
    1078: }

    1080: /*@
    1081:    TaoGetCurrentFunctionEvaluations - Get current number of
    1082:    function evaluations.

    1084:    Not Collective

    1086:    Input Parameters:
    1087: .  tao - the Tao solver context

    1089:    Output Parameters:
    1090: .  nfuncs - the current number of function evaluations

    1092:    Level: intermediate

    1094: .seealso: TaoSetMaximumFunctionEvaluations(), TaoGetMaximumFunctionEvaluations(), TaoGetMaximumIterations()
    1095: @*/

    1097: PetscErrorCode TaoGetCurrentFunctionEvaluations(Tao tao,PetscInt *nfuncs)
    1098: {
    1101:   *nfuncs=PetscMax(tao->nfuncs,tao->nfuncgrads);
    1102:   return(0);
    1103: }

    1105: /*@
    1106:    TaoSetMaximumIterations - Sets a maximum number of iterates.

    1108:    Logically Collective on Tao

    1110:    Input Parameters:
    1111: +  tao - the Tao solver context
    1112: -  maxits - the maximum number of iterates (>=0)

    1114:    Options Database Keys:
    1115: .    -tao_max_it <its> - sets the maximum number of iterations

    1117:    Level: intermediate

    1119: .seealso: TaoSetTolerances(), TaoSetMaximumFunctionEvaluations()
    1120: @*/
    1121: PetscErrorCode TaoSetMaximumIterations(Tao tao,PetscInt maxits)
    1122: {
    1125:   tao->max_it = PetscMax(0,maxits);
    1126:   tao->max_it_changed=PETSC_TRUE;
    1127:   return(0);
    1128: }

    1130: /*@
    1131:    TaoGetMaximumIterations - Sets a maximum number of iterates.

    1133:    Not Collective

    1135:    Input Parameters:
    1136: .  tao - the Tao solver context

    1138:    Output Parameters:
    1139: .  maxits - the maximum number of iterates

    1141:    Level: intermediate

    1143: .seealso: TaoSetMaximumIterations(), TaoGetMaximumFunctionEvaluations()
    1144: @*/
    1145: PetscErrorCode TaoGetMaximumIterations(Tao tao,PetscInt *maxits)
    1146: {
    1149:   *maxits = tao->max_it;
    1150:   return(0);
    1151: }

    1153: /*@
    1154:    TaoSetInitialTrustRegionRadius - Sets the initial trust region radius.

    1156:    Logically collective on Tao

    1158:    Input Parameter:
    1159: +  tao - a TAO optimization solver
    1160: -  radius - the trust region radius

    1162:    Level: intermediate

    1164:    Options Database Key:
    1165: .  -tao_trust0 <t0> - sets initial trust region radius

    1167: .seealso: TaoGetTrustRegionRadius(), TaoSetTrustRegionTolerance()
    1168: @*/
    1169: PetscErrorCode TaoSetInitialTrustRegionRadius(Tao tao, PetscReal radius)
    1170: {
    1173:   tao->trust0 = PetscMax(0.0,radius);
    1174:   tao->trust0_changed=PETSC_TRUE;
    1175:   return(0);
    1176: }

    1178: /*@
    1179:    TaoGetInitialTrustRegionRadius - Sets the initial trust region radius.

    1181:    Not Collective

    1183:    Input Parameter:
    1184: .  tao - a TAO optimization solver

    1186:    Output Parameter:
    1187: .  radius - the trust region radius

    1189:    Level: intermediate

    1191: .seealso: TaoSetInitialTrustRegionRadius(), TaoGetCurrentTrustRegionRadius()
    1192: @*/
    1193: PetscErrorCode TaoGetInitialTrustRegionRadius(Tao tao, PetscReal *radius)
    1194: {
    1197:   *radius = tao->trust0;
    1198:   return(0);
    1199: }

    1201: /*@
    1202:    TaoGetCurrentTrustRegionRadius - Gets the current trust region radius.

    1204:    Not Collective

    1206:    Input Parameter:
    1207: .  tao - a TAO optimization solver

    1209:    Output Parameter:
    1210: .  radius - the trust region radius

    1212:    Level: intermediate

    1214: .seealso: TaoSetInitialTrustRegionRadius(), TaoGetInitialTrustRegionRadius()
    1215: @*/
    1216: PetscErrorCode TaoGetCurrentTrustRegionRadius(Tao tao, PetscReal *radius)
    1217: {
    1220:   *radius = tao->trust;
    1221:   return(0);
    1222: }

    1224: /*@
    1225:   TaoGetTolerances - gets the current values of tolerances

    1227:   Not Collective

    1229:   Input Parameters:
    1230: . tao - the Tao context

    1232:   Output Parameters:
    1233: + gatol - stop if norm of gradient is less than this
    1234: . grtol - stop if relative norm of gradient is less than this
    1235: - gttol - stop if norm of gradient is reduced by a this factor

    1237:   Note: NULL can be used as an argument if not all tolerances values are needed

    1239: .seealso TaoSetTolerances()

    1241:   Level: intermediate
    1242: @*/
    1243: PetscErrorCode TaoGetTolerances(Tao tao, PetscReal *gatol, PetscReal *grtol, PetscReal *gttol)
    1244: {
    1247:   if (gatol) *gatol=tao->gatol;
    1248:   if (grtol) *grtol=tao->grtol;
    1249:   if (gttol) *gttol=tao->gttol;
    1250:   return(0);
    1251: }

    1253: /*@
    1254:   TaoGetKSP - Gets the linear solver used by the optimization solver.
    1255:   Application writers should use TaoGetKSP if they need direct access
    1256:   to the PETSc KSP object.

    1258:   Not Collective

    1260:    Input Parameters:
    1261: .  tao - the TAO solver

    1263:    Output Parameters:
    1264: .  ksp - the KSP linear solver used in the optimization solver

    1266:    Level: intermediate

    1268: @*/
    1269: PetscErrorCode TaoGetKSP(Tao tao, KSP *ksp)
    1270: {
    1272:   *ksp = tao->ksp;
    1273:   return(0);
    1274: }

    1276: /*@
    1277:    TaoGetLinearSolveIterations - Gets the total number of linear iterations
    1278:    used by the TAO solver

    1280:    Not Collective

    1282:    Input Parameter:
    1283: .  tao - TAO context

    1285:    Output Parameter:
    1286: .  lits - number of linear iterations

    1288:    Notes:
    1289:    This counter is reset to zero for each successive call to TaoSolve()

    1291:    Level: intermediate

    1293: .seealso:  TaoGetKSP()
    1294: @*/
    1295: PetscErrorCode  TaoGetLinearSolveIterations(Tao tao,PetscInt *lits)
    1296: {
    1300:   *lits = tao->ksp_tot_its;
    1301:   return(0);
    1302: }

    1304: /*@
    1305:   TaoGetLineSearch - Gets the line search used by the optimization solver.
    1306:   Application writers should use TaoGetLineSearch if they need direct access
    1307:   to the TaoLineSearch object.

    1309:   Not Collective

    1311:    Input Parameters:
    1312: .  tao - the TAO solver

    1314:    Output Parameters:
    1315: .  ls - the line search used in the optimization solver

    1317:    Level: intermediate

    1319: @*/
    1320: PetscErrorCode TaoGetLineSearch(Tao tao, TaoLineSearch *ls)
    1321: {
    1323:   *ls = tao->linesearch;
    1324:   return(0);
    1325: }

    1327: /*@
    1328:   TaoAddLineSearchCounts - Adds the number of function evaluations spent
    1329:   in the line search to the running total.

    1331:    Input Parameters:
    1332: +  tao - the TAO solver
    1333: -  ls - the line search used in the optimization solver

    1335:    Level: developer

    1337: .seealso: TaoLineSearchApply()
    1338: @*/
    1339: PetscErrorCode TaoAddLineSearchCounts(Tao tao)
    1340: {
    1342:   PetscBool      flg;
    1343:   PetscInt       nfeval,ngeval,nfgeval;

    1347:   if (tao->linesearch) {
    1348:     TaoLineSearchIsUsingTaoRoutines(tao->linesearch,&flg);
    1349:     if (!flg) {
    1350:       TaoLineSearchGetNumberFunctionEvaluations(tao->linesearch,&nfeval,&ngeval,&nfgeval);
    1351:       tao->nfuncs+=nfeval;
    1352:       tao->ngrads+=ngeval;
    1353:       tao->nfuncgrads+=nfgeval;
    1354:     }
    1355:   }
    1356:   return(0);
    1357: }

    1359: /*@
    1360:   TaoGetSolutionVector - Returns the vector with the current TAO solution

    1362:   Not Collective

    1364:   Input Parameter:
    1365: . tao - the Tao context

    1367:   Output Parameter:
    1368: . X - the current solution

    1370:   Level: intermediate

    1372:   Note:  The returned vector will be the same object that was passed into TaoSetInitialVector()
    1373: @*/
    1374: PetscErrorCode TaoGetSolutionVector(Tao tao, Vec *X)
    1375: {
    1378:   *X = tao->solution;
    1379:   return(0);
    1380: }

    1382: /*@
    1383:   TaoGetGradientVector - Returns the vector with the current TAO gradient

    1385:   Not Collective

    1387:   Input Parameter:
    1388: . tao - the Tao context

    1390:   Output Parameter:
    1391: . G - the current solution

    1393:   Level: intermediate
    1394: @*/
    1395: PetscErrorCode TaoGetGradientVector(Tao tao, Vec *G)
    1396: {
    1399:   *G = tao->gradient;
    1400:   return(0);
    1401: }

    1403: /*@
    1404:    TaoResetStatistics - Initialize the statistics used by TAO for all of the solvers.
    1405:    These statistics include the iteration number, residual norms, and convergence status.
    1406:    This routine gets called before solving each optimization problem.

    1408:    Collective on Tao

    1410:    Input Parameters:
    1411: .  solver - the Tao context

    1413:    Level: developer

    1415: .seealso: TaoCreate(), TaoSolve()
    1416: @*/
    1417: PetscErrorCode TaoResetStatistics(Tao tao)
    1418: {
    1421:   tao->niter        = 0;
    1422:   tao->nfuncs       = 0;
    1423:   tao->nfuncgrads   = 0;
    1424:   tao->ngrads       = 0;
    1425:   tao->nhess        = 0;
    1426:   tao->njac         = 0;
    1427:   tao->nconstraints = 0;
    1428:   tao->ksp_its      = 0;
    1429:   tao->ksp_tot_its  = 0;
    1430:   tao->reason       = TAO_CONTINUE_ITERATING;
    1431:   tao->residual     = 0.0;
    1432:   tao->cnorm        = 0.0;
    1433:   tao->step         = 0.0;
    1434:   tao->lsflag       = PETSC_FALSE;
    1435:   if (tao->hist_reset) tao->hist_len=0;
    1436:   return(0);
    1437: }

    1439: /*@C
    1440:   TaoSetUpdate - Sets the general-purpose update function called
    1441:   at the beginning of every iteration of the nonlinear solve. Specifically
    1442:   it is called at the top of every iteration, after the new solution and the gradient
    1443:   is determined, but before the Hessian is computed (if applicable).

    1445:   Logically Collective on Tao

    1447:   Input Parameters:
    1448: + tao - The tao solver context
    1449: - func - The function

    1451:   Calling sequence of func:
    1452: $ func (Tao tao, PetscInt step);

    1454: . step - The current step of the iteration

    1456:   Level: advanced

    1458: .seealso TaoSolve()
    1459: @*/
    1460: PetscErrorCode  TaoSetUpdate(Tao tao, PetscErrorCode (*func)(Tao, PetscInt,void*), void *ctx)
    1461: {
    1464:   tao->ops->update = func;
    1465:   tao->user_update = ctx;
    1466:   return(0);
    1467: }

    1469: /*@C
    1470:   TaoSetConvergenceTest - Sets the function that is to be used to test
    1471:   for convergence o fthe iterative minimization solution.  The new convergence
    1472:   testing routine will replace TAO's default convergence test.

    1474:   Logically Collective on Tao

    1476:   Input Parameters:
    1477: + tao - the Tao object
    1478: . conv - the routine to test for convergence
    1479: - ctx - [optional] context for private data for the convergence routine
    1480:         (may be NULL)

    1482:   Calling sequence of conv:
    1483: $   PetscErrorCode conv(Tao tao, void *ctx)

    1485: + tao - the Tao object
    1486: - ctx - [optional] convergence context

    1488:   Note: The new convergence testing routine should call TaoSetConvergedReason().

    1490:   Level: advanced

    1492: .seealso: TaoSetConvergedReason(), TaoGetSolutionStatus(), TaoGetTolerances(), TaoSetMonitor

    1494: @*/
    1495: PetscErrorCode TaoSetConvergenceTest(Tao tao, PetscErrorCode (*conv)(Tao,void*), void *ctx)
    1496: {
    1499:   (tao)->ops->convergencetest = conv;
    1500:   (tao)->cnvP = ctx;
    1501:   return(0);
    1502: }

    1504: /*@C
    1505:    TaoSetMonitor - Sets an ADDITIONAL function that is to be used at every
    1506:    iteration of the solver to display the iteration's
    1507:    progress.

    1509:    Logically Collective on Tao

    1511:    Input Parameters:
    1512: +  tao - the Tao solver context
    1513: .  mymonitor - monitoring routine
    1514: -  mctx - [optional] user-defined context for private data for the
    1515:           monitor routine (may be NULL)

    1517:    Calling sequence of mymonitor:
    1518: $     PetscErrorCode mymonitor(Tao tao,void *mctx)

    1520: +    tao - the Tao solver context
    1521: -    mctx - [optional] monitoring context

    1524:    Options Database Keys:
    1525: +    -tao_monitor        - sets TaoMonitorDefault()
    1526: .    -tao_smonitor       - sets short monitor
    1527: .    -tao_cmonitor       - same as smonitor plus constraint norm
    1528: .    -tao_view_solution   - view solution at each iteration
    1529: .    -tao_view_gradient   - view gradient at each iteration
    1530: .    -tao_view_ls_residual - view least-squares residual vector at each iteration
    1531: -    -tao_cancelmonitors - cancels all monitors that have been hardwired into a code by calls to TaoSetMonitor(), but does not cancel those set via the options database.

    1534:    Notes:
    1535:    Several different monitoring routines may be set by calling
    1536:    TaoSetMonitor() multiple times; all will be called in the
    1537:    order in which they were set.

    1539:    Fortran Notes:
    1540:     Only one monitor function may be set

    1542:    Level: intermediate

    1544: .seealso: TaoMonitorDefault(), TaoCancelMonitors(),  TaoSetDestroyRoutine()
    1545: @*/
    1546: PetscErrorCode TaoSetMonitor(Tao tao, PetscErrorCode (*func)(Tao, void*), void *ctx,PetscErrorCode (*dest)(void**))
    1547: {
    1549:   PetscInt       i;
    1550:   PetscBool      identical;

    1554:   if (tao->numbermonitors >= MAXTAOMONITORS) SETERRQ1(PetscObjectComm((PetscObject)tao),1,"Cannot attach another monitor -- max=",MAXTAOMONITORS);

    1556:   for (i=0; i<tao->numbermonitors;i++) {
    1557:     PetscMonitorCompare((PetscErrorCode (*)(void))func,ctx,dest,(PetscErrorCode (*)(void))tao->monitor[i],tao->monitorcontext[i],tao->monitordestroy[i],&identical);
    1558:     if (identical) return(0);
    1559:   }
    1560:   tao->monitor[tao->numbermonitors] = func;
    1561:   tao->monitorcontext[tao->numbermonitors] = (void*)ctx;
    1562:   tao->monitordestroy[tao->numbermonitors] = dest;
    1563:   ++tao->numbermonitors;
    1564:   return(0);
    1565: }

    1567: /*@
    1568:    TaoCancelMonitors - Clears all the monitor functions for a Tao object.

    1570:    Logically Collective on Tao

    1572:    Input Parameters:
    1573: .  tao - the Tao solver context

    1575:    Options Database:
    1576: .  -tao_cancelmonitors - cancels all monitors that have been hardwired
    1577:     into a code by calls to TaoSetMonitor(), but does not cancel those
    1578:     set via the options database

    1580:    Notes:
    1581:    There is no way to clear one specific monitor from a Tao object.

    1583:    Level: advanced

    1585: .seealso: TaoMonitorDefault(), TaoSetMonitor()
    1586: @*/
    1587: PetscErrorCode TaoCancelMonitors(Tao tao)
    1588: {
    1589:   PetscInt       i;

    1594:   for (i=0;i<tao->numbermonitors;i++) {
    1595:     if (tao->monitordestroy[i]) {
    1596:       (*tao->monitordestroy[i])(&tao->monitorcontext[i]);
    1597:     }
    1598:   }
    1599:   tao->numbermonitors=0;
    1600:   return(0);
    1601: }

    1603: /*@
    1604:    TaoMonitorDefault - Default routine for monitoring progress of the
    1605:    Tao solvers (default).  This monitor prints the function value and gradient
    1606:    norm at each iteration.  It can be turned on from the command line using the
    1607:    -tao_monitor option

    1609:    Collective on Tao

    1611:    Input Parameters:
    1612: +  tao - the Tao context
    1613: -  ctx - PetscViewer context or NULL

    1615:    Options Database Keys:
    1616: .  -tao_monitor

    1618:    Level: advanced

    1620: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
    1621: @*/
    1622: PetscErrorCode TaoMonitorDefault(Tao tao, void *ctx)
    1623: {
    1625:   PetscInt       its, tabs;
    1626:   PetscReal      fct,gnorm;
    1627:   PetscViewer    viewer = (PetscViewer)ctx;

    1631:   its=tao->niter;
    1632:   fct=tao->fc;
    1633:   gnorm=tao->residual;
    1634:   PetscViewerASCIIGetTab(viewer, &tabs);
    1635:   PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
    1636:   if (its == 0 && ((PetscObject)tao)->prefix && !tao->header_printed) {
    1637:      PetscViewerASCIIPrintf(viewer,"  Iteration information for %s solve.\n",((PetscObject)tao)->prefix);
    1638:      tao->header_printed = PETSC_TRUE;
    1639:    }
    1640:   ierr=PetscViewerASCIIPrintf(viewer,"%3D TAO,",its);
    1641:   ierr=PetscViewerASCIIPrintf(viewer,"  Function value: %g,",(double)fct);
    1642:   if (gnorm >= PETSC_INFINITY) {
    1643:     ierr=PetscViewerASCIIPrintf(viewer,"  Residual: Inf \n");
    1644:   } else {
    1645:     ierr=PetscViewerASCIIPrintf(viewer,"  Residual: %g \n",(double)gnorm);
    1646:   }
    1647:   PetscViewerASCIISetTab(viewer, tabs);
    1648:   return(0);
    1649: }

    1651: /*@
    1652:    TaoDefaultGMonitor - Default routine for monitoring progress of the
    1653:    Tao solvers (default) with extra detail on the globalization method.
    1654:    This monitor prints the function value and gradient norm at each
    1655:    iteration, as well as the step size and trust radius. Note that the
    1656:    step size and trust radius may be the same for some algorithms.
    1657:    It can be turned on from the command line using the
    1658:    -tao_gmonitor option

    1660:    Collective on Tao

    1662:    Input Parameters:
    1663: +  tao - the Tao context
    1664: -  ctx - PetscViewer context or NULL

    1666:    Options Database Keys:
    1667: .  -tao_monitor

    1669:    Level: advanced

    1671: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
    1672: @*/
    1673: PetscErrorCode TaoDefaultGMonitor(Tao tao, void *ctx)
    1674: {
    1676:   PetscInt       its, tabs;
    1677:   PetscReal      fct,gnorm,stp,tr;
    1678:   PetscViewer    viewer = (PetscViewer)ctx;

    1682:   its=tao->niter;
    1683:   fct=tao->fc;
    1684:   gnorm=tao->residual;
    1685:   stp=tao->step;
    1686:   tr=tao->trust;
    1687:   PetscViewerASCIIGetTab(viewer, &tabs);
    1688:   PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
    1689:   if (its == 0 && ((PetscObject)tao)->prefix && !tao->header_printed) {
    1690:      PetscViewerASCIIPrintf(viewer,"  Iteration information for %s solve.\n",((PetscObject)tao)->prefix);
    1691:      tao->header_printed = PETSC_TRUE;
    1692:    }
    1693:   ierr=PetscViewerASCIIPrintf(viewer,"%3D TAO,",its);
    1694:   ierr=PetscViewerASCIIPrintf(viewer,"  Function value: %g,",(double)fct);
    1695:   if (gnorm >= PETSC_INFINITY) {
    1696:     ierr=PetscViewerASCIIPrintf(viewer,"  Residual: Inf,");
    1697:   } else {
    1698:     ierr=PetscViewerASCIIPrintf(viewer,"  Residual: %g,",(double)gnorm);
    1699:   }
    1700:   PetscViewerASCIIPrintf(viewer,"  Step: %g,  Trust: %g\n",(double)stp,(double)tr);
    1701:   PetscViewerASCIISetTab(viewer, tabs);
    1702:   return(0);
    1703: }

    1705: /*@
    1706:    TaoDefaultSMonitor - Default routine for monitoring progress of the
    1707:    solver. Same as TaoMonitorDefault() except
    1708:    it prints fewer digits of the residual as the residual gets smaller.
    1709:    This is because the later digits are meaningless and are often
    1710:    different on different machines; by using this routine different
    1711:    machines will usually generate the same output. It can be turned on
    1712:    by using the -tao_smonitor option

    1714:    Collective on Tao

    1716:    Input Parameters:
    1717: +  tao - the Tao context
    1718: -  ctx - PetscViewer context of type ASCII

    1720:    Options Database Keys:
    1721: .  -tao_smonitor

    1723:    Level: advanced

    1725: .seealso: TaoMonitorDefault(), TaoSetMonitor()
    1726: @*/
    1727: PetscErrorCode TaoDefaultSMonitor(Tao tao, void *ctx)
    1728: {
    1730:   PetscInt       its, tabs;
    1731:   PetscReal      fct,gnorm;
    1732:   PetscViewer    viewer = (PetscViewer)ctx;

    1736:   its=tao->niter;
    1737:   fct=tao->fc;
    1738:   gnorm=tao->residual;
    1739:   PetscViewerASCIIGetTab(viewer, &tabs);
    1740:   PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
    1741:   ierr=PetscViewerASCIIPrintf(viewer,"iter = %3D,",its);
    1742:   ierr=PetscViewerASCIIPrintf(viewer," Function value %g,",(double)fct);
    1743:   if (gnorm >= PETSC_INFINITY) {
    1744:     ierr=PetscViewerASCIIPrintf(viewer," Residual: Inf \n");
    1745:   } else if (gnorm > 1.e-6) {
    1746:     ierr=PetscViewerASCIIPrintf(viewer," Residual: %g \n",(double)gnorm);
    1747:   } else if (gnorm > 1.e-11) {
    1748:     ierr=PetscViewerASCIIPrintf(viewer," Residual: < 1.0e-6 \n");
    1749:   } else {
    1750:     ierr=PetscViewerASCIIPrintf(viewer," Residual: < 1.0e-11 \n");
    1751:   }
    1752:   PetscViewerASCIISetTab(viewer, tabs);
    1753:   return(0);
    1754: }

    1756: /*@
    1757:    TaoDefaultCMonitor - same as TaoMonitorDefault() except
    1758:    it prints the norm of the constraints function. It can be turned on
    1759:    from the command line using the -tao_cmonitor option

    1761:    Collective on Tao

    1763:    Input Parameters:
    1764: +  tao - the Tao context
    1765: -  ctx - PetscViewer context or NULL

    1767:    Options Database Keys:
    1768: .  -tao_cmonitor

    1770:    Level: advanced

    1772: .seealso: TaoMonitorDefault(), TaoSetMonitor()
    1773: @*/
    1774: PetscErrorCode TaoDefaultCMonitor(Tao tao, void *ctx)
    1775: {
    1777:   PetscInt       its, tabs;
    1778:   PetscReal      fct,gnorm;
    1779:   PetscViewer    viewer = (PetscViewer)ctx;

    1783:   its=tao->niter;
    1784:   fct=tao->fc;
    1785:   gnorm=tao->residual;
    1786:   PetscViewerASCIIGetTab(viewer, &tabs);
    1787:   PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
    1788:   ierr=PetscViewerASCIIPrintf(viewer,"iter = %D,",its);
    1789:   ierr=PetscViewerASCIIPrintf(viewer," Function value: %g,",(double)fct);
    1790:   ierr=PetscViewerASCIIPrintf(viewer,"  Residual: %g ",(double)gnorm);
    1791:   PetscViewerASCIIPrintf(viewer,"  Constraint: %g \n",(double)tao->cnorm);
    1792:   PetscViewerASCIISetTab(viewer, tabs);
    1793:   return(0);
    1794: }

    1796: /*@C
    1797:    TaoSolutionMonitor - Views the solution at each iteration
    1798:    It can be turned on from the command line using the
    1799:    -tao_view_solution option

    1801:    Collective on Tao

    1803:    Input Parameters:
    1804: +  tao - the Tao context
    1805: -  ctx - PetscViewer context or NULL

    1807:    Options Database Keys:
    1808: .  -tao_view_solution

    1810:    Level: advanced

    1812: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
    1813: @*/
    1814: PetscErrorCode TaoSolutionMonitor(Tao tao, void *ctx)
    1815: {
    1817:   PetscViewer    viewer  = (PetscViewer)ctx;

    1821:   VecView(tao->solution, viewer);
    1822:   return(0);
    1823: }

    1825: /*@C
    1826:    TaoGradientMonitor - Views the gradient at each iteration
    1827:    It can be turned on from the command line using the
    1828:    -tao_view_gradient option

    1830:    Collective on Tao

    1832:    Input Parameters:
    1833: +  tao - the Tao context
    1834: -  ctx - PetscViewer context or NULL

    1836:    Options Database Keys:
    1837: .  -tao_view_gradient

    1839:    Level: advanced

    1841: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
    1842: @*/
    1843: PetscErrorCode TaoGradientMonitor(Tao tao, void *ctx)
    1844: {
    1846:   PetscViewer    viewer = (PetscViewer)ctx;

    1850:   VecView(tao->gradient, viewer);
    1851:   return(0);
    1852: }

    1854: /*@C
    1855:    TaoStepDirectionMonitor - Views the gradient at each iteration
    1856:    It can be turned on from the command line using the
    1857:    -tao_view_gradient option

    1859:    Collective on Tao

    1861:    Input Parameters:
    1862: +  tao - the Tao context
    1863: -  ctx - PetscViewer context or NULL

    1865:    Options Database Keys:
    1866: .  -tao_view_gradient

    1868:    Level: advanced

    1870: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
    1871: @*/
    1872: PetscErrorCode TaoStepDirectionMonitor(Tao tao, void *ctx)
    1873: {
    1875:   PetscViewer    viewer = (PetscViewer)ctx;

    1879:   VecView(tao->stepdirection, viewer);
    1880:   return(0);
    1881: }

    1883: /*@C
    1884:    TaoDrawSolutionMonitor - Plots the solution at each iteration
    1885:    It can be turned on from the command line using the
    1886:    -tao_draw_solution option

    1888:    Collective on Tao

    1890:    Input Parameters:
    1891: +  tao - the Tao context
    1892: -  ctx - TaoMonitorDraw context

    1894:    Options Database Keys:
    1895: .  -tao_draw_solution

    1897:    Level: advanced

    1899: .seealso: TaoSolutionMonitor(), TaoSetMonitor(), TaoDrawGradientMonitor
    1900: @*/
    1901: PetscErrorCode TaoDrawSolutionMonitor(Tao tao, void *ctx)
    1902: {
    1903:   PetscErrorCode    ierr;
    1904:   TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx;

    1907:   if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) return(0);
    1908:   VecView(tao->solution,ictx->viewer);
    1909:   return(0);
    1910: }

    1912: /*@C
    1913:    TaoDrawGradientMonitor - Plots the gradient at each iteration
    1914:    It can be turned on from the command line using the
    1915:    -tao_draw_gradient option

    1917:    Collective on Tao

    1919:    Input Parameters:
    1920: +  tao - the Tao context
    1921: -  ctx - PetscViewer context

    1923:    Options Database Keys:
    1924: .  -tao_draw_gradient

    1926:    Level: advanced

    1928: .seealso: TaoGradientMonitor(), TaoSetMonitor(), TaoDrawSolutionMonitor
    1929: @*/
    1930: PetscErrorCode TaoDrawGradientMonitor(Tao tao, void *ctx)
    1931: {
    1932:   PetscErrorCode    ierr;
    1933:   TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx;

    1936:   if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) return(0);
    1937:   VecView(tao->gradient,ictx->viewer);
    1938:   return(0);
    1939: }

    1941: /*@C
    1942:    TaoDrawStepMonitor - Plots the step direction at each iteration
    1943:    It can be turned on from the command line using the
    1944:    -tao_draw_step option

    1946:    Collective on Tao

    1948:    Input Parameters:
    1949: +  tao - the Tao context
    1950: -  ctx - PetscViewer context

    1952:    Options Database Keys:
    1953: .  -tao_draw_step

    1955:    Level: advanced

    1957: .seealso: TaoSetMonitor(), TaoDrawSolutionMonitor
    1958: @*/
    1959: PetscErrorCode TaoDrawStepMonitor(Tao tao, void *ctx)
    1960: {
    1962:   PetscViewer    viewer = (PetscViewer)(ctx);

    1965:   VecView(tao->stepdirection, viewer);
    1966:   return(0);
    1967: }

    1969: /*@C
    1970:    TaoResidualMonitor - Views the least-squares residual at each iteration
    1971:    It can be turned on from the command line using the
    1972:    -tao_view_ls_residual option

    1974:    Collective on Tao

    1976:    Input Parameters:
    1977: +  tao - the Tao context
    1978: -  ctx - PetscViewer context or NULL

    1980:    Options Database Keys:
    1981: .  -tao_view_ls_residual

    1983:    Level: advanced

    1985: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
    1986: @*/
    1987: PetscErrorCode TaoResidualMonitor(Tao tao, void *ctx)
    1988: {
    1990:   PetscViewer    viewer  = (PetscViewer)ctx;

    1994:   VecView(tao->ls_res,viewer);
    1995:   return(0);
    1996: }

    1998: /*@
    1999:    TaoDefaultConvergenceTest - Determines whether the solver should continue iterating
    2000:    or terminate.

    2002:    Collective on Tao

    2004:    Input Parameters:
    2005: +  tao - the Tao context
    2006: -  dummy - unused dummy context

    2008:    Output Parameter:
    2009: .  reason - for terminating

    2011:    Notes:
    2012:    This routine checks the residual in the optimality conditions, the
    2013:    relative residual in the optimity conditions, the number of function
    2014:    evaluations, and the function value to test convergence.  Some
    2015:    solvers may use different convergence routines.

    2017:    Level: developer

    2019: .seealso: TaoSetTolerances(),TaoGetConvergedReason(),TaoSetConvergedReason()
    2020: @*/

    2022: PetscErrorCode TaoDefaultConvergenceTest(Tao tao,void *dummy)
    2023: {
    2024:   PetscInt           niter=tao->niter, nfuncs=PetscMax(tao->nfuncs,tao->nfuncgrads);
    2025:   PetscInt           max_funcs=tao->max_funcs;
    2026:   PetscReal          gnorm=tao->residual, gnorm0=tao->gnorm0;
    2027:   PetscReal          f=tao->fc, steptol=tao->steptol,trradius=tao->step;
    2028:   PetscReal          gatol=tao->gatol,grtol=tao->grtol,gttol=tao->gttol;
    2029:   PetscReal          catol=tao->catol,crtol=tao->crtol;
    2030:   PetscReal          fmin=tao->fmin, cnorm=tao->cnorm;
    2031:   TaoConvergedReason reason=tao->reason;
    2032:   PetscErrorCode     ierr;

    2036:   if (reason != TAO_CONTINUE_ITERATING) {
    2037:     return(0);
    2038:   }

    2040:   if (PetscIsInfOrNanReal(f)) {
    2041:     PetscInfo(tao,"Failed to converged, function value is Inf or NaN\n");
    2042:     reason = TAO_DIVERGED_NAN;
    2043:   } else if (f <= fmin && cnorm <=catol) {
    2044:     PetscInfo2(tao,"Converged due to function value %g < minimum function value %g\n", (double)f,(double)fmin);
    2045:     reason = TAO_CONVERGED_MINF;
    2046:   } else if (gnorm<= gatol && cnorm <=catol) {
    2047:     PetscInfo2(tao,"Converged due to residual norm ||g(X)||=%g < %g\n",(double)gnorm,(double)gatol);
    2048:     reason = TAO_CONVERGED_GATOL;
    2049:   } else if (f!=0 && PetscAbsReal(gnorm/f) <= grtol && cnorm <= crtol) {
    2050:     PetscInfo2(tao,"Converged due to residual ||g(X)||/|f(X)| =%g < %g\n",(double)(gnorm/f),(double)grtol);
    2051:     reason = TAO_CONVERGED_GRTOL;
    2052:   } else if (gnorm0 != 0 && ((gttol == 0 && gnorm == 0) || gnorm/gnorm0 < gttol) && cnorm <= crtol) {
    2053:     PetscInfo2(tao,"Converged due to relative residual norm ||g(X)||/||g(X0)|| = %g < %g\n",(double)(gnorm/gnorm0),(double)gttol);
    2054:     reason = TAO_CONVERGED_GTTOL;
    2055:   } else if (nfuncs > max_funcs){
    2056:     PetscInfo2(tao,"Exceeded maximum number of function evaluations: %D > %D\n", nfuncs,max_funcs);
    2057:     reason = TAO_DIVERGED_MAXFCN;
    2058:   } else if (tao->lsflag != 0){
    2059:     PetscInfo(tao,"Tao Line Search failure.\n");
    2060:     reason = TAO_DIVERGED_LS_FAILURE;
    2061:   } else if (trradius < steptol && niter > 0){
    2062:     PetscInfo2(tao,"Trust region/step size too small: %g < %g\n", (double)trradius,(double)steptol);
    2063:     reason = TAO_CONVERGED_STEPTOL;
    2064:   } else if (niter >= tao->max_it) {
    2065:     PetscInfo2(tao,"Exceeded maximum number of iterations: %D > %D\n",niter,tao->max_it);
    2066:     reason = TAO_DIVERGED_MAXITS;
    2067:   } else {
    2068:     reason = TAO_CONTINUE_ITERATING;
    2069:   }
    2070:   tao->reason = reason;
    2071:   return(0);
    2072: }

    2074: /*@C
    2075:    TaoSetOptionsPrefix - Sets the prefix used for searching for all
    2076:    TAO options in the database.

    2079:    Logically Collective on Tao

    2081:    Input Parameters:
    2082: +  tao - the Tao context
    2083: -  prefix - the prefix string to prepend to all TAO option requests

    2085:    Notes:
    2086:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    2087:    The first character of all runtime options is AUTOMATICALLY the hyphen.

    2089:    For example, to distinguish between the runtime options for two
    2090:    different TAO solvers, one could call
    2091: .vb
    2092:       TaoSetOptionsPrefix(tao1,"sys1_")
    2093:       TaoSetOptionsPrefix(tao2,"sys2_")
    2094: .ve

    2096:    This would enable use of different options for each system, such as
    2097: .vb
    2098:       -sys1_tao_method blmvm -sys1_tao_gtol 1.e-3
    2099:       -sys2_tao_method lmvm  -sys2_tao_gtol 1.e-4
    2100: .ve

    2103:    Level: advanced

    2105: .seealso: TaoAppendOptionsPrefix(), TaoGetOptionsPrefix()
    2106: @*/

    2108: PetscErrorCode TaoSetOptionsPrefix(Tao tao, const char p[])
    2109: {

    2113:   PetscObjectSetOptionsPrefix((PetscObject)tao,p);
    2114:   if (tao->linesearch) {
    2115:     TaoLineSearchSetOptionsPrefix(tao->linesearch,p);
    2116:   }
    2117:   if (tao->ksp) {
    2118:     KSPSetOptionsPrefix(tao->ksp,p);
    2119:   }
    2120:   return(0);
    2121: }

    2123: /*@C
    2124:    TaoAppendOptionsPrefix - Appends to the prefix used for searching for all
    2125:    TAO options in the database.

    2128:    Logically Collective on Tao

    2130:    Input Parameters:
    2131: +  tao - the Tao solver context
    2132: -  prefix - the prefix string to prepend to all TAO option requests

    2134:    Notes:
    2135:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    2136:    The first character of all runtime options is AUTOMATICALLY the hyphen.

    2139:    Level: advanced

    2141: .seealso: TaoSetOptionsPrefix(), TaoGetOptionsPrefix()
    2142: @*/
    2143: PetscErrorCode TaoAppendOptionsPrefix(Tao tao, const char p[])
    2144: {

    2148:   PetscObjectAppendOptionsPrefix((PetscObject)tao,p);
    2149:   if (tao->linesearch) {
    2150:     TaoLineSearchSetOptionsPrefix(tao->linesearch,p);
    2151:   }
    2152:   if (tao->ksp) {
    2153:     KSPSetOptionsPrefix(tao->ksp,p);
    2154:   }
    2155:   return(0);
    2156: }

    2158: /*@C
    2159:   TaoGetOptionsPrefix - Gets the prefix used for searching for all
    2160:   TAO options in the database

    2162:   Not Collective

    2164:   Input Parameters:
    2165: . tao - the Tao context

    2167:   Output Parameters:
    2168: . prefix - pointer to the prefix string used is returned

    2170:   Notes:
    2171:     On the fortran side, the user should pass in a string 'prefix' of
    2172:   sufficient length to hold the prefix.

    2174:   Level: advanced

    2176: .seealso: TaoSetOptionsPrefix(), TaoAppendOptionsPrefix()
    2177: @*/
    2178: PetscErrorCode TaoGetOptionsPrefix(Tao tao, const char *p[])
    2179: {
    2180:    return PetscObjectGetOptionsPrefix((PetscObject)tao,p);
    2181: }

    2183: /*@C
    2184:    TaoSetType - Sets the method for the unconstrained minimization solver.

    2186:    Collective on Tao

    2188:    Input Parameters:
    2189: +  solver - the Tao solver context
    2190: -  type - a known method

    2192:    Options Database Key:
    2193: .  -tao_type <type> - Sets the method; use -help for a list
    2194:    of available methods (for instance, "-tao_type lmvm" or "-tao_type tron")

    2196:    Available methods include:
    2197: +    nls - Newton's method with line search for unconstrained minimization
    2198: .    ntr - Newton's method with trust region for unconstrained minimization
    2199: .    ntl - Newton's method with trust region, line search for unconstrained minimization
    2200: .    lmvm - Limited memory variable metric method for unconstrained minimization
    2201: .    cg - Nonlinear conjugate gradient method for unconstrained minimization
    2202: .    nm - Nelder-Mead algorithm for derivate-free unconstrained minimization
    2203: .    tron - Newton Trust Region method for bound constrained minimization
    2204: .    gpcg - Newton Trust Region method for quadratic bound constrained minimization
    2205: .    blmvm - Limited memory variable metric method for bound constrained minimization
    2206: -    pounders - Model-based algorithm pounder extended for nonlinear least squares

    2208:   Level: intermediate

    2210: .seealso: TaoCreate(), TaoGetType(), TaoType

    2212: @*/
    2213: PetscErrorCode TaoSetType(Tao tao, TaoType type)
    2214: {
    2216:   PetscErrorCode (*create_xxx)(Tao);
    2217:   PetscBool      issame;

    2222:   PetscObjectTypeCompare((PetscObject)tao,type,&issame);
    2223:   if (issame) return(0);

    2225:   PetscFunctionListFind(TaoList, type, (void(**)(void))&create_xxx);
    2226:   if (!create_xxx) SETERRQ1(PetscObjectComm((PetscObject)tao),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Tao type %s",type);

    2228:   /* Destroy the existing solver information */
    2229:   if (tao->ops->destroy) {
    2230:     (*tao->ops->destroy)(tao);
    2231:   }
    2232:   KSPDestroy(&tao->ksp);
    2233:   TaoLineSearchDestroy(&tao->linesearch);
    2234:   VecDestroy(&tao->gradient);
    2235:   VecDestroy(&tao->stepdirection);

    2237:   tao->ops->setup = NULL;
    2238:   tao->ops->solve = NULL;
    2239:   tao->ops->view  = NULL;
    2240:   tao->ops->setfromoptions = NULL;
    2241:   tao->ops->destroy = NULL;

    2243:   tao->setupcalled = PETSC_FALSE;

    2245:   (*create_xxx)(tao);
    2246:   PetscObjectChangeTypeName((PetscObject)tao,type);
    2247:   return(0);
    2248: }

    2250: /*MC
    2251:    TaoRegister - Adds a method to the TAO package for unconstrained minimization.

    2253:    Synopsis:
    2254:    TaoRegister(char *name_solver,char *path,char *name_Create,PetscErrorCode (*routine_Create)(Tao))

    2256:    Not collective

    2258:    Input Parameters:
    2259: +  sname - name of a new user-defined solver
    2260: -  func - routine to Create method context

    2262:    Notes:
    2263:    TaoRegister() may be called multiple times to add several user-defined solvers.

    2265:    Sample usage:
    2266: .vb
    2267:    TaoRegister("my_solver",MySolverCreate);
    2268: .ve

    2270:    Then, your solver can be chosen with the procedural interface via
    2271: $     TaoSetType(tao,"my_solver")
    2272:    or at runtime via the option
    2273: $     -tao_type my_solver

    2275:    Level: advanced

    2277: .seealso: TaoRegisterAll(), TaoRegisterDestroy()
    2278: M*/
    2279: PetscErrorCode TaoRegister(const char sname[], PetscErrorCode (*func)(Tao))
    2280: {

    2284:   TaoInitializePackage();
    2285:   PetscFunctionListAdd(&TaoList,sname, (void (*)(void))func);
    2286:   return(0);
    2287: }

    2289: /*@C
    2290:    TaoRegisterDestroy - Frees the list of minimization solvers that were
    2291:    registered by TaoRegisterDynamic().

    2293:    Not Collective

    2295:    Level: advanced

    2297: .seealso: TaoRegisterAll(), TaoRegister()
    2298: @*/
    2299: PetscErrorCode TaoRegisterDestroy(void)
    2300: {
    2303:   PetscFunctionListDestroy(&TaoList);
    2304:   TaoRegisterAllCalled = PETSC_FALSE;
    2305:   return(0);
    2306: }

    2308: /*@
    2309:    TaoGetIterationNumber - Gets the number of Tao iterations completed
    2310:    at this time.

    2312:    Not Collective

    2314:    Input Parameter:
    2315: .  tao - Tao context

    2317:    Output Parameter:
    2318: .  iter - iteration number

    2320:    Notes:
    2321:    For example, during the computation of iteration 2 this would return 1.

    2324:    Level: intermediate

    2326: .seealso:   TaoGetLinearSolveIterations(), TaoGetResidualNorm(), TaoGetObjective()
    2327: @*/
    2328: PetscErrorCode  TaoGetIterationNumber(Tao tao,PetscInt *iter)
    2329: {
    2333:   *iter = tao->niter;
    2334:   return(0);
    2335: }

    2337: /*@
    2338:    TaoGetObjective - Gets the current value of the objective function
    2339:    at this time.

    2341:    Not Collective

    2343:    Input Parameter:
    2344: .  tao - Tao context

    2346:    Output Parameter:
    2347: .  value - the current value

    2349:    Level: intermediate

    2351: .seealso:   TaoGetLinearSolveIterations(), TaoGetIterationNumber(), TaoGetResidualNorm()
    2352: @*/
    2353: PetscErrorCode  TaoGetObjective(Tao tao,PetscReal *value)
    2354: {
    2358:   *value = tao->fc;
    2359:   return(0);
    2360: }

    2362: /*@
    2363:    TaoGetResidualNorm - Gets the current value of the norm of the residual
    2364:    at this time.

    2366:    Not Collective

    2368:    Input Parameter:
    2369: .  tao - Tao context

    2371:    Output Parameter:
    2372: .  value - the current value

    2374:    Level: intermediate

    2376:    Developer Note: This is the 2-norm of the residual, we cannot use TaoGetGradientNorm() because that has
    2377:                    a different meaning. For some reason Tao sometimes calls the gradient the residual.

    2379: .seealso:   TaoGetLinearSolveIterations(), TaoGetIterationNumber(), TaoGetObjective()
    2380: @*/
    2381: PetscErrorCode  TaoGetResidualNorm(Tao tao,PetscReal *value)
    2382: {
    2386:   *value = tao->residual;
    2387:   return(0);
    2388: }

    2390: /*@
    2391:    TaoSetIterationNumber - Sets the current iteration number.

    2393:    Not Collective

    2395:    Input Parameter:
    2396: +  tao - Tao context
    2397: -  iter - iteration number

    2399:    Level: developer

    2401: .seealso:   TaoGetLinearSolveIterations()
    2402: @*/
    2403: PetscErrorCode  TaoSetIterationNumber(Tao tao,PetscInt iter)
    2404: {

    2409:   PetscObjectSAWsTakeAccess((PetscObject)tao);
    2410:   tao->niter = iter;
    2411:   PetscObjectSAWsGrantAccess((PetscObject)tao);
    2412:   return(0);
    2413: }

    2415: /*@
    2416:    TaoGetTotalIterationNumber - Gets the total number of Tao iterations
    2417:    completed. This number keeps accumulating if multiple solves
    2418:    are called with the Tao object.

    2420:    Not Collective

    2422:    Input Parameter:
    2423: .  tao - Tao context

    2425:    Output Parameter:
    2426: .  iter - iteration number

    2428:    Notes:
    2429:    The total iteration count is updated after each solve, if there is a current
    2430:    TaoSolve() in progress then those iterations are not yet counted.

    2432:    Level: intermediate

    2434: .seealso:   TaoGetLinearSolveIterations()
    2435: @*/
    2436: PetscErrorCode  TaoGetTotalIterationNumber(Tao tao,PetscInt *iter)
    2437: {
    2441:   *iter = tao->ntotalits;
    2442:   return(0);
    2443: }

    2445: /*@
    2446:    TaoSetTotalIterationNumber - Sets the current total iteration number.

    2448:    Not Collective

    2450:    Input Parameter:
    2451: +  tao - Tao context
    2452: -  iter - iteration number

    2454:    Level: developer

    2456: .seealso:   TaoGetLinearSolveIterations()
    2457: @*/
    2458: PetscErrorCode  TaoSetTotalIterationNumber(Tao tao,PetscInt iter)
    2459: {

    2464:   PetscObjectSAWsTakeAccess((PetscObject)tao);
    2465:   tao->ntotalits = iter;
    2466:   PetscObjectSAWsGrantAccess((PetscObject)tao);
    2467:   return(0);
    2468: }

    2470: /*@
    2471:   TaoSetConvergedReason - Sets the termination flag on a Tao object

    2473:   Logically Collective on Tao

    2475:   Input Parameters:
    2476: + tao - the Tao context
    2477: - reason - one of
    2478: $     TAO_CONVERGED_ATOL (2),
    2479: $     TAO_CONVERGED_RTOL (3),
    2480: $     TAO_CONVERGED_STEPTOL (4),
    2481: $     TAO_CONVERGED_MINF (5),
    2482: $     TAO_CONVERGED_USER (6),
    2483: $     TAO_DIVERGED_MAXITS (-2),
    2484: $     TAO_DIVERGED_NAN (-4),
    2485: $     TAO_DIVERGED_MAXFCN (-5),
    2486: $     TAO_DIVERGED_LS_FAILURE (-6),
    2487: $     TAO_DIVERGED_TR_REDUCTION (-7),
    2488: $     TAO_DIVERGED_USER (-8),
    2489: $     TAO_CONTINUE_ITERATING (0)

    2491:    Level: intermediate

    2493: @*/
    2494: PetscErrorCode TaoSetConvergedReason(Tao tao, TaoConvergedReason reason)
    2495: {
    2498:   tao->reason = reason;
    2499:   return(0);
    2500: }

    2502: /*@
    2503:    TaoGetConvergedReason - Gets the reason the Tao iteration was stopped.

    2505:    Not Collective

    2507:    Input Parameter:
    2508: .  tao - the Tao solver context

    2510:    Output Parameter:
    2511: .  reason - one of
    2512: $  TAO_CONVERGED_GATOL (3)           ||g(X)|| < gatol
    2513: $  TAO_CONVERGED_GRTOL (4)           ||g(X)|| / f(X)  < grtol
    2514: $  TAO_CONVERGED_GTTOL (5)           ||g(X)|| / ||g(X0)|| < gttol
    2515: $  TAO_CONVERGED_STEPTOL (6)         step size small
    2516: $  TAO_CONVERGED_MINF (7)            F < F_min
    2517: $  TAO_CONVERGED_USER (8)            User defined
    2518: $  TAO_DIVERGED_MAXITS (-2)          its > maxits
    2519: $  TAO_DIVERGED_NAN (-4)             Numerical problems
    2520: $  TAO_DIVERGED_MAXFCN (-5)          fevals > max_funcsals
    2521: $  TAO_DIVERGED_LS_FAILURE (-6)      line search failure
    2522: $  TAO_DIVERGED_TR_REDUCTION (-7)    trust region failure
    2523: $  TAO_DIVERGED_USER(-8)             (user defined)
    2524:  $  TAO_CONTINUE_ITERATING (0)

    2526:    where
    2527: +  X - current solution
    2528: .  X0 - initial guess
    2529: .  f(X) - current function value
    2530: .  f(X*) - true solution (estimated)
    2531: .  g(X) - current gradient
    2532: .  its - current iterate number
    2533: .  maxits - maximum number of iterates
    2534: .  fevals - number of function evaluations
    2535: -  max_funcsals - maximum number of function evaluations

    2537:    Level: intermediate

    2539: .seealso: TaoSetConvergenceTest(), TaoSetTolerances()

    2541: @*/
    2542: PetscErrorCode TaoGetConvergedReason(Tao tao, TaoConvergedReason *reason)
    2543: {
    2547:   *reason = tao->reason;
    2548:   return(0);
    2549: }

    2551: /*@
    2552:   TaoGetSolutionStatus - Get the current iterate, objective value,
    2553:   residual, infeasibility, and termination

    2555:   Not Collective

    2557:    Input Parameters:
    2558: .  tao - the Tao context

    2560:    Output Parameters:
    2561: +  iterate - the current iterate number (>=0)
    2562: .  f - the current function value
    2563: .  gnorm - the square of the gradient norm, duality gap, or other measure indicating distance from optimality.
    2564: .  cnorm - the infeasibility of the current solution with regard to the constraints.
    2565: .  xdiff - the step length or trust region radius of the most recent iterate.
    2566: -  reason - The termination reason, which can equal TAO_CONTINUE_ITERATING

    2568:    Level: intermediate

    2570:    Note:
    2571:    TAO returns the values set by the solvers in the routine TaoMonitor().

    2573:    Note:
    2574:    If any of the output arguments are set to NULL, no corresponding value will be returned.

    2576: .seealso: TaoMonitor(), TaoGetConvergedReason()
    2577: @*/
    2578: PetscErrorCode TaoGetSolutionStatus(Tao tao, PetscInt *its, PetscReal *f, PetscReal *gnorm, PetscReal *cnorm, PetscReal *xdiff, TaoConvergedReason *reason)
    2579: {
    2581:   if (its) *its=tao->niter;
    2582:   if (f) *f=tao->fc;
    2583:   if (gnorm) *gnorm=tao->residual;
    2584:   if (cnorm) *cnorm=tao->cnorm;
    2585:   if (reason) *reason=tao->reason;
    2586:   if (xdiff) *xdiff=tao->step;
    2587:   return(0);
    2588: }

    2590: /*@C
    2591:    TaoGetType - Gets the current Tao algorithm.

    2593:    Not Collective

    2595:    Input Parameter:
    2596: .  tao - the Tao solver context

    2598:    Output Parameter:
    2599: .  type - Tao method

    2601:    Level: intermediate

    2603: @*/
    2604: PetscErrorCode TaoGetType(Tao tao,TaoType *type)
    2605: {
    2609:   *type=((PetscObject)tao)->type_name;
    2610:   return(0);
    2611: }

    2613: /*@C
    2614:   TaoMonitor - Monitor the solver and the current solution.  This
    2615:   routine will record the iteration number and residual statistics,
    2616:   call any monitors specified by the user, and calls the convergence-check routine.

    2618:    Input Parameters:
    2619: +  tao - the Tao context
    2620: .  its - the current iterate number (>=0)
    2621: .  f - the current objective function value
    2622: .  res - the gradient norm, square root of the duality gap, or other measure indicating distince from optimality.  This measure will be recorded and
    2623:           used for some termination tests.
    2624: .  cnorm - the infeasibility of the current solution with regard to the constraints.
    2625: -  steplength - multiple of the step direction added to the previous iterate.

    2627:    Output Parameters:
    2628: .  reason - The termination reason, which can equal TAO_CONTINUE_ITERATING

    2630:    Options Database Key:
    2631: .  -tao_monitor - Use the default monitor, which prints statistics to standard output

    2633: .seealso TaoGetConvergedReason(), TaoMonitorDefault(), TaoSetMonitor()

    2635:    Level: developer

    2637: @*/
    2638: PetscErrorCode TaoMonitor(Tao tao, PetscInt its, PetscReal f, PetscReal res, PetscReal cnorm, PetscReal steplength)
    2639: {
    2641:   PetscInt       i;

    2645:   tao->fc = f;
    2646:   tao->residual = res;
    2647:   tao->cnorm = cnorm;
    2648:   tao->step = steplength;
    2649:   if (!its) {
    2650:     tao->cnorm0 = cnorm; tao->gnorm0 = res;
    2651:   }
    2652:   if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(res)) SETERRQ(PetscObjectComm((PetscObject)tao),PETSC_ERR_USER, "User provided compute function generated Inf or NaN");
    2653:   for (i=0;i<tao->numbermonitors;i++) {
    2654:     (*tao->monitor[i])(tao,tao->monitorcontext[i]);
    2655:   }
    2656:   return(0);
    2657: }

    2659: /*@
    2660:    TaoSetConvergenceHistory - Sets the array used to hold the convergence history.

    2662:    Logically Collective on Tao

    2664:    Input Parameters:
    2665: +  tao - the Tao solver context
    2666: .  obj   - array to hold objective value history
    2667: .  resid - array to hold residual history
    2668: .  cnorm - array to hold constraint violation history
    2669: .  lits - integer array holds the number of linear iterations for each Tao iteration
    2670: .  na  - size of obj, resid, and cnorm
    2671: -  reset - PetscTrue indicates each new minimization resets the history counter to zero,
    2672:            else it continues storing new values for new minimizations after the old ones

    2674:    Notes:
    2675:    If set, TAO will fill the given arrays with the indicated
    2676:    information at each iteration.  If 'obj','resid','cnorm','lits' are
    2677:    *all* NULL then space (using size na, or 1000 if na is PETSC_DECIDE or
    2678:    PETSC_DEFAULT) is allocated for the history.
    2679:    If not all are NULL, then only the non-NULL information categories
    2680:    will be stored, the others will be ignored.

    2682:    Any convergence information after iteration number 'na' will not be stored.

    2684:    This routine is useful, e.g., when running a code for purposes
    2685:    of accurate performance monitoring, when no I/O should be done
    2686:    during the section of code that is being timed.

    2688:    Level: intermediate

    2690: .seealso: TaoGetConvergenceHistory()

    2692: @*/
    2693: PetscErrorCode TaoSetConvergenceHistory(Tao tao, PetscReal obj[], PetscReal resid[], PetscReal cnorm[], PetscInt lits[], PetscInt na,PetscBool reset)
    2694: {

    2704:   if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
    2705:   if (!obj && !resid && !cnorm && !lits) {
    2706:     PetscCalloc4(na,&obj,na,&resid,na,&cnorm,na,&lits);
    2707:     tao->hist_malloc = PETSC_TRUE;
    2708:   }

    2710:   tao->hist_obj = obj;
    2711:   tao->hist_resid = resid;
    2712:   tao->hist_cnorm = cnorm;
    2713:   tao->hist_lits = lits;
    2714:   tao->hist_max   = na;
    2715:   tao->hist_reset = reset;
    2716:   tao->hist_len = 0;
    2717:   return(0);
    2718: }

    2720: /*@C
    2721:    TaoGetConvergenceHistory - Gets the arrays used to hold the convergence history.

    2723:    Collective on Tao

    2725:    Input Parameter:
    2726: .  tao - the Tao context

    2728:    Output Parameters:
    2729: +  obj   - array used to hold objective value history
    2730: .  resid - array used to hold residual history
    2731: .  cnorm - array used to hold constraint violation history
    2732: .  lits  - integer array used to hold linear solver iteration count
    2733: -  nhist  - size of obj, resid, cnorm, and lits

    2735:    Notes:
    2736:     This routine must be preceded by calls to TaoSetConvergenceHistory()
    2737:     and TaoSolve(), otherwise it returns useless information.

    2739:     The calling sequence for this routine in Fortran is
    2740: $   call TaoGetConvergenceHistory(Tao tao, PetscInt nhist, PetscErrorCode ierr)

    2742:    This routine is useful, e.g., when running a code for purposes
    2743:    of accurate performance monitoring, when no I/O should be done
    2744:    during the section of code that is being timed.

    2746:    Level: advanced

    2748: .seealso: TaoSetConvergenceHistory()

    2750: @*/
    2751: PetscErrorCode TaoGetConvergenceHistory(Tao tao, PetscReal **obj, PetscReal **resid, PetscReal **cnorm, PetscInt **lits, PetscInt *nhist)
    2752: {
    2755:   if (obj)   *obj   = tao->hist_obj;
    2756:   if (cnorm) *cnorm = tao->hist_cnorm;
    2757:   if (resid) *resid = tao->hist_resid;
    2758:   if (nhist) *nhist = tao->hist_len;
    2759:   return(0);
    2760: }

    2762: /*@
    2763:    TaoSetApplicationContext - Sets the optional user-defined context for
    2764:    a solver.

    2766:    Logically Collective on Tao

    2768:    Input Parameters:
    2769: +  tao  - the Tao context
    2770: -  usrP - optional user context

    2772:    Level: intermediate

    2774: .seealso: TaoGetApplicationContext(), TaoSetApplicationContext()
    2775: @*/
    2776: PetscErrorCode  TaoSetApplicationContext(Tao tao,void *usrP)
    2777: {
    2780:   tao->user = usrP;
    2781:   return(0);
    2782: }

    2784: /*@
    2785:    TaoGetApplicationContext - Gets the user-defined context for a
    2786:    TAO solvers.

    2788:    Not Collective

    2790:    Input Parameter:
    2791: .  tao  - Tao context

    2793:    Output Parameter:
    2794: .  usrP - user context

    2796:    Level: intermediate

    2798: .seealso: TaoSetApplicationContext()
    2799: @*/
    2800: PetscErrorCode  TaoGetApplicationContext(Tao tao,void *usrP)
    2801: {
    2804:   *(void**)usrP = tao->user;
    2805:   return(0);
    2806: }

    2808: /*@
    2809:    TaoSetGradientNorm - Sets the matrix used to define the inner product that measures the size of the gradient.

    2811:    Collective on tao

    2813:    Input Parameters:
    2814: +  tao  - the Tao context
    2815: -  M    - gradient norm

    2817:    Level: beginner

    2819: .seealso: TaoGetGradientNorm(), TaoGradientNorm()
    2820: @*/
    2821: PetscErrorCode  TaoSetGradientNorm(Tao tao, Mat M)
    2822: {

    2827:   PetscObjectReference((PetscObject)M);
    2828:   MatDestroy(&tao->gradient_norm);
    2829:   VecDestroy(&tao->gradient_norm_tmp);
    2830:   tao->gradient_norm = M;
    2831:   MatCreateVecs(M, NULL, &tao->gradient_norm_tmp);
    2832:   return(0);
    2833: }

    2835: /*@
    2836:    TaoGetGradientNorm - Returns the matrix used to define the inner product for measuring the size of the gradient.

    2838:    Not Collective

    2840:    Input Parameter:
    2841: .  tao  - Tao context

    2843:    Output Parameter:
    2844: .  M - gradient norm

    2846:    Level: beginner

    2848: .seealso: TaoSetGradientNorm(), TaoGradientNorm()
    2849: @*/
    2850: PetscErrorCode  TaoGetGradientNorm(Tao tao, Mat *M)
    2851: {
    2854:   *M = tao->gradient_norm;
    2855:   return(0);
    2856: }

    2858: /*c
    2859:    TaoGradientNorm - Compute the norm with respect to the inner product the user has set.

    2861:    Collective on tao

    2863:    Input Parameter:
    2864: .  tao      - the Tao context
    2865: .  gradient - the gradient to be computed
    2866: .  norm     - the norm type

    2868:    Output Parameter:
    2869: .  gnorm    - the gradient norm

    2871:    Level: developer

    2873: .seealso: TaoSetGradientNorm(), TaoGetGradientNorm()
    2874: @*/
    2875: PetscErrorCode  TaoGradientNorm(Tao tao, Vec gradient, NormType type, PetscReal *gnorm)
    2876: {

    2884:   if (tao->gradient_norm) {
    2885:     PetscScalar gnorms;

    2887:     if (type != NORM_2) SETERRQ(PetscObjectComm((PetscObject)gradient), PETSC_ERR_ARG_WRONG, "Norm type must be NORM_2 if an inner product for the gradient norm is set.");
    2888:     MatMult(tao->gradient_norm, gradient, tao->gradient_norm_tmp);
    2889:     VecDot(gradient, tao->gradient_norm_tmp, &gnorms);
    2890:     *gnorm = PetscRealPart(PetscSqrtScalar(gnorms));
    2891:   } else {
    2892:     VecNorm(gradient, type, gnorm);
    2893:   }
    2894:   return(0);
    2895: }

    2897: /*@C
    2898:    TaoMonitorDrawCtxCreate - Creates the monitor context for TaoMonitorDrawCtx

    2900:    Collective on Tao

    2902:    Output Patameter:
    2903: .    ctx - the monitor context

    2905:    Options Database:
    2906: .   -tao_draw_solution_initial - show initial guess as well as current solution

    2908:    Level: intermediate

    2910: .seealso: TaoMonitorSet(), TaoMonitorDefault(), VecView(), TaoMonitorDrawCtx()
    2911: @*/
    2912: PetscErrorCode  TaoMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TaoMonitorDrawCtx *ctx)
    2913: {
    2914:   PetscErrorCode   ierr;

    2917:   PetscNew(ctx);
    2918:   PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);
    2919:   PetscViewerSetFromOptions((*ctx)->viewer);
    2920:   (*ctx)->howoften = howoften;
    2921:   return(0);
    2922: }

    2924: /*@C
    2925:    TaoMonitorDrawCtxDestroy - Destroys the monitor context for TaoMonitorDrawSolution()

    2927:    Collective on Tao

    2929:    Input Parameters:
    2930: .    ctx - the monitor context

    2932:    Level: intermediate

    2934: .seealso: TaoMonitorSet(), TaoMonitorDefault(), VecView(), TaoMonitorDrawSolution()
    2935: @*/
    2936: PetscErrorCode  TaoMonitorDrawCtxDestroy(TaoMonitorDrawCtx *ictx)
    2937: {

    2941:   PetscViewerDestroy(&(*ictx)->viewer);
    2942:   PetscFree(*ictx);
    2943:   return(0);
    2944: }