Actual source code: taosolver.c
petsc-3.10.5 2019-03-28
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_",0};

     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 on MPI_Comm

     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=0;
     70:   tao->ops->computeobjectiveandgradient=0;
     71:   tao->ops->computegradient=0;
     72:   tao->ops->computehessian=0;
     73:   tao->ops->computeseparableobjective=0;
     74:   tao->ops->computeconstraints=0;
     75:   tao->ops->computejacobian=0;
     76:   tao->ops->computejacobianequality=0;
     77:   tao->ops->computejacobianinequality=0;
     78:   tao->ops->computeequalityconstraints=0;
     79:   tao->ops->computeinequalityconstraints=0;
     80:   tao->ops->convergencetest=TaoDefaultConvergenceTest;
     81:   tao->ops->convergencedestroy=0;
     82:   tao->ops->computedual=0;
     83:   tao->ops->setup=0;
     84:   tao->ops->solve=0;
     85:   tao->ops->view=0;
     86:   tao->ops->setfromoptions=0;
     87:   tao->ops->destroy=0;

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

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

    148:   tao->numbermonitors=0;
    149:   tao->viewsolution=PETSC_FALSE;
    150:   tao->viewhessian=PETSC_FALSE;
    151:   tao->viewgradient=PETSC_FALSE;
    152:   tao->viewjacobian=PETSC_FALSE;
    153:   tao->viewconstraints = PETSC_FALSE;
    154:
    155:   tao->bounded = PETSC_FALSE;

    157:   /* These flags prevents algorithms from overriding user options */
    158:   tao->max_it_changed   =PETSC_FALSE;
    159:   tao->max_funcs_changed=PETSC_FALSE;
    160:   tao->gatol_changed    =PETSC_FALSE;
    161:   tao->grtol_changed    =PETSC_FALSE;
    162:   tao->gttol_changed    =PETSC_FALSE;
    163:   tao->steptol_changed  =PETSC_FALSE;
    164:   tao->trust0_changed   =PETSC_FALSE;
    165:   tao->fmin_changed     =PETSC_FALSE;
    166:   tao->catol_changed    =PETSC_FALSE;
    167:   tao->crtol_changed    =PETSC_FALSE;
    168:   TaoResetStatistics(tao);
    169:   *newtao = tao;
    170:   return(0);
    171: }

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

    176:   Collective on Tao

    178:   Input Parameters:
    179: . tao - the Tao context

    181:   Notes:
    182:   The user must set up the Tao with calls to TaoSetInitialVector(),
    183:   TaoSetObjectiveRoutine(),
    184:   TaoSetGradientRoutine(), and (if using 2nd order method) TaoSetHessianRoutine().

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

    189:   Level: beginner

    191: .seealso: TaoCreate(), TaoSetObjectiveRoutine(), TaoSetGradientRoutine(), TaoSetHessianRoutine(), TaoGetConvergedReason()
    192:  @*/
    193: PetscErrorCode TaoSolve(Tao tao)
    194: {
    195:   PetscErrorCode   ierr;
    196:   static PetscBool set = PETSC_FALSE;

    200:   PetscCitationsRegister("@TechReport{tao-user-ref,\n"
    201:                                 "title   = {Toolkit for Advanced Optimization (TAO) Users Manual},\n"
    202:                                 "author  = {Todd Munson and Jason Sarich and Stefan Wild and Steve Benson and Lois Curfman McInnes},\n"
    203:                                 "Institution = {Argonne National Laboratory},\n"
    204:                                 "Year   = 2014,\n"
    205:                                 "Number = {ANL/MCS-TM-322 - Revision 3.5},\n"
    206:                                 "url    = {http://www.mcs.anl.gov/tao}\n}\n",&set);

    208:   TaoSetUp(tao);
    209:   TaoResetStatistics(tao);
    210:   if (tao->linesearch) {
    211:     TaoLineSearchReset(tao->linesearch);
    212:   }

    214:   PetscLogEventBegin(TAO_Solve,tao,0,0,0);
    215:   if (tao->ops->solve){ (*tao->ops->solve)(tao); }
    216:   PetscLogEventEnd(TAO_Solve,tao,0,0,0);

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

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

    223:   if (tao->printreason) {
    224:     if (tao->reason > 0) {
    225:       PetscPrintf(((PetscObject)tao)->comm,"TAO solve converged due to %s iterations %D\n",TaoConvergedReasons[tao->reason],tao->niter);
    226:     } else {
    227:       PetscPrintf(((PetscObject)tao)->comm,"TAO solve did not converge due to %s iteration %D\n",TaoConvergedReasons[tao->reason],tao->niter);
    228:     }
    229:   }
    230:   return(0);
    231: }

    233: /*@
    234:   TaoSetUp - Sets up the internal data structures for the later use
    235:   of a Tao solver

    237:   Collective on tao

    239:   Input Parameters:
    240: . tao - the TAO context

    242:   Notes:
    243:   The user will not need to explicitly call TaoSetUp(), as it will
    244:   automatically be called in TaoSolve().  However, if the user
    245:   desires to call it explicitly, it should come after TaoCreate()
    246:   and any TaoSetSomething() routines, but before TaoSolve().

    248:   Level: advanced

    250: .seealso: TaoCreate(), TaoSolve()
    251: @*/
    252: PetscErrorCode TaoSetUp(Tao tao)
    253: {

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

    260:   if (!tao->solution) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TaoSetInitialVector");
    261:   if (tao->ops->setup) {
    262:     (*tao->ops->setup)(tao);
    263:   }
    264:   tao->setupcalled = PETSC_TRUE;
    265:   return(0);
    266: }

    268: /*@
    269:   TaoDestroy - Destroys the TAO context that was created with
    270:   TaoCreate()

    272:   Collective on Tao

    274:   Input Parameter:
    275: . tao - the Tao context

    277:   Level: beginner

    279: .seealso: TaoCreate(), TaoSolve()
    280: @*/
    281: PetscErrorCode TaoDestroy(Tao *tao)
    282: {

    286:   if (!*tao) return(0);
    288:   if (--((PetscObject)*tao)->refct > 0) {*tao=0;return(0);}

    290:   if ((*tao)->ops->destroy) {
    291:     (*((*tao))->ops->destroy)(*tao);
    292:   }
    293:   KSPDestroy(&(*tao)->ksp);
    294:   TaoLineSearchDestroy(&(*tao)->linesearch);

    296:   if ((*tao)->ops->convergencedestroy) {
    297:     (*(*tao)->ops->convergencedestroy)((*tao)->cnvP);
    298:     if ((*tao)->jacobian_state_inv) {
    299:       MatDestroy(&(*tao)->jacobian_state_inv);
    300:     }
    301:   }
    302:   VecDestroy(&(*tao)->solution);
    303:   VecDestroy(&(*tao)->gradient);

    305:   if ((*tao)->gradient_norm) {
    306:     PetscObjectDereference((PetscObject)(*tao)->gradient_norm);
    307:     VecDestroy(&(*tao)->gradient_norm_tmp);
    308:   }

    310:   VecDestroy(&(*tao)->XL);
    311:   VecDestroy(&(*tao)->XU);
    312:   VecDestroy(&(*tao)->IL);
    313:   VecDestroy(&(*tao)->IU);
    314:   VecDestroy(&(*tao)->DE);
    315:   VecDestroy(&(*tao)->DI);
    316:   VecDestroy(&(*tao)->constraints_equality);
    317:   VecDestroy(&(*tao)->constraints_inequality);
    318:   VecDestroy(&(*tao)->stepdirection);
    319:   MatDestroy(&(*tao)->hessian_pre);
    320:   MatDestroy(&(*tao)->hessian);
    321:   MatDestroy(&(*tao)->jacobian_pre);
    322:   MatDestroy(&(*tao)->jacobian);
    323:   MatDestroy(&(*tao)->jacobian_state_pre);
    324:   MatDestroy(&(*tao)->jacobian_state);
    325:   MatDestroy(&(*tao)->jacobian_state_inv);
    326:   MatDestroy(&(*tao)->jacobian_design);
    327:   MatDestroy(&(*tao)->jacobian_equality);
    328:   MatDestroy(&(*tao)->jacobian_equality_pre);
    329:   MatDestroy(&(*tao)->jacobian_inequality);
    330:   MatDestroy(&(*tao)->jacobian_inequality_pre);
    331:   ISDestroy(&(*tao)->state_is);
    332:   ISDestroy(&(*tao)->design_is);
    333:   VecDestroy(&(*tao)->sep_weights_v);
    334:   TaoCancelMonitors(*tao);
    335:   if ((*tao)->hist_malloc) {
    336:     PetscFree((*tao)->hist_obj);
    337:     PetscFree((*tao)->hist_resid);
    338:     PetscFree((*tao)->hist_cnorm);
    339:     PetscFree((*tao)->hist_lits);
    340:   }
    341:   if ((*tao)->sep_weights_n) {
    342:     PetscFree((*tao)->sep_weights_rows);
    343:     PetscFree((*tao)->sep_weights_cols);
    344:     PetscFree((*tao)->sep_weights_w);
    345:   }
    346:   PetscHeaderDestroy(tao);
    347:   return(0);
    348: }

    350: /*@
    351:   TaoSetFromOptions - Sets various Tao parameters from user
    352:   options.

    354:   Collective on Tao

    356:   Input Paremeter:
    357: . tao - the Tao solver context

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

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

    390:   Level: beginner
    391: @*/
    392: PetscErrorCode TaoSetFromOptions(Tao tao)
    393: {
    395:   TaoType        default_type = TAOLMVM;
    396:   char           type[256], monfilename[PETSC_MAX_PATH_LEN];
    397:   PetscViewer    monviewer;
    398:   PetscBool      flg;
    399:   MPI_Comm       comm;

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

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

    408:   PetscObjectOptionsBegin((PetscObject)tao);
    409:   {
    410:     TaoRegisterAll();
    411:     if (((PetscObject)tao)->type_name) {
    412:       default_type = ((PetscObject)tao)->type_name;
    413:     }
    414:     /* Check for type from options */
    415:     PetscOptionsFList("-tao_type","Tao Solver type","TaoSetType",TaoList,default_type,type,256,&flg);
    416:     if (flg) {
    417:       TaoSetType(tao,type);
    418:     } else if (!((PetscObject)tao)->type_name) {
    419:       TaoSetType(tao,default_type);
    420:     }

    422:     PetscOptionsReal("-tao_catol","Stop if constraints violations within","TaoSetConstraintTolerances",tao->catol,&tao->catol,&flg);
    423:     if (flg) tao->catol_changed=PETSC_TRUE;
    424:     PetscOptionsReal("-tao_crtol","Stop if relative contraint violations within","TaoSetConstraintTolerances",tao->crtol,&tao->crtol,&flg);
    425:     if (flg) tao->crtol_changed=PETSC_TRUE;
    426:     PetscOptionsReal("-tao_gatol","Stop if norm of gradient less than","TaoSetTolerances",tao->gatol,&tao->gatol,&flg);
    427:     if (flg) tao->gatol_changed=PETSC_TRUE;
    428:     PetscOptionsReal("-tao_grtol","Stop if norm of gradient divided by the function value is less than","TaoSetTolerances",tao->grtol,&tao->grtol,&flg);
    429:     if (flg) tao->grtol_changed=PETSC_TRUE;
    430:     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);
    431:     if (flg) tao->gttol_changed=PETSC_TRUE;
    432:     PetscOptionsInt("-tao_max_it","Stop if iteration number exceeds","TaoSetMaximumIterations",tao->max_it,&tao->max_it,&flg);
    433:     if (flg) tao->max_it_changed=PETSC_TRUE;
    434:     PetscOptionsInt("-tao_max_funcs","Stop if number of function evaluations exceeds","TaoSetMaximumFunctionEvaluations",tao->max_funcs,&tao->max_funcs,&flg);
    435:     if (flg) tao->max_funcs_changed=PETSC_TRUE;
    436:     PetscOptionsReal("-tao_fmin","Stop if function less than","TaoSetFunctionLowerBound",tao->fmin,&tao->fmin,&flg);
    437:     if (flg) tao->fmin_changed=PETSC_TRUE;
    438:     PetscOptionsReal("-tao_steptol","Stop if step size or trust region radius less than","",tao->steptol,&tao->steptol,&flg);
    439:     if (flg) tao->steptol_changed=PETSC_TRUE;
    440:     PetscOptionsReal("-tao_trust0","Initial trust region radius","TaoSetTrustRegionRadius",tao->trust0,&tao->trust0,&flg);
    441:     if (flg) tao->trust0_changed=PETSC_TRUE;
    442:     PetscOptionsString("-tao_view_solution","view solution vector after each evaluation","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
    443:     if (flg) {
    444:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    445:       TaoSetMonitor(tao,TaoSolutionMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    446:     }

    448:     PetscOptionsBool("-tao_converged_reason","Print reason for TAO converged","TaoSolve",tao->printreason,&tao->printreason,NULL);
    449:     PetscOptionsString("-tao_view_gradient","view gradient vector after each evaluation","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
    450:     if (flg) {
    451:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    452:       TaoSetMonitor(tao,TaoGradientMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    453:     }

    455:     PetscOptionsString("-tao_view_stepdirection","view step direction vector after each iteration","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
    456:     if (flg) {
    457:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    458:       TaoSetMonitor(tao,TaoStepDirectionMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    459:     }

    461:     PetscOptionsString("-tao_view_separableobjective","view separable objective vector after each evaluation","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
    462:     if (flg) {
    463:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    464:       TaoSetMonitor(tao,TaoSeparableObjectiveMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    465:     }

    467:     PetscOptionsString("-tao_monitor","Use the default convergence monitor","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
    468:     if (flg) {
    469:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    470:       TaoSetMonitor(tao,TaoMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    471:     }

    473:     PetscOptionsString("-tao_gmonitor","Use the convergence monitor with extra globalization info","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
    474:     if (flg) {
    475:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    476:       TaoSetMonitor(tao,TaoDefaultGMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    477:     }

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

    485:     PetscOptionsString("-tao_cmonitor","Use the default convergence monitor with constraint norm","TaoSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
    486:     if (flg) {
    487:       PetscViewerASCIIOpen(comm,monfilename,&monviewer);
    488:       TaoSetMonitor(tao,TaoDefaultCMonitor,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    489:     }

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

    496:     flg = PETSC_FALSE;
    497:     PetscOptionsBool("-tao_draw_solution","Plot solution vector at each iteration","TaoSetMonitor",flg,&flg,NULL);
    498:     if (flg) {
    499:       TaoMonitorDrawCtx drawctx;
    500:       PetscInt          howoften = 1;
    501:       TaoMonitorDrawCtxCreate(PetscObjectComm((PetscObject)tao),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&drawctx);
    502:       TaoSetMonitor(tao,TaoDrawSolutionMonitor,drawctx,(PetscErrorCode (*)(void**))TaoMonitorDrawCtxDestroy);
    503:     }

    505:     flg = PETSC_FALSE;
    506:     PetscOptionsBool("-tao_draw_step","plots step direction at each iteration","TaoSetMonitor",flg,&flg,NULL);
    507:     if (flg) {
    508:       TaoSetMonitor(tao,TaoDrawStepMonitor,NULL,NULL);
    509:     }

    511:     flg = PETSC_FALSE;
    512:     PetscOptionsBool("-tao_draw_gradient","plots gradient at each iteration","TaoSetMonitor",flg,&flg,NULL);
    513:     if (flg) {
    514:       TaoMonitorDrawCtx drawctx;
    515:       PetscInt          howoften = 1;
    516:       TaoMonitorDrawCtxCreate(PetscObjectComm((PetscObject)tao),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&drawctx);
    517:       TaoSetMonitor(tao,TaoDrawGradientMonitor,drawctx,(PetscErrorCode (*)(void**))TaoMonitorDrawCtxDestroy);
    518:     }
    519:     flg = PETSC_FALSE;
    520:     PetscOptionsBool("-tao_fd_gradient","compute gradient using finite differences","TaoDefaultComputeGradient",flg,&flg,NULL);
    521:     if (flg) {
    522:       TaoSetGradientRoutine(tao,TaoDefaultComputeGradient,NULL);
    523:     }
    524:     flg = PETSC_FALSE;
    525:     PetscOptionsBool("-tao_fd_hessian","compute hessian using finite differences","TaoDefaultComputeHessian",flg,&flg,NULL);
    526:     if (flg) {
    527:       Mat H;

    529:       MatCreate(PetscObjectComm((PetscObject)tao),&H);
    530:       MatSetType(H,MATAIJ);
    531:       TaoSetHessianRoutine(tao,H,H,TaoDefaultComputeHessian,NULL);
    532:       MatDestroy(&H);
    533:     }
    534:     flg = PETSC_FALSE;
    535:     PetscOptionsBool("-tao_mf_hessian","compute matrix-free hessian using finite differences","TaoDefaultComputeHessianMFFD",flg,&flg,NULL);
    536:     if (flg) {
    537:       Mat H;

    539:       MatCreate(PetscObjectComm((PetscObject)tao),&H);
    540:       TaoSetHessianRoutine(tao,H,H,TaoDefaultComputeHessianMFFD,NULL);
    541:       MatDestroy(&H);
    542:     }
    543:     PetscOptionsEnum("-tao_subset_type","subset type","",TaoSubSetTypes,(PetscEnum)tao->subset_type,(PetscEnum*)&tao->subset_type,NULL);

    545:     if (tao->ops->setfromoptions) {
    546:       (*tao->ops->setfromoptions)(PetscOptionsObject,tao);
    547:     }
    548:   }
    549:   PetscOptionsEnd();
    550:   return(0);
    551: }

    553: /*@C
    554:   TaoView - Prints information about the Tao

    556:   Collective on Tao

    558:   InputParameters:
    559: + tao - the Tao context
    560: - viewer - visualization context

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

    565:   Notes:
    566:   The available visualization contexts include
    567: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    568: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    569:          output where only the first processor opens
    570:          the file.  All other processors send their
    571:          data to the first processor to print.

    573:   Level: beginner

    575: .seealso: PetscViewerASCIIOpen()
    576: @*/
    577: PetscErrorCode TaoView(Tao tao, PetscViewer viewer)
    578: {
    579:   PetscErrorCode      ierr;
    580:   PetscBool           isascii,isstring;
    581:   TaoType             type;

    585:   if (!viewer) {
    586:     PetscViewerASCIIGetStdout(((PetscObject)tao)->comm,&viewer);
    587:   }

    591:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    592:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
    593:   if (isascii) {
    594:     PetscObjectPrintClassNamePrefixType((PetscObject)tao,viewer);

    596:     if (tao->ops->view) {
    597:       PetscViewerASCIIPushTab(viewer);
    598:       (*tao->ops->view)(tao,viewer);
    599:       PetscViewerASCIIPopTab(viewer);
    600:     }
    601:     if (tao->linesearch) {
    602:       PetscViewerASCIIPushTab(viewer);
    603:       TaoLineSearchView(tao->linesearch,viewer);
    604:       PetscViewerASCIIPopTab(viewer);
    605:     }
    606:     if (tao->ksp) {
    607:       PetscViewerASCIIPushTab(viewer);
    608:       KSPView(tao->ksp,viewer);
    609:       PetscViewerASCIIPrintf(viewer,"total KSP iterations: %D\n",tao->ksp_tot_its);
    610:       PetscViewerASCIIPopTab(viewer);
    611:     }

    613:     PetscViewerASCIIPushTab(viewer);

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

    619:     PetscViewerASCIIPrintf(viewer,"convergence tolerances: gatol=%g,",(double)tao->gatol);
    620:     PetscViewerASCIIPrintf(viewer," steptol=%g,",(double)tao->steptol);
    621:     PetscViewerASCIIPrintf(viewer," gttol=%g\n",(double)tao->gttol);
    622:     PetscViewerASCIIPrintf(viewer,"Residual in Function/Gradient:=%g\n",(double)tao->residual);

    624:     if (tao->cnorm>0 || tao->catol>0 || tao->crtol>0){
    625:       ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances:");
    626:       ierr=PetscViewerASCIIPrintf(viewer," catol=%g,",(double)tao->catol);
    627:       ierr=PetscViewerASCIIPrintf(viewer," crtol=%g\n",(double)tao->crtol);
    628:       PetscViewerASCIIPrintf(viewer,"Residual in Constraints:=%g\n",(double)tao->cnorm);
    629:     }

    631:     if (tao->trust < tao->steptol){
    632:       ierr=PetscViewerASCIIPrintf(viewer,"convergence tolerances: steptol=%g\n",(double)tao->steptol);
    633:       ierr=PetscViewerASCIIPrintf(viewer,"Final trust region radius:=%g\n",(double)tao->trust);
    634:     }

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

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

    644:     if (tao->nfuncs>0){
    645:       PetscViewerASCIIPrintf(viewer,"total number of function evaluations=%D,",tao->nfuncs);
    646:       PetscViewerASCIIPrintf(viewer,"                max: %D\n",tao->max_funcs);
    647:     }
    648:     if (tao->ngrads>0){
    649:       PetscViewerASCIIPrintf(viewer,"total number of gradient evaluations=%D,",tao->ngrads);
    650:       PetscViewerASCIIPrintf(viewer,"                max: %D\n",tao->max_funcs);
    651:     }
    652:     if (tao->nfuncgrads>0){
    653:       PetscViewerASCIIPrintf(viewer,"total number of function/gradient evaluations=%D,",tao->nfuncgrads);
    654:       PetscViewerASCIIPrintf(viewer,"    (max: %D)\n",tao->max_funcs);
    655:     }
    656:     if (tao->nhess>0){
    657:       PetscViewerASCIIPrintf(viewer,"total number of Hessian evaluations=%D\n",tao->nhess);
    658:     }
    659:     /*  if (tao->linear_its>0){
    660:      PetscViewerASCIIPrintf(viewer,"  total Krylov method iterations=%D\n",tao->linear_its);
    661:      }*/
    662:     if (tao->nconstraints>0){
    663:       PetscViewerASCIIPrintf(viewer,"total number of constraint function evaluations=%D\n",tao->nconstraints);
    664:     }
    665:     if (tao->njac>0){
    666:       PetscViewerASCIIPrintf(viewer,"total number of Jacobian evaluations=%D\n",tao->njac);
    667:     }

    669:     if (tao->reason>0){
    670:       PetscViewerASCIIPrintf(viewer,    "Solution converged: ");
    671:       switch (tao->reason) {
    672:       case TAO_CONVERGED_GATOL:
    673:         PetscViewerASCIIPrintf(viewer," ||g(X)|| <= gatol\n");
    674:         break;
    675:       case TAO_CONVERGED_GRTOL:
    676:         PetscViewerASCIIPrintf(viewer," ||g(X)||/|f(X)| <= grtol\n");
    677:         break;
    678:       case TAO_CONVERGED_GTTOL:
    679:         PetscViewerASCIIPrintf(viewer," ||g(X)||/||g(X0)|| <= gttol\n");
    680:         break;
    681:       case TAO_CONVERGED_STEPTOL:
    682:         PetscViewerASCIIPrintf(viewer," Steptol -- step size small\n");
    683:         break;
    684:       case TAO_CONVERGED_MINF:
    685:         PetscViewerASCIIPrintf(viewer," Minf --  f < fmin\n");
    686:         break;
    687:       case TAO_CONVERGED_USER:
    688:         PetscViewerASCIIPrintf(viewer," User Terminated\n");
    689:         break;
    690:       default:
    691:         PetscViewerASCIIPrintf(viewer,"\n");
    692:         break;
    693:       }

    695:     } else {
    696:       PetscViewerASCIIPrintf(viewer,"Solver terminated: %d",tao->reason);
    697:       switch (tao->reason) {
    698:       case TAO_DIVERGED_MAXITS:
    699:         PetscViewerASCIIPrintf(viewer," Maximum Iterations\n");
    700:         break;
    701:       case TAO_DIVERGED_NAN:
    702:         PetscViewerASCIIPrintf(viewer," NAN or Inf encountered\n");
    703:         break;
    704:       case TAO_DIVERGED_MAXFCN:
    705:         PetscViewerASCIIPrintf(viewer," Maximum Function Evaluations\n");
    706:         break;
    707:       case TAO_DIVERGED_LS_FAILURE:
    708:         PetscViewerASCIIPrintf(viewer," Line Search Failure\n");
    709:         break;
    710:       case TAO_DIVERGED_TR_REDUCTION:
    711:         PetscViewerASCIIPrintf(viewer," Trust Region too small\n");
    712:         break;
    713:       case TAO_DIVERGED_USER:
    714:         PetscViewerASCIIPrintf(viewer," User Terminated\n");
    715:         break;
    716:       default:
    717:         PetscViewerASCIIPrintf(viewer,"\n");
    718:         break;
    719:       }
    720:     }
    721:     PetscViewerASCIIPopTab(viewer);
    722:   } else if (isstring) {
    723:     TaoGetType(tao,&type);
    724:     PetscViewerStringSPrintf(viewer," %-3.3s",type);
    725:   }
    726:   return(0);
    727: }

    729: /*@
    730:   TaoSetTolerances - Sets parameters used in TAO convergence tests

    732:   Logically collective on Tao

    734:   Input Parameters:
    735: + tao - the Tao context
    736: . gatol - stop if norm of gradient is less than this
    737: . grtol - stop if relative norm of gradient is less than this
    738: - gttol - stop if norm of gradient is reduced by this factor

    740:   Options Database Keys:
    741: + -tao_gatol <gatol> - Sets gatol
    742: . -tao_grtol <grtol> - Sets grtol
    743: - -tao_gttol <gttol> - Sets gttol

    745:   Stopping Criteria:
    746: $ ||g(X)||                            <= gatol
    747: $ ||g(X)|| / |f(X)|                   <= grtol
    748: $ ||g(X)|| / ||g(X0)||                <= gttol

    750:   Notes:
    751:   Use PETSC_DEFAULT to leave one or more tolerances unchanged.

    753:   Level: beginner

    755: .seealso: TaoGetTolerances()

    757: @*/
    758: PetscErrorCode TaoSetTolerances(Tao tao, PetscReal gatol, PetscReal grtol, PetscReal gttol)
    759: {

    765:   if (gatol != PETSC_DEFAULT) {
    766:     if (gatol<0) {
    767:       PetscInfo(tao,"Tried to set negative gatol -- ignored.\n");
    768:     } else {
    769:       tao->gatol = PetscMax(0,gatol);
    770:       tao->gatol_changed=PETSC_TRUE;
    771:     }
    772:   }

    774:   if (grtol != PETSC_DEFAULT) {
    775:     if (grtol<0) {
    776:       PetscInfo(tao,"Tried to set negative grtol -- ignored.\n");
    777:     } else {
    778:       tao->grtol = PetscMax(0,grtol);
    779:       tao->grtol_changed=PETSC_TRUE;
    780:     }
    781:   }

    783:   if (gttol != PETSC_DEFAULT) {
    784:     if (gttol<0) {
    785:       PetscInfo(tao,"Tried to set negative gttol -- ignored.\n");
    786:     } else {
    787:       tao->gttol = PetscMax(0,gttol);
    788:       tao->gttol_changed=PETSC_TRUE;
    789:     }
    790:   }
    791:   return(0);
    792: }

    794: /*@
    795:   TaoSetConstraintTolerances - Sets constraint tolerance parameters used in TAO  convergence tests

    797:   Logically collective on Tao

    799:   Input Parameters:
    800: + tao - the Tao context
    801: . catol - absolute constraint tolerance, constraint norm must be less than catol for used for gatol convergence criteria
    802: - crtol - relative contraint tolerance, constraint norm must be less than crtol for used for gatol, gttol convergence criteria

    804:   Options Database Keys:
    805: + -tao_catol <catol> - Sets catol
    806: - -tao_crtol <crtol> - Sets crtol

    808:   Notes:
    809:   Use PETSC_DEFAULT to leave any tolerance unchanged.

    811:   Level: intermediate

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

    815: @*/
    816: PetscErrorCode TaoSetConstraintTolerances(Tao tao, PetscReal catol, PetscReal crtol)
    817: {

    823:   if (catol != PETSC_DEFAULT) {
    824:     if (catol<0) {
    825:       PetscInfo(tao,"Tried to set negative catol -- ignored.\n");
    826:     } else {
    827:       tao->catol = PetscMax(0,catol);
    828:       tao->catol_changed=PETSC_TRUE;
    829:     }
    830:   }

    832:   if (crtol != PETSC_DEFAULT) {
    833:     if (crtol<0) {
    834:       PetscInfo(tao,"Tried to set negative crtol -- ignored.\n");
    835:     } else {
    836:       tao->crtol = PetscMax(0,crtol);
    837:       tao->crtol_changed=PETSC_TRUE;
    838:     }
    839:   }
    840:   return(0);
    841: }

    843: /*@
    844:   TaoGetConstraintTolerances - Gets constraint tolerance parameters used in TAO  convergence tests

    846:   Not ollective

    848:   Input Parameter:
    849: . tao - the Tao context

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

    855:   Level: intermediate

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

    859: @*/
    860: PetscErrorCode TaoGetConstraintTolerances(Tao tao, PetscReal *catol, PetscReal *crtol)
    861: {
    864:   if (catol) *catol = tao->catol;
    865:   if (crtol) *crtol = tao->crtol;
    866:   return(0);
    867: }

    869: /*@
    870:    TaoSetFunctionLowerBound - Sets a bound on the solution objective value.
    871:    When an approximate solution with an objective value below this number
    872:    has been found, the solver will terminate.

    874:    Logically Collective on Tao

    876:    Input Parameters:
    877: +  tao - the Tao solver context
    878: -  fmin - the tolerance

    880:    Options Database Keys:
    881: .    -tao_fmin <fmin> - sets the minimum function value

    883:    Level: intermediate

    885: .seealso: TaoSetTolerances()
    886: @*/
    887: PetscErrorCode TaoSetFunctionLowerBound(Tao tao,PetscReal fmin)
    888: {
    891:   tao->fmin = fmin;
    892:   tao->fmin_changed=PETSC_TRUE;
    893:   return(0);
    894: }

    896: /*@
    897:    TaoGetFunctionLowerBound - Gets the bound on the solution objective value.
    898:    When an approximate solution with an objective value below this number
    899:    has been found, the solver will terminate.

    901:    Not collective on Tao

    903:    Input Parameters:
    904: .  tao - the Tao solver context

    906:    OutputParameters:
    907: .  fmin - the minimum function value

    909:    Level: intermediate

    911: .seealso: TaoSetFunctionLowerBound()
    912: @*/
    913: PetscErrorCode TaoGetFunctionLowerBound(Tao tao,PetscReal *fmin)
    914: {
    917:   *fmin = tao->fmin;
    918:   return(0);
    919: }

    921: /*@
    922:    TaoSetMaximumFunctionEvaluations - Sets a maximum number of
    923:    function evaluations.

    925:    Logically Collective on Tao

    927:    Input Parameters:
    928: +  tao - the Tao solver context
    929: -  nfcn - the maximum number of function evaluations (>=0)

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

    934:    Level: intermediate

    936: .seealso: TaoSetTolerances(), TaoSetMaximumIterations()
    937: @*/

    939: PetscErrorCode TaoSetMaximumFunctionEvaluations(Tao tao,PetscInt nfcn)
    940: {
    943:   tao->max_funcs = PetscMax(0,nfcn);
    944:   tao->max_funcs_changed=PETSC_TRUE;
    945:   return(0);
    946: }

    948: /*@
    949:    TaoGetMaximumFunctionEvaluations - Sets a maximum number of
    950:    function evaluations.

    952:    Not Collective

    954:    Input Parameters:
    955: .  tao - the Tao solver context

    957:    Output Parameters:
    958: .  nfcn - the maximum number of function evaluations

    960:    Level: intermediate

    962: .seealso: TaoSetMaximumFunctionEvaluations(), TaoGetMaximumIterations()
    963: @*/

    965: PetscErrorCode TaoGetMaximumFunctionEvaluations(Tao tao,PetscInt *nfcn)
    966: {
    969:   *nfcn = tao->max_funcs;
    970:   return(0);
    971: }

    973: /*@
    974:    TaoGetCurrentFunctionEvaluations - Get current number of
    975:    function evaluations.

    977:    Not Collective

    979:    Input Parameters:
    980: .  tao - the Tao solver context

    982:    Output Parameters:
    983: .  nfuncs - the current number of function evaluations

    985:    Level: intermediate

    987: .seealso: TaoSetMaximumFunctionEvaluations(), TaoGetMaximumFunctionEvaluations(), TaoGetMaximumIterations()
    988: @*/

    990: PetscErrorCode TaoGetCurrentFunctionEvaluations(Tao tao,PetscInt *nfuncs)
    991: {
    994:   *nfuncs=PetscMax(tao->nfuncs,tao->nfuncgrads);
    995:   return(0);
    996: }

    998: /*@
    999:    TaoSetMaximumIterations - Sets a maximum number of iterates.

    1001:    Logically Collective on Tao

    1003:    Input Parameters:
    1004: +  tao - the Tao solver context
    1005: -  maxits - the maximum number of iterates (>=0)

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

    1010:    Level: intermediate

    1012: .seealso: TaoSetTolerances(), TaoSetMaximumFunctionEvaluations()
    1013: @*/
    1014: PetscErrorCode TaoSetMaximumIterations(Tao tao,PetscInt maxits)
    1015: {
    1018:   tao->max_it = PetscMax(0,maxits);
    1019:   tao->max_it_changed=PETSC_TRUE;
    1020:   return(0);
    1021: }

    1023: /*@
    1024:    TaoGetMaximumIterations - Sets a maximum number of iterates.

    1026:    Not Collective

    1028:    Input Parameters:
    1029: .  tao - the Tao solver context

    1031:    Output Parameters:
    1032: .  maxits - the maximum number of iterates

    1034:    Level: intermediate

    1036: .seealso: TaoSetMaximumIterations(), TaoGetMaximumFunctionEvaluations()
    1037: @*/
    1038: PetscErrorCode TaoGetMaximumIterations(Tao tao,PetscInt *maxits)
    1039: {
    1042:   *maxits = tao->max_it;
    1043:   return(0);
    1044: }

    1046: /*@
    1047:    TaoSetInitialTrustRegionRadius - Sets the initial trust region radius.

    1049:    Logically collective on Tao

    1051:    Input Parameter:
    1052: +  tao - a TAO optimization solver
    1053: -  radius - the trust region radius

    1055:    Level: intermediate

    1057:    Options Database Key:
    1058: .  -tao_trust0 <t0> - sets initial trust region radius

    1060: .seealso: TaoGetTrustRegionRadius(), TaoSetTrustRegionTolerance()
    1061: @*/
    1062: PetscErrorCode TaoSetInitialTrustRegionRadius(Tao tao, PetscReal radius)
    1063: {
    1066:   tao->trust0 = PetscMax(0.0,radius);
    1067:   tao->trust0_changed=PETSC_TRUE;
    1068:   return(0);
    1069: }

    1071: /*@
    1072:    TaoGetInitialTrustRegionRadius - Sets the initial trust region radius.

    1074:    Not Collective

    1076:    Input Parameter:
    1077: .  tao - a TAO optimization solver

    1079:    Output Parameter:
    1080: .  radius - the trust region radius

    1082:    Level: intermediate

    1084: .seealso: TaoSetInitialTrustRegionRadius(), TaoGetCurrentTrustRegionRadius()
    1085: @*/
    1086: PetscErrorCode TaoGetInitialTrustRegionRadius(Tao tao, PetscReal *radius)
    1087: {
    1090:   *radius = tao->trust0;
    1091:   return(0);
    1092: }

    1094: /*@
    1095:    TaoGetCurrentTrustRegionRadius - Gets the current trust region radius.

    1097:    Not Collective

    1099:    Input Parameter:
    1100: .  tao - a TAO optimization solver

    1102:    Output Parameter:
    1103: .  radius - the trust region radius

    1105:    Level: intermediate

    1107: .seealso: TaoSetInitialTrustRegionRadius(), TaoGetInitialTrustRegionRadius()
    1108: @*/
    1109: PetscErrorCode TaoGetCurrentTrustRegionRadius(Tao tao, PetscReal *radius)
    1110: {
    1113:   *radius = tao->trust;
    1114:   return(0);
    1115: }

    1117: /*@
    1118:   TaoGetTolerances - gets the current values of tolerances

    1120:   Not Collective

    1122:   Input Parameters:
    1123: . tao - the Tao context

    1125:   Output Parameters:
    1126: + gatol - stop if norm of gradient is less than this
    1127: . grtol - stop if relative norm of gradient is less than this
    1128: - gttol - stop if norm of gradient is reduced by a this factor

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

    1132: .seealso TaoSetTolerances()

    1134:   Level: intermediate
    1135: @*/
    1136: PetscErrorCode TaoGetTolerances(Tao tao, PetscReal *gatol, PetscReal *grtol, PetscReal *gttol)
    1137: {
    1140:   if (gatol) *gatol=tao->gatol;
    1141:   if (grtol) *grtol=tao->grtol;
    1142:   if (gttol) *gttol=tao->gttol;
    1143:   return(0);
    1144: }

    1146: /*@
    1147:   TaoGetKSP - Gets the linear solver used by the optimization solver.
    1148:   Application writers should use TaoGetKSP if they need direct access
    1149:   to the PETSc KSP object.

    1151:   Not Collective

    1153:    Input Parameters:
    1154: .  tao - the TAO solver

    1156:    Output Parameters:
    1157: .  ksp - the KSP linear solver used in the optimization solver

    1159:    Level: intermediate

    1161: @*/
    1162: PetscErrorCode TaoGetKSP(Tao tao, KSP *ksp)
    1163: {
    1165:   *ksp = tao->ksp;
    1166:   return(0);
    1167: }

    1169: /*@
    1170:    TaoGetLinearSolveIterations - Gets the total number of linear iterations
    1171:    used by the TAO solver

    1173:    Not Collective

    1175:    Input Parameter:
    1176: .  tao - TAO context

    1178:    Output Parameter:
    1179: .  lits - number of linear iterations

    1181:    Notes:
    1182:    This counter is reset to zero for each successive call to TaoSolve()

    1184:    Level: intermediate

    1186: .keywords: TAO

    1188: .seealso:  TaoGetKSP()
    1189: @*/
    1190: PetscErrorCode  TaoGetLinearSolveIterations(Tao tao,PetscInt *lits)
    1191: {
    1195:   *lits = tao->ksp_tot_its;
    1196:   return(0);
    1197: }

    1199: /*@
    1200:   TaoGetLineSearch - Gets the line search used by the optimization solver.
    1201:   Application writers should use TaoGetLineSearch if they need direct access
    1202:   to the TaoLineSearch object.

    1204:   Not Collective

    1206:    Input Parameters:
    1207: .  tao - the TAO solver

    1209:    Output Parameters:
    1210: .  ls - the line search used in the optimization solver

    1212:    Level: intermediate

    1214: @*/
    1215: PetscErrorCode TaoGetLineSearch(Tao tao, TaoLineSearch *ls)
    1216: {
    1218:   *ls = tao->linesearch;
    1219:   return(0);
    1220: }

    1222: /*@
    1223:   TaoAddLineSearchCounts - Adds the number of function evaluations spent
    1224:   in the line search to the running total.

    1226:    Input Parameters:
    1227: +  tao - the TAO solver
    1228: -  ls - the line search used in the optimization solver

    1230:    Level: developer

    1232: .seealso: TaoLineSearchApply()
    1233: @*/
    1234: PetscErrorCode TaoAddLineSearchCounts(Tao tao)
    1235: {
    1237:   PetscBool      flg;
    1238:   PetscInt       nfeval,ngeval,nfgeval;

    1242:   if (tao->linesearch) {
    1243:     TaoLineSearchIsUsingTaoRoutines(tao->linesearch,&flg);
    1244:     if (!flg) {
    1245:       TaoLineSearchGetNumberFunctionEvaluations(tao->linesearch,&nfeval,&ngeval,&nfgeval);
    1246:       tao->nfuncs+=nfeval;
    1247:       tao->ngrads+=ngeval;
    1248:       tao->nfuncgrads+=nfgeval;
    1249:     }
    1250:   }
    1251:   return(0);
    1252: }

    1254: /*@
    1255:   TaoGetSolutionVector - Returns the vector with the current TAO solution

    1257:   Not Collective

    1259:   Input Parameter:
    1260: . tao - the Tao context

    1262:   Output Parameter:
    1263: . X - the current solution

    1265:   Level: intermediate

    1267:   Note:  The returned vector will be the same object that was passed into TaoSetInitialVector()
    1268: @*/
    1269: PetscErrorCode TaoGetSolutionVector(Tao tao, Vec *X)
    1270: {
    1273:   *X = tao->solution;
    1274:   return(0);
    1275: }

    1277: /*@
    1278:   TaoGetGradientVector - Returns the vector with the current TAO gradient

    1280:   Not Collective

    1282:   Input Parameter:
    1283: . tao - the Tao context

    1285:   Output Parameter:
    1286: . G - the current solution

    1288:   Level: intermediate
    1289: @*/
    1290: PetscErrorCode TaoGetGradientVector(Tao tao, Vec *G)
    1291: {
    1294:   *G = tao->gradient;
    1295:   return(0);
    1296: }

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

    1303:    Collective on Tao

    1305:    Input Parameters:
    1306: .  solver - the Tao context

    1308:    Level: developer

    1310: .seealso: TaoCreate(), TaoSolve()
    1311: @*/
    1312: PetscErrorCode TaoResetStatistics(Tao tao)
    1313: {
    1316:   tao->niter        = 0;
    1317:   tao->nfuncs       = 0;
    1318:   tao->nfuncgrads   = 0;
    1319:   tao->ngrads       = 0;
    1320:   tao->nhess        = 0;
    1321:   tao->njac         = 0;
    1322:   tao->nconstraints = 0;
    1323:   tao->ksp_its      = 0;
    1324:   tao->ksp_tot_its  = 0;
    1325:   tao->reason       = TAO_CONTINUE_ITERATING;
    1326:   tao->residual     = 0.0;
    1327:   tao->cnorm        = 0.0;
    1328:   tao->step         = 0.0;
    1329:   tao->lsflag       = PETSC_FALSE;
    1330:   if (tao->hist_reset) tao->hist_len=0;
    1331:   return(0);
    1332: }

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

    1339:   Logically Collective on Tao

    1341:   Input Parameters:
    1342: + tao - the Tao object
    1343: . conv - the routine to test for convergence
    1344: - ctx - [optional] context for private data for the convergence routine
    1345:         (may be NULL)

    1347:   Calling sequence of conv:
    1348: $   PetscErrorCode conv(Tao tao, void *ctx)

    1350: + tao - the Tao object
    1351: - ctx - [optional] convergence context

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

    1355:   Level: advanced

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

    1359: @*/
    1360: PetscErrorCode TaoSetConvergenceTest(Tao tao, PetscErrorCode (*conv)(Tao,void*), void *ctx)
    1361: {
    1364:   (tao)->ops->convergencetest = conv;
    1365:   (tao)->cnvP = ctx;
    1366:   return(0);
    1367: }

    1369: /*@C
    1370:    TaoSetMonitor - Sets an ADDITIONAL function that is to be used at every
    1371:    iteration of the solver to display the iteration's
    1372:    progress.

    1374:    Logically Collective on Tao

    1376:    Input Parameters:
    1377: +  tao - the Tao solver context
    1378: .  mymonitor - monitoring routine
    1379: -  mctx - [optional] user-defined context for private data for the
    1380:           monitor routine (may be NULL)

    1382:    Calling sequence of mymonitor:
    1383: $     int mymonitor(Tao tao,void *mctx)

    1385: +    tao - the Tao solver context
    1386: -    mctx - [optional] monitoring context

    1389:    Options Database Keys:
    1390: +    -tao_monitor        - sets TaoMonitorDefault()
    1391: .    -tao_smonitor       - sets short monitor
    1392: .    -tao_cmonitor       - same as smonitor plus constraint norm
    1393: .    -tao_view_solution   - view solution at each iteration
    1394: .    -tao_view_gradient   - view gradient at each iteration
    1395: .    -tao_view_separableobjective - view separable objective function at each iteration
    1396: -    -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.

    1399:    Notes:
    1400:    Several different monitoring routines may be set by calling
    1401:    TaoSetMonitor() multiple times; all will be called in the
    1402:    order in which they were set.

    1404:    Fortran Notes:
    1405:     Only one monitor function may be set

    1407:    Level: intermediate

    1409: .seealso: TaoMonitorDefault(), TaoCancelMonitors(),  TaoSetDestroyRoutine()
    1410: @*/
    1411: PetscErrorCode TaoSetMonitor(Tao tao, PetscErrorCode (*func)(Tao, void*), void *ctx,PetscErrorCode (*dest)(void**))
    1412: {
    1414:   PetscInt       i;
    1415:   PetscBool      identical;

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

    1421:   for (i=0; i<tao->numbermonitors;i++) {
    1422:     PetscMonitorCompare((PetscErrorCode (*)(void))func,ctx,dest,(PetscErrorCode (*)(void))tao->monitor[i],tao->monitorcontext[i],tao->monitordestroy[i],&identical);
    1423:     if (identical) return(0);
    1424:   }
    1425:   tao->monitor[tao->numbermonitors] = func;
    1426:   tao->monitorcontext[tao->numbermonitors] = (void*)ctx;
    1427:   tao->monitordestroy[tao->numbermonitors] = dest;
    1428:   ++tao->numbermonitors;
    1429:   return(0);
    1430: }

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

    1435:    Logically Collective on Tao

    1437:    Input Parameters:
    1438: .  tao - the Tao solver context

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

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

    1448:    Level: advanced

    1450: .seealso: TaoMonitorDefault(), TaoSetMonitor()
    1451: @*/
    1452: PetscErrorCode TaoCancelMonitors(Tao tao)
    1453: {
    1454:   PetscInt       i;

    1459:   for (i=0;i<tao->numbermonitors;i++) {
    1460:     if (tao->monitordestroy[i]) {
    1461:       (*tao->monitordestroy[i])(&tao->monitorcontext[i]);
    1462:     }
    1463:   }
    1464:   tao->numbermonitors=0;
    1465:   return(0);
    1466: }

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

    1474:    Collective on Tao

    1476:    Input Parameters:
    1477: +  tao - the Tao context
    1478: -  ctx - PetscViewer context or NULL

    1480:    Options Database Keys:
    1481: .  -tao_monitor

    1483:    Level: advanced

    1485: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
    1486: @*/
    1487: PetscErrorCode TaoMonitorDefault(Tao tao, void *ctx)
    1488: {
    1490:   PetscInt       its, tabs;
    1491:   PetscReal      fct,gnorm;
    1492:   PetscViewer    viewer = (PetscViewer)ctx;

    1496:   its=tao->niter;
    1497:   fct=tao->fc;
    1498:   gnorm=tao->residual;
    1499:   PetscViewerASCIIGetTab(viewer, &tabs);
    1500:   PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
    1501:   if (its == 0 && ((PetscObject)tao)->prefix) {
    1502:      PetscViewerASCIIPrintf(viewer,"  Iteration information for %s solve.\n",((PetscObject)tao)->prefix);
    1503:    }
    1504:   ierr=PetscViewerASCIIPrintf(viewer,"%3D TAO,",its);
    1505:   ierr=PetscViewerASCIIPrintf(viewer,"  Function value: %g,",(double)fct);
    1506:   if (gnorm >= PETSC_INFINITY) {
    1507:     ierr=PetscViewerASCIIPrintf(viewer,"  Residual: Inf \n");
    1508:   } else {
    1509:     ierr=PetscViewerASCIIPrintf(viewer,"  Residual: %g \n",(double)gnorm);
    1510:   }
    1511:   PetscViewerASCIISetTab(viewer, tabs);
    1512:   return(0);
    1513: }
    1514:
    1515: /*@
    1516:    TaoDefaultGMonitor - Default routine for monitoring progress of the
    1517:    Tao solvers (default) with extra detail on the globalization method.
    1518:    This monitor prints the function value and gradient norm at each
    1519:    iteration, as well as the step size and trust radius. Note that the
    1520:    step size and trust radius may be the same for some algorithms.
    1521:    It can be turned on from the command line using the
    1522:    -tao_gmonitor option

    1524:    Collective on Tao

    1526:    Input Parameters:
    1527: +  tao - the Tao context
    1528: -  ctx - PetscViewer context or NULL

    1530:    Options Database Keys:
    1531: .  -tao_monitor

    1533:    Level: advanced

    1535: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
    1536: @*/
    1537: PetscErrorCode TaoDefaultGMonitor(Tao tao, void *ctx)
    1538: {
    1540:   PetscInt       its, tabs;
    1541:   PetscReal      fct,gnorm,stp,tr;
    1542:   PetscViewer    viewer = (PetscViewer)ctx;

    1546:   its=tao->niter;
    1547:   fct=tao->fc;
    1548:   gnorm=tao->residual;
    1549:   stp=tao->step;
    1550:   tr=tao->trust;
    1551:   PetscViewerASCIIGetTab(viewer, &tabs);
    1552:   PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
    1553:   if (its == 0 && ((PetscObject)tao)->prefix) {
    1554:      PetscViewerASCIIPrintf(viewer,"  Iteration information for %s solve.\n",((PetscObject)tao)->prefix);
    1555:    }
    1556:   ierr=PetscViewerASCIIPrintf(viewer,"%3D TAO,",its);
    1557:   ierr=PetscViewerASCIIPrintf(viewer,"  Function value: %g,",(double)fct);
    1558:   if (gnorm >= PETSC_INFINITY) {
    1559:     ierr=PetscViewerASCIIPrintf(viewer,"  Residual: Inf,");
    1560:   } else {
    1561:     ierr=PetscViewerASCIIPrintf(viewer,"  Residual: %g,",(double)gnorm);
    1562:   }
    1563:   PetscViewerASCIIPrintf(viewer,"  Step: %g,  Trust: %g\n",(double)stp,(double)tr);
    1564:   PetscViewerASCIISetTab(viewer, tabs);
    1565:   return(0);
    1566: }

    1568: /*@
    1569:    TaoDefaultSMonitor - Default routine for monitoring progress of the
    1570:    solver. Same as TaoMonitorDefault() except
    1571:    it prints fewer digits of the residual as the residual gets smaller.
    1572:    This is because the later digits are meaningless and are often
    1573:    different on different machines; by using this routine different
    1574:    machines will usually generate the same output. It can be turned on
    1575:    by using the -tao_smonitor option

    1577:    Collective on Tao

    1579:    Input Parameters:
    1580: +  tao - the Tao context
    1581: -  ctx - PetscViewer context of type ASCII

    1583:    Options Database Keys:
    1584: .  -tao_smonitor

    1586:    Level: advanced

    1588: .seealso: TaoMonitorDefault(), TaoSetMonitor()
    1589: @*/
    1590: PetscErrorCode TaoDefaultSMonitor(Tao tao, void *ctx)
    1591: {
    1593:   PetscInt       its, tabs;
    1594:   PetscReal      fct,gnorm;
    1595:   PetscViewer    viewer = (PetscViewer)ctx;

    1599:   its=tao->niter;
    1600:   fct=tao->fc;
    1601:   gnorm=tao->residual;
    1602:   PetscViewerASCIIGetTab(viewer, &tabs);
    1603:   PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
    1604:   ierr=PetscViewerASCIIPrintf(viewer,"iter = %3D,",its);
    1605:   ierr=PetscViewerASCIIPrintf(viewer," Function value %g,",(double)fct);
    1606:   if (gnorm >= PETSC_INFINITY) {
    1607:     ierr=PetscViewerASCIIPrintf(viewer," Residual: Inf \n");
    1608:   } else if (gnorm > 1.e-6) {
    1609:     ierr=PetscViewerASCIIPrintf(viewer," Residual: %g \n",(double)gnorm);
    1610:   } else if (gnorm > 1.e-11) {
    1611:     ierr=PetscViewerASCIIPrintf(viewer," Residual: < 1.0e-6 \n");
    1612:   } else {
    1613:     ierr=PetscViewerASCIIPrintf(viewer," Residual: < 1.0e-11 \n");
    1614:   }
    1615:   PetscViewerASCIISetTab(viewer, tabs);
    1616:   return(0);
    1617: }

    1619: /*@
    1620:    TaoDefaultCMonitor - same as TaoMonitorDefault() except
    1621:    it prints the norm of the constraints function. It can be turned on
    1622:    from the command line using the -tao_cmonitor option

    1624:    Collective on Tao

    1626:    Input Parameters:
    1627: +  tao - the Tao context
    1628: -  ctx - PetscViewer context or NULL

    1630:    Options Database Keys:
    1631: .  -tao_cmonitor

    1633:    Level: advanced

    1635: .seealso: TaoMonitorDefault(), TaoSetMonitor()
    1636: @*/
    1637: PetscErrorCode TaoDefaultCMonitor(Tao tao, void *ctx)
    1638: {
    1640:   PetscInt       its, tabs;
    1641:   PetscReal      fct,gnorm;
    1642:   PetscViewer    viewer = (PetscViewer)ctx;

    1646:   its=tao->niter;
    1647:   fct=tao->fc;
    1648:   gnorm=tao->residual;
    1649:   PetscViewerASCIIGetTab(viewer, &tabs);
    1650:   PetscViewerASCIISetTab(viewer, ((PetscObject)tao)->tablevel);
    1651:   ierr=PetscViewerASCIIPrintf(viewer,"iter = %D,",its);
    1652:   ierr=PetscViewerASCIIPrintf(viewer," Function value: %g,",(double)fct);
    1653:   ierr=PetscViewerASCIIPrintf(viewer,"  Residual: %g ",(double)gnorm);
    1654:   PetscViewerASCIIPrintf(viewer,"  Constraint: %g \n",(double)tao->cnorm);
    1655:   PetscViewerASCIISetTab(viewer, tabs);
    1656:   return(0);
    1657: }

    1659: /*@C
    1660:    TaoSolutionMonitor - Views the solution at each iteration
    1661:    It can be turned on from the command line using the
    1662:    -tao_view_solution option

    1664:    Collective on Tao

    1666:    Input Parameters:
    1667: +  tao - the Tao context
    1668: -  ctx - PetscViewer context or NULL

    1670:    Options Database Keys:
    1671: .  -tao_view_solution

    1673:    Level: advanced

    1675: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
    1676: @*/
    1677: PetscErrorCode TaoSolutionMonitor(Tao tao, void *ctx)
    1678: {
    1680:   PetscViewer    viewer  = (PetscViewer)ctx;;

    1684:   VecView(tao->solution, viewer);
    1685:   return(0);
    1686: }

    1688: /*@C
    1689:    TaoGradientMonitor - Views the gradient at each iteration
    1690:    It can be turned on from the command line using the
    1691:    -tao_view_gradient option

    1693:    Collective on Tao

    1695:    Input Parameters:
    1696: +  tao - the Tao context
    1697: -  ctx - PetscViewer context or NULL

    1699:    Options Database Keys:
    1700: .  -tao_view_gradient

    1702:    Level: advanced

    1704: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
    1705: @*/
    1706: PetscErrorCode TaoGradientMonitor(Tao tao, void *ctx)
    1707: {
    1709:   PetscViewer    viewer = (PetscViewer)ctx;

    1713:   VecView(tao->gradient, viewer);
    1714:   return(0);
    1715: }

    1717: /*@C
    1718:    TaoStepDirectionMonitor - Views the gradient at each iteration
    1719:    It can be turned on from the command line using the
    1720:    -tao_view_gradient option

    1722:    Collective on Tao

    1724:    Input Parameters:
    1725: +  tao - the Tao context
    1726: -  ctx - PetscViewer context or NULL

    1728:    Options Database Keys:
    1729: .  -tao_view_gradient

    1731:    Level: advanced

    1733: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
    1734: @*/
    1735: PetscErrorCode TaoStepDirectionMonitor(Tao tao, void *ctx)
    1736: {
    1738:   PetscViewer    viewer = (PetscViewer)ctx;

    1742:   VecView(tao->stepdirection, viewer);
    1743:   return(0);
    1744: }

    1746: /*@C
    1747:    TaoDrawSolutionMonitor - Plots the solution at each iteration
    1748:    It can be turned on from the command line using the
    1749:    -tao_draw_solution option

    1751:    Collective on Tao

    1753:    Input Parameters:
    1754: +  tao - the Tao context
    1755: -  ctx - TaoMonitorDraw context

    1757:    Options Database Keys:
    1758: .  -tao_draw_solution

    1760:    Level: advanced

    1762: .seealso: TaoSolutionMonitor(), TaoSetMonitor(), TaoDrawGradientMonitor
    1763: @*/
    1764: PetscErrorCode TaoDrawSolutionMonitor(Tao tao, void *ctx)
    1765: {
    1766:   PetscErrorCode    ierr;
    1767:   TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx;

    1770:   if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) return(0);
    1771:   VecView(tao->solution,ictx->viewer);
    1772:   return(0);
    1773: }

    1775: /*@C
    1776:    TaoDrawGradientMonitor - Plots the gradient at each iteration
    1777:    It can be turned on from the command line using the
    1778:    -tao_draw_gradient option

    1780:    Collective on Tao

    1782:    Input Parameters:
    1783: +  tao - the Tao context
    1784: -  ctx - PetscViewer context

    1786:    Options Database Keys:
    1787: .  -tao_draw_gradient

    1789:    Level: advanced

    1791: .seealso: TaoGradientMonitor(), TaoSetMonitor(), TaoDrawSolutionMonitor
    1792: @*/
    1793: PetscErrorCode TaoDrawGradientMonitor(Tao tao, void *ctx)
    1794: {
    1795:   PetscErrorCode    ierr;
    1796:   TaoMonitorDrawCtx ictx = (TaoMonitorDrawCtx)ctx;

    1799:   if (!(((ictx->howoften > 0) && (!(tao->niter % ictx->howoften))) || ((ictx->howoften == -1) && tao->reason))) return(0);
    1800:   VecView(tao->gradient,ictx->viewer);
    1801:   return(0);
    1802: }

    1804: /*@C
    1805:    TaoDrawStepMonitor - Plots the step direction at each iteration
    1806:    It can be turned on from the command line using the
    1807:    -tao_draw_step option

    1809:    Collective on Tao

    1811:    Input Parameters:
    1812: +  tao - the Tao context
    1813: -  ctx - PetscViewer context

    1815:    Options Database Keys:
    1816: .  -tao_draw_step

    1818:    Level: advanced

    1820: .seealso: TaoSetMonitor(), TaoDrawSolutionMonitor
    1821: @*/
    1822: PetscErrorCode TaoDrawStepMonitor(Tao tao, void *ctx)
    1823: {
    1825:   PetscViewer    viewer = (PetscViewer)(ctx);

    1828:   VecView(tao->stepdirection, viewer);
    1829:   return(0);
    1830: }

    1832: /*@C
    1833:    TaoSeparableObjectiveMonitor - Views the separable objective function at each iteration
    1834:    It can be turned on from the command line using the
    1835:    -tao_view_separableobjective option

    1837:    Collective on Tao

    1839:    Input Parameters:
    1840: +  tao - the Tao context
    1841: -  ctx - PetscViewer context or NULL

    1843:    Options Database Keys:
    1844: .  -tao_view_separableobjective

    1846:    Level: advanced

    1848: .seealso: TaoDefaultSMonitor(), TaoSetMonitor()
    1849: @*/
    1850: PetscErrorCode TaoSeparableObjectiveMonitor(Tao tao, void *ctx)
    1851: {
    1853:   PetscViewer    viewer  = (PetscViewer)ctx;

    1857:   VecView(tao->sep_objective,viewer);
    1858:   return(0);
    1859: }

    1861: /*@
    1862:    TaoDefaultConvergenceTest - Determines whether the solver should continue iterating
    1863:    or terminate.

    1865:    Collective on Tao

    1867:    Input Parameters:
    1868: +  tao - the Tao context
    1869: -  dummy - unused dummy context

    1871:    Output Parameter:
    1872: .  reason - for terminating

    1874:    Notes:
    1875:    This routine checks the residual in the optimality conditions, the
    1876:    relative residual in the optimity conditions, the number of function
    1877:    evaluations, and the function value to test convergence.  Some
    1878:    solvers may use different convergence routines.

    1880:    Level: developer

    1882: .seealso: TaoSetTolerances(),TaoGetConvergedReason(),TaoSetConvergedReason()
    1883: @*/

    1885: PetscErrorCode TaoDefaultConvergenceTest(Tao tao,void *dummy)
    1886: {
    1887:   PetscInt           niter=tao->niter, nfuncs=PetscMax(tao->nfuncs,tao->nfuncgrads);
    1888:   PetscInt           max_funcs=tao->max_funcs;
    1889:   PetscReal          gnorm=tao->residual, gnorm0=tao->gnorm0;
    1890:   PetscReal          f=tao->fc, steptol=tao->steptol,trradius=tao->step;
    1891:   PetscReal          gatol=tao->gatol,grtol=tao->grtol,gttol=tao->gttol;
    1892:   PetscReal          catol=tao->catol,crtol=tao->crtol;
    1893:   PetscReal          fmin=tao->fmin, cnorm=tao->cnorm;
    1894:   TaoConvergedReason reason=tao->reason;
    1895:   PetscErrorCode     ierr;

    1899:   if (reason != TAO_CONTINUE_ITERATING) {
    1900:     return(0);
    1901:   }

    1903:   if (PetscIsInfOrNanReal(f)) {
    1904:     PetscInfo(tao,"Failed to converged, function value is Inf or NaN\n");
    1905:     reason = TAO_DIVERGED_NAN;
    1906:   } else if (f <= fmin && cnorm <=catol) {
    1907:     PetscInfo2(tao,"Converged due to function value %g < minimum function value %g\n", (double)f,(double)fmin);
    1908:     reason = TAO_CONVERGED_MINF;
    1909:   } else if (gnorm<= gatol && cnorm <=catol) {
    1910:     PetscInfo2(tao,"Converged due to residual norm ||g(X)||=%g < %g\n",(double)gnorm,(double)gatol);
    1911:     reason = TAO_CONVERGED_GATOL;
    1912:   } else if ( f!=0 && PetscAbsReal(gnorm/f) <= grtol && cnorm <= crtol) {
    1913:     PetscInfo2(tao,"Converged due to residual ||g(X)||/|f(X)| =%g < %g\n",(double)(gnorm/f),(double)grtol);
    1914:     reason = TAO_CONVERGED_GRTOL;
    1915:   } else if (gnorm0 != 0 && ((gttol == 0 && gnorm == 0) || gnorm/gnorm0 < gttol) && cnorm <= crtol) {
    1916:     PetscInfo2(tao,"Converged due to relative residual norm ||g(X)||/||g(X0)|| = %g < %g\n",(double)(gnorm/gnorm0),(double)gttol);
    1917:     reason = TAO_CONVERGED_GTTOL;
    1918:   } else if (nfuncs > max_funcs){
    1919:     PetscInfo2(tao,"Exceeded maximum number of function evaluations: %D > %D\n", nfuncs,max_funcs);
    1920:     reason = TAO_DIVERGED_MAXFCN;
    1921:   } else if ( tao->lsflag != 0 ){
    1922:     PetscInfo(tao,"Tao Line Search failure.\n");
    1923:     reason = TAO_DIVERGED_LS_FAILURE;
    1924:   } else if (trradius < steptol && niter > 0){
    1925:     PetscInfo2(tao,"Trust region/step size too small: %g < %g\n", (double)trradius,(double)steptol);
    1926:     reason = TAO_CONVERGED_STEPTOL;
    1927:   } else if (niter >= tao->max_it) {
    1928:     PetscInfo2(tao,"Exceeded maximum number of iterations: %D > %D\n",niter,tao->max_it);
    1929:     reason = TAO_DIVERGED_MAXITS;
    1930:   } else {
    1931:     reason = TAO_CONTINUE_ITERATING;
    1932:   }
    1933:   tao->reason = reason;
    1934:   return(0);
    1935: }

    1937: /*@C
    1938:    TaoSetOptionsPrefix - Sets the prefix used for searching for all
    1939:    TAO options in the database.

    1942:    Logically Collective on Tao

    1944:    Input Parameters:
    1945: +  tao - the Tao context
    1946: -  prefix - the prefix string to prepend to all TAO option requests

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

    1952:    For example, to distinguish between the runtime options for two
    1953:    different TAO solvers, one could call
    1954: .vb
    1955:       TaoSetOptionsPrefix(tao1,"sys1_")
    1956:       TaoSetOptionsPrefix(tao2,"sys2_")
    1957: .ve

    1959:    This would enable use of different options for each system, such as
    1960: .vb
    1961:       -sys1_tao_method blmvm -sys1_tao_gtol 1.e-3
    1962:       -sys2_tao_method lmvm  -sys2_tao_gtol 1.e-4
    1963: .ve

    1966:    Level: advanced

    1968: .seealso: TaoAppendOptionsPrefix(), TaoGetOptionsPrefix()
    1969: @*/

    1971: PetscErrorCode TaoSetOptionsPrefix(Tao tao, const char p[])
    1972: {

    1976:   PetscObjectSetOptionsPrefix((PetscObject)tao,p);
    1977:   if (tao->linesearch) {
    1978:     TaoLineSearchSetOptionsPrefix(tao->linesearch,p);
    1979:   }
    1980:   if (tao->ksp) {
    1981:     KSPSetOptionsPrefix(tao->ksp,p);
    1982:   }
    1983:   return(0);
    1984: }

    1986: /*@C
    1987:    TaoAppendOptionsPrefix - Appends to the prefix used for searching for all
    1988:    TAO options in the database.

    1991:    Logically Collective on Tao

    1993:    Input Parameters:
    1994: +  tao - the Tao solver context
    1995: -  prefix - the prefix string to prepend to all TAO option requests

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

    2002:    Level: advanced

    2004: .seealso: TaoSetOptionsPrefix(), TaoGetOptionsPrefix()
    2005: @*/
    2006: PetscErrorCode TaoAppendOptionsPrefix(Tao tao, const char p[])
    2007: {

    2011:   PetscObjectAppendOptionsPrefix((PetscObject)tao,p);
    2012:   if (tao->linesearch) {
    2013:     TaoLineSearchSetOptionsPrefix(tao->linesearch,p);
    2014:   }
    2015:   if (tao->ksp) {
    2016:     KSPSetOptionsPrefix(tao->ksp,p);
    2017:   }
    2018:   return(0);
    2019: }

    2021: /*@C
    2022:   TaoGetOptionsPrefix - Gets the prefix used for searching for all
    2023:   TAO options in the database

    2025:   Not Collective

    2027:   Input Parameters:
    2028: . tao - the Tao context

    2030:   Output Parameters:
    2031: . prefix - pointer to the prefix string used is returned

    2033:   Notes:
    2034:     On the fortran side, the user should pass in a string 'prefix' of
    2035:   sufficient length to hold the prefix.

    2037:   Level: advanced

    2039: .seealso: TaoSetOptionsPrefix(), TaoAppendOptionsPrefix()
    2040: @*/
    2041: PetscErrorCode TaoGetOptionsPrefix(Tao tao, const char *p[])
    2042: {
    2043:    return PetscObjectGetOptionsPrefix((PetscObject)tao,p);
    2044: }

    2046: /*@C
    2047:    TaoSetType - Sets the method for the unconstrained minimization solver.

    2049:    Collective on Tao

    2051:    Input Parameters:
    2052: +  solver - the Tao solver context
    2053: -  type - a known method

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

    2059:    Available methods include:
    2060: +    nls - Newton's method with line search for unconstrained minimization
    2061: .    ntr - Newton's method with trust region for unconstrained minimization
    2062: .    ntl - Newton's method with trust region, line search for unconstrained minimization
    2063: .    lmvm - Limited memory variable metric method for unconstrained minimization
    2064: .    cg - Nonlinear conjugate gradient method for unconstrained minimization
    2065: .    nm - Nelder-Mead algorithm for derivate-free unconstrained minimization
    2066: .    tron - Newton Trust Region method for bound constrained minimization
    2067: .    gpcg - Newton Trust Region method for quadratic bound constrained minimization
    2068: .    blmvm - Limited memory variable metric method for bound constrained minimization
    2069: -    pounders - Model-based algorithm pounder extended for nonlinear least squares

    2071:   Level: intermediate

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

    2075: @*/
    2076: PetscErrorCode TaoSetType(Tao tao, TaoType type)
    2077: {
    2079:   PetscErrorCode (*create_xxx)(Tao);
    2080:   PetscBool      issame;

    2085:   PetscObjectTypeCompare((PetscObject)tao,type,&issame);
    2086:   if (issame) return(0);

    2088:   PetscFunctionListFind(TaoList, type, (void(**)(void))&create_xxx);
    2089:   if (!create_xxx) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Tao type %s",type);

    2091:   /* Destroy the existing solver information */
    2092:   if (tao->ops->destroy) {
    2093:     (*tao->ops->destroy)(tao);
    2094:   }
    2095:   KSPDestroy(&tao->ksp);
    2096:   TaoLineSearchDestroy(&tao->linesearch);
    2097:   VecDestroy(&tao->gradient);
    2098:   VecDestroy(&tao->stepdirection);

    2100:   tao->ops->setup = 0;
    2101:   tao->ops->solve = 0;
    2102:   tao->ops->view  = 0;
    2103:   tao->ops->setfromoptions = 0;
    2104:   tao->ops->destroy = 0;

    2106:   tao->setupcalled = PETSC_FALSE;

    2108:   (*create_xxx)(tao);
    2109:   PetscObjectChangeTypeName((PetscObject)tao,type);
    2110:   return(0);
    2111: }

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

    2116:    Synopsis:
    2117:    TaoRegister(char *name_solver,char *path,char *name_Create,int (*routine_Create)(Tao))

    2119:    Not collective

    2121:    Input Parameters:
    2122: +  sname - name of a new user-defined solver
    2123: -  func - routine to Create method context

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

    2128:    Sample usage:
    2129: .vb
    2130:    TaoRegister("my_solver",MySolverCreate);
    2131: .ve

    2133:    Then, your solver can be chosen with the procedural interface via
    2134: $     TaoSetType(tao,"my_solver")
    2135:    or at runtime via the option
    2136: $     -tao_type my_solver

    2138:    Level: advanced

    2140: .seealso: TaoRegisterAll(), TaoRegisterDestroy()
    2141: M*/
    2142: PetscErrorCode TaoRegister(const char sname[], PetscErrorCode (*func)(Tao))
    2143: {

    2147:   TaoInitializePackage();
    2148:   PetscFunctionListAdd(&TaoList,sname, (void (*)(void))func);
    2149:   return(0);
    2150: }

    2152: /*@C
    2153:    TaoRegisterDestroy - Frees the list of minimization solvers that were
    2154:    registered by TaoRegisterDynamic().

    2156:    Not Collective

    2158:    Level: advanced

    2160: .seealso: TaoRegisterAll(), TaoRegister()
    2161: @*/
    2162: PetscErrorCode TaoRegisterDestroy(void)
    2163: {
    2166:   PetscFunctionListDestroy(&TaoList);
    2167:   TaoRegisterAllCalled = PETSC_FALSE;
    2168:   return(0);
    2169: }

    2171: /*@
    2172:    TaoGetIterationNumber - Gets the number of Tao iterations completed
    2173:    at this time.

    2175:    Not Collective

    2177:    Input Parameter:
    2178: .  tao - Tao context

    2180:    Output Parameter:
    2181: .  iter - iteration number

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

    2187:    Level: intermediate

    2189: .keywords: Tao, nonlinear, get, iteration, number,

    2191: .seealso:   TaoGetLinearSolveIterations(), TaoGetResidualNorm(), TaoGetObjective()
    2192: @*/
    2193: PetscErrorCode  TaoGetIterationNumber(Tao tao,PetscInt *iter)
    2194: {
    2198:   *iter = tao->niter;
    2199:   return(0);
    2200: }

    2202: /*@
    2203:    TaoGetObjective - Gets the current value of the objective function
    2204:    at this time.

    2206:    Not Collective

    2208:    Input Parameter:
    2209: .  tao - Tao context

    2211:    Output Parameter:
    2212: .  value - the current value

    2214:    Level: intermediate

    2216: .keywords: Tao, nonlinear, get, iteration, number,

    2218: .seealso:   TaoGetLinearSolveIterations(), TaoGetIterationNumber(), TaoGetResidualNorm()
    2219: @*/
    2220: PetscErrorCode  TaoGetObjective(Tao tao,PetscReal *value)
    2221: {
    2225:   *value = tao->fc;
    2226:   return(0);
    2227: }

    2229: /*@
    2230:    TaoGetResidualNorm - Gets the current value of the norm of the residual
    2231:    at this time.

    2233:    Not Collective

    2235:    Input Parameter:
    2236: .  tao - Tao context

    2238:    Output Parameter:
    2239: .  value - the current value

    2241:    Level: intermediate

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

    2246: .keywords: Tao, nonlinear, get, iteration, number,

    2248: .seealso:   TaoGetLinearSolveIterations(), TaoGetIterationNumber(), TaoGetObjective()
    2249: @*/
    2250: PetscErrorCode  TaoGetResidualNorm(Tao tao,PetscReal *value)
    2251: {
    2255:   *value = tao->residual;
    2256:   return(0);
    2257: }

    2259: /*@
    2260:    TaoSetIterationNumber - Sets the current iteration number.

    2262:    Not Collective

    2264:    Input Parameter:
    2265: .  tao - Tao context
    2266: .  iter - iteration number

    2268:    Level: developer

    2270: .keywords: Tao, nonlinear, set, iteration, number,

    2272: .seealso:   TaoGetLinearSolveIterations()
    2273: @*/
    2274: PetscErrorCode  TaoSetIterationNumber(Tao tao,PetscInt iter)
    2275: {

    2280:   PetscObjectSAWsTakeAccess((PetscObject)tao);
    2281:   tao->niter = iter;
    2282:   PetscObjectSAWsGrantAccess((PetscObject)tao);
    2283:   return(0);
    2284: }

    2286: /*@
    2287:    TaoGetTotalIterationNumber - Gets the total number of Tao iterations
    2288:    completed. This number keeps accumulating if multiple solves
    2289:    are called with the Tao object.

    2291:    Not Collective

    2293:    Input Parameter:
    2294: .  tao - Tao context

    2296:    Output Parameter:
    2297: .  iter - iteration number

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

    2303:    Level: intermediate

    2305: .keywords: Tao, nonlinear, get, iteration, number,

    2307: .seealso:   TaoGetLinearSolveIterations()
    2308: @*/
    2309: PetscErrorCode  TaoGetTotalIterationNumber(Tao tao,PetscInt *iter)
    2310: {
    2314:   *iter = tao->ntotalits;
    2315:   return(0);
    2316: }

    2318: /*@
    2319:    TaoSetTotalIterationNumber - Sets the current total iteration number.

    2321:    Not Collective

    2323:    Input Parameter:
    2324: .  tao - Tao context
    2325: .  iter - iteration number

    2327:    Level: developer

    2329: .keywords: Tao, nonlinear, set, iteration, number,

    2331: .seealso:   TaoGetLinearSolveIterations()
    2332: @*/
    2333: PetscErrorCode  TaoSetTotalIterationNumber(Tao tao,PetscInt iter)
    2334: {

    2339:   PetscObjectSAWsTakeAccess((PetscObject)tao);
    2340:   tao->ntotalits = iter;
    2341:   PetscObjectSAWsGrantAccess((PetscObject)tao);
    2342:   return(0);
    2343: }

    2345: /*@
    2346:   TaoSetConvergedReason - Sets the termination flag on a Tao object

    2348:   Logically Collective on Tao

    2350:   Input Parameters:
    2351: + tao - the Tao context
    2352: - reason - one of
    2353: $     TAO_CONVERGED_ATOL (2),
    2354: $     TAO_CONVERGED_RTOL (3),
    2355: $     TAO_CONVERGED_STEPTOL (4),
    2356: $     TAO_CONVERGED_MINF (5),
    2357: $     TAO_CONVERGED_USER (6),
    2358: $     TAO_DIVERGED_MAXITS (-2),
    2359: $     TAO_DIVERGED_NAN (-4),
    2360: $     TAO_DIVERGED_MAXFCN (-5),
    2361: $     TAO_DIVERGED_LS_FAILURE (-6),
    2362: $     TAO_DIVERGED_TR_REDUCTION (-7),
    2363: $     TAO_DIVERGED_USER (-8),
    2364: $     TAO_CONTINUE_ITERATING (0)

    2366:    Level: intermediate

    2368: @*/
    2369: PetscErrorCode TaoSetConvergedReason(Tao tao, TaoConvergedReason reason)
    2370: {
    2373:   tao->reason = reason;
    2374:   return(0);
    2375: }

    2377: /*@
    2378:    TaoGetConvergedReason - Gets the reason the Tao iteration was stopped.

    2380:    Not Collective

    2382:    Input Parameter:
    2383: .  tao - the Tao solver context

    2385:    Output Parameter:
    2386: .  reason - one of
    2387: $  TAO_CONVERGED_GATOL (3)           ||g(X)|| < gatol
    2388: $  TAO_CONVERGED_GRTOL (4)           ||g(X)|| / f(X)  < grtol
    2389: $  TAO_CONVERGED_GTTOL (5)           ||g(X)|| / ||g(X0)|| < gttol
    2390: $  TAO_CONVERGED_STEPTOL (6)         step size small
    2391: $  TAO_CONVERGED_MINF (7)            F < F_min
    2392: $  TAO_CONVERGED_USER (8)            User defined
    2393: $  TAO_DIVERGED_MAXITS (-2)          its > maxits
    2394: $  TAO_DIVERGED_NAN (-4)             Numerical problems
    2395: $  TAO_DIVERGED_MAXFCN (-5)          fevals > max_funcsals
    2396: $  TAO_DIVERGED_LS_FAILURE (-6)      line search failure
    2397: $  TAO_DIVERGED_TR_REDUCTION (-7)    trust region failure
    2398: $  TAO_DIVERGED_USER(-8)             (user defined)
    2399:  $  TAO_CONTINUE_ITERATING (0)

    2401:    where
    2402: +  X - current solution
    2403: .  X0 - initial guess
    2404: .  f(X) - current function value
    2405: .  f(X*) - true solution (estimated)
    2406: .  g(X) - current gradient
    2407: .  its - current iterate number
    2408: .  maxits - maximum number of iterates
    2409: .  fevals - number of function evaluations
    2410: -  max_funcsals - maximum number of function evaluations

    2412:    Level: intermediate

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

    2416: @*/
    2417: PetscErrorCode TaoGetConvergedReason(Tao tao, TaoConvergedReason *reason)
    2418: {
    2422:   *reason = tao->reason;
    2423:   return(0);
    2424: }

    2426: /*@
    2427:   TaoGetSolutionStatus - Get the current iterate, objective value,
    2428:   residual, infeasibility, and termination

    2430:   Not Collective

    2432:    Input Parameters:
    2433: .  tao - the Tao context

    2435:    Output Parameters:
    2436: +  iterate - the current iterate number (>=0)
    2437: .  f - the current function value
    2438: .  gnorm - the square of the gradient norm, duality gap, or other measure indicating distance from optimality.
    2439: .  cnorm - the infeasibility of the current solution with regard to the constraints.
    2440: .  xdiff - the step length or trust region radius of the most recent iterate.
    2441: -  reason - The termination reason, which can equal TAO_CONTINUE_ITERATING

    2443:    Level: intermediate

    2445:    Note:
    2446:    TAO returns the values set by the solvers in the routine TaoMonitor().

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

    2451: .seealso: TaoMonitor(), TaoGetConvergedReason()
    2452: @*/
    2453: PetscErrorCode TaoGetSolutionStatus(Tao tao, PetscInt *its, PetscReal *f, PetscReal *gnorm, PetscReal *cnorm, PetscReal *xdiff, TaoConvergedReason *reason)
    2454: {
    2456:   if (its) *its=tao->niter;
    2457:   if (f) *f=tao->fc;
    2458:   if (gnorm) *gnorm=tao->residual;
    2459:   if (cnorm) *cnorm=tao->cnorm;
    2460:   if (reason) *reason=tao->reason;
    2461:   if (xdiff) *xdiff=tao->step;
    2462:   return(0);
    2463: }

    2465: /*@C
    2466:    TaoGetType - Gets the current Tao algorithm.

    2468:    Not Collective

    2470:    Input Parameter:
    2471: .  tao - the Tao solver context

    2473:    Output Parameter:
    2474: .  type - Tao method

    2476:    Level: intermediate

    2478: @*/
    2479: PetscErrorCode TaoGetType(Tao tao,TaoType *type)
    2480: {
    2484:   *type=((PetscObject)tao)->type_name;
    2485:   return(0);
    2486: }

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

    2493:    Input Parameters:
    2494: +  tao - the Tao context
    2495: .  its - the current iterate number (>=0)
    2496: .  f - the current objective function value
    2497: .  res - the gradient norm, square root of the duality gap, or other measure indicating distince from optimality.  This measure will be recorded and
    2498:           used for some termination tests.
    2499: .  cnorm - the infeasibility of the current solution with regard to the constraints.
    2500: -  steplength - multiple of the step direction added to the previous iterate.

    2502:    Output Parameters:
    2503: .  reason - The termination reason, which can equal TAO_CONTINUE_ITERATING

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

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

    2510:    Level: developer

    2512: @*/
    2513: PetscErrorCode TaoMonitor(Tao tao, PetscInt its, PetscReal f, PetscReal res, PetscReal cnorm, PetscReal steplength)
    2514: {
    2516:   PetscInt       i;

    2520:   tao->fc = f;
    2521:   tao->residual = res;
    2522:   tao->cnorm = cnorm;
    2523:   tao->step = steplength;
    2524:   if (!its) {
    2525:     tao->cnorm0 = cnorm; tao->gnorm0 = res;
    2526:   }
    2527:   if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(res)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN");
    2528:   for (i=0;i<tao->numbermonitors;i++) {
    2529:     (*tao->monitor[i])(tao,tao->monitorcontext[i]);
    2530:   }
    2531:   return(0);
    2532: }

    2534: /*@
    2535:    TaoSetConvergenceHistory - Sets the array used to hold the convergence history.

    2537:    Logically Collective on Tao

    2539:    Input Parameters:
    2540: +  tao - the Tao solver context
    2541: .  obj   - array to hold objective value history
    2542: .  resid - array to hold residual history
    2543: .  cnorm - array to hold constraint violation history
    2544: .  lits - integer array holds the number of linear iterations for each Tao iteration
    2545: .  na  - size of obj, resid, and cnorm
    2546: -  reset - PetscTrue indicates each new minimization resets the history counter to zero,
    2547:            else it continues storing new values for new minimizations after the old ones

    2549:    Notes:
    2550:    If set, TAO will fill the given arrays with the indicated
    2551:    information at each iteration.  If 'obj','resid','cnorm','lits' are
    2552:    *all* NULL then space (using size na, or 1000 if na is PETSC_DECIDE or
    2553:    PETSC_DEFAULT) is allocated for the history.
    2554:    If not all are NULL, then only the non-NULL information categories
    2555:    will be stored, the others will be ignored.

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

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

    2563:    Level: intermediate

    2565: .seealso: TaoGetConvergenceHistory()

    2567: @*/
    2568: PetscErrorCode TaoSetConvergenceHistory(Tao tao, PetscReal obj[], PetscReal resid[], PetscReal cnorm[], PetscInt lits[], PetscInt na,PetscBool reset)
    2569: {

    2579:   if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
    2580:   if (!obj && !resid && !cnorm && !lits) {
    2581:     PetscCalloc1(na,&obj);
    2582:     PetscCalloc1(na,&resid);
    2583:     PetscCalloc1(na,&cnorm);
    2584:     PetscCalloc1(na,&lits);
    2585:     tao->hist_malloc=PETSC_TRUE;
    2586:   }

    2588:   tao->hist_obj = obj;
    2589:   tao->hist_resid = resid;
    2590:   tao->hist_cnorm = cnorm;
    2591:   tao->hist_lits = lits;
    2592:   tao->hist_max   = na;
    2593:   tao->hist_reset = reset;
    2594:   tao->hist_len = 0;
    2595:   return(0);
    2596: }

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

    2601:    Collective on Tao

    2603:    Input Parameter:
    2604: .  tao - the Tao context

    2606:    Output Parameters:
    2607: +  obj   - array used to hold objective value history
    2608: .  resid - array used to hold residual history
    2609: .  cnorm - array used to hold constraint violation history
    2610: .  lits  - integer array used to hold linear solver iteration count
    2611: -  nhist  - size of obj, resid, cnorm, and lits (will be less than or equal to na given in TaoSetHistory)

    2613:    Notes:
    2614:     This routine must be preceded by calls to TaoSetConvergenceHistory()
    2615:     and TaoSolve(), otherwise it returns useless information.

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

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

    2624:    Level: advanced

    2626: .seealso: TaoSetConvergenceHistory()

    2628: @*/
    2629: PetscErrorCode TaoGetConvergenceHistory(Tao tao, PetscReal **obj, PetscReal **resid, PetscReal **cnorm, PetscInt **lits, PetscInt *nhist)
    2630: {
    2633:   if (obj)   *obj   = tao->hist_obj;
    2634:   if (cnorm) *cnorm = tao->hist_cnorm;
    2635:   if (resid) *resid = tao->hist_resid;
    2636:   if (nhist) *nhist   = tao->hist_len;
    2637:   return(0);
    2638: }

    2640: /*@
    2641:    TaoSetApplicationContext - Sets the optional user-defined context for
    2642:    a solver.

    2644:    Logically Collective on Tao

    2646:    Input Parameters:
    2647: +  tao  - the Tao context
    2648: -  usrP - optional user context

    2650:    Level: intermediate

    2652: .seealso: TaoGetApplicationContext(), TaoSetApplicationContext()
    2653: @*/
    2654: PetscErrorCode  TaoSetApplicationContext(Tao tao,void *usrP)
    2655: {
    2658:   tao->user = usrP;
    2659:   return(0);
    2660: }

    2662: /*@
    2663:    TaoGetApplicationContext - Gets the user-defined context for a
    2664:    TAO solvers.

    2666:    Not Collective

    2668:    Input Parameter:
    2669: .  tao  - Tao context

    2671:    Output Parameter:
    2672: .  usrP - user context

    2674:    Level: intermediate

    2676: .seealso: TaoSetApplicationContext()
    2677: @*/
    2678: PetscErrorCode  TaoGetApplicationContext(Tao tao,void *usrP)
    2679: {
    2682:   *(void**)usrP = tao->user;
    2683:   return(0);
    2684: }

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

    2689:    Collective on tao

    2691:    Input Parameters:
    2692: +  tao  - the Tao context
    2693: -  M    - gradient norm

    2695:    Level: beginner

    2697: .seealso: TaoGetGradientNorm(), TaoGradientNorm()
    2698: @*/
    2699: PetscErrorCode  TaoSetGradientNorm(Tao tao, Mat M)
    2700: {

    2706:   if (tao->gradient_norm) {
    2707:     PetscObjectDereference((PetscObject)tao->gradient_norm);
    2708:     VecDestroy(&tao->gradient_norm_tmp);
    2709:   }

    2711:   PetscObjectReference((PetscObject)M);
    2712:   tao->gradient_norm = M;
    2713:   MatCreateVecs(M, NULL, &tao->gradient_norm_tmp);
    2714:   return(0);
    2715: }

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

    2720:    Not Collective

    2722:    Input Parameter:
    2723: .  tao  - Tao context

    2725:    Output Parameter:
    2726: .  M - gradient norm

    2728:    Level: beginner

    2730: .seealso: TaoSetGradientNorm(), TaoGradientNorm()
    2731: @*/
    2732: PetscErrorCode  TaoGetGradientNorm(Tao tao, Mat *M)
    2733: {
    2736:   *M = tao->gradient_norm;
    2737:   return(0);
    2738: }

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

    2743:    Collective on tao

    2745:    Input Parameter:
    2746: .  tao      - the Tao context
    2747: .  gradient - the gradient to be computed
    2748: .  norm     - the norm type

    2750:    Output Parameter:
    2751: .  gnorm    - the gradient norm

    2753:    Level: developer

    2755: .seealso: TaoSetGradientNorm(), TaoGetGradientNorm()
    2756: @*/
    2757: PetscErrorCode  TaoGradientNorm(Tao tao, Vec gradient, NormType type, PetscReal *gnorm)
    2758: {

    2764:   if (tao->gradient_norm) {
    2765:     PetscScalar gnorms;

    2767:     if (type != NORM_2) SETERRQ(PetscObjectComm((PetscObject)gradient), PETSC_ERR_ARG_WRONGSTATE, "Norm type must be NORM_2 if an inner product for the gradient norm is set.");
    2768:     MatMult(tao->gradient_norm, gradient, tao->gradient_norm_tmp);
    2769:     VecDot(gradient, tao->gradient_norm_tmp, &gnorms);
    2770:     *gnorm = PetscRealPart(PetscSqrtScalar(gnorms));
    2771:   } else {
    2772:     VecNorm(gradient, type, gnorm);
    2773:   }
    2774:   return(0);
    2775: }

    2777: /*@C
    2778:    TaoMonitorDrawCtxCreate - Creates the monitor context for TaoMonitorDrawCtx

    2780:    Collective on Tao

    2782:    Output Patameter:
    2783: .    ctx - the monitor context

    2785:    Options Database:
    2786: .   -tao_draw_solution_initial - show initial guess as well as current solution

    2788:    Level: intermediate

    2790: .keywords: Tao,  vector, monitor, view

    2792: .seealso: TaoMonitorSet(), TaoMonitorDefault(), VecView(), TaoMonitorDrawCtx()
    2793: @*/
    2794: PetscErrorCode  TaoMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TaoMonitorDrawCtx *ctx)
    2795: {
    2796:   PetscErrorCode   ierr;

    2799:   PetscNew(ctx);
    2800:   PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);
    2801:   PetscViewerSetFromOptions((*ctx)->viewer);
    2802:   (*ctx)->howoften = howoften;
    2803:   return(0);
    2804: }

    2806: /*@C
    2807:    TaoMonitorDrawCtxDestroy - Destroys the monitor context for TaoMonitorDrawSolution()

    2809:    Collective on Tao

    2811:    Input Parameters:
    2812: .    ctx - the monitor context

    2814:    Level: intermediate

    2816: .keywords: Tao,  vector, monitor, view

    2818: .seealso: TaoMonitorSet(), TaoMonitorDefault(), VecView(), TaoMonitorDrawSolution()
    2819: @*/
    2820: PetscErrorCode  TaoMonitorDrawCtxDestroy(TaoMonitorDrawCtx *ictx)
    2821: {

    2825:   PetscViewerDestroy(&(*ictx)->viewer);
    2826:   PetscFree(*ictx);
    2827:   return(0);
    2828: }