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: }