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